I can draw a bar chart using Swift Charts framework.
Now I want to perform 2 actions in below bar chart.
- Action on tap on green bar
- Action on tap on X axis red highlighted rectangle area with label text
I have used tap gesture but it’s not working on tapping point 2 area.
import SwiftUI
import Charts
struct Item: Identifiable {
let id = UUID()
let month: String
let revenue: Double
let visits: Double
}
struct TapChart: View {
let items: [Item] = [
Item(month: "Jan", revenue: 100, visits: 2),
Item(month: "Feb", revenue: 200, visits: 1),
Item(month: "Mar", revenue: 150, visits: 4),
Item(month: "Apr", revenue: 130, visits: 0),
Item(month: "May", revenue: 300, visits: 3),
Item(month: "Jun", revenue: 50, visits: 2)
]
var myItems = [Item]()
var body: some View {
Chart {
ForEach(items) { items in
BarMark(
x: .value("Month", items.month),
y: .value("Revenue", items.revenue)
)
.foregroundStyle(Color.green.gradient)
}
}
.chartForegroundStyleScale([
"SEO Revenue" : Color(.green),
"Visits": Color(.purple)
])
.chartLegend(position: .top, alignment: .bottomTrailing)
.chartXAxis {
AxisMarks { axis in
AxisValueLabel(centered: true) {
Text("(items[axis.index].month)")
.font(.system(size: 12, weight: .bold))
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(Color.red.opacity(0.3))
.cornerRadius(4)
.onTapGesture {
print("(items[axis.index].month)")
}
}
}
}
.chartYAxis(.visible)
.padding()
.cornerRadius(15)
.frame(height: 300)
}
}
Thanks in advance.
2
Answers
I think you would have to reinvent your own axis marks with a
chartOverlay
To prevent the labels to be clipped by the plot area, you should also add some bottom padding:
As for detecting taps on the bars, you can do:
In iOS 17, Apple introduced a native way to handle selections in charts using chartXSelection. This makes it easier to create interactive visualizations without custom handling.