drawCrossLineText method

  1. @override
void drawCrossLineText(
  1. Canvas canvas,
  2. Size size
)
override

Implementation

@override
void drawCrossLineText(Canvas canvas, Size size) {
  // 使用手指位置
  double x = selectX;
  double y = selectY;

  // 确保Y坐标在主图区域内
  if (y < mTopPadding) y = mTopPadding;
  if (y > mMainRect.bottom) y = mMainRect.bottom;

  // 根据Y坐标计算对应的价格
  double currentPrice = mMainRenderer.getYFromPrice(y);

  // 获取最新价格(最后一个数据点的收盘价)
  double latestPrice = 0;
  if (datas != null && datas!.isNotEmpty) {
    latestPrice = datas!.last.close;
  }

  // 计算涨跌幅
  double changeAmount = currentPrice - latestPrice;
  double changePercent =
      latestPrice != 0 ? (changeAmount / latestPrice) * 100 : 0;

  // 创建价格文本(简化显示)
  String priceText = currentPrice.toStringAsFixed(fixedLength);
  String changeText =
      "${changePercent >= 0 ? '+' : ''}${changePercent.toStringAsFixed(2)}%";

  // 使用默认文本颜色
  Color textColor = chartColors.defaultTextColor;

  // 绘制价格文本
  TextPainter priceTp = getTextPainter(priceText, textColor);
  TextPainter changeTp = getTextPainter(changeText, textColor);

  double textHeight = priceTp.height;
  double priceWidth = priceTp.width;
  double changeWidth = changeTp.width;
  double maxWidth = math.max(priceWidth, changeWidth);

  double w1 = 8;
  double w2 = 6;
  double lineSpacing = 2; // 行间距
  double totalTextHeight = textHeight * 2 + lineSpacing; // 两行文本总高度
  double r = totalTextHeight / 2 + w2; // 背景框半高

  // 计算文本垂直居中位置
  double topMargin = (totalTextHeight - textHeight * 2 - lineSpacing) / 2;
  double priceY = y - totalTextHeight / 2 + topMargin; // 价格文本Y位置(顶对齐到背景框内)
  double changeY = priceY + textHeight + lineSpacing; // 涨跌幅文本Y位置

  double textX;
  bool isLeft = false;

  // 判断标签应该显示在左侧还是右侧
  if (x < mWidth / 2) {
    isLeft = false;
    textX = 1;

    // 绘制统一背景
    Path path = Path();
    path.moveTo(textX, y - r);
    path.lineTo(textX, y + r);
    path.lineTo(maxWidth + 2 * w1, y + r);
    path.lineTo(maxWidth + 2 * w1 + w2, y);
    path.lineTo(maxWidth + 2 * w1, y - r);
    path.close();
    canvas.drawPath(path, selectPointPaint);
    canvas.drawPath(path, selectorBorderPaint);

    // 绘制文本
    priceTp.paint(canvas, Offset(textX + w1, priceY));
    changeTp.paint(canvas, Offset(textX + w1, changeY));
  } else {
    isLeft = true;
    textX = mWidth - maxWidth - 1 - 2 * w1 - w2;

    // 绘制统一背景
    Path path = Path();
    path.moveTo(textX, y);
    path.lineTo(textX + w2, y + r);
    path.lineTo(mWidth - 2, y + r);
    path.lineTo(mWidth - 2, y - r);
    path.lineTo(textX + w2, y - r);
    path.close();
    canvas.drawPath(path, selectPointPaint);
    canvas.drawPath(path, selectorBorderPaint);

    // 绘制文本
    priceTp.paint(canvas, Offset(textX + w1 + w2, priceY));
    changeTp.paint(canvas, Offset(textX + w1 + w2, changeY));
  }

  // 绘制底部时间标签(仍然基于最近的数据点)
  var index = calculateSelectedX(selectX);
  KLineEntity point = getItem(index);

  TextPainter dateTp =
      getTextPainter(getDate(point.time), chartColors.crossTextColor);
  double dateWidth = dateTp.width;
  double dateX = x;
  double dateY = size.height - mBottomPadding;

  if (dateX < dateWidth + 2 * w1) {
    dateX = 1 + dateWidth / 2 + w1;
  } else if (mWidth - dateX < dateWidth + 2 * w1) {
    dateX = mWidth - 1 - dateWidth / 2 - w1;
  }

  double baseLine = textHeight / 2;
  canvas.drawRect(
      Rect.fromLTRB(dateX - dateWidth / 2 - w1, dateY,
          dateX + dateWidth / 2 + w1, dateY + baseLine + r / 2),
      selectPointPaint);
  canvas.drawRect(
      Rect.fromLTRB(dateX - dateWidth / 2 - w1, dateY,
          dateX + dateWidth / 2 + w1, dateY + baseLine + r / 2),
      selectorBorderPaint);

  dateTp.paint(canvas, Offset(dateX - dateWidth / 2, dateY));

  //长按显示这条数据详情
  sink?.add(InfoWindowEntity(point, isLeft: isLeft));
}