@k2b/ui 0.51.0 → 0.52.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/dist/base.css +3 -0
- package/dist/browser/actions/Toolbar.js +8 -2
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/charts/core/bar-labels.js +5 -0
- package/dist/browser/charts/core/bar-labels.js.map +1 -0
- package/dist/browser/charts/core/bubble.js +166 -0
- package/dist/browser/charts/core/bubble.js.map +1 -0
- package/dist/browser/charts/core/default-styles.js +83 -0
- package/dist/browser/charts/core/default-styles.js.map +1 -0
- package/dist/browser/charts/core/funnel-layout.js +79 -0
- package/dist/browser/charts/core/funnel-layout.js.map +1 -0
- package/dist/browser/charts/core/funnel.js +27 -0
- package/dist/browser/charts/core/funnel.js.map +1 -0
- package/dist/browser/charts/core/index.js +6 -1
- package/dist/browser/charts/core/index.js.map +1 -1
- package/dist/browser/charts/core/pareto.js +120 -0
- package/dist/browser/charts/core/pareto.js.map +1 -0
- package/dist/browser/charts/core/radar.js +101 -0
- package/dist/browser/charts/core/radar.js.map +1 -0
- package/dist/browser/charts/core/registry.js +11 -1
- package/dist/browser/charts/core/registry.js.map +1 -1
- package/dist/browser/charts/core/render-size.js +3 -1
- package/dist/browser/charts/core/render-size.js.map +1 -1
- package/dist/browser/charts/core/render.js +19 -0
- package/dist/browser/charts/core/render.js.map +1 -1
- package/dist/browser/charts/core/snapshot.js +1 -1
- package/dist/browser/charts/core/snapshot.js.map +1 -1
- package/dist/browser/charts/core/svg-barGauge.js +67 -0
- package/dist/browser/charts/core/svg-barGauge.js.map +1 -0
- package/dist/browser/charts/core/svg-boxplot.js +127 -0
- package/dist/browser/charts/core/svg-boxplot.js.map +1 -0
- package/dist/browser/charts/core/svg-common.js +1065 -0
- package/dist/browser/charts/core/svg-common.js.map +1 -0
- package/dist/browser/charts/core/svg-gauge.js +185 -0
- package/dist/browser/charts/core/svg-gauge.js.map +1 -0
- package/dist/browser/charts/core/svg-heatmap.js +80 -0
- package/dist/browser/charts/core/svg-heatmap.js.map +1 -0
- package/dist/browser/charts/core/svg-histogram.js +73 -0
- package/dist/browser/charts/core/svg-histogram.js.map +1 -0
- package/dist/browser/charts/core/svg-renderers.js +9 -1777
- package/dist/browser/charts/core/svg-renderers.js.map +1 -1
- package/dist/browser/charts/core/svg-scatter.js +114 -0
- package/dist/browser/charts/core/svg-scatter.js.map +1 -0
- package/dist/browser/charts/core/treemap.js +138 -0
- package/dist/browser/charts/core/treemap.js.map +1 -0
- package/dist/browser/charts/description.js.map +1 -1
- package/dist/browser/content/ChartRoot.js +21 -7
- package/dist/browser/content/ChartRoot.js.map +1 -1
- package/dist/browser/content/ChartSnapshotView.js +4 -1
- package/dist/browser/content/ChartSnapshotView.js.map +1 -1
- package/dist/browser/content/DataTable.js +186 -193
- package/dist/browser/content/DataTable.js.map +1 -1
- package/dist/browser/content/Lightbox.js +55 -23
- package/dist/browser/content/Lightbox.js.map +1 -1
- package/dist/browser/content/ThumbnailStrip.js +174 -0
- package/dist/browser/content/ThumbnailStrip.js.map +1 -0
- package/dist/browser/content/chart-bar.js +98 -0
- package/dist/browser/content/chart-bar.js.map +1 -1
- package/dist/browser/content/chart-inspection-core.js +28 -8
- package/dist/browser/content/chart-inspection-core.js.map +1 -1
- package/dist/browser/content/chart-message-catalog.js +18 -0
- package/dist/browser/content/chart-message-catalog.js.map +1 -1
- package/dist/browser/content/index.js +1 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/content/thumbnail-strip-messages.js +24 -0
- package/dist/browser/content/thumbnail-strip-messages.js.map +1 -0
- package/dist/browser/inputs/ChoiceInputs.js +132 -101
- package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
- package/dist/browser/inputs/index.js +1 -0
- package/dist/browser/inputs/index.js.map +1 -1
- package/dist/browser/inputs/markdown/MarkdownSelectionToolbar.js +330 -0
- package/dist/browser/inputs/markdown/MarkdownSelectionToolbar.js.map +1 -0
- package/dist/browser/internal/field.js +96 -77
- package/dist/browser/internal/field.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +7 -5
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +92 -68
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +82 -70
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/surfaces/stat-cell-messages.js +4 -2
- package/dist/browser/surfaces/stat-cell-messages.js.map +1 -1
- package/dist/browser/widgets/DashboardFrame.js +93 -88
- package/dist/browser/widgets/DashboardFrame.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +8 -2
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/charts/core/bar-labels.js +5 -0
- package/dist/ssr/charts/core/bar-labels.js.map +1 -0
- package/dist/ssr/charts/core/bubble.js +166 -0
- package/dist/ssr/charts/core/bubble.js.map +1 -0
- package/dist/ssr/charts/core/default-styles.js +83 -0
- package/dist/ssr/charts/core/default-styles.js.map +1 -0
- package/dist/ssr/charts/core/funnel-layout.js +79 -0
- package/dist/ssr/charts/core/funnel-layout.js.map +1 -0
- package/dist/ssr/charts/core/funnel.js +27 -0
- package/dist/ssr/charts/core/funnel.js.map +1 -0
- package/dist/ssr/charts/core/index.js +6 -1
- package/dist/ssr/charts/core/index.js.map +1 -1
- package/dist/ssr/charts/core/pareto.js +120 -0
- package/dist/ssr/charts/core/pareto.js.map +1 -0
- package/dist/ssr/charts/core/radar.js +101 -0
- package/dist/ssr/charts/core/radar.js.map +1 -0
- package/dist/ssr/charts/core/registry.js +11 -1
- package/dist/ssr/charts/core/registry.js.map +1 -1
- package/dist/ssr/charts/core/render-size.js +3 -1
- package/dist/ssr/charts/core/render-size.js.map +1 -1
- package/dist/ssr/charts/core/render.js +19 -0
- package/dist/ssr/charts/core/render.js.map +1 -1
- package/dist/ssr/charts/core/snapshot.js +1 -1
- package/dist/ssr/charts/core/snapshot.js.map +1 -1
- package/dist/ssr/charts/core/svg-barGauge.js +67 -0
- package/dist/ssr/charts/core/svg-barGauge.js.map +1 -0
- package/dist/ssr/charts/core/svg-boxplot.js +127 -0
- package/dist/ssr/charts/core/svg-boxplot.js.map +1 -0
- package/dist/ssr/charts/core/svg-common.js +1065 -0
- package/dist/ssr/charts/core/svg-common.js.map +1 -0
- package/dist/ssr/charts/core/svg-gauge.js +185 -0
- package/dist/ssr/charts/core/svg-gauge.js.map +1 -0
- package/dist/ssr/charts/core/svg-heatmap.js +80 -0
- package/dist/ssr/charts/core/svg-heatmap.js.map +1 -0
- package/dist/ssr/charts/core/svg-histogram.js +73 -0
- package/dist/ssr/charts/core/svg-histogram.js.map +1 -0
- package/dist/ssr/charts/core/svg-renderers.js +9 -1777
- package/dist/ssr/charts/core/svg-renderers.js.map +1 -1
- package/dist/ssr/charts/core/svg-scatter.js +114 -0
- package/dist/ssr/charts/core/svg-scatter.js.map +1 -0
- package/dist/ssr/charts/core/treemap.js +138 -0
- package/dist/ssr/charts/core/treemap.js.map +1 -0
- package/dist/ssr/charts/description.js.map +1 -1
- package/dist/ssr/content/ChartRoot.js +21 -7
- package/dist/ssr/content/ChartRoot.js.map +1 -1
- package/dist/ssr/content/ChartSnapshotView.js +1 -0
- package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
- package/dist/ssr/content/DataTable.js +12 -16
- package/dist/ssr/content/DataTable.js.map +1 -1
- package/dist/ssr/content/Lightbox.js +32 -3
- package/dist/ssr/content/Lightbox.js.map +1 -1
- package/dist/ssr/content/ThumbnailStrip.js +103 -0
- package/dist/ssr/content/ThumbnailStrip.js.map +1 -0
- package/dist/ssr/content/chart-bar.js +98 -0
- package/dist/ssr/content/chart-bar.js.map +1 -1
- package/dist/ssr/content/chart-inspection-core.js +28 -8
- package/dist/ssr/content/chart-inspection-core.js.map +1 -1
- package/dist/ssr/content/chart-message-catalog.js +18 -0
- package/dist/ssr/content/chart-message-catalog.js.map +1 -1
- package/dist/ssr/content/index.js +1 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/content/thumbnail-strip-messages.js +24 -0
- package/dist/ssr/content/thumbnail-strip-messages.js.map +1 -0
- package/dist/ssr/inputs/ChoiceInputs.js +55 -40
- package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
- package/dist/ssr/inputs/index.js +1 -0
- package/dist/ssr/inputs/index.js.map +1 -1
- package/dist/ssr/inputs/markdown/MarkdownSelectionToolbar.js +293 -0
- package/dist/ssr/inputs/markdown/MarkdownSelectionToolbar.js.map +1 -0
- package/dist/ssr/internal/field.js +36 -24
- package/dist/ssr/internal/field.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +5 -1
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +40 -26
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +29 -18
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/surfaces/stat-cell-messages.js +4 -2
- package/dist/ssr/surfaces/stat-cell-messages.js.map +1 -1
- package/dist/ssr/widgets/DashboardFrame.js +6 -11
- package/dist/ssr/widgets/DashboardFrame.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/Toolbar.d.ts +2 -0
- package/dist/types/charts/core/bar-labels.d.ts +1 -0
- package/dist/types/charts/core/bubble.d.ts +66 -0
- package/dist/types/charts/core/default-styles.d.ts +1 -0
- package/dist/types/charts/core/funnel-layout.d.ts +43 -0
- package/dist/types/charts/core/funnel.d.ts +13 -0
- package/dist/types/charts/core/index.d.ts +6 -1
- package/dist/types/charts/core/pareto.d.ts +40 -0
- package/dist/types/charts/core/radar.d.ts +47 -0
- package/dist/types/charts/core/registry.d.ts +10 -0
- package/dist/types/charts/core/render-size.d.ts +1 -1
- package/dist/types/charts/core/svg-barGauge.d.ts +3 -0
- package/dist/types/charts/core/svg-boxplot.d.ts +18 -0
- package/dist/types/charts/core/svg-common.d.ts +612 -0
- package/dist/types/charts/core/svg-gauge.d.ts +6 -0
- package/dist/types/charts/core/svg-heatmap.d.ts +6 -0
- package/dist/types/charts/core/svg-histogram.d.ts +16 -0
- package/dist/types/charts/core/svg-renderers.d.ts +8 -612
- package/dist/types/charts/core/svg-scatter.d.ts +23 -0
- package/dist/types/charts/core/treemap.d.ts +45 -0
- package/dist/types/charts/description.d.ts +63 -0
- package/dist/types/content/ChartRoot.d.ts +1 -1
- package/dist/types/content/Lightbox.d.ts +2 -0
- package/dist/types/content/ThumbnailStrip.d.ts +29 -0
- package/dist/types/content/chart-bar.d.ts +38 -2
- package/dist/types/content/chart-inspection-core.d.ts +7 -0
- package/dist/types/content/chart-inspection.d.ts +1 -0
- package/dist/types/content/chart-message-catalog.d.ts +8 -0
- package/dist/types/content/index.d.ts +1 -0
- package/dist/types/content/thumbnail-strip-messages.d.ts +10 -0
- package/dist/types/inputs/ChoiceInputs.d.ts +2 -0
- package/dist/types/inputs/index.d.ts +2 -0
- package/dist/types/inputs/markdown/MarkdownSelectionToolbar.d.ts +19 -0
- package/dist/types/internal/field.d.ts +2 -0
- package/dist/types/layout/PanelDialog.d.ts +5 -0
- package/dist/types/surfaces/stat-cell-messages.d.ts +1 -0
- package/dist/types/widgets/DashboardFrame.d.ts +4 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["charts/core/snapshot.ts"],"sourcesContent":["import { calendarLayout } from \"./calendar\";\nimport { type ChartSelection, type ChartTooltip, type ChartTooltipFormatter, isChartDatum } from \"./inspection\";\nimport { type ChartRenderOptions, chartRenderHeight, renderChartSvg } from \"./render\";\nimport { escapeXml } from \"./svg-renderers\";\nimport type { ChartDatum, ChartKind } from \"./types\";\n\n/** Trusted output of prepareChartSnapshot; never accept arbitrary user SVG. */\nexport type ChartSnapshot = {\n kind: ChartKind;\n svg: string;\n width: number;\n height: number;\n stretch: boolean;\n minWidth?: number;\n marks: readonly { key: string; rowKey: string; datum: ChartDatum; tooltip: ChartTooltip; reference?: boolean }[];\n};\n\n// Matches metadata emitted by our SVG renderer, not arbitrary XML.\nconst decodeAttribute = (value: string) =>\n value\n .replace(/"/g, '\"')\n .replace(/'|'/g, \"'\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/&/g, \"&\");\n\n/** Pure SVG preparation for server or browser. Transfer only this output across SSR boundaries. */\nexport function prepareChartSnapshot(\n options: ChartRenderOptions,\n inspection: {\n key: (selection: ChartSelection) => string;\n /** Defaults to the mark key for one-to-one charts. */\n rowKey?: (selection: ChartSelection) => string;\n tooltip: ChartTooltipFormatter;\n reference?: (selection: ChartSelection) => boolean;\n },\n sizing: Parameters<typeof chartRenderHeight>[1] = {},\n): ChartSnapshot {\n const calendar = options.kind === \"heatmap\" && options.layout === \"calendar\" ? calendarLayout(options) : undefined;\n const width = calendar?.width ?? 480;\n const height = chartRenderHeight(options, sizing);\n const svg = renderChartSvg(options, width, height);\n const marks: ChartSnapshot[\"marks\"][number][] = [];\n const keys = new Set<string>();\n for (const match of svg.matchAll(/data-chart-datum=\"([^\"]*)\"/g)) {\n const datum: unknown = JSON.parse(decodeAttribute(match[1]!));\n if (!isChartDatum(datum)) throw new Error(\"Invalid renderer chart metadata\");\n const selection = { kind: options.kind, datum };\n const key = inspection.key(selection);\n if (!key || keys.has(key)) throw new Error(\"Chart snapshot requires a unique nonempty key for every mark\");\n keys.add(key);\n const rowKey = inspection.rowKey?.(selection) ?? key;\n if (!rowKey) throw new Error(\"Chart marks require a nonempty rowKey\");\n marks.push({\n key,\n rowKey,\n datum,\n tooltip: inspection.tooltip(selection),\n ...(inspection.reference?.(selection) ? { reference: true } : {}),\n });\n }\n let markIndex = 0;\n const formattedSvg = svg.replace(\n /(<g data-chart-role=\"[^\"]*\" data-chart-datum=\"[^\"]*\"><title>)[\\s\\S]*?<\\/title>/g,\n (_match, opening: string, offset: number) => {\n const mark = marks[markIndex++]!;\n const tooltip = mark.tooltip;\n const text = [tooltip.title, ...tooltip.rows.map((row) => `${row.label}: ${row.value}`)].filter(Boolean).join(\" · \");\n if (mark.reference) {\n const children = svg.slice(offset, svg.indexOf(\"</g>\", offset));\n const palette = (Number(children.match(/stdlib-chart-series-(\\d+)/)?.[1] ?? mark.datum.seriesIndex ?? 0) % 8) + 1;\n opening = opening.replace(\n \"<g \",\n `<g data-chart-reference=\"true\" style=\"--k2b-chart-reference-color:var(--stdlib-chart-c${palette})\" `,\n );\n }\n return `${opening}${escapeXml(text)}</title>`;\n },\n );\n return {\n kind: options.kind,\n svg: formattedSvg,\n width,\n height,\n ...(calendar ? { minWidth: calendar.minWidth } : {}),\n stretch: !calendar && ![\"map\", \"pie\", \"donut\", \"gauge\"].includes(options.kind),\n marks,\n };\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"names":[],"sources":["charts/core/snapshot.ts"],"sourcesContent":["import { calendarLayout } from \"./calendar\";\nimport { type ChartSelection, type ChartTooltip, type ChartTooltipFormatter, isChartDatum } from \"./inspection\";\nimport { type ChartRenderOptions, chartRenderHeight, renderChartSvg } from \"./render\";\nimport { escapeXml } from \"./svg-renderers\";\nimport type { ChartDatum, ChartKind } from \"./types\";\n\n/** Trusted output of prepareChartSnapshot; never accept arbitrary user SVG. */\nexport type ChartSnapshot = {\n kind: ChartKind;\n svg: string;\n width: number;\n height: number;\n stretch: boolean;\n minWidth?: number;\n marks: readonly { key: string; rowKey: string; datum: ChartDatum; tooltip: ChartTooltip; reference?: boolean }[];\n};\n\n// Matches metadata emitted by our SVG renderer, not arbitrary XML.\nconst decodeAttribute = (value: string) =>\n value\n .replace(/"/g, '\"')\n .replace(/'|'/g, \"'\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/&/g, \"&\");\n\n/** Pure SVG preparation for server or browser. Transfer only this output across SSR boundaries. */\nexport function prepareChartSnapshot(\n options: ChartRenderOptions,\n inspection: {\n key: (selection: ChartSelection) => string;\n /** Defaults to the mark key for one-to-one charts. */\n rowKey?: (selection: ChartSelection) => string;\n tooltip: ChartTooltipFormatter;\n reference?: (selection: ChartSelection) => boolean;\n },\n sizing: Parameters<typeof chartRenderHeight>[1] = {},\n): ChartSnapshot {\n const calendar = options.kind === \"heatmap\" && options.layout === \"calendar\" ? calendarLayout(options) : undefined;\n const width = calendar?.width ?? 480;\n const height = chartRenderHeight(options, sizing);\n const svg = renderChartSvg(options, width, height);\n const marks: ChartSnapshot[\"marks\"][number][] = [];\n const keys = new Set<string>();\n for (const match of svg.matchAll(/data-chart-datum=\"([^\"]*)\"/g)) {\n const datum: unknown = JSON.parse(decodeAttribute(match[1]!));\n if (!isChartDatum(datum)) throw new Error(\"Invalid renderer chart metadata\");\n const selection = { kind: options.kind, datum };\n const key = inspection.key(selection);\n if (!key || keys.has(key)) throw new Error(\"Chart snapshot requires a unique nonempty key for every mark\");\n keys.add(key);\n const rowKey = inspection.rowKey?.(selection) ?? key;\n if (!rowKey) throw new Error(\"Chart marks require a nonempty rowKey\");\n marks.push({\n key,\n rowKey,\n datum,\n tooltip: inspection.tooltip(selection),\n ...(inspection.reference?.(selection) ? { reference: true } : {}),\n });\n }\n let markIndex = 0;\n const formattedSvg = svg.replace(\n /(<g data-chart-role=\"[^\"]*\" data-chart-datum=\"[^\"]*\"><title>)[\\s\\S]*?<\\/title>/g,\n (_match, opening: string, offset: number) => {\n const mark = marks[markIndex++]!;\n const tooltip = mark.tooltip;\n const text = [tooltip.title, ...tooltip.rows.map((row) => `${row.label}: ${row.value}`)].filter(Boolean).join(\" · \");\n if (mark.reference) {\n const children = svg.slice(offset, svg.indexOf(\"</g>\", offset));\n const palette = (Number(children.match(/stdlib-chart-series-(\\d+)/)?.[1] ?? mark.datum.seriesIndex ?? 0) % 8) + 1;\n opening = opening.replace(\n \"<g \",\n `<g data-chart-reference=\"true\" style=\"--k2b-chart-reference-color:var(--stdlib-chart-c${palette})\" `,\n );\n }\n return `${opening}${escapeXml(text)}</title>`;\n },\n );\n return {\n kind: options.kind,\n svg: formattedSvg,\n width,\n height,\n ...(calendar ? { minWidth: calendar.minWidth } : {}),\n stretch: !calendar && ![\"map\", \"pie\", \"donut\", \"gauge\", \"radar\"].includes(options.kind),\n marks,\n };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Ported SVG algorithm, kept verbatim; separate module for per-kind frame loading.
|
|
2
|
+
import { chartDatumSvg, clamp, escapeXml, fmt, formatNumberValue, normalizeMinMax, renderHeader, svgRoot, thresholdFillAttr, thresholdForIndex, thresholdIndexForValue } from "./svg-common";
|
|
3
|
+
/** Render compact horizontal bar gauges for multiple reduced metrics. */
|
|
4
|
+
export const barGauge = opts => {
|
|
5
|
+
const width = opts.width ?? 420;
|
|
6
|
+
const rowHeight = 28;
|
|
7
|
+
const top = opts.title || opts.subtitle ? 42 : 16;
|
|
8
|
+
const height = opts.height ?? Math.max(80, top + opts.data.length * rowHeight + 14);
|
|
9
|
+
const header = renderHeader(width, opts.title, opts.subtitle);
|
|
10
|
+
const body = [header.svg];
|
|
11
|
+
const labelW = Math.min(140, Math.max(74, width * 0.34));
|
|
12
|
+
const valueW = 56;
|
|
13
|
+
const trackX = labelW + 14;
|
|
14
|
+
const trackW = Math.max(24, width - trackX - valueW - 14);
|
|
15
|
+
const trackH = 10;
|
|
16
|
+
const sourceIndices = opts.data.flatMap((d, index) => Number.isFinite(d.value) ? [index] : []);
|
|
17
|
+
const data = opts.data.filter(d => Number.isFinite(d.value));
|
|
18
|
+
if (data.length === 0) {
|
|
19
|
+
body.push(`<text class="stdlib-chart-empty-text" x="${fmt(width / 2)}" y="${fmt(height / 2)}" text-anchor="middle">No data</text>`);
|
|
20
|
+
return svgRoot({
|
|
21
|
+
width,
|
|
22
|
+
height,
|
|
23
|
+
className: opts.className
|
|
24
|
+
}, body.join(""));
|
|
25
|
+
}
|
|
26
|
+
data.forEach((d, i) => {
|
|
27
|
+
const [min, max] = normalizeMinMax(d.min ?? opts.min, d.max ?? opts.max);
|
|
28
|
+
const pct = clamp((d.value - min) / (max - min), 0, 1);
|
|
29
|
+
const y = top + i * rowHeight;
|
|
30
|
+
const thresholdIdx = thresholdIndexForValue(d.value, opts.thresholds, min, max);
|
|
31
|
+
const threshold = thresholdForIndex(opts.thresholds, thresholdIdx);
|
|
32
|
+
const thresholdColor = threshold?.color;
|
|
33
|
+
const unit = d.unit ?? opts.unit ?? "";
|
|
34
|
+
const start = body.length;
|
|
35
|
+
body.push(`<text class="stdlib-chart-bar-gauge-label" x="12" y="${fmt(y + 12)}" dominant-baseline="middle">${escapeXml(d.label)}</text>`);
|
|
36
|
+
body.push(`<rect class="stdlib-chart-bar-gauge-track" x="${fmt(trackX)}" y="${fmt(y + 7)}" width="${fmt(trackW)}" height="${fmt(trackH)}" rx="2"/>`);
|
|
37
|
+
body.push(`<rect class="stdlib-chart-bar-gauge-fill stdlib-chart-series-${thresholdIdx % 8}"${thresholdFillAttr(thresholdColor)} x="${fmt(trackX)}" y="${fmt(y + 7)}" width="${fmt(trackW * pct)}" height="${fmt(trackH)}" rx="2"/>`);
|
|
38
|
+
body.push(`<text class="stdlib-chart-bar-gauge-value" x="${fmt(width - 12)}" y="${fmt(y + 12)}" text-anchor="end" dominant-baseline="middle">${escapeXml(formatNumberValue(d.value, opts.format, unit))}</text>`);
|
|
39
|
+
const shapes = body.splice(start).join("");
|
|
40
|
+
body.push(chartDatumSvg(shapes, {
|
|
41
|
+
index: sourceIndices[i],
|
|
42
|
+
role: "item",
|
|
43
|
+
label: d.label,
|
|
44
|
+
anchor: [trackX + trackW / 2, y + 12],
|
|
45
|
+
values: [{
|
|
46
|
+
key: "value",
|
|
47
|
+
value: d.value,
|
|
48
|
+
formatted: formatNumberValue(d.value, opts.format, unit)
|
|
49
|
+
}, {
|
|
50
|
+
key: "min",
|
|
51
|
+
value: min
|
|
52
|
+
}, {
|
|
53
|
+
key: "max",
|
|
54
|
+
value: max
|
|
55
|
+
}, ...(threshold ? [{
|
|
56
|
+
key: "threshold",
|
|
57
|
+
value: threshold.label ?? threshold.value
|
|
58
|
+
}] : [])]
|
|
59
|
+
}, opts.inspect));
|
|
60
|
+
});
|
|
61
|
+
return svgRoot({
|
|
62
|
+
width,
|
|
63
|
+
height,
|
|
64
|
+
className: opts.className
|
|
65
|
+
}, body.join(""));
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=svg-barGauge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["charts/core/svg-barGauge.ts"],"sourcesContent":["// Ported SVG algorithm, kept verbatim; separate module for per-kind frame loading.\nimport {\n type BarGaugeOptions,\n chartDatumSvg,\n clamp,\n escapeXml,\n fmt,\n formatNumberValue,\n normalizeMinMax,\n renderHeader,\n svgRoot,\n thresholdFillAttr,\n thresholdForIndex,\n thresholdIndexForValue,\n} from \"./svg-common\";\n/** Render compact horizontal bar gauges for multiple reduced metrics. */\nexport const barGauge = (opts: BarGaugeOptions): string => {\n const width = opts.width ?? 420;\n const rowHeight = 28;\n const top = opts.title || opts.subtitle ? 42 : 16;\n const height = opts.height ?? Math.max(80, top + opts.data.length * rowHeight + 14);\n const header = renderHeader(width, opts.title, opts.subtitle);\n const body: string[] = [header.svg];\n const labelW = Math.min(140, Math.max(74, width * 0.34));\n const valueW = 56;\n const trackX = labelW + 14;\n const trackW = Math.max(24, width - trackX - valueW - 14);\n const trackH = 10;\n const sourceIndices = opts.data.flatMap((d, index) => (Number.isFinite(d.value) ? [index] : []));\n const data = opts.data.filter((d) => Number.isFinite(d.value));\n\n if (data.length === 0) {\n body.push(`<text class=\"stdlib-chart-empty-text\" x=\"${fmt(width / 2)}\" y=\"${fmt(height / 2)}\" text-anchor=\"middle\">No data</text>`);\n return svgRoot({ width, height, className: opts.className }, body.join(\"\"));\n }\n\n data.forEach((d, i) => {\n const [min, max] = normalizeMinMax(d.min ?? opts.min, d.max ?? opts.max);\n const pct = clamp((d.value - min) / (max - min), 0, 1);\n const y = top + i * rowHeight;\n const thresholdIdx = thresholdIndexForValue(d.value, opts.thresholds, min, max);\n const threshold = thresholdForIndex(opts.thresholds, thresholdIdx);\n const thresholdColor = threshold?.color;\n const unit = d.unit ?? opts.unit ?? \"\";\n const start = body.length;\n body.push(\n `<text class=\"stdlib-chart-bar-gauge-label\" x=\"12\" y=\"${fmt(y + 12)}\" dominant-baseline=\"middle\">${escapeXml(d.label)}</text>`,\n );\n body.push(\n `<rect class=\"stdlib-chart-bar-gauge-track\" x=\"${fmt(trackX)}\" y=\"${fmt(y + 7)}\" width=\"${fmt(trackW)}\" height=\"${fmt(trackH)}\" rx=\"2\"/>`,\n );\n body.push(\n `<rect class=\"stdlib-chart-bar-gauge-fill stdlib-chart-series-${thresholdIdx % 8}\"${thresholdFillAttr(thresholdColor)} x=\"${fmt(trackX)}\" y=\"${fmt(y + 7)}\" width=\"${fmt(trackW * pct)}\" height=\"${fmt(trackH)}\" rx=\"2\"/>`,\n );\n body.push(\n `<text class=\"stdlib-chart-bar-gauge-value\" x=\"${fmt(width - 12)}\" y=\"${fmt(y + 12)}\" text-anchor=\"end\" dominant-baseline=\"middle\">${escapeXml(formatNumberValue(d.value, opts.format, unit))}</text>`,\n );\n const shapes = body.splice(start).join(\"\");\n body.push(\n chartDatumSvg(\n shapes,\n {\n index: sourceIndices[i]!,\n role: \"item\",\n label: d.label,\n anchor: [trackX + trackW / 2, y + 12],\n values: [\n { key: \"value\", value: d.value, formatted: formatNumberValue(d.value, opts.format, unit) },\n { key: \"min\", value: min },\n { key: \"max\", value: max },\n ...(threshold ? [{ key: \"threshold\", value: threshold.label ?? threshold.value }] : []),\n ],\n },\n opts.inspect,\n ),\n );\n });\n\n return svgRoot({ width, height, className: opts.className }, body.join(\"\"));\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// Ported SVG algorithm, kept verbatim; separate module for per-kind frame loading.
|
|
2
|
+
import { chartDatumSvg, computeAxisScale, computeBoxStats, computePlotArea, DEFAULT_HEIGHT, DEFAULT_WIDTH, emptyChart, fmt, normalizePadding, pickMapper, renderHeader, renderReferenceLines, renderXAxisCategorical, renderYAxis, svgRoot } from "./svg-common";
|
|
3
|
+
/**
|
|
4
|
+
* Render a box plot (Tukey style): box for the IQR (Q1-Q3), median line,
|
|
5
|
+
* whiskers extending to 1.5×IQR fences, and individual outlier dots.
|
|
6
|
+
*
|
|
7
|
+
* Useful for comparing distributions across categorical groups (e.g. test
|
|
8
|
+
* scores per class, reaction times per condition).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* charts.boxplot({
|
|
12
|
+
* groups: [
|
|
13
|
+
* { label: "Class A", values: scoresA },
|
|
14
|
+
* { label: "Class B", values: scoresB },
|
|
15
|
+
* ],
|
|
16
|
+
* yAxis: { label: "Score" },
|
|
17
|
+
* });
|
|
18
|
+
*/
|
|
19
|
+
export const boxplot = opts => {
|
|
20
|
+
const width = opts.width ?? DEFAULT_WIDTH;
|
|
21
|
+
const height = opts.height ?? DEFAULT_HEIGHT;
|
|
22
|
+
const padding = normalizePadding(opts.padding);
|
|
23
|
+
const header = renderHeader(width, opts.title, opts.subtitle);
|
|
24
|
+
const showOutliers = opts.showOutliers ?? true;
|
|
25
|
+
const stats = opts.groups.map((g, index) => ({
|
|
26
|
+
index,
|
|
27
|
+
count: g.values.filter(Number.isFinite).length,
|
|
28
|
+
label: g.label,
|
|
29
|
+
s: computeBoxStats(g.values)
|
|
30
|
+
}));
|
|
31
|
+
const valid = stats.filter(g => g.s !== null);
|
|
32
|
+
if (valid.length === 0) return emptyChart(width, height, opts.className);
|
|
33
|
+
const area = computePlotArea(width, height, padding, false, !!opts.yAxis?.label, header.height, 0);
|
|
34
|
+
|
|
35
|
+
// Collect all values relevant for the y-domain: whisker extremes + outliers.
|
|
36
|
+
const axisValues = [];
|
|
37
|
+
for (const g of valid) {
|
|
38
|
+
axisValues.push(g.s.whiskerLow, g.s.whiskerHigh);
|
|
39
|
+
if (showOutliers) axisValues.push(...g.s.outliers);
|
|
40
|
+
}
|
|
41
|
+
const yAxis = computeAxisScale(axisValues, opts.yAxis);
|
|
42
|
+
const yMap = pickMapper(yAxis.scale);
|
|
43
|
+
const body = [];
|
|
44
|
+
body.push(renderYAxis(yAxis, area, opts.yAxis));
|
|
45
|
+
body.push(renderXAxisCategorical(valid.map(g => g.label), area, height, undefined));
|
|
46
|
+
const slot = (area.x1 - area.x0) / valid.length;
|
|
47
|
+
const boxWidth = slot * 0.6;
|
|
48
|
+
const boxOffset = slot * 0.2;
|
|
49
|
+
for (let i = 0; i < valid.length; i++) {
|
|
50
|
+
const g = valid[i];
|
|
51
|
+
const cx = area.x0 + slot * i + slot / 2;
|
|
52
|
+
const x = area.x0 + slot * i + boxOffset;
|
|
53
|
+
const seriesIdx = opts.colorByBox ? i % 8 : 0;
|
|
54
|
+
const seriesCls = `stdlib-chart-series-${seriesIdx}`;
|
|
55
|
+
const yQ1 = yMap(g.s.q1, yAxis.domain, [area.y1, area.y0]);
|
|
56
|
+
const yQ2 = yMap(g.s.q2, yAxis.domain, [area.y1, area.y0]);
|
|
57
|
+
const yQ3 = yMap(g.s.q3, yAxis.domain, [area.y1, area.y0]);
|
|
58
|
+
const yWhiskerLow = yMap(g.s.whiskerLow, yAxis.domain, [area.y1, area.y0]);
|
|
59
|
+
const yWhiskerHigh = yMap(g.s.whiskerHigh, yAxis.domain, [area.y1, area.y0]);
|
|
60
|
+
|
|
61
|
+
// Whisker line (vertical) from low whisker to high whisker, behind the box.
|
|
62
|
+
body.push(`<line class="stdlib-chart-box-whisker" x1="${fmt(cx)}" y1="${fmt(yWhiskerHigh)}" x2="${fmt(cx)}" y2="${fmt(yWhiskerLow)}"/>`);
|
|
63
|
+
// Whisker caps.
|
|
64
|
+
const capW = boxWidth * 0.4;
|
|
65
|
+
body.push(`<line class="stdlib-chart-box-cap" x1="${fmt(cx - capW / 2)}" y1="${fmt(yWhiskerHigh)}" x2="${fmt(cx + capW / 2)}" y2="${fmt(yWhiskerHigh)}"/>`);
|
|
66
|
+
body.push(`<line class="stdlib-chart-box-cap" x1="${fmt(cx - capW / 2)}" y1="${fmt(yWhiskerLow)}" x2="${fmt(cx + capW / 2)}" y2="${fmt(yWhiskerLow)}"/>`);
|
|
67
|
+
// Box (Q1 to Q3).
|
|
68
|
+
body.push(chartDatumSvg(`<rect class="stdlib-chart-box ${seriesCls}" x="${fmt(x)}" y="${fmt(yQ3)}" width="${fmt(boxWidth)}" height="${fmt(yQ1 - yQ3)}"/>`, {
|
|
69
|
+
index: g.index,
|
|
70
|
+
role: "box",
|
|
71
|
+
label: g.label,
|
|
72
|
+
anchor: [cx, yQ2],
|
|
73
|
+
values: [{
|
|
74
|
+
key: "count",
|
|
75
|
+
value: g.count
|
|
76
|
+
}, ...["q1", "q2", "q3", "whiskerLow", "whiskerHigh"].map(key => ({
|
|
77
|
+
key,
|
|
78
|
+
value: g.s[key]
|
|
79
|
+
})).map(field => ({
|
|
80
|
+
...field,
|
|
81
|
+
formatted: opts.yAxis?.format?.(field.value)
|
|
82
|
+
}))]
|
|
83
|
+
}, opts.inspect));
|
|
84
|
+
// Median line.
|
|
85
|
+
body.push(`<line class="stdlib-chart-box-median" x1="${fmt(x)}" y1="${fmt(yQ2)}" x2="${fmt(x + boxWidth)}" y2="${fmt(yQ2)}"/>`);
|
|
86
|
+
// Outliers.
|
|
87
|
+
if (showOutliers) {
|
|
88
|
+
const sourceIndices = new Map();
|
|
89
|
+
if (opts.inspect) opts.groups[g.index].values.forEach((value, index) => {
|
|
90
|
+
const indices = sourceIndices.get(value) ?? [];
|
|
91
|
+
indices.push(index);
|
|
92
|
+
sourceIndices.set(value, indices);
|
|
93
|
+
});
|
|
94
|
+
for (const v of g.s.outliers) {
|
|
95
|
+
const sourceIndex = sourceIndices.get(v)?.shift() ?? 0;
|
|
96
|
+
const oy = yMap(v, yAxis.domain, [area.y1, area.y0]);
|
|
97
|
+
body.push(chartDatumSvg(`<circle class="stdlib-chart-box-outlier ${seriesCls}" cx="${fmt(cx)}" cy="${fmt(oy)}" r="2.5"/>`, {
|
|
98
|
+
index: sourceIndex,
|
|
99
|
+
seriesIndex: g.index,
|
|
100
|
+
role: "outlier",
|
|
101
|
+
label: g.label,
|
|
102
|
+
anchor: [cx, oy],
|
|
103
|
+
values: [{
|
|
104
|
+
key: "value",
|
|
105
|
+
value: v,
|
|
106
|
+
formatted: opts.yAxis?.format?.(v)
|
|
107
|
+
}]
|
|
108
|
+
}, opts.inspect));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (opts.references && opts.references.length > 0) {
|
|
113
|
+
const yRefs = opts.references.filter(r => (r.axis ?? "y") === "y");
|
|
114
|
+
if (yRefs.length > 0) {
|
|
115
|
+
body.push(renderReferenceLines(yRefs, {
|
|
116
|
+
domain: [0, 1],
|
|
117
|
+
scale: "linear"
|
|
118
|
+
}, yAxis, area));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return svgRoot({
|
|
122
|
+
width,
|
|
123
|
+
height,
|
|
124
|
+
className: opts.className
|
|
125
|
+
}, header.svg + body.join(""));
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=svg-boxplot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["charts/core/svg-boxplot.ts"],"sourcesContent":["// Ported SVG algorithm, kept verbatim; separate module for per-kind frame loading.\nimport {\n type BoxPlotOptions,\n chartDatumSvg,\n computeAxisScale,\n computeBoxStats,\n computePlotArea,\n DEFAULT_HEIGHT,\n DEFAULT_WIDTH,\n emptyChart,\n fmt,\n normalizePadding,\n pickMapper,\n renderHeader,\n renderReferenceLines,\n renderXAxisCategorical,\n renderYAxis,\n svgRoot,\n} from \"./svg-common\";\n/**\n * Render a box plot (Tukey style): box for the IQR (Q1-Q3), median line,\n * whiskers extending to 1.5×IQR fences, and individual outlier dots.\n *\n * Useful for comparing distributions across categorical groups (e.g. test\n * scores per class, reaction times per condition).\n *\n * @example\n * charts.boxplot({\n * groups: [\n * { label: \"Class A\", values: scoresA },\n * { label: \"Class B\", values: scoresB },\n * ],\n * yAxis: { label: \"Score\" },\n * });\n */\nexport const boxplot = (opts: BoxPlotOptions): string => {\n const width = opts.width ?? DEFAULT_WIDTH;\n const height = opts.height ?? DEFAULT_HEIGHT;\n const padding = normalizePadding(opts.padding);\n const header = renderHeader(width, opts.title, opts.subtitle);\n\n const showOutliers = opts.showOutliers ?? true;\n\n const stats = opts.groups.map((g, index) => ({\n index,\n count: g.values.filter(Number.isFinite).length,\n label: g.label,\n s: computeBoxStats(g.values),\n }));\n const valid = stats.filter((g) => g.s !== null) as Array<{\n label: string;\n index: number;\n count: number;\n s: NonNullable<ReturnType<typeof computeBoxStats>>;\n }>;\n if (valid.length === 0) return emptyChart(width, height, opts.className);\n\n const area = computePlotArea(width, height, padding, false, !!opts.yAxis?.label, header.height, 0);\n\n // Collect all values relevant for the y-domain: whisker extremes + outliers.\n const axisValues: number[] = [];\n for (const g of valid) {\n axisValues.push(g.s.whiskerLow, g.s.whiskerHigh);\n if (showOutliers) axisValues.push(...g.s.outliers);\n }\n const yAxis = computeAxisScale(axisValues, opts.yAxis);\n const yMap = pickMapper(yAxis.scale);\n\n const body: string[] = [];\n body.push(renderYAxis(yAxis, area, opts.yAxis));\n body.push(\n renderXAxisCategorical(\n valid.map((g) => g.label),\n area,\n height,\n undefined,\n ),\n );\n\n const slot = (area.x1 - area.x0) / valid.length;\n const boxWidth = slot * 0.6;\n const boxOffset = slot * 0.2;\n\n for (let i = 0; i < valid.length; i++) {\n const g = valid[i]!;\n const cx = area.x0 + slot * i + slot / 2;\n const x = area.x0 + slot * i + boxOffset;\n const seriesIdx = opts.colorByBox ? i % 8 : 0;\n const seriesCls = `stdlib-chart-series-${seriesIdx}`;\n const yQ1 = yMap(g.s.q1, yAxis.domain, [area.y1, area.y0]);\n const yQ2 = yMap(g.s.q2, yAxis.domain, [area.y1, area.y0]);\n const yQ3 = yMap(g.s.q3, yAxis.domain, [area.y1, area.y0]);\n const yWhiskerLow = yMap(g.s.whiskerLow, yAxis.domain, [area.y1, area.y0]);\n const yWhiskerHigh = yMap(g.s.whiskerHigh, yAxis.domain, [area.y1, area.y0]);\n\n // Whisker line (vertical) from low whisker to high whisker, behind the box.\n body.push(\n `<line class=\"stdlib-chart-box-whisker\" x1=\"${fmt(cx)}\" y1=\"${fmt(yWhiskerHigh)}\" x2=\"${fmt(cx)}\" y2=\"${fmt(yWhiskerLow)}\"/>`,\n );\n // Whisker caps.\n const capW = boxWidth * 0.4;\n body.push(\n `<line class=\"stdlib-chart-box-cap\" x1=\"${fmt(cx - capW / 2)}\" y1=\"${fmt(yWhiskerHigh)}\" x2=\"${fmt(cx + capW / 2)}\" y2=\"${fmt(yWhiskerHigh)}\"/>`,\n );\n body.push(\n `<line class=\"stdlib-chart-box-cap\" x1=\"${fmt(cx - capW / 2)}\" y1=\"${fmt(yWhiskerLow)}\" x2=\"${fmt(cx + capW / 2)}\" y2=\"${fmt(yWhiskerLow)}\"/>`,\n );\n // Box (Q1 to Q3).\n body.push(\n chartDatumSvg(\n `<rect class=\"stdlib-chart-box ${seriesCls}\" x=\"${fmt(x)}\" y=\"${fmt(yQ3)}\" width=\"${fmt(boxWidth)}\" height=\"${fmt(yQ1 - yQ3)}\"/>`,\n {\n index: g.index,\n role: \"box\",\n label: g.label,\n anchor: [cx, yQ2],\n values: [\n { key: \"count\", value: g.count },\n ...([\"q1\", \"q2\", \"q3\", \"whiskerLow\", \"whiskerHigh\"] as const)\n .map((key) => ({ key, value: g.s[key] }))\n .map((field) => ({ ...field, formatted: opts.yAxis?.format?.(field.value) })),\n ],\n },\n opts.inspect,\n ),\n );\n // Median line.\n body.push(`<line class=\"stdlib-chart-box-median\" x1=\"${fmt(x)}\" y1=\"${fmt(yQ2)}\" x2=\"${fmt(x + boxWidth)}\" y2=\"${fmt(yQ2)}\"/>`);\n // Outliers.\n if (showOutliers) {\n const sourceIndices = new Map<number, number[]>();\n if (opts.inspect)\n opts.groups[g.index]!.values.forEach((value, index) => {\n const indices = sourceIndices.get(value) ?? [];\n indices.push(index);\n sourceIndices.set(value, indices);\n });\n for (const v of g.s.outliers) {\n const sourceIndex = sourceIndices.get(v)?.shift() ?? 0;\n const oy = yMap(v, yAxis.domain, [area.y1, area.y0]);\n body.push(\n chartDatumSvg(\n `<circle class=\"stdlib-chart-box-outlier ${seriesCls}\" cx=\"${fmt(cx)}\" cy=\"${fmt(oy)}\" r=\"2.5\"/>`,\n {\n index: sourceIndex,\n seriesIndex: g.index,\n role: \"outlier\",\n label: g.label,\n anchor: [cx, oy],\n values: [{ key: \"value\", value: v, formatted: opts.yAxis?.format?.(v) }],\n },\n opts.inspect,\n ),\n );\n }\n }\n }\n\n if (opts.references && opts.references.length > 0) {\n const yRefs = opts.references.filter((r) => (r.axis ?? \"y\") === \"y\");\n if (yRefs.length > 0) {\n body.push(renderReferenceLines(yRefs, { domain: [0, 1], scale: \"linear\" }, yAxis, area));\n }\n }\n\n return svgRoot({ width, height, className: opts.className }, header.svg + body.join(\"\"));\n};\n"],"mappings":"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","ignoreList":[]}
|