drawTooltip function

void drawTooltip(
  1. Canvas canvas, {
  2. required Offset anchor,
  3. required Size container,
  4. required List<TooltipRow> rows,
  5. required Color background,
  6. required Color textColor,
  7. required Color mutedTextColor,
  8. String? title,
})

Draws a rounded tooltip panel near anchor, laying out an optional title above rows. The panel is kept fully inside container (flipped to the other side of the anchor and clamped to the edges as needed), so it never clips off-screen. Reuses the shared text cache via drawChartText.

Implementation

void drawTooltip(
  Canvas canvas, {
  required Offset anchor,
  required Size container,
  required List<TooltipRow> rows,
  required Color background,
  required Color textColor,
  required Color mutedTextColor,
  String? title,
}) {
  final hasTitle = title != null && title.isNotEmpty;
  if (rows.isEmpty && !hasTitle) return;

  const pad = 8.0;
  const rowH = 16.0;
  const swatchSize = 8.0;
  const swatchGap = 6.0;
  const fontSize = 10.0;

  var maxW = 0.0;
  if (hasTitle) {
    maxW = math.max(
      maxW,
      _layoutLabel(title, textColor, fontSize, FontWeight.w600).width,
    );
  }
  for (final r in rows) {
    final textW = _layoutLabel(
      r.text,
      textColor,
      fontSize,
      FontWeight.normal,
    ).width;
    final w = textW + (r.swatch != null ? swatchSize + swatchGap : 0.0);
    maxW = math.max(maxW, w);
  }

  final titleH = hasTitle ? rowH : 0.0;
  final boxW = maxW + pad * 2;
  final boxH = titleH + rows.length * rowH + pad * 2;

  // Prefer the right of the anchor; flip left if it would overflow, then clamp.
  var left = anchor.dx + 12;
  if (left + boxW > container.width) left = anchor.dx - 12 - boxW;
  left = left.clamp(0.0, math.max(0.0, container.width - boxW));
  final top = anchor.dy
      .clamp(0.0, math.max(0.0, container.height - boxH))
      .toDouble();

  canvas.drawRRect(
    RRect.fromRectAndRadius(
      Rect.fromLTWH(left, top, boxW, boxH),
      const Radius.circular(8),
    ),
    Paint()..color = background,
  );

  var cy = top + pad;
  if (hasTitle) {
    drawChartText(
      canvas,
      title,
      Offset(left + pad, cy),
      color: mutedTextColor,
      fontSize: fontSize,
      weight: FontWeight.w600,
    );
    cy += rowH;
  }
  for (final r in rows) {
    var tx = left + pad;
    if (r.swatch != null) {
      canvas.drawRRect(
        RRect.fromRectAndRadius(
          Rect.fromLTWH(
            tx,
            cy + (fontSize - swatchSize) / 2 + 2,
            swatchSize,
            swatchSize,
          ),
          const Radius.circular(2),
        ),
        Paint()..color = r.swatch!,
      );
      tx += swatchSize + swatchGap;
    }
    drawChartText(
      canvas,
      r.text,
      Offset(tx, cy),
      color: textColor,
      fontSize: fontSize,
    );
    cy += rowH;
  }
}