iosswiftswiftuihealthkitswiftui-charts

SwiftUI Charts BarMark aligning annotation to top of chart


I'm trying out Swifts Charts. I am trying to align the annotation to the top of the chart, but I am not able to do it.

What I am trying to achieve is something like this: enter image description here

But this is done with HStack on top of the chart, and it does not align 100%. So instead I am using the annotations modifier. The result is this:

enter image description here

But as you can see, the values are directly on top of the bar, which is not the result I am looking for.

The code used for the annotations is here:

.annotation {
   Text("\(Int(item.price))")
     .font(.system(size: 8))
     .rotationEffect(.degrees(270))
     .padding()
 }

I have tried to add in a VStack, put in the Text and a Spacer underneath, but that did not help. I also tried with:

.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)

But that did not help either.

Hope you guys can help me you here :) Thanks in advance.


Solution

  • You can use .annotation(position: .overlay, alignment: .bottom) which gives you an annotation overlay over the mark that starts at the bottom of the mark.

    enter image description here

    Here is an example:

    struct ContentView: View {
    
        let data: [(Int, Int)] = {
            (0...20).map { ($0, Int.random(in: 0...500)) }
        }()
    
        @State private var selectedX = 6
        
        var body: some View {
            
            VStack {
                Chart {
                    ForEach(data.indices, id: \.self) { i in
                        let (x,y) = data[i]
                        BarMark(
                            x: .value("x", x),
                            y: .value("y", y)
                        )
                        .annotation(position: .overlay, alignment: .bottom, spacing: 0) {
                            Text("\(y)")
                                .font(.system(size: 8))
                                .frame(width: 570 , alignment: .trailing)
                                .rotationEffect(.degrees(-90))
                        }
                    }
                }
                .chartXScale(domain: 0...20)
                .chartYScale(domain: 0...550)
                .chartYAxis(.hidden)
                .frame(height: 300)
             
            }
            .padding()
        }
    }