Jetpack Compose自定义K线图缩放滑动后选中索引错误问题
Jetpack Compose自定义K线图点击索引匹配问题解决方案
以下是针对缩放/滑动后K线点击索引不匹配问题的具体排查和修复步骤:
正确转换触摸坐标到原始图表坐标系
缩放和平移操作会改变图表的绘制坐标系,触摸事件的坐标需要先转换为图表本地坐标,再做逆变换抵消缩放和平移的影响,才能映射到原始K线数据的坐标系:pointerInput(Unit) { detectTapGestures { screenOffset -> val layoutCoords = layoutCoordinates ?: return@detectTapGestures // 将屏幕坐标转为图表本地坐标(相对于图表左上角) val localOffset = layoutCoords.localPositionOf(LocalView.current.layoutCoordinates, screenOffset) // 逆变换:抵消缩放和平移,得到原始坐标系下的X坐标 val originalX = (localOffset.x - translationX) / scaleX val targetIndex = calculateKlineIndex(originalX) // 处理选中逻辑 } }基于可视起始索引计算目标K线
缩放滑动后,可视区域的起始K线索引不再是0,需维护visibleStartIndex变量记录当前显示的第一个K线索引,计算时结合单K线宽度(含间距)得出目标索引:private val klineWidth = 50f // 单K线宽度(含间距) private var visibleStartIndex by remember { mutableStateOf(0) } private fun calculateKlineIndex(originalX: Float): Int { if (originalX < 0 || klineData.isEmpty()) return -1 // 计算相对于可视起始索引的偏移量 val offset = (originalX / klineWidth).toInt() val targetIndex = visibleStartIndex + offset // 确保索引在合法范围内 return targetIndex.coerceIn(0, klineData.lastIndex) }同步更新缩放/平移状态与可视起始索引
在滑动或缩放操作时,实时更新translationX、scaleX和visibleStartIndex,避免状态不一致导致的索引计算错误:detectDragGestures { change, dragAmount -> change.consume() translationX += dragAmount.x updateVisibleStartIndex() } detectTransformGestures { _, pan, zoom, _ -> scaleX = (scaleX * zoom).coerceIn(1f, 5f) // 限制缩放范围 translationX += pan.x updateVisibleStartIndex() } private fun updateVisibleStartIndex() { val maxVisibleIndex = klineData.lastIndex - getVisibleKlineCount() // 根据平移量和缩放比例计算起始索引 val calculatedStart = (-translationX / (klineWidth * scaleX)).toInt() visibleStartIndex = calculatedStart.coerceIn(0, maxVisibleIndex) // 修正平移量,防止超出数据边界 translationX = -visibleStartIndex * klineWidth * scaleX } private fun getVisibleKlineCount(): Int { // 根据图表宽度和单K线宽度计算可视K线数量 return (size.width / (klineWidth * scaleX)).toInt() + 1 }验证坐标转换逻辑
可以在绘制K线时,为每个K线叠加绘制对应的索引文本,或者在触摸时打印originalX、offset、targetIndex等参数,对比实际点击的K线位置,快速定位是坐标转换错误还是索引计算逻辑问题。
内容的提问来源于stack exchange,提问作者Hulusi Şimşek
相关产品推荐
相关产品推荐

