I'm trying to implement a way to detect hovering gesture on Chart
in SwiftUI.
At first I tried adding .onHover()
modifier to BarMark
like below, but it seems it doesn't work because BarMark
does not conform to View
Protocol while .onHover()
is defined View
.
Chart(modules) { module in
BarMark(x: .value("name", module.name), y: .value("Score", module.score)).onHover { over in
details = module.name
} // gives error
}
So does that mean If I want to show additional data when user hover over the Chart graph, then I have to create my own Chart graph rather than using Chart
from Charts
framework?
You could try this approach, using an .chartOverlay
and .onContinuousHover
. You will have to adjust the location calculations to suit your purpose.
struct ContentView: View {
let measurement: [Measurement] = [
Measurement(id: "1", val: 11.2),
Measurement(id: "2", val: 22.2),
Measurement(id: "3", val: 38.2)
]
@State var select = "0"
@State var isHovering = false
var body: some View {
Chart {
ForEach(measurement) { data in
BarMark(x: .value("Time", data.id), y: .value("val", data.val))
.foregroundStyle(select == data.id ? .blue : .red)
}
}
.chartOverlay { proxy in
GeometryReader { geometry in
ZStack(alignment: .top) {
Rectangle().fill(.clear).contentShape(Rectangle())
.onContinuousHover { phase in
switch phase {
case .active(let location):
bar(at: location, proxy: proxy, geometry: geometry)
isHovering = true
case .ended:
isHovering = false
}
}
}
}
}
}
func bar(at location: CGPoint, proxy: ChartProxy, geometry: GeometryProxy) {
let xPosition = location.x - geometry[proxy.plotAreaFrame].origin.x
let yPosition = location.y - geometry[proxy.plotAreaFrame].origin.y
guard let month: String = proxy.value(atX: xPosition) else { return }
guard let measure: Double = proxy.value(atY: yPosition) else { return }
// more logic here ....
select = month
}
}
struct Measurement: Identifiable {
var id: String
var val: Double
}
If you want to just tap on the BarMarks
, see my other answer at: How to change the color of BarView in SwiftUI charts when we tap on it
Try to create a custom view that wraps the BarMark
and conforms to the View
protocol, and then add the onHover() modifier to this custom view.
Alternatively, you could create your own chart using a combination of SwiftUI views and gesture recognizers, and use the onHover()
modifier or a HoverGesture
to detect when the user is hovering over a specific area of the chart.
In any case, you would have to create your own chart, which would involve more work, but it would also give you more control over the appearance and behavior of the chart.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.