如何查询Swift Charts中LineMark指定x值对应的y值?
解决SwiftUI Chart折线图指定x位置的y值获取问题
方法1:手动计算线性插值y值
SwiftUI Chart的LineMark默认采用线性插值连接数据点,针对你x轴间隔相等的场景,两个连续整数点x=n(对应y值y1)和x=n+1(对应y值y2),中间位置x=n+0.5的y值可直接通过线性插值公式计算:
let midY = (y1 + y2) / 2.0
你需要提前把数据点的x、y值存储下来(避免在ForEach里临时生成随机值),示例代码如下:
struct DataPoint: Identifiable { let id = UUID() let x: Int let y: Int } // 预先生成带x和y的数据集 let dataPoints = (0...10).map { DataPoint(x: $0, y: Int.random(in: 0...100)) } // 计算指定两个点中间位置的y值 func midYBetween(index: Int) -> Double? { guard index < dataPoints.count - 1 else { return nil } let point1 = dataPoints[index] let point2 = dataPoints[index + 1] return Double(point1.y + point2.y) / 2.0 }
之后就可以用这个计算出的y值在Chart中放置贴合折线的覆盖层。
方法2:利用ChartProxy获取渲染后坐标(通用场景)
如果需要适配非等间隔x轴、非线性插值的折线,可以通过ChartProxy结合PlotReader获取指定x位置对应的y值:
- 给Chart绑定
chartProxy:
@State private var chartProxy: ChartProxy? Chart(dataPoints) { point in LineMark(x: .value("X", point.x), y: .value("Y", point.y), series: "Line") } .chartProxy($chartProxy)
- 实现获取y值的方法:
func getY(at targetX: Double) -> Double? { guard let proxy = chartProxy else { return nil } // 将目标x值转换为图表坐标系的位置 guard let xPos = proxy.position(forX: targetX) else { return nil } // 读取该x位置对应的折线y坐标并转换为数据值 let plotReader = PlotReader { plotArea in let screenPoint = CGPoint(x: xPos, y: 0) let convertedPoint = plotArea.layer.convert(screenPoint, from: plotArea.coordinateSpace) return proxy.value(atY: convertedPoint.y) } return plotReader.read() }
注意:该方法需要在Chart完成渲染后调用(比如在onAppear或用户交互事件中),才能获取有效数据。
内容的提问来源于stack exchange,提问作者swiftyboi
相关产品推荐
相关产品推荐

