minerva-design 1.17.2 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/custom-elements.json +10 -6
- package/dist/angular/fesm2022/minerva-angular.mjs +173 -70
- package/dist/angular/fesm2022/minerva-angular.mjs.map +1 -1
- package/dist/angular/types/minerva-angular.d.ts +33 -21
- package/dist/charts/core.cjs +1 -1
- package/dist/charts/core.d.cts +1 -0
- package/dist/charts/core.d.ts +1 -0
- package/dist/charts/core.js +22 -21
- package/dist/charts/engine/chart.cjs +1 -1
- package/dist/charts/engine/chart.cjs.map +1 -1
- package/dist/charts/engine/chart.js +414 -376
- package/dist/charts/engine/chart.js.map +1 -1
- package/dist/charts/engine/overlay.cjs +1 -1
- package/dist/charts/engine/overlay.cjs.map +1 -1
- package/dist/charts/engine/overlay.d.cts +5 -0
- package/dist/charts/engine/overlay.d.ts +5 -0
- package/dist/charts/engine/overlay.js +94 -69
- package/dist/charts/engine/overlay.js.map +1 -1
- package/dist/charts/engine/quadrant-card.cjs +2 -0
- package/dist/charts/engine/quadrant-card.cjs.map +1 -0
- package/dist/charts/engine/quadrant-card.d.cts +83 -0
- package/dist/charts/engine/quadrant-card.d.ts +83 -0
- package/dist/charts/engine/quadrant-card.js +154 -0
- package/dist/charts/engine/quadrant-card.js.map +1 -0
- package/dist/charts/engine/scene.cjs +1 -1
- package/dist/charts/engine/scene.cjs.map +1 -1
- package/dist/charts/engine/scene.d.cts +5 -0
- package/dist/charts/engine/scene.d.ts +5 -0
- package/dist/charts/engine/scene.js +32 -32
- package/dist/charts/engine/scene.js.map +1 -1
- package/dist/charts/engine/types.d.cts +14 -0
- package/dist/charts/engine/types.d.ts +14 -0
- package/dist/charts/index.cjs +1 -1
- package/dist/charts/index.js +28 -27
- package/dist/charts/react/Chart.cjs +1 -1
- package/dist/charts/react/Chart.cjs.map +1 -1
- package/dist/charts/react/Chart.d.cts +4 -2
- package/dist/charts/react/Chart.d.ts +4 -2
- package/dist/charts/react/Chart.js +42 -42
- package/dist/charts/react/Chart.js.map +1 -1
- package/dist/charts/react/charts.cjs +1 -1
- package/dist/charts/react/charts.cjs.map +1 -1
- package/dist/charts/react/charts.js +395 -391
- package/dist/charts/react/charts.js.map +1 -1
- package/dist/charts/react/types.d.cts +8 -2
- package/dist/charts/react/types.d.ts +8 -2
- package/dist/core/contracts.cjs +1 -1
- package/dist/core/contracts.cjs.map +1 -1
- package/dist/core/contracts.js +1 -1
- package/dist/core/contracts.js.map +1 -1
- package/dist/native/charts/src/engine/overlay.cjs +1 -1
- package/dist/native/charts/src/engine/overlay.cjs.map +1 -1
- package/dist/native/charts/src/engine/overlay.js +89 -65
- package/dist/native/charts/src/engine/overlay.js.map +1 -1
- package/dist/native/charts/src/engine/scene.cjs +1 -1
- package/dist/native/charts/src/engine/scene.cjs.map +1 -1
- package/dist/native/charts/src/engine/scene.js +32 -32
- package/dist/native/charts/src/engine/scene.js.map +1 -1
- package/dist/react/components/QuadrantTaskBoard/QuadrantTaskBoard.cjs +1 -1
- package/dist/react/components/QuadrantTaskBoard/QuadrantTaskBoard.cjs.map +1 -1
- package/dist/react/components/QuadrantTaskBoard/QuadrantTaskBoard.js +14 -8
- package/dist/react/components/QuadrantTaskBoard/QuadrantTaskBoard.js.map +1 -1
- package/dist/react/components/QuadrantTaskBoard/quadrantTaskBoard.module.scss.cjs +1 -1
- package/dist/react/components/QuadrantTaskBoard/quadrantTaskBoard.module.scss.cjs.map +1 -1
- package/dist/react/components/QuadrantTaskBoard/quadrantTaskBoard.module.scss.js +16 -15
- package/dist/react/components/QuadrantTaskBoard/quadrantTaskBoard.module.scss.js.map +1 -1
- package/dist/react/style.css +1 -1
- package/dist/react/styles/quadrant-task-board.css +1 -1
- package/dist/taro/index.js +1521 -1496
- package/dist/taro/style.css +22 -0
- package/dist/uni/manifest.d.ts +34 -34
- package/dist/uni/manifest.js +34 -39
- package/dist/uni/style.css +22 -0
- package/dist/vue/components/Chart/QuadrantChart.vue.d.ts +4 -3
- package/dist/vue/components/Chart/QuadrantChart.vue.js.map +1 -1
- package/dist/vue/components/Chart/QuadrantChart.vue_vue_type_script_setup_true_lang.js +186 -142
- package/dist/vue/components/Chart/QuadrantChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/vue/components/Chart/cartesian.d.ts +5 -1
- package/dist/vue/components/Chart/cartesian.js +2 -0
- package/dist/vue/components/Chart/cartesian.js.map +1 -1
- package/dist/vue/components/QuadrantTaskBoard/QuadrantTaskBoard.vue.js.map +1 -1
- package/dist/vue/components/QuadrantTaskBoard/QuadrantTaskBoard.vue_vue_type_script_setup_true_lang.js +18 -12
- package/dist/vue/components/QuadrantTaskBoard/QuadrantTaskBoard.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/weapp/charts/canvas.js +48 -11
- package/dist/weapp/controls.wxss +22 -0
- package/dist/web-components/components/chart/chart.d.ts +4 -1
- package/dist/web-components/components/chart/chart.js +3 -1
- package/dist/web-components/components/chart/chart.js.map +1 -1
- package/dist/web-components/components/chart/charts.d.ts +34 -14
- package/dist/web-components/components/chart/charts.js +145 -98
- package/dist/web-components/components/chart/charts.js.map +1 -1
- package/dist/web-components/components/quadrant-task-board/quadrant-task-board.d.ts +8 -8
- package/dist/web-components/components/quadrant-task-board/quadrant-task-board.js +16 -12
- package/dist/web-components/components/quadrant-task-board/quadrant-task-board.js.map +1 -1
- package/dist/web-components/styles/QuadrantTaskBoard/quadrantTaskBoard.css.js +1 -1
- package/dist/web-components/styles/QuadrantTaskBoard/quadrantTaskBoard.css.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","names":["INSIDE_PAD","insideLabelColor","alpha","fill","seen","mix","background","l","relativeLuminance","font","theme","weight","size","crisp","v","pill","r","h","w","ctx","x","y","textBox","s","at","toScreen","a","free","px","plot","py","width","height","rectOf","xLo","xHi","yLo","yHi","along","lo","hi","screenRect","hasAreaTitle","fitText","text","max","chars","mid","areaTitleLayout","lineHeight","fontSize","labelSize","badgeSize","badge","measure","t","badgeWidth","detail","detailWidth","room","label","line","description","lineWidth","sum","p","descriptionWidth","pos","top","startOf","parts","lineOf","drawBackground","input","scales","bottomTicks","yTicks","xTicks","leftTicks","bottomPx","leftPx","toCss","base","lastRight","order","i","b","left","lastBottom","rows","rowHeight","y2","y2Ticks","right","overlaps","inside","haloText","halo","color","insideBox","bar","x0","x1","y0","y1","CELL_PAD","cellBox","bounds","slack","c","occupied","o","gap","sideY","sides","beside","side","stacked","box","cuts","cw","best","total","keep","boxes","cut","placeLabels","placed","labels","fit","above","below","drawArrows","arrows","pts","first","next","prev","tip","b0","b1","drawForeground","labelHeight","where","title","muted","cy","textColor"],"sources":["../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { mix, relativeLuminance, toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport { screenRect, toScreen, type Rect, type Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n badge?: string;\n detail?: string;\n description?: string;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /**\n * Fixed side (bar values: above / below, left / right of horizontal\n * bars; `inside` the `bar`); any free side around the dot otherwise\n */\n placement?: \"above\" | \"below\" | \"left\" | \"right\" | \"inside\";\n /** `inside` labels: the bar, in CSS pixels */\n bar?: Rect;\n /** `inside` labels: at the start of the bar (horizontal bars) or centered */\n align?: \"start\" | \"center\";\n /**\n * Text color contrasting with a solid bar (`inside` labels), drawn\n * without a halo; the text color of the theme with a halo otherwise\n */\n color?: string;\n /**\n * Cell the label stays in (`labelCells`: the quadrant of the dot), in CSS\n * pixels: on the side of the dot with more room, cut with an ellipsis\n * when it does not fit\n */\n bounds?: Rect;\n}\n\n/** Padding of the labels inside the bars, CSS pixels */\nconst INSIDE_PAD = 6;\n\n/**\n * Color of a text written on a bar of color `fill` (alpha included) over\n * `background`: white or near-black, whichever contrasts more; `undefined`\n * for translucent bars (the theme text color with a halo reads better)\n */\nexport const insideLabelColor = (\n fill: Rgba,\n background: Rgba,\n): string | undefined => {\n const alpha = fill[3];\n if (alpha < 0.6) return undefined;\n const seen = mix(background, fill, alpha);\n const l = relativeLuminance(seen);\n // WCAG contrast with white (L = 1) and with #111827 (L ≈ 0.012)\n return 1.05 / (l + 0.05) >= (l + 0.05) / 0.062\n ? \"#ffffff\"\n : \"rgba(17, 24, 39, 0.92)\";\n};\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Path of a rounded box with half-height corners */\nconst pill = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n) => {\n const r = Math.min(h / 2, w / 2);\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w - r, y);\n ctx.arcTo(x + w, y, x + w, y + r, r);\n ctx.lineTo(x + w, y + h - r);\n ctx.arcTo(x + w, y + h, x + w - r, y + h, r);\n ctx.lineTo(x + r, y + h);\n ctx.arcTo(x, y + h, x, y + h - r, r);\n ctx.lineTo(x, y + r);\n ctx.arcTo(x, y, x + r, y, r);\n ctx.closePath();\n};\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const at = toScreen(s, a.x ?? 0, a.y ?? 0);\n const free = s.horizontal\n ? { x: a.y === undefined, y: a.x === undefined }\n : { x: a.x === undefined, y: a.y === undefined };\n const px = free.x ? plot.x + plot.width / 2 : at.x;\n const py = free.y ? plot.y + plot.height / 2 : at.y;\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\n/** Screen box of an area annotation, clipped to the plot */\nexport const rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n // clamp every edge to the plot first: an open edge maps to ±Infinity and\n // `Infinity - Infinity` would make the size NaN (nothing drawn)\n const [xLo, xHi] = s.horizontal\n ? [plot.y, plot.y + plot.height]\n : [plot.x, plot.x + plot.width];\n const [yLo, yHi] = s.horizontal\n ? [plot.x, plot.x + plot.width]\n : [plot.y, plot.y + plot.height];\n const along = (px: number, lo: number, hi: number) =>\n px < lo ? lo : px > hi ? hi : px;\n return screenRect(\n s,\n along(s.xToPx(a.x0 ?? -Infinity), xLo, xHi),\n along(s.xToPx(a.x1 ?? Infinity), xLo, xHi),\n along(s.yToPx(a.y0 ?? -Infinity), yLo, yHi),\n along(s.yToPx(a.y1 ?? Infinity), yLo, yHi),\n );\n};\n\n/** A text of the title block of an area: badge, label, detail or description */\nexport interface AreaText {\n kind: \"badge\" | \"label\" | \"detail\" | \"description\";\n text: string;\n /** Box of the text (the pill of a badge), CSS pixels */\n x: number;\n y: number;\n width: number;\n height: number;\n /** Font size and weight */\n size: number;\n weight: number;\n}\n\n/** Title block of an area annotation, in its `labelPosition` corner */\nexport interface AreaTitle {\n parts: AreaText[];\n /** Box around the parts (the point labels avoid it) */\n box: Rect;\n}\n\n/** Whether an area annotation has a title block */\nexport const hasAreaTitle = (a: ResolvedRect): boolean =>\n !!(a.label || a.badge || a.detail || a.description);\n\n/** Text cut with an ellipsis to fit `max` pixels (\"\" when nothing fits) */\nconst fitText = (\n text: string,\n max: number,\n width: (text: string) => number,\n): string => {\n if (width(text) <= max) return text;\n const chars = Array.from(text);\n let lo = 0;\n let hi = chars.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (width(`${chars.slice(0, mid).join(\"\")}…`) <= max) lo = mid;\n else hi = mid - 1;\n }\n return lo > 0 ? `${chars.slice(0, lo).join(\"\").trimEnd()}…` : \"\";\n};\n\n/**\n * Layout of the title block of an area: `[badge] label detail` on the first\n * line, the description under it; the block sits in the `labelPosition`\n * corner, 10px from the edges, and the texts are cut to the area width\n */\nexport const areaTitleLayout = (\n a: ResolvedRect,\n r: Rect,\n fontSize: number,\n measure: (text: string, size: number, weight: number) => number,\n): AreaTitle | null => {\n if (!hasAreaTitle(a) || r.width <= 0 || r.height <= 0) return null;\n const pad = 10;\n const lineHeight = fontSize + 4;\n const max = Math.max(0, r.width - pad * 2);\n const labelSize = fontSize + 1;\n const badgeSize = Math.max(9, fontSize - 1);\n const gap = 6;\n const badge = a.badge\n ? fitText(a.badge, Math.max(0, max - 10), (t) => measure(t, badgeSize, 700))\n : \"\";\n const badgeWidth = badge ? measure(badge, badgeSize, 700) + 10 : 0;\n let detail = a.detail ?? \"\";\n let detailWidth = detail ? measure(detail, fontSize, 500) : 0;\n const room = () =>\n max - (badge ? badgeWidth + gap : 0) - (detail ? detailWidth + gap : 0);\n // a narrow area keeps the title rather than the detail\n if (detail && a.label && room() < 32) {\n detail = \"\";\n detailWidth = 0;\n }\n if (detail && room() < 0) {\n detail = fitText(\n detail,\n Math.max(0, max - (badge ? badgeWidth + gap : 0)),\n (t) => measure(t, fontSize, 500),\n );\n detailWidth = detail ? measure(detail, fontSize, 500) : 0;\n }\n const label = a.label\n ? fitText(a.label, Math.max(0, room()), (t) => measure(t, labelSize, 600))\n : \"\";\n const line: AreaText[] = [];\n if (badge)\n line.push({\n kind: \"badge\",\n text: badge,\n x: 0,\n y: 0,\n width: badgeWidth,\n height: lineHeight,\n size: badgeSize,\n weight: 700,\n });\n if (label)\n line.push({\n kind: \"label\",\n text: label,\n x: 0,\n y: 0,\n width: measure(label, labelSize, 600),\n height: lineHeight,\n size: labelSize,\n weight: 600,\n });\n if (detail)\n line.push({\n kind: \"detail\",\n text: detail,\n x: 0,\n y: 0,\n width: detailWidth,\n height: lineHeight,\n size: fontSize,\n weight: 500,\n });\n const description = a.description\n ? fitText(a.description, max, (t) => measure(t, fontSize, 400))\n : \"\";\n const lineWidth =\n line.reduce((sum, p) => sum + p.width, 0) +\n Math.max(0, line.length - 1) * gap;\n const descriptionWidth = description\n ? measure(description, fontSize, 400)\n : 0;\n if (!line.length && !description) return null;\n const height =\n (line.length ? lineHeight : 0) +\n (description ? lineHeight + (line.length ? 2 : 0) : 0);\n const pos = a.labelPosition;\n const top = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - height\n : r.y + (r.height - height) / 2;\n const startOf = (width: number) =>\n pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - width\n : r.x + (r.width - width) / 2;\n const parts: AreaText[] = [];\n let x = startOf(lineWidth);\n for (const p of line) {\n parts.push({ ...p, x, y: top });\n x += p.width + gap;\n }\n if (description)\n parts.push({\n kind: \"description\",\n text: description,\n x: startOf(descriptionWidth),\n y: top + (line.length ? lineHeight + 2 : 0),\n width: descriptionWidth,\n height: lineHeight,\n size: fontSize,\n weight: 400,\n });\n const width = Math.max(lineWidth, descriptionWidth);\n return {\n parts,\n box: { x: startOf(width), y: top, width, height },\n };\n};\n\n/**\n * Where a reference line goes: `vertical` lines run at screen x `at`,\n * horizontal ones at screen y `at`\n */\nexport const lineOf = (\n a: ResolvedLine,\n s: Scales,\n): { vertical: boolean; at: number } => {\n const vertical = (a.axis === \"x\") !== s.horizontal;\n return {\n vertical,\n at: a.axis === \"x\" ? s.xToPx(a.value) : s.yToPx(a.value),\n };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n /** Right axis (dual axis charts) */\n y2?: AxisModel | null;\n y2Ticks?: AxisTicks | null;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, xTicks, yTicks } = input;\n const { plot } = scales;\n // horizontal charts: the value axis along the bottom, the x axis on the left\n const x = scales.horizontal ? input.y : input.x;\n const y = scales.horizontal ? input.x : input.y;\n const bottomTicks = scales.horizontal ? yTicks : xTicks;\n const leftTicks = scales.horizontal ? xTicks : yTicks;\n const bottomPx = scales.horizontal ? scales.yToPx : scales.xToPx;\n const leftPx = scales.horizontal ? scales.xToPx : scales.yToPx;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of leftTicks.values) {\n const py = crisp(leftPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of bottomTicks.values) {\n const px = crisp(bottomPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = bottomTicks.values\n .map((v, i) => ({ px: bottomPx(v), text: bottomTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n let lastBottom = -Infinity;\n // top to bottom: category rows of horizontal charts never overlap\n const rows = leftTicks.values\n .map((v, i) => ({ py: leftPx(v), text: leftTicks.labels[i] }))\n .sort((a, b) => a.py - b.py);\n const rowHeight = theme.fontSize + 2;\n for (const { py, text } of rows) {\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) continue;\n if (scales.horizontal) {\n if (py - rowHeight / 2 < lastBottom) continue;\n lastBottom = py + rowHeight / 2;\n }\n ctx.fillText(text, plot.x - 8, py);\n }\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n\n // right axis\n const y2 = scales.horizontal ? null : input.y2;\n const y2Ticks = input.y2Ticks;\n if (y2 && y2Ticks && y2.visible) {\n const right = plot.x + plot.width;\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n y2Ticks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(y2Ticks.labels[i], right + 8, py);\n });\n if (y2.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(input.width - line / 2 - 4, plot.y + plot.height / 2);\n ctx.rotate(Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y2.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/**\n * Box of a label inside its bar (the visible part of it): the text cut with\n * an ellipsis to fit, at the start of horizontal bars and centered in\n * vertical ones; `null` when the bar is too small\n */\nconst insideBox = (\n label: PointLabel,\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n): { label: PointLabel; box: Rect } | null => {\n const bar = label.bar;\n if (!bar) return null;\n const x0 = Math.max(bar.x, plot.x);\n const x1 = Math.min(bar.x + bar.width, plot.x + plot.width);\n const y0 = Math.max(bar.y, plot.y);\n const y1 = Math.min(bar.y + bar.height, plot.y + plot.height);\n if (y1 - y0 < height - 2) return null;\n const text = fitText(label.text, x1 - x0 - INSIDE_PAD * 2, measure);\n if (!text) return null;\n const w = measure(text);\n const x = label.align === \"start\" ? x0 + INSIDE_PAD : (x0 + x1) / 2 - w / 2;\n return {\n label: text === label.text ? label : { ...label, text },\n box: { x, y: (y0 + y1) / 2 - height / 2, width: w, height },\n };\n};\n\n/** Room kept between a label and the edges of its cell, CSS pixels */\nconst CELL_PAD = 2;\n\n/**\n * Box of a label kept inside a cell of the plot (`bounds`): beside the dot\n * on the side with more room in the cell (moved up or down into the cell\n * near its edges), else above or below it (moved sideways into the cell);\n * cut with an ellipsis to the room left when the whole text fits nowhere;\n * `null` when no free slot is left\n */\nconst cellBox = (\n label: PointLabel,\n bounds: Rect,\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: readonly Rect[],\n): { label: PointLabel; box: Rect } | null => {\n const x0 = Math.max(bounds.x, plot.x) + CELL_PAD;\n const x1 = Math.min(bounds.x + bounds.width, plot.x + plot.width) - CELL_PAD;\n const y0 = Math.max(bounds.y, plot.y) + CELL_PAD;\n const y1 =\n Math.min(bounds.y + bounds.height, plot.y + plot.height) - CELL_PAD;\n if (x1 - x0 <= 0 || y1 - y0 < height) return null;\n // a hair of slack: a text cut to the exact room ends on the edge\n const slack = {\n x: x0 - 0.01,\n y: y0 - 0.01,\n width: x1 - x0 + 0.02,\n height: y1 - y0 + 0.02,\n };\n const free = (c: Rect) =>\n inside(c, slack) && !occupied.some((o) => overlaps(o, c));\n const gap = label.r + 4;\n // centered on the dot, moved into the cell near its top or bottom edge\n const sideY = Math.min(Math.max(label.y - height / 2, y0), y1 - height);\n const room = { right: x1 - (label.x + gap), left: label.x - gap - x0 };\n const sides: (\"right\" | \"left\")[] =\n room.right >= room.left ? [\"right\", \"left\"] : [\"left\", \"right\"];\n const beside = (side: \"right\" | \"left\", w: number): Rect[] => [\n {\n x: side === \"right\" ? label.x + gap : label.x - gap - w,\n y: sideY,\n width: w,\n height,\n },\n ];\n const stacked = (w: number): Rect[] => {\n // slid sideways into the cell near its edges (still over the dot)\n const x = Math.min(Math.max(label.x - w / 2, x0), x1 - w);\n return [\n { x, y: label.y - gap - height, width: w, height },\n { x, y: label.y + gap, width: w, height },\n ];\n };\n const w = measure(label.text);\n const whole = [\n ...beside(sides[0]!, w),\n ...beside(sides[1]!, w),\n ...stacked(w),\n ];\n const box = whole.find(free);\n if (box) return { label, box };\n // the whole text fits nowhere: cut it to the room beside the dot or above\n // / below it, keeping the longest text (the roomiest side on ties)\n const cuts: [number, (w: number) => Rect[]][] = [\n [room[sides[0]!], (cw) => beside(sides[0]!, cw)],\n [room[sides[1]!], (cw) => beside(sides[1]!, cw)],\n [x1 - x0, stacked],\n ];\n let best: { label: PointLabel; box: Rect } | null = null;\n // a cut keeps enough of the name to tell it (else the label is skipped,\n // like an overlapping one: the tooltip still names the point)\n const total = Array.from(label.text).length;\n const keep = Math.min(4, Math.ceil(total * 0.4));\n for (const [max, boxes] of cuts) {\n const text = fitText(label.text, max, measure);\n if (!text || (best && text.length <= best.label.text.length)) continue;\n if (Array.from(text).length - 1 < keep) continue;\n const cut = boxes(measure(text)).find(free);\n if (cut) best = { label: { ...label, text }, box: cut };\n }\n return best;\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n if (label.placement === \"inside\") {\n const fit = insideBox(label, plot, measure, height);\n if (fit) placed.push(fit);\n continue;\n }\n if (label.bounds) {\n const fit = cellBox(label, label.bounds, plot, measure, height, occupied);\n if (!fit) continue;\n occupied.push(fit.box);\n placed.push(fit);\n continue;\n }\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const right = {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const left = {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : label.placement === \"right\"\n ? [right, left]\n : label.placement === \"left\"\n ? [left, right]\n : [\n {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n /** Lines between consecutive bars (waterfall connectors), drawn first */\n connectors?: readonly {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n color: string;\n width: number;\n dash: readonly number[];\n }[];\n /** Dependency arrows (Gantt charts), drawn over the connectors */\n arrows?: readonly ArrowPath[];\n}\n\n/** An elbow arrow in stage pixels (see `dependencyArrows`) */\nexport interface ArrowPath {\n points: readonly { x: number; y: number }[];\n head: readonly { x: number; y: number }[];\n color: string;\n width: number;\n}\n\n/** Elbow arrows: polylines with rounded corners and filled heads */\nexport const drawArrows = (\n ctx: CanvasRenderingContext2D,\n arrows: readonly ArrowPath[],\n) => {\n for (const a of arrows) {\n const pts = a.points;\n const first = pts[0];\n if (!first) continue;\n ctx.strokeStyle = a.color;\n ctx.fillStyle = a.color;\n ctx.lineWidth = a.width;\n ctx.lineJoin = \"round\";\n ctx.setLineDash([]);\n ctx.beginPath();\n ctx.moveTo(first.x, first.y);\n for (let i = 1; i < pts.length; i++) {\n const p = pts[i]!;\n const next = pts[i + 1];\n const prev = pts[i - 1]!;\n if (next && typeof ctx.arcTo === \"function\") {\n // rounded elbow, at most half of the shorter leg\n const r = Math.min(\n 4,\n Math.hypot(p.x - prev.x, p.y - prev.y) / 2,\n Math.hypot(next.x - p.x, next.y - p.y) / 2,\n );\n ctx.arcTo(p.x, p.y, next.x, next.y, r);\n } else {\n ctx.lineTo(p.x, p.y);\n }\n }\n ctx.stroke();\n const [tip, b0, b1] = a.head;\n if (tip && b0 && b1) {\n ctx.beginPath();\n ctx.moveTo(tip.x, tip.y);\n ctx.lineTo(b0.x, b0.y);\n ctx.lineTo(b1.x, b1.y);\n ctx.closePath();\n ctx.fill();\n }\n }\n};\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n for (const c of input.connectors ?? []) {\n ctx.strokeStyle = c.color;\n ctx.lineWidth = c.width;\n ctx.setLineDash([...c.dash]);\n ctx.beginPath();\n // crisp hairlines along the pixel grid\n const along = c.y0 === c.y1;\n const x0 = along ? c.x0 : crisp(c.x0);\n const y0 = along ? crisp(c.y0) : c.y0;\n ctx.moveTo(x0, y0);\n ctx.lineTo(along ? c.x1 : x0, along ? y0 : c.y1);\n ctx.stroke();\n }\n ctx.setLineDash([]);\n if (input.arrows?.length) drawArrows(ctx, input.arrows);\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n const where = lineOf(a, scales);\n if (!where.vertical) {\n const py = crisp(where.at);\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(where.at);\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !hasAreaTitle(a)) continue;\n const title = areaTitleLayout(\n a,\n rectOf(a, scales),\n theme.fontSize,\n (text, size, weight) => {\n ctx.font = font(theme, size, weight);\n return ctx.measureText(text).width;\n },\n );\n if (!title) continue;\n const color = toCss(a.labelColor);\n const muted = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n for (const p of title.parts) {\n const cy = p.y + p.height / 2;\n if (p.kind === \"badge\") {\n const h = p.height - 2;\n pill(ctx, p.x, cy - h / 2, p.width, h);\n ctx.fillStyle = toCss(a.labelColor, 0.16);\n ctx.fill();\n ctx.font = font(theme, p.size, p.weight);\n ctx.fillStyle = color;\n ctx.fillText(p.text, p.x + 5, cy);\n continue;\n }\n ctx.font = font(theme, p.size, p.weight);\n ctx.fillStyle = p.kind === \"label\" ? color : muted;\n ctx.fillText(p.text, p.x, cy);\n }\n occupied.push(title.box);\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n let placed: { label: PointLabel; box: Rect }[] = [];\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n const y = box.y + box.height / 2;\n if (label.color) {\n ctx.fillStyle = label.color;\n ctx.fillText(label.text, box.x, y);\n } else haloText(ctx, label.text, box.x, y, textColor, halo);\n }\n }\n ctx.restore();\n return placed;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"overlay.js","names":["INSIDE_PAD","insideLabelColor","alpha","fill","seen","mix","background","l","relativeLuminance","font","theme","weight","size","crisp","v","pill","r","h","w","ctx","x","y","textBox","s","at","toScreen","a","free","px","plot","py","width","height","rectOf","xLo","xHi","yLo","yHi","along","lo","hi","screenRect","hasAreaTitle","fitText","text","max","chars","mid","areaTitleLayout","lineHeight","fontSize","labelSize","badgeSize","badge","measure","t","badgeWidth","detail","detailWidth","room","label","line","description","lineWidth","sum","p","descriptionWidth","pos","top","startOf","parts","lineOf","drawBackground","input","scales","bottomTicks","yTicks","xTicks","leftTicks","bottomPx","leftPx","toCss","base","lastRight","order","i","b","left","lastBottom","rows","rowHeight","y2","y2Ticks","right","overlaps","inside","haloText","halo","color","insideBox","bar","x0","x1","y0","y1","CELL_PAD","LABEL_GAP","distanceTo","cellBox","bounds","slack","others","dots","d","c","spaced","occupied","o","own","far","gap","sideY","sides","beside","side","corners","stacked","box","cuts","cw","best","total","keep","boxes","cut","placeLabels","placed","labels","fit","above","below","drawArrows","arrows","pts","first","next","prev","tip","b0","b1","drawForeground","labelHeight","where","title","muted","cy","textColor"],"sources":["../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { mix, relativeLuminance, toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport { screenRect, toScreen, type Rect, type Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n badge?: string;\n detail?: string;\n description?: string;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /**\n * Fixed side (bar values: above / below, left / right of horizontal\n * bars; `inside` the `bar`); any free side around the dot otherwise\n */\n placement?: \"above\" | \"below\" | \"left\" | \"right\" | \"inside\";\n /** `inside` labels: the bar, in CSS pixels */\n bar?: Rect;\n /** `inside` labels: at the start of the bar (horizontal bars) or centered */\n align?: \"start\" | \"center\";\n /**\n * Text color contrasting with a solid bar (`inside` labels), drawn\n * without a halo; the text color of the theme with a halo otherwise\n */\n color?: string;\n /**\n * Cell the label stays in (`labelCells`: the quadrant of the dot), in CSS\n * pixels: on the side of the dot with more room, cut with an ellipsis\n * when it does not fit\n */\n bounds?: Rect;\n /**\n * Placed (it keeps its room) but not drawn: a card over the chart names\n * the point\n */\n hidden?: boolean;\n}\n\n/** Padding of the labels inside the bars, CSS pixels */\nconst INSIDE_PAD = 6;\n\n/**\n * Color of a text written on a bar of color `fill` (alpha included) over\n * `background`: white or near-black, whichever contrasts more; `undefined`\n * for translucent bars (the theme text color with a halo reads better)\n */\nexport const insideLabelColor = (\n fill: Rgba,\n background: Rgba,\n): string | undefined => {\n const alpha = fill[3];\n if (alpha < 0.6) return undefined;\n const seen = mix(background, fill, alpha);\n const l = relativeLuminance(seen);\n // WCAG contrast with white (L = 1) and with #111827 (L ≈ 0.012)\n return 1.05 / (l + 0.05) >= (l + 0.05) / 0.062\n ? \"#ffffff\"\n : \"rgba(17, 24, 39, 0.92)\";\n};\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Path of a rounded box with half-height corners */\nconst pill = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n) => {\n const r = Math.min(h / 2, w / 2);\n ctx.beginPath();\n ctx.moveTo(x + r, y);\n ctx.lineTo(x + w - r, y);\n ctx.arcTo(x + w, y, x + w, y + r, r);\n ctx.lineTo(x + w, y + h - r);\n ctx.arcTo(x + w, y + h, x + w - r, y + h, r);\n ctx.lineTo(x + r, y + h);\n ctx.arcTo(x, y + h, x, y + h - r, r);\n ctx.lineTo(x, y + r);\n ctx.arcTo(x, y, x + r, y, r);\n ctx.closePath();\n};\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const at = toScreen(s, a.x ?? 0, a.y ?? 0);\n const free = s.horizontal\n ? { x: a.y === undefined, y: a.x === undefined }\n : { x: a.x === undefined, y: a.y === undefined };\n const px = free.x ? plot.x + plot.width / 2 : at.x;\n const py = free.y ? plot.y + plot.height / 2 : at.y;\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\n/** Screen box of an area annotation, clipped to the plot */\nexport const rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n // clamp every edge to the plot first: an open edge maps to ±Infinity and\n // `Infinity - Infinity` would make the size NaN (nothing drawn)\n const [xLo, xHi] = s.horizontal\n ? [plot.y, plot.y + plot.height]\n : [plot.x, plot.x + plot.width];\n const [yLo, yHi] = s.horizontal\n ? [plot.x, plot.x + plot.width]\n : [plot.y, plot.y + plot.height];\n const along = (px: number, lo: number, hi: number) =>\n px < lo ? lo : px > hi ? hi : px;\n return screenRect(\n s,\n along(s.xToPx(a.x0 ?? -Infinity), xLo, xHi),\n along(s.xToPx(a.x1 ?? Infinity), xLo, xHi),\n along(s.yToPx(a.y0 ?? -Infinity), yLo, yHi),\n along(s.yToPx(a.y1 ?? Infinity), yLo, yHi),\n );\n};\n\n/** A text of the title block of an area: badge, label, detail or description */\nexport interface AreaText {\n kind: \"badge\" | \"label\" | \"detail\" | \"description\";\n text: string;\n /** Box of the text (the pill of a badge), CSS pixels */\n x: number;\n y: number;\n width: number;\n height: number;\n /** Font size and weight */\n size: number;\n weight: number;\n}\n\n/** Title block of an area annotation, in its `labelPosition` corner */\nexport interface AreaTitle {\n parts: AreaText[];\n /** Box around the parts (the point labels avoid it) */\n box: Rect;\n}\n\n/** Whether an area annotation has a title block */\nexport const hasAreaTitle = (a: ResolvedRect): boolean =>\n !!(a.label || a.badge || a.detail || a.description);\n\n/** Text cut with an ellipsis to fit `max` pixels (\"\" when nothing fits) */\nconst fitText = (\n text: string,\n max: number,\n width: (text: string) => number,\n): string => {\n if (width(text) <= max) return text;\n const chars = Array.from(text);\n let lo = 0;\n let hi = chars.length;\n while (lo < hi) {\n const mid = Math.ceil((lo + hi) / 2);\n if (width(`${chars.slice(0, mid).join(\"\")}…`) <= max) lo = mid;\n else hi = mid - 1;\n }\n return lo > 0 ? `${chars.slice(0, lo).join(\"\").trimEnd()}…` : \"\";\n};\n\n/**\n * Layout of the title block of an area: `[badge] label detail` on the first\n * line, the description under it; the block sits in the `labelPosition`\n * corner, 10px from the edges, and the texts are cut to the area width\n */\nexport const areaTitleLayout = (\n a: ResolvedRect,\n r: Rect,\n fontSize: number,\n measure: (text: string, size: number, weight: number) => number,\n): AreaTitle | null => {\n if (!hasAreaTitle(a) || r.width <= 0 || r.height <= 0) return null;\n const pad = 10;\n const lineHeight = fontSize + 4;\n const max = Math.max(0, r.width - pad * 2);\n const labelSize = fontSize + 1;\n const badgeSize = Math.max(9, fontSize - 1);\n const gap = 6;\n const badge = a.badge\n ? fitText(a.badge, Math.max(0, max - 10), (t) => measure(t, badgeSize, 700))\n : \"\";\n const badgeWidth = badge ? measure(badge, badgeSize, 700) + 10 : 0;\n let detail = a.detail ?? \"\";\n let detailWidth = detail ? measure(detail, fontSize, 500) : 0;\n const room = () =>\n max - (badge ? badgeWidth + gap : 0) - (detail ? detailWidth + gap : 0);\n // a narrow area keeps the title rather than the detail\n if (detail && a.label && room() < 32) {\n detail = \"\";\n detailWidth = 0;\n }\n if (detail && room() < 0) {\n detail = fitText(\n detail,\n Math.max(0, max - (badge ? badgeWidth + gap : 0)),\n (t) => measure(t, fontSize, 500),\n );\n detailWidth = detail ? measure(detail, fontSize, 500) : 0;\n }\n const label = a.label\n ? fitText(a.label, Math.max(0, room()), (t) => measure(t, labelSize, 600))\n : \"\";\n const line: AreaText[] = [];\n if (badge)\n line.push({\n kind: \"badge\",\n text: badge,\n x: 0,\n y: 0,\n width: badgeWidth,\n height: lineHeight,\n size: badgeSize,\n weight: 700,\n });\n if (label)\n line.push({\n kind: \"label\",\n text: label,\n x: 0,\n y: 0,\n width: measure(label, labelSize, 600),\n height: lineHeight,\n size: labelSize,\n weight: 600,\n });\n if (detail)\n line.push({\n kind: \"detail\",\n text: detail,\n x: 0,\n y: 0,\n width: detailWidth,\n height: lineHeight,\n size: fontSize,\n weight: 500,\n });\n const description = a.description\n ? fitText(a.description, max, (t) => measure(t, fontSize, 400))\n : \"\";\n const lineWidth =\n line.reduce((sum, p) => sum + p.width, 0) +\n Math.max(0, line.length - 1) * gap;\n const descriptionWidth = description\n ? measure(description, fontSize, 400)\n : 0;\n if (!line.length && !description) return null;\n const height =\n (line.length ? lineHeight : 0) +\n (description ? lineHeight + (line.length ? 2 : 0) : 0);\n const pos = a.labelPosition;\n const top = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - height\n : r.y + (r.height - height) / 2;\n const startOf = (width: number) =>\n pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - width\n : r.x + (r.width - width) / 2;\n const parts: AreaText[] = [];\n let x = startOf(lineWidth);\n for (const p of line) {\n parts.push({ ...p, x, y: top });\n x += p.width + gap;\n }\n if (description)\n parts.push({\n kind: \"description\",\n text: description,\n x: startOf(descriptionWidth),\n y: top + (line.length ? lineHeight + 2 : 0),\n width: descriptionWidth,\n height: lineHeight,\n size: fontSize,\n weight: 400,\n });\n const width = Math.max(lineWidth, descriptionWidth);\n return {\n parts,\n box: { x: startOf(width), y: top, width, height },\n };\n};\n\n/**\n * Where a reference line goes: `vertical` lines run at screen x `at`,\n * horizontal ones at screen y `at`\n */\nexport const lineOf = (\n a: ResolvedLine,\n s: Scales,\n): { vertical: boolean; at: number } => {\n const vertical = (a.axis === \"x\") !== s.horizontal;\n return {\n vertical,\n at: a.axis === \"x\" ? s.xToPx(a.value) : s.yToPx(a.value),\n };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n /** Right axis (dual axis charts) */\n y2?: AxisModel | null;\n y2Ticks?: AxisTicks | null;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, xTicks, yTicks } = input;\n const { plot } = scales;\n // horizontal charts: the value axis along the bottom, the x axis on the left\n const x = scales.horizontal ? input.y : input.x;\n const y = scales.horizontal ? input.x : input.y;\n const bottomTicks = scales.horizontal ? yTicks : xTicks;\n const leftTicks = scales.horizontal ? xTicks : yTicks;\n const bottomPx = scales.horizontal ? scales.yToPx : scales.xToPx;\n const leftPx = scales.horizontal ? scales.xToPx : scales.yToPx;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of leftTicks.values) {\n const py = crisp(leftPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of bottomTicks.values) {\n const px = crisp(bottomPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = bottomTicks.values\n .map((v, i) => ({ px: bottomPx(v), text: bottomTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n let lastBottom = -Infinity;\n // top to bottom: category rows of horizontal charts never overlap\n const rows = leftTicks.values\n .map((v, i) => ({ py: leftPx(v), text: leftTicks.labels[i] }))\n .sort((a, b) => a.py - b.py);\n const rowHeight = theme.fontSize + 2;\n for (const { py, text } of rows) {\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) continue;\n if (scales.horizontal) {\n if (py - rowHeight / 2 < lastBottom) continue;\n lastBottom = py + rowHeight / 2;\n }\n ctx.fillText(text, plot.x - 8, py);\n }\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n\n // right axis\n const y2 = scales.horizontal ? null : input.y2;\n const y2Ticks = input.y2Ticks;\n if (y2 && y2Ticks && y2.visible) {\n const right = plot.x + plot.width;\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n y2Ticks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(y2Ticks.labels[i], right + 8, py);\n });\n if (y2.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(input.width - line / 2 - 4, plot.y + plot.height / 2);\n ctx.rotate(Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y2.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/**\n * Box of a label inside its bar (the visible part of it): the text cut with\n * an ellipsis to fit, at the start of horizontal bars and centered in\n * vertical ones; `null` when the bar is too small\n */\nconst insideBox = (\n label: PointLabel,\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n): { label: PointLabel; box: Rect } | null => {\n const bar = label.bar;\n if (!bar) return null;\n const x0 = Math.max(bar.x, plot.x);\n const x1 = Math.min(bar.x + bar.width, plot.x + plot.width);\n const y0 = Math.max(bar.y, plot.y);\n const y1 = Math.min(bar.y + bar.height, plot.y + plot.height);\n if (y1 - y0 < height - 2) return null;\n const text = fitText(label.text, x1 - x0 - INSIDE_PAD * 2, measure);\n if (!text) return null;\n const w = measure(text);\n const x = label.align === \"start\" ? x0 + INSIDE_PAD : (x0 + x1) / 2 - w / 2;\n return {\n label: text === label.text ? label : { ...label, text },\n box: { x, y: (y0 + y1) / 2 - height / 2, width: w, height },\n };\n};\n\n/** Room kept between a label and the edges of its cell, CSS pixels */\nconst CELL_PAD = 2;\n/** Room kept between two labels of a cell (they never touch), CSS pixels */\nconst LABEL_GAP = { x: 4, y: 2 };\n\n/** Distance from a point to the nearest point of a box */\nconst distanceTo = (x: number, y: number, r: Rect) =>\n Math.hypot(\n Math.max(r.x - x, 0, x - (r.x + r.width)),\n Math.max(r.y - y, 0, y - (r.y + r.height)),\n );\n\n/** A dot of a cell label: its label is told apart from the others by it */\ntype Dot = Pick<PointLabel, \"x\" | \"y\" | \"r\">;\n\n/**\n * Box of a label kept inside a cell of the plot (`bounds`): beside the dot\n * on the side with more room in the cell (moved up or down into the cell\n * near its edges), else above or below it (moved sideways into the cell),\n * else beside it half a line up or down;\n * cut with an ellipsis to the room left when the whole text fits nowhere;\n * `null` when no free slot is left. A slot is free when it keeps a gap to\n * the other labels and its own dot is the nearest one (it covers no other\n * dot): a crowded cell never pairs a name with the wrong dot\n */\nconst cellBox = (\n label: PointLabel,\n bounds: Rect,\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: readonly Rect[],\n dots: readonly Dot[] = [],\n): { label: PointLabel; box: Rect } | null => {\n const x0 = Math.max(bounds.x, plot.x) + CELL_PAD;\n const x1 = Math.min(bounds.x + bounds.width, plot.x + plot.width) - CELL_PAD;\n const y0 = Math.max(bounds.y, plot.y) + CELL_PAD;\n const y1 =\n Math.min(bounds.y + bounds.height, plot.y + plot.height) - CELL_PAD;\n if (x1 - x0 <= 0 || y1 - y0 < height) return null;\n // a hair of slack: a text cut to the exact room ends on the edge\n const slack = {\n x: x0 - 0.01,\n y: y0 - 0.01,\n width: x1 - x0 + 0.02,\n height: y1 - y0 + 0.02,\n };\n // the other dots: those at the very spot of this one count as its own\n const others = dots.filter(\n (d) => Math.abs(d.x - label.x) >= 0.5 || Math.abs(d.y - label.y) >= 0.5,\n );\n const free = (c: Rect) => {\n if (!inside(c, slack)) return false;\n const spaced = {\n x: c.x - LABEL_GAP.x,\n y: c.y - LABEL_GAP.y,\n width: c.width + LABEL_GAP.x * 2,\n height: c.height + LABEL_GAP.y * 2,\n };\n if (occupied.some((o) => overlaps(o, spaced))) return false;\n const own = distanceTo(label.x, label.y, c);\n return others.every((d) => {\n const far = distanceTo(d.x, d.y, c);\n return far >= d.r + 2 && far > own;\n });\n };\n const gap = label.r + 4;\n // centered on the dot, moved into the cell near its top or bottom edge\n const sideY = Math.min(Math.max(label.y - height / 2, y0), y1 - height);\n const room = { right: x1 - (label.x + gap), left: label.x - gap - x0 };\n const sides: (\"right\" | \"left\")[] =\n room.right >= room.left ? [\"right\", \"left\"] : [\"left\", \"right\"];\n const beside = (side: \"right\" | \"left\", w: number): Rect[] => [\n {\n x: side === \"right\" ? label.x + gap : label.x - gap - w,\n y: sideY,\n width: w,\n height,\n },\n ];\n // beside the dot, raised or lowered by half a line: a crowded cell gets\n // more slots still next to their own dot\n const corners = (side: \"right\" | \"left\", w: number): Rect[] =>\n [label.y - height - 1, label.y + 1].map((y) => ({\n x: side === \"right\" ? label.x + gap : label.x - gap - w,\n y: Math.min(Math.max(y, y0), y1 - height),\n width: w,\n height,\n }));\n const stacked = (w: number): Rect[] => {\n // slid sideways into the cell near its edges (still over the dot)\n const x = Math.min(Math.max(label.x - w / 2, x0), x1 - w);\n return [\n { x, y: label.y - gap - height, width: w, height },\n { x, y: label.y + gap, width: w, height },\n ];\n };\n const w = measure(label.text);\n const whole = [\n ...beside(sides[0]!, w),\n ...beside(sides[1]!, w),\n ...stacked(w),\n ...corners(sides[0]!, w),\n ...corners(sides[1]!, w),\n ];\n const box = whole.find(free);\n if (box) return { label, box };\n // the whole text fits nowhere: cut it to the room beside the dot or above\n // / below it, keeping the longest text (the roomiest side on ties)\n const cuts: [number, (w: number) => Rect[]][] = [\n [\n room[sides[0]!],\n (cw) => [...beside(sides[0]!, cw), ...corners(sides[0]!, cw)],\n ],\n [\n room[sides[1]!],\n (cw) => [...beside(sides[1]!, cw), ...corners(sides[1]!, cw)],\n ],\n [x1 - x0, stacked],\n ];\n let best: { label: PointLabel; box: Rect } | null = null;\n // a cut keeps enough of the name to tell it (else the label is skipped,\n // like an overlapping one: the tooltip still names the point)\n const total = Array.from(label.text).length;\n const keep = Math.min(4, Math.ceil(total * 0.4));\n for (const [max, boxes] of cuts) {\n const text = fitText(label.text, max, measure);\n if (!text || (best && text.length <= best.label.text.length)) continue;\n if (Array.from(text).length - 1 < keep) continue;\n const cut = boxes(measure(text)).find(free);\n if (cut) best = { label: { ...label, text }, box: cut };\n }\n return best;\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n // the dots of the labels kept in cells (labels placed later included)\n const dots = labels.filter((label) => label.bounds);\n for (const label of labels) {\n if (label.placement === \"inside\") {\n const fit = insideBox(label, plot, measure, height);\n if (fit) placed.push(fit);\n continue;\n }\n if (label.bounds) {\n const fit = cellBox(\n label,\n label.bounds,\n plot,\n measure,\n height,\n occupied,\n dots,\n );\n if (!fit) continue;\n occupied.push(fit.box);\n placed.push(fit);\n continue;\n }\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const right = {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const left = {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : label.placement === \"right\"\n ? [right, left]\n : label.placement === \"left\"\n ? [left, right]\n : [\n {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n /** Lines between consecutive bars (waterfall connectors), drawn first */\n connectors?: readonly {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n color: string;\n width: number;\n dash: readonly number[];\n }[];\n /** Dependency arrows (Gantt charts), drawn over the connectors */\n arrows?: readonly ArrowPath[];\n}\n\n/** An elbow arrow in stage pixels (see `dependencyArrows`) */\nexport interface ArrowPath {\n points: readonly { x: number; y: number }[];\n head: readonly { x: number; y: number }[];\n color: string;\n width: number;\n}\n\n/** Elbow arrows: polylines with rounded corners and filled heads */\nexport const drawArrows = (\n ctx: CanvasRenderingContext2D,\n arrows: readonly ArrowPath[],\n) => {\n for (const a of arrows) {\n const pts = a.points;\n const first = pts[0];\n if (!first) continue;\n ctx.strokeStyle = a.color;\n ctx.fillStyle = a.color;\n ctx.lineWidth = a.width;\n ctx.lineJoin = \"round\";\n ctx.setLineDash([]);\n ctx.beginPath();\n ctx.moveTo(first.x, first.y);\n for (let i = 1; i < pts.length; i++) {\n const p = pts[i]!;\n const next = pts[i + 1];\n const prev = pts[i - 1]!;\n if (next && typeof ctx.arcTo === \"function\") {\n // rounded elbow, at most half of the shorter leg\n const r = Math.min(\n 4,\n Math.hypot(p.x - prev.x, p.y - prev.y) / 2,\n Math.hypot(next.x - p.x, next.y - p.y) / 2,\n );\n ctx.arcTo(p.x, p.y, next.x, next.y, r);\n } else {\n ctx.lineTo(p.x, p.y);\n }\n }\n ctx.stroke();\n const [tip, b0, b1] = a.head;\n if (tip && b0 && b1) {\n ctx.beginPath();\n ctx.moveTo(tip.x, tip.y);\n ctx.lineTo(b0.x, b0.y);\n ctx.lineTo(b1.x, b1.y);\n ctx.closePath();\n ctx.fill();\n }\n }\n};\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n for (const c of input.connectors ?? []) {\n ctx.strokeStyle = c.color;\n ctx.lineWidth = c.width;\n ctx.setLineDash([...c.dash]);\n ctx.beginPath();\n // crisp hairlines along the pixel grid\n const along = c.y0 === c.y1;\n const x0 = along ? c.x0 : crisp(c.x0);\n const y0 = along ? crisp(c.y0) : c.y0;\n ctx.moveTo(x0, y0);\n ctx.lineTo(along ? c.x1 : x0, along ? y0 : c.y1);\n ctx.stroke();\n }\n ctx.setLineDash([]);\n if (input.arrows?.length) drawArrows(ctx, input.arrows);\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n const where = lineOf(a, scales);\n if (!where.vertical) {\n const py = crisp(where.at);\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(where.at);\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !hasAreaTitle(a)) continue;\n const title = areaTitleLayout(\n a,\n rectOf(a, scales),\n theme.fontSize,\n (text, size, weight) => {\n ctx.font = font(theme, size, weight);\n return ctx.measureText(text).width;\n },\n );\n if (!title) continue;\n const color = toCss(a.labelColor);\n const muted = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n for (const p of title.parts) {\n const cy = p.y + p.height / 2;\n if (p.kind === \"badge\") {\n const h = p.height - 2;\n pill(ctx, p.x, cy - h / 2, p.width, h);\n ctx.fillStyle = toCss(a.labelColor, 0.16);\n ctx.fill();\n ctx.font = font(theme, p.size, p.weight);\n ctx.fillStyle = color;\n ctx.fillText(p.text, p.x + 5, cy);\n continue;\n }\n ctx.font = font(theme, p.size, p.weight);\n ctx.fillStyle = p.kind === \"label\" ? color : muted;\n ctx.fillText(p.text, p.x, cy);\n }\n occupied.push(title.box);\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n let placed: { label: PointLabel; box: Rect }[] = [];\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n if (label.hidden) continue;\n const y = box.y + box.height / 2;\n if (label.color) {\n ctx.fillStyle = label.color;\n ctx.fillText(label.text, box.x, y);\n } else haloText(ctx, label.text, box.x, y, textColor, halo);\n }\n }\n ctx.restore();\n return placed;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./tooltip.cjs"),t=require("./presets.cjs"),n=require("./quadrant-keyboard.cjs");var r=5,i=7,a=18,o=24,s=6,c=180,l=e=>({...e,tooltip:!1,interaction:typeof e.interaction==`object`?{...e.interaction,dragLabel:!1,hoverLabel:!1}:e.interaction}),u=e=>e?`${e.x}|${e.y}|${e.label??``}`:null,d=(e,t,n)=>(e-t)/(n-t||1),f=(c,l)=>{let f=l,p=null,m=null,h=null,g=null,_=null,v=!1,y=null,b=null,x=!1,S=``,C=null,w=null,T=null,E=0,D=c.ownerDocument,O=D.defaultView,k=D.createElement(`div`);k.className=`minerva-chart-quadrant-card`,e.styleTooltip(k,{zIndex:`3`,boxSizing:`border-box`,maxWidth:`min(280px, calc(100% + 12px))`,paddingTop:`${r}px`,paddingBottom:`${r}px`,borderRadius:`12px`,fontSize:`12px`,lineHeight:`18px`});let A=D.createElement(`span`);A.setAttribute(`aria-hidden`,`true`),A.dataset.cardDot=``,A.style.cssText=`position:absolute;border-radius:50%;pointer-events:none`;let j=D.createElement(`div`);j.dataset.cardContent=``,j.style.cssText=`display:grid;column-gap:6px;align-items:center`;let M=D.createElement(`div`);M.setAttribute(`aria-hidden`,`true`),M.style.cssText=`grid-area:label;min-width:0;cursor:pointer`;let N=D.createElement(`strong`);N.style.cssText=`display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600`;let P=D.createElement(`div`);M.append(N,P);let F=D.createElement(`div`);F.dataset.cardActions=``,F.style.cssText=`grid-area:actions;align-self:start;display:flex;align-items:center;height:${o}px`;let I=D.createElement(`span`);I.setAttribute(`aria-hidden`,`true`),I.style.cssText=`grid-area:meta;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary-color, #6b7280);font-size:11px;line-height:16px`,j.append(M,F,I),k.append(A,j);let L=()=>f.config.points,R=e=>e===null?null:{index:e,key:u(L()[e])},z=e=>e&&e.key!==null&&u(L()[e.index])===e.key?e.index:null,B=()=>{let e=f.selectedIndex;return f.showSelected&&e!=null&&L()[e]?e:null},V=()=>v?null:z(m)??(f.hover===!1?null:z(p))??z(h)??B(),H=()=>{if(g!==null)return L()[g]?g:null;let e=V(),t=e===null?void 0:L()[e];return t&&Number.isFinite(t.x)&&Number.isFinite(t.y)?e:null},U=e=>g===null&&!!f.hasActions?.(e),W=()=>{let r=y,l=r===null?void 0:L()[r];if(r===null||!l||!k.parentNode)return;let{config:u}=f;x||(x=!0,e.themeTooltip(k,k));let p=g===null?null:_,m=p??l,[h,v]=u.xDomain??[0,10],[b,C]=u.yDomain??[0,10],w=d(m.x,h,v),T=u.reverseX?1-w:w,E=parseFloat(c.style.width)||c.clientWidth,D=parseFloat(c.style.height)||c.clientHeight,O=T*E,M=(1-d(m.y,b,C))*D,N=l.size??f.pointSize??12,P=U(r),F=P?o:a,R=9+N/2+(p?8:0),z=k.offsetWidth,B=k.offsetHeight,V=T>.6;if(z){let e=O-R+z-E,t=z-R-O,n=k.dataset.side;V=n===`start`&&e<=s?!1:n===`end`&&t<=s||e>0&&t<e}let H=M-(6+F/2);B&&(H=Math.max(-6,Math.min(H,D+s-B)));let W=V?`end`:`start`;k.dataset.side=W;let G=`${W}|${P}|${N}`;if(S!==G){S=G;let e=`${8+N+i}px`,t=P?`4px`:`12px`;k.style.paddingLeft=V?t:e,k.style.paddingRight=V?e:t,k.style.textAlign=V?`right`:`left`,j.style.minHeight=`${F}px`,j.style.gridTemplateAreas=V?`"actions label" ". meta"`:`"label actions" "meta ."`,j.style.gridTemplateColumns=V?`auto minmax(0, 1fr)`:`minmax(0, 1fr) auto`,A.style.width=`${N}px`,A.style.height=`${N}px`}k.style.transform=`translate(${O}px, ${H}px) translate(${V?`calc(-100% + ${R}px)`:`${-R}px`}, 0)`;let K=t.quadrantOf(u,m.x,m.y),q=u.quadrants?.[K],J=n.quadrantName(K,u,t.quadrantLabels(f.locale)),Y=q?.badge?`${q.badge} · ${J}`:J;I.textContent!==Y&&(I.textContent=Y);let X=t.quadrantOf(u,l.x,l.y),Z=l.color??u.quadrants?.[X]?.color??t.DEFAULT_QUADRANT_COLORS[X];A.style.display=p?`none`:`block`,A.style.left=V?`auto`:`8px`,A.style.right=V?`8px`:`auto`,A.style.top=`${M-H-1-N/2}px`,A.style.background=Z,A.style.boxShadow=`0 0 0 2px var(--surface-color, var(--background-color, #fff)), 0 0 0 4px color-mix(in srgb, ${Z} 45%, transparent)`},G=e=>{e.key===`Escape`&&g===null&&y!==null&&($.dismiss(),f.onDismiss?.())},K=()=>{let e=H(),t=e!==y;if(y=e,e===null)k.parentNode&&(k.remove(),D.removeEventListener(`keydown`,G)),S=``,delete k.dataset.side;else{let n=L()[e];t&&(x=!1,delete k.dataset.side),k.dataset.pointPreview=String(e),g===null?delete k.dataset.dragging:k.dataset.dragging=``;let r=!!f.custom&&g===null;N.textContent=n.label??``,N.style.display=r?`none`:`block`,P.style.display=r?`block`:`none`,I.style.display=r?`none`:`block`,F.style.display=U(e)?`flex`:`none`,j.style.pointerEvents=g===null?`auto`:`none`,k.parentNode||(c.appendChild(k),D.addEventListener(`keydown`,G))}f.chart?.setLabelHidden(e!==null&&g===null?{seriesIndex:0,index:e}:null),W();let n=g===null?e:null;n!==b&&(b=n,f.onChange?.(n))},q=e=>{if(w&&clearTimeout(w),w=null,e!==null)return m=R(e),K();w=setTimeout(()=>{w=null,m=null,K()},180)},J=()=>{y!==null&&g===null&&q(y)},Y=()=>q(null),X=e=>{j.contains(e.relatedTarget)||q(null)},Z=()=>{y!==null&&g===null&&f.onClick?.(y)};j.addEventListener(`pointerenter`,J),j.addEventListener(`pointerleave`,Y),j.addEventListener(`focusin`,J),j.addEventListener(`focusout`,X),M.addEventListener(`click`,Z);let Q=typeof ResizeObserver==`function`?new ResizeObserver(()=>W()):null;Q?.observe(k),Q?.observe(c);let $={element:k,actions:F,content:P,get index(){return y},update(e){let t=f.selectedIndex;f=e,e.showSelected&&e.selectedIndex!==t&&e.selectedIndex!=null&&(v=!1),K()},hover(e){if(C&&clearTimeout(C),C=null,e!==null)return p=R(e),v=!1,K();C=setTimeout(()=>{C=null,p=null,K()},180)},focus(e){if(T&&clearTimeout(T),T=null,e===null){if(!h)return;T=setTimeout(()=>{T=null,h=null,K()},0);return}h=R(e),v=!1,K()},drag(e,t){g=e,_=e===null?null:t??null,e!==null&&(v=!1,m=null),K()},move(e){if(_=e,!O?.requestAnimationFrame)return W();E||(E=O.requestAnimationFrame(()=>{E=0,W()}))},dismiss(){v=!0,m=null,p=null,w&&clearTimeout(w),C&&clearTimeout(C),w=C=null,K()},place:W,destroy(){C&&clearTimeout(C),w&&clearTimeout(w),T&&clearTimeout(T),E&&O?.cancelAnimationFrame(E),Q?.disconnect(),D.removeEventListener(`keydown`,G),j.removeEventListener(`pointerenter`,J),j.removeEventListener(`pointerleave`,Y),j.removeEventListener(`focusin`,J),j.removeEventListener(`focusout`,X),M.removeEventListener(`click`,Z),k.remove(),f.chart?.setLabelHidden(null)}};return K(),$};exports.CARD_LINGER_MS=c,exports.createQuadrantPointCard=f,exports.withQuadrantCard=l;
|
|
2
|
+
//# sourceMappingURL=quadrant-card.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quadrant-card.cjs","names":["quadrantOf","quadrantName","quadrantLabels","DEFAULT_QUADRANT_COLORS","require_tooltip","require_presets","require_quadrant_keyboard","CARD_PAD_Y","CARD_DOT_GAP","CARD_ROW","CARD_ACTIONS_ROW","CARD_OVERHANG","CARD_LINGER_MS","withQuadrantCard","options","keyOf","point","fraction","v","a","b","createQuadrantPointCard","initial","hovered","held","focused","dragging","dragAt","dismissed","shown","reported","themed","layout","hoverTimer","holdTimer","focusTimer","frame","doc","host","win","card","dot","body","label","name","content","actions","meta","points","refTo","index","valid","ref","selected","activeIndex","cardIndex","withActions","place","live","at","x0","x1","config","y0","y1","fx","visualX","plotWidth","plotHeight","left","top","size","hasActions","row","reach","width","height","mirrored","overRight","overLeft","was","cardTop","side","nextLayout","lead","trail","corner","region","where","text","own","color","onKey","event","api","render","changed","custom","report","hold","onEnter","onLeave","onFocusOut","onClick","resizeObserver","selection","next"],"sources":["../../../../charts/src/engine/quadrant-card.ts"],"sourcesContent":["// The point card of the quadrant matrices, shared by every renderer: one\n// glass card for the hovered, focused, dragged (or, on boards, selected)\n// point. Its dot lies on the point, the name and the quadrant beside it, the\n// actions of the host (edit, delete...) in its first row. The card is DOM\n// placed by hand: hover, focus and drag moves render no framework component;\n// the host only fills the actions box (and, in React, a custom content) when\n// the point of the card changes.\n\nimport {\n DEFAULT_QUADRANT_COLORS,\n quadrantLabels,\n quadrantOf,\n type QuadrantPoint,\n} from \"./presets\";\nimport {\n quadrantName,\n type QuadrantAccessibleConfig,\n} from \"./quadrant-keyboard\";\nimport { styleTooltip, themeTooltip } from \"./tooltip\";\nimport type { ChartInstance, ChartOptions } from \"./types\";\n\n/** Settings of the point card of a quadrant matrix */\nexport interface QuadrantPointCardOptions {\n /** The points and the geometry of the matrix */\n config: QuadrantAccessibleConfig;\n /** Language of the built-in quadrant names */\n locale?: string;\n /** Diameter of the dots (`pointSize`); 12 by default */\n pointSize?: number;\n /** A hovered point shows the card; `false` (no tooltip): focus and drag only */\n hover?: boolean;\n /** The selected point */\n selectedIndex?: number | null;\n /**\n * The selected point keeps the card (boards: its actions stay at hand);\n * otherwise a selection shows only its ring\n */\n showSelected?: boolean;\n /** The card of this point has actions: the host fills `actions` */\n hasActions?: (index: number) => boolean;\n /** The host fills `content` (a custom card) instead of the name and quadrant */\n custom?: boolean;\n /** The engine of the chart: the drawn label of the point gives way to the card */\n chart?: ChartInstance | null;\n /** A click on the name of the card (like a click on the dot) */\n onClick?: (index: number) => void;\n /**\n * The point whose actions (or custom content) the host renders changed;\n * `null`: none (no card, or a drag)\n */\n onChange?: (index: number | null) => void;\n /** Escape closed the card */\n onDismiss?: () => void;\n}\n\n/** Position of a dragged point, in data values */\nexport interface QuadrantCardPosition {\n x: number;\n y: number;\n}\n\n/** The point card of a quadrant matrix */\nexport interface QuadrantPointCard {\n /** Root of the card (`.minerva-chart-quadrant-card`); in the DOM while shown */\n readonly element: HTMLElement;\n /** Box of the actions of the host, in the first row of the card */\n readonly actions: HTMLElement;\n /** Box of a custom content (`custom`), in place of the name and quadrant */\n readonly content: HTMLElement;\n /** The point of the card, `null` while hidden */\n readonly index: number | null;\n /** Applies new settings (new points: the card keeps its point while it is the same) */\n update(options: QuadrantPointCardOptions): void;\n /** The hovered point of the engine (`null`: the card lingers a moment, then goes) */\n hover(index: number | null): void;\n /** The focused point button */\n focus(index: number | null): void;\n /** A point is dragged (`null`: the drag ended); the card follows `move` */\n drag(index: number | null, at?: QuadrantCardPosition): void;\n /** New position of the dragged point (placed once per frame) */\n move(at: QuadrantCardPosition): void;\n /** Hides the card until another point is hovered, focused or selected */\n dismiss(): void;\n /** Places the card again (the plot or the content of the host changed) */\n place(): void;\n destroy(): void;\n}\n\n/** Room between the edge of the point card and its dot, CSS pixels */\nexport const CARD_PAD_X = 8;\nconst CARD_PAD_Y = 5;\n/** Room between the dot of the card and its text */\nconst CARD_DOT_GAP = 7;\n/** Height of the first row of the card: the name, or the name and actions */\nconst CARD_ROW = 18;\nconst CARD_ACTIONS_ROW = 24;\n/** How far the card may reach past the plot edges */\nconst CARD_OVERHANG = 6;\n/**\n * The card stays this long after the pointer leaves its dot: time to reach\n * its actions\n */\nexport const CARD_LINGER_MS = 180;\n\n/**\n * Engine options of a matrix showing the point card: no engine tooltip, no\n * label chip and no drag pill beside it\n */\nexport const withQuadrantCard = (options: ChartOptions): ChartOptions => ({\n ...options,\n tooltip: false,\n interaction:\n typeof options.interaction === \"object\"\n ? { ...options.interaction, dragLabel: false, hoverLabel: false }\n : options.interaction,\n});\n\n/** A point named by its content: new arrays of the same points keep it */\nconst keyOf = (point: QuadrantPoint | undefined) =>\n point ? `${point.x}|${point.y}|${point.label ?? \"\"}` : null;\n\ninterface PointRef {\n index: number;\n key: string | null;\n}\n\nconst fraction = (v: number, a: number, b: number) => (v - a) / (b - a || 1);\n\n/**\n * Mounts the point card of a quadrant matrix in `host`, a box covering the\n * plot area (its `style.width` / `style.height`, else its client size)\n */\nexport const createQuadrantPointCard = (\n host: HTMLElement,\n initial: QuadrantPointCardOptions,\n): QuadrantPointCard => {\n let options = initial;\n let hovered: PointRef | null = null;\n let held: PointRef | null = null;\n let focused: PointRef | null = null;\n let dragging: number | null = null;\n let dragAt: QuadrantCardPosition | null = null;\n let dismissed = false;\n let shown: number | null = null;\n let reported: number | null = null;\n let themed = false;\n let layout = \"\";\n let hoverTimer: ReturnType<typeof setTimeout> | null = null;\n let holdTimer: ReturnType<typeof setTimeout> | null = null;\n let focusTimer: ReturnType<typeof setTimeout> | null = null;\n let frame = 0;\n const doc = host.ownerDocument;\n const win = doc.defaultView;\n\n const card = doc.createElement(\"div\");\n card.className = \"minerva-chart-quadrant-card\";\n styleTooltip(card, {\n zIndex: \"3\",\n boxSizing: \"border-box\",\n maxWidth: \"min(280px, calc(100% + 12px))\",\n paddingTop: `${CARD_PAD_Y}px`,\n paddingBottom: `${CARD_PAD_Y}px`,\n borderRadius: \"12px\",\n fontSize: \"12px\",\n lineHeight: \"18px\",\n });\n const dot = doc.createElement(\"span\");\n dot.setAttribute(\"aria-hidden\", \"true\");\n dot.dataset.cardDot = \"\";\n dot.style.cssText = \"position:absolute;border-radius:50%;pointer-events:none\";\n // the dot lets the pointer through to the chart (hover, drag); the text\n // and the actions hold the card\n const body = doc.createElement(\"div\");\n body.dataset.cardContent = \"\";\n body.style.cssText = \"display:grid;column-gap:6px;align-items:center\";\n // a click on the name acts like a click on the dot\n const label = doc.createElement(\"div\");\n label.setAttribute(\"aria-hidden\", \"true\");\n label.style.cssText = \"grid-area:label;min-width:0;cursor:pointer\";\n const name = doc.createElement(\"strong\");\n name.style.cssText =\n \"display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600\";\n const content = doc.createElement(\"div\");\n label.append(name, content);\n const actions = doc.createElement(\"div\");\n actions.dataset.cardActions = \"\";\n actions.style.cssText = `grid-area:actions;align-self:start;display:flex;align-items:center;height:${CARD_ACTIONS_ROW}px`;\n const meta = doc.createElement(\"span\");\n meta.setAttribute(\"aria-hidden\", \"true\");\n meta.style.cssText =\n \"grid-area:meta;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\" +\n \"color:var(--text-secondary-color, #6b7280);font-size:11px;line-height:16px\";\n body.append(label, actions, meta);\n card.append(dot, body);\n\n const points = () => options.config.points;\n const refTo = (index: number | null): PointRef | null =>\n index === null ? null : { index, key: keyOf(points()[index]) };\n const valid = (ref: PointRef | null) =>\n ref && ref.key !== null && keyOf(points()[ref.index]) === ref.key\n ? ref.index\n : null;\n const selected = () => {\n const index = options.selectedIndex;\n return options.showSelected &&\n index !== null &&\n index !== undefined &&\n points()[index]\n ? index\n : null;\n };\n const activeIndex = () =>\n dismissed\n ? null\n : (valid(held) ??\n (options.hover !== false ? valid(hovered) : null) ??\n valid(focused) ??\n selected());\n const cardIndex = () => {\n if (dragging !== null) return points()[dragging] ? dragging : null;\n const index = activeIndex();\n const point = index === null ? undefined : points()[index];\n return point && Number.isFinite(point.x) && Number.isFinite(point.y)\n ? index\n : null;\n };\n const withActions = (index: number) =>\n dragging === null && !!options.hasActions?.(index);\n\n const place = () => {\n const index = shown;\n const point = index === null ? undefined : points()[index];\n if (index === null || !point || !card.parentNode) return;\n const { config } = options;\n if (!themed) {\n themed = true;\n // the colors of the theme around it, read again for every new point\n themeTooltip(card, card);\n }\n const live = dragging !== null ? dragAt : null;\n const at = live ?? point;\n const [x0, x1] = config.xDomain ?? [0, 10];\n const [y0, y1] = config.yDomain ?? [0, 10];\n const fx = fraction(at.x, x0, x1);\n const visualX = config.reverseX ? 1 - fx : fx;\n const plotWidth = parseFloat(host.style.width) || host.clientWidth;\n const plotHeight = parseFloat(host.style.height) || host.clientHeight;\n const left = visualX * plotWidth;\n const top = (1 - fraction(at.y, y0, y1)) * plotHeight;\n const size = point.size ?? options.pointSize ?? 12;\n const hasActions = withActions(index);\n const row = hasActions ? CARD_ACTIONS_ROW : CARD_ROW;\n // the dot of the card lies on the point (the border is 1px); the lifted\n // dot of a drag is larger: the card keeps off it\n const reach = 1 + CARD_PAD_X + size / 2 + (live ? 8 : 0);\n const width = card.offsetWidth;\n const height = card.offsetHeight;\n // the text on the side with room (mirrored near the right edge); a side\n // that still fits is kept (no flipping back and forth in a drag)\n let mirrored = visualX > 0.6;\n if (width) {\n const overRight = left - reach + width - plotWidth;\n const overLeft = width - reach - left;\n const was = card.dataset.side;\n mirrored =\n was === \"start\" && overRight <= CARD_OVERHANG\n ? false\n : was === \"end\" && overLeft <= CARD_OVERHANG\n ? true\n : overRight > 0 && overLeft < overRight;\n }\n // the dot on the first row, the card kept in the plot near its edges\n let cardTop = top - (1 + CARD_PAD_Y + row / 2);\n if (height)\n cardTop = Math.max(\n -CARD_OVERHANG,\n Math.min(cardTop, plotHeight + CARD_OVERHANG - height),\n );\n const side = mirrored ? \"end\" : \"start\";\n card.dataset.side = side;\n const nextLayout = `${side}|${hasActions}|${size}`;\n if (layout !== nextLayout) {\n layout = nextLayout;\n const lead = `${CARD_PAD_X + size + CARD_DOT_GAP}px`;\n const trail = hasActions ? \"4px\" : \"12px\";\n card.style.paddingLeft = mirrored ? trail : lead;\n card.style.paddingRight = mirrored ? lead : trail;\n card.style.textAlign = mirrored ? \"right\" : \"left\";\n body.style.minHeight = `${row}px`;\n body.style.gridTemplateAreas = mirrored\n ? '\"actions label\" \". meta\"'\n : '\"label actions\" \"meta .\"';\n body.style.gridTemplateColumns = mirrored\n ? \"auto minmax(0, 1fr)\"\n : \"minmax(0, 1fr) auto\";\n dot.style.width = `${size}px`;\n dot.style.height = `${size}px`;\n }\n card.style.transform = `translate(${left}px, ${cardTop}px) translate(${\n mirrored ? `calc(-100% + ${reach}px)` : `${-reach}px`\n }, 0)`;\n // the quadrant under the point (live in a drag)\n const corner = quadrantOf(config, at.x, at.y);\n const region = config.quadrants?.[corner];\n const where = quadrantName(corner, config, quadrantLabels(options.locale));\n const text = region?.badge ? `${region.badge} · ${where}` : where;\n if (meta.textContent !== text) meta.textContent = text;\n const own = quadrantOf(config, point.x, point.y);\n const color =\n point.color ??\n config.quadrants?.[own]?.color ??\n DEFAULT_QUADRANT_COLORS[own];\n dot.style.display = live ? \"none\" : \"block\";\n dot.style.left = mirrored ? \"auto\" : `${CARD_PAD_X}px`;\n dot.style.right = mirrored ? `${CARD_PAD_X}px` : \"auto\";\n dot.style.top = `${top - cardTop - 1 - size / 2}px`;\n dot.style.background = color;\n dot.style.boxShadow = `0 0 0 2px var(--surface-color, var(--background-color, #fff)), 0 0 0 4px color-mix(in srgb, ${color} 45%, transparent)`;\n };\n\n const onKey = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || dragging !== null || shown === null) return;\n api.dismiss();\n options.onDismiss?.();\n };\n\n const render = () => {\n const index = cardIndex();\n const changed = index !== shown;\n shown = index;\n if (index === null) {\n if (card.parentNode) {\n card.remove();\n doc.removeEventListener(\"keydown\", onKey);\n }\n layout = \"\";\n delete card.dataset.side;\n } else {\n const point = points()[index]!;\n if (changed) {\n // a new point: its colors, its side\n themed = false;\n delete card.dataset.side;\n }\n card.dataset.pointPreview = String(index);\n if (dragging !== null) card.dataset.dragging = \"\";\n else delete card.dataset.dragging;\n const custom = !!options.custom && dragging === null;\n name.textContent = point.label ?? \"\";\n name.style.display = custom ? \"none\" : \"block\";\n content.style.display = custom ? \"block\" : \"none\";\n meta.style.display = custom ? \"none\" : \"block\";\n actions.style.display = withActions(index) ? \"flex\" : \"none\";\n body.style.pointerEvents = dragging !== null ? \"none\" : \"auto\";\n if (!card.parentNode) {\n host.appendChild(card);\n doc.addEventListener(\"keydown\", onKey);\n }\n }\n // the card names the point: its drawn label gives way (keeping its place)\n options.chart?.setLabelHidden(\n index !== null && dragging === null ? { seriesIndex: 0, index } : null,\n );\n place();\n const report = dragging === null ? index : null;\n if (report !== reported) {\n reported = report;\n options.onChange?.(report);\n }\n };\n\n const hold = (index: number | null) => {\n if (holdTimer) clearTimeout(holdTimer);\n holdTimer = null;\n if (index !== null) {\n held = refTo(index);\n return render();\n }\n holdTimer = setTimeout(() => {\n holdTimer = null;\n held = null;\n render();\n }, CARD_LINGER_MS);\n };\n const onEnter = () => {\n if (shown !== null && dragging === null) hold(shown);\n };\n const onLeave = () => hold(null);\n const onFocusOut = (event: FocusEvent) => {\n if (!body.contains(event.relatedTarget as Node | null)) hold(null);\n };\n const onClick = () => {\n if (shown !== null && dragging === null) options.onClick?.(shown);\n };\n body.addEventListener(\"pointerenter\", onEnter);\n body.addEventListener(\"pointerleave\", onLeave);\n body.addEventListener(\"focusin\", onEnter);\n body.addEventListener(\"focusout\", onFocusOut);\n label.addEventListener(\"click\", onClick);\n\n // the size of the card follows its content (actions, custom content)\n const resizeObserver =\n typeof ResizeObserver === \"function\"\n ? new ResizeObserver(() => place())\n : null;\n resizeObserver?.observe(card);\n // and its place follows the plot\n resizeObserver?.observe(host);\n\n const api: QuadrantPointCard = {\n element: card,\n actions,\n content,\n get index() {\n return shown;\n },\n update(next) {\n const selection = options.selectedIndex;\n options = next;\n if (\n next.showSelected &&\n next.selectedIndex !== selection &&\n next.selectedIndex != null\n )\n dismissed = false;\n render();\n },\n hover(index) {\n if (hoverTimer) clearTimeout(hoverTimer);\n hoverTimer = null;\n if (index !== null) {\n hovered = refTo(index);\n dismissed = false;\n return render();\n }\n // off the dot: the card stays a moment (the pointer may be on its way\n // to the actions)\n hoverTimer = setTimeout(() => {\n hoverTimer = null;\n hovered = null;\n render();\n }, CARD_LINGER_MS);\n },\n focus(index) {\n if (focusTimer) clearTimeout(focusTimer);\n focusTimer = null;\n if (index === null) {\n // focus leaving a point button may be on its way into the actions\n // of the card: they hold it first\n if (!focused) return;\n focusTimer = setTimeout(() => {\n focusTimer = null;\n focused = null;\n render();\n }, 0);\n return;\n }\n focused = refTo(index);\n dismissed = false;\n render();\n },\n drag(index, at) {\n dragging = index;\n dragAt = index === null ? null : (at ?? null);\n if (index !== null) {\n dismissed = false;\n held = null;\n }\n render();\n },\n move(at) {\n dragAt = at;\n if (!win?.requestAnimationFrame) return place();\n if (!frame)\n frame = win.requestAnimationFrame(() => {\n frame = 0;\n place();\n });\n },\n dismiss() {\n dismissed = true;\n held = null;\n hovered = null;\n if (holdTimer) clearTimeout(holdTimer);\n if (hoverTimer) clearTimeout(hoverTimer);\n holdTimer = hoverTimer = null;\n render();\n },\n place,\n destroy() {\n if (hoverTimer) clearTimeout(hoverTimer);\n if (holdTimer) clearTimeout(holdTimer);\n if (focusTimer) clearTimeout(focusTimer);\n if (frame) win?.cancelAnimationFrame(frame);\n resizeObserver?.disconnect();\n doc.removeEventListener(\"keydown\", onKey);\n body.removeEventListener(\"pointerenter\", onEnter);\n body.removeEventListener(\"pointerleave\", onLeave);\n body.removeEventListener(\"focusin\", onEnter);\n body.removeEventListener(\"focusout\", onFocusOut);\n label.removeEventListener(\"click\", onClick);\n card.remove();\n options.chart?.setLabelHidden(null);\n },\n };\n render();\n return api;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { QuadrantAccessibleConfig } from './quadrant-keyboard.cjs';
|
|
2
|
+
import { ChartInstance, ChartOptions } from './types.cjs';
|
|
3
|
+
/** Settings of the point card of a quadrant matrix */
|
|
4
|
+
export interface QuadrantPointCardOptions {
|
|
5
|
+
/** The points and the geometry of the matrix */
|
|
6
|
+
config: QuadrantAccessibleConfig;
|
|
7
|
+
/** Language of the built-in quadrant names */
|
|
8
|
+
locale?: string;
|
|
9
|
+
/** Diameter of the dots (`pointSize`); 12 by default */
|
|
10
|
+
pointSize?: number;
|
|
11
|
+
/** A hovered point shows the card; `false` (no tooltip): focus and drag only */
|
|
12
|
+
hover?: boolean;
|
|
13
|
+
/** The selected point */
|
|
14
|
+
selectedIndex?: number | null;
|
|
15
|
+
/**
|
|
16
|
+
* The selected point keeps the card (boards: its actions stay at hand);
|
|
17
|
+
* otherwise a selection shows only its ring
|
|
18
|
+
*/
|
|
19
|
+
showSelected?: boolean;
|
|
20
|
+
/** The card of this point has actions: the host fills `actions` */
|
|
21
|
+
hasActions?: (index: number) => boolean;
|
|
22
|
+
/** The host fills `content` (a custom card) instead of the name and quadrant */
|
|
23
|
+
custom?: boolean;
|
|
24
|
+
/** The engine of the chart: the drawn label of the point gives way to the card */
|
|
25
|
+
chart?: ChartInstance | null;
|
|
26
|
+
/** A click on the name of the card (like a click on the dot) */
|
|
27
|
+
onClick?: (index: number) => void;
|
|
28
|
+
/**
|
|
29
|
+
* The point whose actions (or custom content) the host renders changed;
|
|
30
|
+
* `null`: none (no card, or a drag)
|
|
31
|
+
*/
|
|
32
|
+
onChange?: (index: number | null) => void;
|
|
33
|
+
/** Escape closed the card */
|
|
34
|
+
onDismiss?: () => void;
|
|
35
|
+
}
|
|
36
|
+
/** Position of a dragged point, in data values */
|
|
37
|
+
export interface QuadrantCardPosition {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
}
|
|
41
|
+
/** The point card of a quadrant matrix */
|
|
42
|
+
export interface QuadrantPointCard {
|
|
43
|
+
/** Root of the card (`.minerva-chart-quadrant-card`); in the DOM while shown */
|
|
44
|
+
readonly element: HTMLElement;
|
|
45
|
+
/** Box of the actions of the host, in the first row of the card */
|
|
46
|
+
readonly actions: HTMLElement;
|
|
47
|
+
/** Box of a custom content (`custom`), in place of the name and quadrant */
|
|
48
|
+
readonly content: HTMLElement;
|
|
49
|
+
/** The point of the card, `null` while hidden */
|
|
50
|
+
readonly index: number | null;
|
|
51
|
+
/** Applies new settings (new points: the card keeps its point while it is the same) */
|
|
52
|
+
update(options: QuadrantPointCardOptions): void;
|
|
53
|
+
/** The hovered point of the engine (`null`: the card lingers a moment, then goes) */
|
|
54
|
+
hover(index: number | null): void;
|
|
55
|
+
/** The focused point button */
|
|
56
|
+
focus(index: number | null): void;
|
|
57
|
+
/** A point is dragged (`null`: the drag ended); the card follows `move` */
|
|
58
|
+
drag(index: number | null, at?: QuadrantCardPosition): void;
|
|
59
|
+
/** New position of the dragged point (placed once per frame) */
|
|
60
|
+
move(at: QuadrantCardPosition): void;
|
|
61
|
+
/** Hides the card until another point is hovered, focused or selected */
|
|
62
|
+
dismiss(): void;
|
|
63
|
+
/** Places the card again (the plot or the content of the host changed) */
|
|
64
|
+
place(): void;
|
|
65
|
+
destroy(): void;
|
|
66
|
+
}
|
|
67
|
+
/** Room between the edge of the point card and its dot, CSS pixels */
|
|
68
|
+
export declare const CARD_PAD_X = 8;
|
|
69
|
+
/**
|
|
70
|
+
* The card stays this long after the pointer leaves its dot: time to reach
|
|
71
|
+
* its actions
|
|
72
|
+
*/
|
|
73
|
+
export declare const CARD_LINGER_MS = 180;
|
|
74
|
+
/**
|
|
75
|
+
* Engine options of a matrix showing the point card: no engine tooltip, no
|
|
76
|
+
* label chip and no drag pill beside it
|
|
77
|
+
*/
|
|
78
|
+
export declare const withQuadrantCard: (options: ChartOptions) => ChartOptions;
|
|
79
|
+
/**
|
|
80
|
+
* Mounts the point card of a quadrant matrix in `host`, a box covering the
|
|
81
|
+
* plot area (its `style.width` / `style.height`, else its client size)
|
|
82
|
+
*/
|
|
83
|
+
export declare const createQuadrantPointCard: (host: HTMLElement, initial: QuadrantPointCardOptions) => QuadrantPointCard;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { QuadrantAccessibleConfig } from './quadrant-keyboard.js';
|
|
2
|
+
import { ChartInstance, ChartOptions } from './types.js';
|
|
3
|
+
/** Settings of the point card of a quadrant matrix */
|
|
4
|
+
export interface QuadrantPointCardOptions {
|
|
5
|
+
/** The points and the geometry of the matrix */
|
|
6
|
+
config: QuadrantAccessibleConfig;
|
|
7
|
+
/** Language of the built-in quadrant names */
|
|
8
|
+
locale?: string;
|
|
9
|
+
/** Diameter of the dots (`pointSize`); 12 by default */
|
|
10
|
+
pointSize?: number;
|
|
11
|
+
/** A hovered point shows the card; `false` (no tooltip): focus and drag only */
|
|
12
|
+
hover?: boolean;
|
|
13
|
+
/** The selected point */
|
|
14
|
+
selectedIndex?: number | null;
|
|
15
|
+
/**
|
|
16
|
+
* The selected point keeps the card (boards: its actions stay at hand);
|
|
17
|
+
* otherwise a selection shows only its ring
|
|
18
|
+
*/
|
|
19
|
+
showSelected?: boolean;
|
|
20
|
+
/** The card of this point has actions: the host fills `actions` */
|
|
21
|
+
hasActions?: (index: number) => boolean;
|
|
22
|
+
/** The host fills `content` (a custom card) instead of the name and quadrant */
|
|
23
|
+
custom?: boolean;
|
|
24
|
+
/** The engine of the chart: the drawn label of the point gives way to the card */
|
|
25
|
+
chart?: ChartInstance | null;
|
|
26
|
+
/** A click on the name of the card (like a click on the dot) */
|
|
27
|
+
onClick?: (index: number) => void;
|
|
28
|
+
/**
|
|
29
|
+
* The point whose actions (or custom content) the host renders changed;
|
|
30
|
+
* `null`: none (no card, or a drag)
|
|
31
|
+
*/
|
|
32
|
+
onChange?: (index: number | null) => void;
|
|
33
|
+
/** Escape closed the card */
|
|
34
|
+
onDismiss?: () => void;
|
|
35
|
+
}
|
|
36
|
+
/** Position of a dragged point, in data values */
|
|
37
|
+
export interface QuadrantCardPosition {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
}
|
|
41
|
+
/** The point card of a quadrant matrix */
|
|
42
|
+
export interface QuadrantPointCard {
|
|
43
|
+
/** Root of the card (`.minerva-chart-quadrant-card`); in the DOM while shown */
|
|
44
|
+
readonly element: HTMLElement;
|
|
45
|
+
/** Box of the actions of the host, in the first row of the card */
|
|
46
|
+
readonly actions: HTMLElement;
|
|
47
|
+
/** Box of a custom content (`custom`), in place of the name and quadrant */
|
|
48
|
+
readonly content: HTMLElement;
|
|
49
|
+
/** The point of the card, `null` while hidden */
|
|
50
|
+
readonly index: number | null;
|
|
51
|
+
/** Applies new settings (new points: the card keeps its point while it is the same) */
|
|
52
|
+
update(options: QuadrantPointCardOptions): void;
|
|
53
|
+
/** The hovered point of the engine (`null`: the card lingers a moment, then goes) */
|
|
54
|
+
hover(index: number | null): void;
|
|
55
|
+
/** The focused point button */
|
|
56
|
+
focus(index: number | null): void;
|
|
57
|
+
/** A point is dragged (`null`: the drag ended); the card follows `move` */
|
|
58
|
+
drag(index: number | null, at?: QuadrantCardPosition): void;
|
|
59
|
+
/** New position of the dragged point (placed once per frame) */
|
|
60
|
+
move(at: QuadrantCardPosition): void;
|
|
61
|
+
/** Hides the card until another point is hovered, focused or selected */
|
|
62
|
+
dismiss(): void;
|
|
63
|
+
/** Places the card again (the plot or the content of the host changed) */
|
|
64
|
+
place(): void;
|
|
65
|
+
destroy(): void;
|
|
66
|
+
}
|
|
67
|
+
/** Room between the edge of the point card and its dot, CSS pixels */
|
|
68
|
+
export declare const CARD_PAD_X = 8;
|
|
69
|
+
/**
|
|
70
|
+
* The card stays this long after the pointer leaves its dot: time to reach
|
|
71
|
+
* its actions
|
|
72
|
+
*/
|
|
73
|
+
export declare const CARD_LINGER_MS = 180;
|
|
74
|
+
/**
|
|
75
|
+
* Engine options of a matrix showing the point card: no engine tooltip, no
|
|
76
|
+
* label chip and no drag pill beside it
|
|
77
|
+
*/
|
|
78
|
+
export declare const withQuadrantCard: (options: ChartOptions) => ChartOptions;
|
|
79
|
+
/**
|
|
80
|
+
* Mounts the point card of a quadrant matrix in `host`, a box covering the
|
|
81
|
+
* plot area (its `style.width` / `style.height`, else its client size)
|
|
82
|
+
*/
|
|
83
|
+
export declare const createQuadrantPointCard: (host: HTMLElement, initial: QuadrantPointCardOptions) => QuadrantPointCard;
|