// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ // ┃ Copyright (c) 2017, the Perspective Authors. ┃ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃ // ┃ This file is part of the Perspective library, distributed under the terms ┃ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ import type { Context2D } from "../canvas-types"; import type { Theme } from "../../theme/theme"; /** * Draw a freestanding tooltip box anchored near (cx, cy), measuring * lines, sizing/clamping the box, painting bg/border, and laying out * text rows. Shared by sunburst + treemap which need a non-PlotLayout * anchor. */ export function drawTooltipBox( ctx: Context2D, theme: Theme, lines: string[], cx: number, cy: number, cssWidth: number, cssHeight: number, fontFamily: string, ): void { if (lines.length === 0) { return; } const { tooltipBg, tooltipText, tooltipBorder } = theme; ctx.font = `11px ${fontFamily}`; const lineHeight = 16; const padding = 8; let maxWidth = 0; for (const line of lines) { const w = ctx.measureText(line).width; if (w > maxWidth) { maxWidth = w; } } const boxW = maxWidth + padding * 2; const boxH = lines.length * lineHeight + padding * 2 - 4; let tx = cx + 12; let ty = cy - boxH - 8; if (tx + boxW > cssWidth) { tx = cx - boxW - 12; } if (tx < 0) { tx = 4; } if (ty < 0) { ty = cy + 12; } if (ty + boxH > cssHeight) { ty = cssHeight - boxH - 4; } ctx.fillStyle = tooltipBg; ctx.strokeStyle = tooltipBorder; ctx.lineWidth = 1; ctx.beginPath(); ctx.roundRect(tx, ty, boxW, boxH, 4); ctx.fill(); ctx.stroke(); ctx.fillStyle = tooltipText; ctx.textAlign = "left"; ctx.textBaseline = "top"; for (let i = 0; i < lines.length; i++) { ctx.fillText(lines[i], tx + padding, ty + padding + i * lineHeight); } }