magnetSnap method
磁铁吸附功能 - 将点吸附到最近的K线数据点
Implementation
Offset magnetSnap(
Offset point,
List<KLineEntity>? datas,
double scaleX,
double scrollX,
double Function(double) getX,
double Function(double) getY,
Rect chartRect,
) {
if (!_isMagnetMode || datas == null || datas.isEmpty) {
return point;
}
try {
// 计算最近的K线索引
double chartWidth = chartRect.width;
double pointWidth = chartWidth / (datas.length * scaleX);
int dataIndex =
((point.dx - chartRect.left) / pointWidth + scrollX).round();
// 确保索引在有效范围内
dataIndex = dataIndex.clamp(0, datas.length - 1);
if (dataIndex < 0 || dataIndex >= datas.length) {
return point;
}
KLineEntity kLine = datas[dataIndex];
// 计算K线的各个价格点在屏幕上的Y坐标
double openY = getY(kLine.open);
double closeY = getY(kLine.close);
double highY = getY(kLine.high);
double lowY = getY(kLine.low);
// 计算K线在屏幕上的X坐标
double kLineX = getX(dataIndex.toDouble());
// 找到距离点击点最近的价格点
List<Offset> pricePoints = [
Offset(kLineX, openY), // 开盘价
Offset(kLineX, closeY), // 收盘价
Offset(kLineX, highY), // 最高价
Offset(kLineX, lowY), // 最低价
];
// 计算距离并找到最近的点
double minDistance = double.infinity;
Offset snapPoint = point;
for (Offset pricePoint in pricePoints) {
double distance = (point - pricePoint).distance;
if (distance < minDistance) {
minDistance = distance;
snapPoint = pricePoint;
}
}
// 只有在合理距离内才吸附(比如50像素内)
const double snapThreshold = 50.0;
if (minDistance <= snapThreshold) {
debugPrint(
'磁铁吸附: 从 $point 吸附到 $snapPoint (距离: ${minDistance.toStringAsFixed(1)})');
return snapPoint;
}
} catch (e) {
debugPrint('磁铁吸附计算错误: $e');
}
return point;
}