如何让Swift Charts的X轴区域响应chartXSelection点击?
实现SwiftUI Chart的X轴点击选择功能
问题描述
希望让SwiftUI的chartXSelection(value:)修饰符在用户点击X轴上的数值时也能触发选择,而不仅限于在图表绘图区域内点击拖动。
示例代码
private struct PlotPoint { let x: Double let y: Double } private struct PlotSeries: Identifiable { let id: Int let name: String let points: [PlotPoint] } private let data: [PlotSeries] = [ PlotSeries(id: 0, name: "Series A", points: stride(from: 0.0, through: 1.0, by: 0.05).map { y in PlotPoint(x: y*y, y: y) }), PlotSeries(id: 1, name: "Series B", points: stride(from: 0.0, through: 1.0, by: 0.05).map { y in PlotPoint(x: y*y, y: y/2) }) ] struct AxisTap: View { @State private var selectedX: Double? var body: some View { VStack { Chart { if let selectedX { BarMark(xStart: .value("x", selectedX), xEnd: .value("x", selectedX + 0.05)) .foregroundStyle(.yellow.opacity(0.5)) } ForEach(data) { series in let plot = LinePlot( series.points, x: .value("x", \.x), y: .value("y", \.y)) plot .symbol(by: .value("Series", series.name)) .foregroundStyle(by: .value("Series", series.name)) } } .chartXAxis { AxisMarks() { value in AxisGridLine() AxisTick() AxisValueLabel() { if let axisValue = value.as(Double.self) { VStack { Text("|") Text("v") Text("\(axisValue.formatted())") } } } } } .chartXSelection(value: $selectedX) .padding() Text("selectedX is: \(selectedX ?? 0.0)") } } }
解决方案
默认情况下,chartXSelection仅监听图表的绘图区域手势,X轴的标签区域不在其响应范围内。要实现点击X轴数值触发选择,只需给AxisValueLabel的内容添加自定义点击手势,手动更新选中的X值即可:
修改chartXAxis中的AxisValueLabel部分:
AxisValueLabel() { if let axisValue = value.as(Double.self) { VStack { Text("|") Text("v") Text("\(axisValue.formatted())") } // 添加点击手势,手动设置选中的X值 .onTapGesture { selectedX = axisValue } } }
效果说明
- 点击X轴上的任意数值标签,
selectedX会立即更新为对应的值,下方文本会同步显示选中结果 - 原有的图表区域拖动选择功能不受影响,两种交互方式可以共存
内容的提问来源于stack exchange,提问作者Curious Jorge
相关产品推荐
相关产品推荐

