@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.
Files changed (206) hide show
  1. package/dist/base.css +3 -0
  2. package/dist/browser/actions/Toolbar.js +8 -2
  3. package/dist/browser/actions/Toolbar.js.map +1 -1
  4. package/dist/browser/charts/core/bar-labels.js +5 -0
  5. package/dist/browser/charts/core/bar-labels.js.map +1 -0
  6. package/dist/browser/charts/core/bubble.js +166 -0
  7. package/dist/browser/charts/core/bubble.js.map +1 -0
  8. package/dist/browser/charts/core/default-styles.js +83 -0
  9. package/dist/browser/charts/core/default-styles.js.map +1 -0
  10. package/dist/browser/charts/core/funnel-layout.js +79 -0
  11. package/dist/browser/charts/core/funnel-layout.js.map +1 -0
  12. package/dist/browser/charts/core/funnel.js +27 -0
  13. package/dist/browser/charts/core/funnel.js.map +1 -0
  14. package/dist/browser/charts/core/index.js +6 -1
  15. package/dist/browser/charts/core/index.js.map +1 -1
  16. package/dist/browser/charts/core/pareto.js +120 -0
  17. package/dist/browser/charts/core/pareto.js.map +1 -0
  18. package/dist/browser/charts/core/radar.js +101 -0
  19. package/dist/browser/charts/core/radar.js.map +1 -0
  20. package/dist/browser/charts/core/registry.js +11 -1
  21. package/dist/browser/charts/core/registry.js.map +1 -1
  22. package/dist/browser/charts/core/render-size.js +3 -1
  23. package/dist/browser/charts/core/render-size.js.map +1 -1
  24. package/dist/browser/charts/core/render.js +19 -0
  25. package/dist/browser/charts/core/render.js.map +1 -1
  26. package/dist/browser/charts/core/snapshot.js +1 -1
  27. package/dist/browser/charts/core/snapshot.js.map +1 -1
  28. package/dist/browser/charts/core/svg-barGauge.js +67 -0
  29. package/dist/browser/charts/core/svg-barGauge.js.map +1 -0
  30. package/dist/browser/charts/core/svg-boxplot.js +127 -0
  31. package/dist/browser/charts/core/svg-boxplot.js.map +1 -0
  32. package/dist/browser/charts/core/svg-common.js +1065 -0
  33. package/dist/browser/charts/core/svg-common.js.map +1 -0
  34. package/dist/browser/charts/core/svg-gauge.js +185 -0
  35. package/dist/browser/charts/core/svg-gauge.js.map +1 -0
  36. package/dist/browser/charts/core/svg-heatmap.js +80 -0
  37. package/dist/browser/charts/core/svg-heatmap.js.map +1 -0
  38. package/dist/browser/charts/core/svg-histogram.js +73 -0
  39. package/dist/browser/charts/core/svg-histogram.js.map +1 -0
  40. package/dist/browser/charts/core/svg-renderers.js +9 -1777
  41. package/dist/browser/charts/core/svg-renderers.js.map +1 -1
  42. package/dist/browser/charts/core/svg-scatter.js +114 -0
  43. package/dist/browser/charts/core/svg-scatter.js.map +1 -0
  44. package/dist/browser/charts/core/treemap.js +138 -0
  45. package/dist/browser/charts/core/treemap.js.map +1 -0
  46. package/dist/browser/charts/description.js.map +1 -1
  47. package/dist/browser/content/ChartRoot.js +21 -7
  48. package/dist/browser/content/ChartRoot.js.map +1 -1
  49. package/dist/browser/content/ChartSnapshotView.js +4 -1
  50. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  51. package/dist/browser/content/DataTable.js +186 -193
  52. package/dist/browser/content/DataTable.js.map +1 -1
  53. package/dist/browser/content/Lightbox.js +55 -23
  54. package/dist/browser/content/Lightbox.js.map +1 -1
  55. package/dist/browser/content/ThumbnailStrip.js +174 -0
  56. package/dist/browser/content/ThumbnailStrip.js.map +1 -0
  57. package/dist/browser/content/chart-bar.js +98 -0
  58. package/dist/browser/content/chart-bar.js.map +1 -1
  59. package/dist/browser/content/chart-inspection-core.js +28 -8
  60. package/dist/browser/content/chart-inspection-core.js.map +1 -1
  61. package/dist/browser/content/chart-message-catalog.js +18 -0
  62. package/dist/browser/content/chart-message-catalog.js.map +1 -1
  63. package/dist/browser/content/index.js +1 -0
  64. package/dist/browser/content/index.js.map +1 -1
  65. package/dist/browser/content/thumbnail-strip-messages.js +24 -0
  66. package/dist/browser/content/thumbnail-strip-messages.js.map +1 -0
  67. package/dist/browser/inputs/ChoiceInputs.js +132 -101
  68. package/dist/browser/inputs/ChoiceInputs.js.map +1 -1
  69. package/dist/browser/inputs/index.js +1 -0
  70. package/dist/browser/inputs/index.js.map +1 -1
  71. package/dist/browser/inputs/markdown/MarkdownSelectionToolbar.js +330 -0
  72. package/dist/browser/inputs/markdown/MarkdownSelectionToolbar.js.map +1 -0
  73. package/dist/browser/internal/field.js +96 -77
  74. package/dist/browser/internal/field.js.map +1 -1
  75. package/dist/browser/layout/AppWorkspace.js +7 -5
  76. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  77. package/dist/browser/layout/PanelDialog.js +92 -68
  78. package/dist/browser/layout/PanelDialog.js.map +1 -1
  79. package/dist/browser/surfaces/StatCell.js +82 -70
  80. package/dist/browser/surfaces/StatCell.js.map +1 -1
  81. package/dist/browser/surfaces/stat-cell-messages.js +4 -2
  82. package/dist/browser/surfaces/stat-cell-messages.js.map +1 -1
  83. package/dist/browser/widgets/DashboardFrame.js +93 -88
  84. package/dist/browser/widgets/DashboardFrame.js.map +1 -1
  85. package/dist/ssr/actions/Toolbar.js +8 -2
  86. package/dist/ssr/actions/Toolbar.js.map +1 -1
  87. package/dist/ssr/charts/core/bar-labels.js +5 -0
  88. package/dist/ssr/charts/core/bar-labels.js.map +1 -0
  89. package/dist/ssr/charts/core/bubble.js +166 -0
  90. package/dist/ssr/charts/core/bubble.js.map +1 -0
  91. package/dist/ssr/charts/core/default-styles.js +83 -0
  92. package/dist/ssr/charts/core/default-styles.js.map +1 -0
  93. package/dist/ssr/charts/core/funnel-layout.js +79 -0
  94. package/dist/ssr/charts/core/funnel-layout.js.map +1 -0
  95. package/dist/ssr/charts/core/funnel.js +27 -0
  96. package/dist/ssr/charts/core/funnel.js.map +1 -0
  97. package/dist/ssr/charts/core/index.js +6 -1
  98. package/dist/ssr/charts/core/index.js.map +1 -1
  99. package/dist/ssr/charts/core/pareto.js +120 -0
  100. package/dist/ssr/charts/core/pareto.js.map +1 -0
  101. package/dist/ssr/charts/core/radar.js +101 -0
  102. package/dist/ssr/charts/core/radar.js.map +1 -0
  103. package/dist/ssr/charts/core/registry.js +11 -1
  104. package/dist/ssr/charts/core/registry.js.map +1 -1
  105. package/dist/ssr/charts/core/render-size.js +3 -1
  106. package/dist/ssr/charts/core/render-size.js.map +1 -1
  107. package/dist/ssr/charts/core/render.js +19 -0
  108. package/dist/ssr/charts/core/render.js.map +1 -1
  109. package/dist/ssr/charts/core/snapshot.js +1 -1
  110. package/dist/ssr/charts/core/snapshot.js.map +1 -1
  111. package/dist/ssr/charts/core/svg-barGauge.js +67 -0
  112. package/dist/ssr/charts/core/svg-barGauge.js.map +1 -0
  113. package/dist/ssr/charts/core/svg-boxplot.js +127 -0
  114. package/dist/ssr/charts/core/svg-boxplot.js.map +1 -0
  115. package/dist/ssr/charts/core/svg-common.js +1065 -0
  116. package/dist/ssr/charts/core/svg-common.js.map +1 -0
  117. package/dist/ssr/charts/core/svg-gauge.js +185 -0
  118. package/dist/ssr/charts/core/svg-gauge.js.map +1 -0
  119. package/dist/ssr/charts/core/svg-heatmap.js +80 -0
  120. package/dist/ssr/charts/core/svg-heatmap.js.map +1 -0
  121. package/dist/ssr/charts/core/svg-histogram.js +73 -0
  122. package/dist/ssr/charts/core/svg-histogram.js.map +1 -0
  123. package/dist/ssr/charts/core/svg-renderers.js +9 -1777
  124. package/dist/ssr/charts/core/svg-renderers.js.map +1 -1
  125. package/dist/ssr/charts/core/svg-scatter.js +114 -0
  126. package/dist/ssr/charts/core/svg-scatter.js.map +1 -0
  127. package/dist/ssr/charts/core/treemap.js +138 -0
  128. package/dist/ssr/charts/core/treemap.js.map +1 -0
  129. package/dist/ssr/charts/description.js.map +1 -1
  130. package/dist/ssr/content/ChartRoot.js +21 -7
  131. package/dist/ssr/content/ChartRoot.js.map +1 -1
  132. package/dist/ssr/content/ChartSnapshotView.js +1 -0
  133. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  134. package/dist/ssr/content/DataTable.js +12 -16
  135. package/dist/ssr/content/DataTable.js.map +1 -1
  136. package/dist/ssr/content/Lightbox.js +32 -3
  137. package/dist/ssr/content/Lightbox.js.map +1 -1
  138. package/dist/ssr/content/ThumbnailStrip.js +103 -0
  139. package/dist/ssr/content/ThumbnailStrip.js.map +1 -0
  140. package/dist/ssr/content/chart-bar.js +98 -0
  141. package/dist/ssr/content/chart-bar.js.map +1 -1
  142. package/dist/ssr/content/chart-inspection-core.js +28 -8
  143. package/dist/ssr/content/chart-inspection-core.js.map +1 -1
  144. package/dist/ssr/content/chart-message-catalog.js +18 -0
  145. package/dist/ssr/content/chart-message-catalog.js.map +1 -1
  146. package/dist/ssr/content/index.js +1 -0
  147. package/dist/ssr/content/index.js.map +1 -1
  148. package/dist/ssr/content/thumbnail-strip-messages.js +24 -0
  149. package/dist/ssr/content/thumbnail-strip-messages.js.map +1 -0
  150. package/dist/ssr/inputs/ChoiceInputs.js +55 -40
  151. package/dist/ssr/inputs/ChoiceInputs.js.map +1 -1
  152. package/dist/ssr/inputs/index.js +1 -0
  153. package/dist/ssr/inputs/index.js.map +1 -1
  154. package/dist/ssr/inputs/markdown/MarkdownSelectionToolbar.js +293 -0
  155. package/dist/ssr/inputs/markdown/MarkdownSelectionToolbar.js.map +1 -0
  156. package/dist/ssr/internal/field.js +36 -24
  157. package/dist/ssr/internal/field.js.map +1 -1
  158. package/dist/ssr/layout/AppWorkspace.js +5 -1
  159. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  160. package/dist/ssr/layout/PanelDialog.js +40 -26
  161. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  162. package/dist/ssr/surfaces/StatCell.js +29 -18
  163. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  164. package/dist/ssr/surfaces/stat-cell-messages.js +4 -2
  165. package/dist/ssr/surfaces/stat-cell-messages.js.map +1 -1
  166. package/dist/ssr/widgets/DashboardFrame.js +6 -11
  167. package/dist/ssr/widgets/DashboardFrame.js.map +1 -1
  168. package/dist/styles.css +1 -1
  169. package/dist/types/actions/Toolbar.d.ts +2 -0
  170. package/dist/types/charts/core/bar-labels.d.ts +1 -0
  171. package/dist/types/charts/core/bubble.d.ts +66 -0
  172. package/dist/types/charts/core/default-styles.d.ts +1 -0
  173. package/dist/types/charts/core/funnel-layout.d.ts +43 -0
  174. package/dist/types/charts/core/funnel.d.ts +13 -0
  175. package/dist/types/charts/core/index.d.ts +6 -1
  176. package/dist/types/charts/core/pareto.d.ts +40 -0
  177. package/dist/types/charts/core/radar.d.ts +47 -0
  178. package/dist/types/charts/core/registry.d.ts +10 -0
  179. package/dist/types/charts/core/render-size.d.ts +1 -1
  180. package/dist/types/charts/core/svg-barGauge.d.ts +3 -0
  181. package/dist/types/charts/core/svg-boxplot.d.ts +18 -0
  182. package/dist/types/charts/core/svg-common.d.ts +612 -0
  183. package/dist/types/charts/core/svg-gauge.d.ts +6 -0
  184. package/dist/types/charts/core/svg-heatmap.d.ts +6 -0
  185. package/dist/types/charts/core/svg-histogram.d.ts +16 -0
  186. package/dist/types/charts/core/svg-renderers.d.ts +8 -612
  187. package/dist/types/charts/core/svg-scatter.d.ts +23 -0
  188. package/dist/types/charts/core/treemap.d.ts +45 -0
  189. package/dist/types/charts/description.d.ts +63 -0
  190. package/dist/types/content/ChartRoot.d.ts +1 -1
  191. package/dist/types/content/Lightbox.d.ts +2 -0
  192. package/dist/types/content/ThumbnailStrip.d.ts +29 -0
  193. package/dist/types/content/chart-bar.d.ts +38 -2
  194. package/dist/types/content/chart-inspection-core.d.ts +7 -0
  195. package/dist/types/content/chart-inspection.d.ts +1 -0
  196. package/dist/types/content/chart-message-catalog.d.ts +8 -0
  197. package/dist/types/content/index.d.ts +1 -0
  198. package/dist/types/content/thumbnail-strip-messages.d.ts +10 -0
  199. package/dist/types/inputs/ChoiceInputs.d.ts +2 -0
  200. package/dist/types/inputs/index.d.ts +2 -0
  201. package/dist/types/inputs/markdown/MarkdownSelectionToolbar.d.ts +19 -0
  202. package/dist/types/internal/field.d.ts +2 -0
  203. package/dist/types/layout/PanelDialog.d.ts +5 -0
  204. package/dist/types/surfaces/stat-cell-messages.d.ts +1 -0
  205. package/dist/types/widgets/DashboardFrame.d.ts +4 -1
  206. package/package.json +2 -2
@@ -0,0 +1,79 @@
1
+ import { chartTextWidth, headerHeight, wrapLabel } from "../../content/chart-bar";
2
+ import { chartMessages } from "../../content/chart-message-catalog";
3
+ import { barPercent } from "./bar-labels";
4
+ /** Ratios use the original start/previous observation. Geometry fits the largest observed step, including rises. */
5
+ export function funnelLayout(spec, size = {
6
+ width: 480,
7
+ height: 280
8
+ }) {
9
+ if (spec.data.some(d => d.value !== null && (!Number.isFinite(d.value) || d.value < 0))) throw new RangeError("Funnel values must be finite and nonnegative, or null");
10
+ const unit = size.width / 296;
11
+ const numbers = new Intl.NumberFormat(spec.locale ?? "en");
12
+ const format = spec.valueFormat ?? (v => numbers.format(v));
13
+ const labels = chartMessages.resolve([spec.locale ?? "en"]).t;
14
+ const percent = barPercent(spec.locale);
15
+ const share = (value, denominator) => value === null || denominator == null || denominator === 0 ? null : value / denominator;
16
+ const left = Math.min(96 * unit, size.width * 0.3);
17
+ const right = Math.max(104 * unit, ...spec.data.map(d => d.value === null ? 0 : (chartTextWidth(format(d.value)) + 8) * unit));
18
+ const plot = Math.max(0, size.width - left - right - 8);
19
+ const center = left + plot / 2;
20
+ const top = headerHeight(spec);
21
+ const pitch = (size.height - top) / Math.max(1, spec.data.length);
22
+ const height = Math.min(pitch * 0.6, 34);
23
+ const max = Math.max(0, ...spec.data.map(d => d.value ?? 0));
24
+ const steps = spec.data.map((d, index) => {
25
+ const startShare = share(d.value, spec.data[0]?.value);
26
+ const previousShare = index ? share(d.value, spec.data[index - 1]?.value) : null;
27
+ const y = top + index * pitch + (pitch - height) / 2;
28
+ const fields = [{
29
+ key: "value",
30
+ value: d.value ?? "–",
31
+ formatted: d.value === null ? "–" : format(d.value)
32
+ }, {
33
+ key: "startPercent",
34
+ value: startShare === null ? "–" : startShare * 100,
35
+ formatted: startShare === null ? "–" : percent.format(startShare)
36
+ }, ...(index ? [{
37
+ key: "previousPercent",
38
+ value: previousShare === null ? "–" : previousShare * 100,
39
+ formatted: previousShare === null ? "–" : percent.format(previousShare)
40
+ }] : [])];
41
+ const datum = {
42
+ role: "item",
43
+ index,
44
+ label: d.label,
45
+ anchor: [center, y],
46
+ values: fields
47
+ };
48
+ return {
49
+ ...d,
50
+ index,
51
+ center,
52
+ y,
53
+ width: d.value === null || max === 0 ? 0 : d.value / max * plot,
54
+ startShare,
55
+ previousShare,
56
+ datum,
57
+ labelLines: wrapLabel(d.label, (left / unit - 8) * 11 / 12.5, 2).lines,
58
+ valueText: fields[0].formatted,
59
+ shareText: `${fields[1].formatted} ${labels.chartBarStart}`,
60
+ title: `${d.label} · ${fields[0].formatted} · ${labels.chartFields({
61
+ key: "startPercent"
62
+ })}: ${fields[1].formatted}${index ? ` · ${labels.chartFields({
63
+ key: "previousPercent"
64
+ })}: ${fields[2].formatted}` : ""}`
65
+ };
66
+ });
67
+ return {
68
+ ...size,
69
+ unit,
70
+ left,
71
+ right,
72
+ center,
73
+ top,
74
+ pitch,
75
+ barHeight: height,
76
+ steps
77
+ };
78
+ }
79
+ //# sourceMappingURL=funnel-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["charts/core/funnel-layout.ts"],"sourcesContent":["import { chartTextWidth, headerHeight, wrapLabel } from \"../../content/chart-bar\";\nimport { chartMessages } from \"../../content/chart-message-catalog\";\nimport { barPercent } from \"./bar-labels\";\nimport type { ChartDatum } from \"./types\";\n\nexport type FunnelOptions = {\n data: { label: string; value: number | null }[];\n valueFormat?: (value: number) => string;\n locale?: string;\n title?: string;\n subtitle?: string;\n className?: string;\n};\n\n/** Ratios use the original start/previous observation. Geometry fits the largest observed step, including rises. */\nexport function funnelLayout(spec: FunnelOptions, size = { width: 480, height: 280 }) {\n if (spec.data.some((d) => d.value !== null && (!Number.isFinite(d.value) || d.value < 0)))\n throw new RangeError(\"Funnel values must be finite and nonnegative, or null\");\n const unit = size.width / 296;\n const numbers = new Intl.NumberFormat(spec.locale ?? \"en\");\n const format = spec.valueFormat ?? ((v: number) => numbers.format(v));\n const labels = chartMessages.resolve([spec.locale ?? \"en\"]).t;\n const percent = barPercent(spec.locale);\n const share = (value: number | null, denominator: number | null | undefined) =>\n value === null || denominator == null || denominator === 0 ? null : value / denominator;\n const left = Math.min(96 * unit, size.width * 0.3);\n const right = Math.max(104 * unit, ...spec.data.map((d) => (d.value === null ? 0 : (chartTextWidth(format(d.value)) + 8) * unit)));\n const plot = Math.max(0, size.width - left - right - 8);\n const center = left + plot / 2;\n const top = headerHeight(spec);\n const pitch = (size.height - top) / Math.max(1, spec.data.length);\n const height = Math.min(pitch * 0.6, 34);\n const max = Math.max(0, ...spec.data.map((d) => d.value ?? 0));\n const steps = spec.data.map((d, index) => {\n const startShare = share(d.value, spec.data[0]?.value);\n const previousShare = index ? share(d.value, spec.data[index - 1]?.value) : null;\n const y = top + index * pitch + (pitch - height) / 2;\n const fields = [\n { key: \"value\", value: d.value ?? \"–\", formatted: d.value === null ? \"–\" : format(d.value) },\n {\n key: \"startPercent\",\n value: startShare === null ? \"–\" : startShare * 100,\n formatted: startShare === null ? \"–\" : percent.format(startShare),\n },\n ...(index\n ? [\n {\n key: \"previousPercent\",\n value: previousShare === null ? \"–\" : previousShare * 100,\n formatted: previousShare === null ? \"–\" : percent.format(previousShare),\n },\n ]\n : []),\n ];\n const datum: ChartDatum = { role: \"item\", index, label: d.label, anchor: [center, y], values: fields };\n return {\n ...d,\n index,\n center,\n y,\n width: d.value === null || max === 0 ? 0 : (d.value / max) * plot,\n startShare,\n previousShare,\n datum,\n labelLines: wrapLabel(d.label, ((left / unit - 8) * 11) / 12.5, 2).lines,\n valueText: fields[0]!.formatted,\n shareText: `${fields[1]!.formatted} ${labels.chartBarStart}`,\n title: `${d.label} · ${fields[0]!.formatted} · ${labels.chartFields({ key: \"startPercent\" })}: ${fields[1]!.formatted}${index ? ` · ${labels.chartFields({ key: \"previousPercent\" })}: ${fields[2]!.formatted}` : \"\"}`,\n };\n });\n return { ...size, unit, left, right, center, top, pitch, barHeight: height, steps };\n}\n\nexport type FunnelLayout = ReturnType<typeof funnelLayout>;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,27 @@
1
+ import { funnelLayout } from "./funnel-layout";
2
+ import { chartDatumSvg, escapeXml, renderHeader, svgRoot } from "./svg-renderers";
3
+ export { funnelLayout } from "./funnel-layout";
4
+ export function renderFunnelSvg(spec) {
5
+ return renderFunnelLayoutSvg(spec, funnelLayout(spec, spec));
6
+ }
7
+
8
+ /** Draw the same geometry reserved before a lazy host loads its renderer. */
9
+ export function renderFunnelLayoutSvg(spec, g) {
10
+ const text = (x, y, value, anchor = "start", cls = "stdlib-chart-tick-label") => `<text class="${cls}" x="${x}" y="${y}" text-anchor="${anchor}">${escapeXml(value)}</text>`;
11
+ const parts = [renderHeader(spec.width, spec.title, spec.subtitle).svg];
12
+ for (const step of g.steps) {
13
+ const next = g.steps[step.index + 1];
14
+ if (next && step.value !== null && next.value !== null) parts.push(`<polygon points="${g.center - step.width / 2},${step.y + g.barHeight} ${g.center + step.width / 2},${step.y + g.barHeight} ${g.center + next.width / 2},${next.y} ${g.center - next.width / 2},${next.y}" style="fill:var(--stdlib-chart-c1,#3b82f6);fill-opacity:.09"/>`);
15
+ const marks = `<rect class="k2b-chart-category-band" fill="none" pointer-events="all" x="0" y="${g.top + step.index * g.pitch}" width="${g.width}" height="${g.pitch}" rx="6"/>${step.value === null ? "" : `<rect class="stdlib-chart-bar" x="${g.center - step.width / 2}" y="${step.y}" width="${step.width}" height="${g.barHeight}" rx="3" style="fill:var(--stdlib-chart-c1,#3b82f6);fill-opacity:${Math.max(0.3, 1 - step.index * 0.14)}" stroke="none" stroke-width="0"/>`}`;
16
+ parts.push(chartDatumSvg(marks, step.datum, spec.inspect ?? false, step.title));
17
+ const lines = step.labelLines;
18
+ lines.forEach((line, i) => parts.push(text(0, step.y + g.barHeight / 2 + 4 + (lines.length > 1 ? i === 0 ? -6.5 : 6.5 : 0), line)));
19
+ parts.push(text(g.width, step.y + g.barHeight / 2 + (step.index ? -2 : 4), step.valueText, "end", "stdlib-chart-bar-value"));
20
+ if (step.index) parts.push(text(g.width, step.y + g.barHeight / 2 + 12, step.shareText, "end"));
21
+ }
22
+ return svgRoot({
23
+ ...spec,
24
+ className: [spec.className, "k2b-chart-funnel"].filter(Boolean).join(" ")
25
+ }, parts.join("")).replace("</style>", ".k2b-chart-funnel :is(.stdlib-chart-tick-label,.stdlib-chart-bar-value){font-size:12.5px}</style>").replace("<svg ", '<svg data-bar-layout="rows" ');
26
+ }
27
+ //# sourceMappingURL=funnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["charts/core/funnel.ts"],"sourcesContent":["import { type FunnelLayout, type FunnelOptions, funnelLayout } from \"./funnel-layout\";\nimport { chartDatumSvg, escapeXml, renderHeader, svgRoot } from \"./svg-renderers\";\n\nexport { type FunnelLayout, type FunnelOptions, funnelLayout } from \"./funnel-layout\";\n\nexport function renderFunnelSvg(spec: FunnelOptions & { width: number; height: number; inspect?: boolean }) {\n return renderFunnelLayoutSvg(spec, funnelLayout(spec, spec));\n}\n\n/** Draw the same geometry reserved before a lazy host loads its renderer. */\nexport function renderFunnelLayoutSvg(spec: FunnelOptions & { width: number; height: number; inspect?: boolean }, g: FunnelLayout) {\n const text = (x: number, y: number, value: string, anchor = \"start\", cls = \"stdlib-chart-tick-label\") =>\n `<text class=\"${cls}\" x=\"${x}\" y=\"${y}\" text-anchor=\"${anchor}\">${escapeXml(value)}</text>`;\n const parts: string[] = [renderHeader(spec.width, spec.title, spec.subtitle).svg];\n for (const step of g.steps) {\n const next = g.steps[step.index + 1];\n if (next && step.value !== null && next.value !== null)\n parts.push(\n `<polygon points=\"${g.center - step.width / 2},${step.y + g.barHeight} ${g.center + step.width / 2},${step.y + g.barHeight} ${g.center + next.width / 2},${next.y} ${g.center - next.width / 2},${next.y}\" style=\"fill:var(--stdlib-chart-c1,#3b82f6);fill-opacity:.09\"/>`,\n );\n const marks = `<rect class=\"k2b-chart-category-band\" fill=\"none\" pointer-events=\"all\" x=\"0\" y=\"${g.top + step.index * g.pitch}\" width=\"${g.width}\" height=\"${g.pitch}\" rx=\"6\"/>${step.value === null ? \"\" : `<rect class=\"stdlib-chart-bar\" x=\"${g.center - step.width / 2}\" y=\"${step.y}\" width=\"${step.width}\" height=\"${g.barHeight}\" rx=\"3\" style=\"fill:var(--stdlib-chart-c1,#3b82f6);fill-opacity:${Math.max(0.3, 1 - step.index * 0.14)}\" stroke=\"none\" stroke-width=\"0\"/>`}`;\n parts.push(chartDatumSvg(marks, step.datum, spec.inspect ?? false, step.title));\n const lines = step.labelLines;\n lines.forEach((line, i) => parts.push(text(0, step.y + g.barHeight / 2 + 4 + (lines.length > 1 ? (i === 0 ? -6.5 : 6.5) : 0), line)));\n parts.push(text(g.width, step.y + g.barHeight / 2 + (step.index ? -2 : 4), step.valueText, \"end\", \"stdlib-chart-bar-value\"));\n if (step.index) parts.push(text(g.width, step.y + g.barHeight / 2 + 12, step.shareText, \"end\"));\n }\n return svgRoot({ ...spec, className: [spec.className, \"k2b-chart-funnel\"].filter(Boolean).join(\" \") }, parts.join(\"\"))\n .replace(\"</style>\", \".k2b-chart-funnel :is(.stdlib-chart-tick-label,.stdlib-chart-bar-value){font-size:12.5px}</style>\")\n .replace(\"<svg \", '<svg data-bar-layout=\"rows\" ');\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,17 +1,22 @@
1
1
  /** Portable chart contracts. This entry never imports Solid or browser APIs. */
2
2
 
3
- export { barChartLayout, renderBarChartSvg, seriesBarLayout } from "../../content/chart-bar";
3
+ export { barChartLayout, rankedBarLayout, renderBarChartSvg, seriesBarLayout } from "../../content/chart-bar";
4
4
  export { renderStateTimelineSvg, stateTimelineDomain, stateTimelineHeight } from "../../content/chart-state-timeline";
5
5
  export { areaLayout, renderAreaSvg } from "./area";
6
+ export * from "./bubble";
6
7
  export * from "./calendar";
8
+ export { funnelLayout, renderFunnelLayoutSvg, renderFunnelSvg } from "./funnel";
7
9
  export { hbarLayout, renderHbarLayoutSvg, renderHbarSvg } from "./hbar";
8
10
  export * from "./inspection";
9
11
  export { map } from "./map";
12
+ export * from "./pareto";
13
+ export * from "./radar";
10
14
  export * from "./render";
11
15
  export { chartRenderHeight, preservesAspectRatio } from "./render-size";
12
16
  export * from "./snapshot";
13
17
  export { charts } from "./svg";
14
18
  export { arcPathD, autoBin, bar, barGauge, boxplot, chartDatumSvg, computeBoxStats, computeDomain, donut, escapeXml, extendDomainToNice, gauge, heatmap, histogram, line, linearRegression, linePathD, mapLog, mapRange, markerPath, niceLogTicks, niceStep, normalizePadding, pie, scatter, smoothPathD, sparkline, stat, stateTimeline, stepPathD, svgRoot } from "./svg-renderers";
19
+ export * from "./treemap";
15
20
  export { chartDatumRoles } from "./types";
16
21
  export { renderWaterfallLayoutSvg, renderWaterfallSvg, waterfallLayout } from "./waterfall";
17
22
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["charts/core/index.ts"],"sourcesContent":["/** Portable chart contracts. This entry never imports Solid or browser APIs. */\n\nexport { type BarChartLayout, type BarChartOptions, barChartLayout, renderBarChartSvg, seriesBarLayout } from \"../../content/chart-bar\";\nexport {\n renderStateTimelineSvg,\n type StateTimelineChartOptions,\n type StateTimelineDomain,\n stateTimelineDomain,\n stateTimelineHeight,\n} from \"../../content/chart-state-timeline\";\nexport { type ChartTimeAxis } from \"../../content/chart-time-axis\";\nexport { type AreaOptions, areaLayout, renderAreaSvg } from \"./area\";\nexport * from \"./calendar\";\nexport { type HorizontalBarLayout, type HorizontalBarOptions, hbarLayout, renderHbarLayoutSvg, renderHbarSvg } from \"./hbar\";\nexport * from \"./inspection\";\nexport { map } from \"./map\";\nexport * from \"./render\";\nexport { chartRenderHeight, preservesAspectRatio } from \"./render-size\";\nexport * from \"./snapshot\";\nexport { charts } from \"./svg\";\nexport {\n type AxisOptions,\n arcPathD,\n autoBin,\n type BarItem,\n bar,\n barGauge,\n boxplot,\n type ChartOptions,\n chartDatumSvg,\n computeBoxStats,\n computeDomain,\n donut,\n escapeXml,\n extendDomainToNice,\n gauge,\n heatmap,\n histogram,\n type LineStyle,\n line,\n linearRegression,\n linePathD,\n type MapOptions,\n type MapPoint,\n type MapSeries,\n type MapViewport,\n type MarkerShape,\n mapLog,\n mapRange,\n markerPath,\n niceLogTicks,\n niceStep,\n normalizePadding,\n type Padding,\n type Point,\n pie,\n type ReferenceLine,\n type Series,\n type SliceItem,\n scatter,\n smoothPathD,\n sparkline,\n stat,\n stateTimeline,\n stepPathD,\n svgRoot,\n} from \"./svg-renderers\";\nexport {\n type ChartDateFormat,\n type ChartDatum,\n type ChartDatumRole,\n type ChartFormat,\n type ChartKind,\n type ChartNumberFormat,\n chartDatumRoles,\n} from \"./types\";\n\nexport { renderWaterfallLayoutSvg, renderWaterfallSvg, type WaterfallLayout, type WaterfallOptions, waterfallLayout } from \"./waterfall\";\n"],"mappings":"AAAA;;AAEA,SAAoD,cAAc,EAAE,iBAAiB,EAAE,eAAe,QAAQ,yBAAyB;AACvI,SACE,sBAAsB,EAGtB,mBAAmB,EACnB,mBAAmB,QACd,oCAAoC;AAE3C,SAA2B,UAAU,EAAE,aAAa,QAAQ,QAAQ;AACpE,cAAc,YAAY;AAC1B,SAA8D,UAAU,EAAE,mBAAmB,EAAE,aAAa,QAAQ,QAAQ;AAC5H,cAAc,cAAc;AAC5B,SAAS,GAAG,QAAQ,OAAO;AAC3B,cAAc,UAAU;AACxB,SAAS,iBAAiB,EAAE,oBAAoB,QAAQ,eAAe;AACvE,cAAc,YAAY;AAC1B,SAAS,MAAM,QAAQ,OAAO;AAC9B,SAEE,QAAQ,EACR,OAAO,EAEP,GAAG,EACH,QAAQ,EACR,OAAO,EAEP,aAAa,EACb,eAAe,EACf,aAAa,EACb,KAAK,EACL,SAAS,EACT,kBAAkB,EAClB,KAAK,EACL,OAAO,EACP,SAAS,EAET,IAAI,EACJ,gBAAgB,EAChB,SAAS,EAMT,MAAM,EACN,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAGhB,GAAG,EAIH,OAAO,EACP,WAAW,EACX,SAAS,EACT,IAAI,EACJ,aAAa,EACb,SAAS,EACT,OAAO,QACF,iBAAiB;AACxB,SAOE,eAAe,QACV,SAAS;AAEhB,SAAS,wBAAwB,EAAE,kBAAkB,EAA+C,eAAe,QAAQ,aAAa","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["charts/core/index.ts"],"sourcesContent":["/** Portable chart contracts. This entry never imports Solid or browser APIs. */\n\nexport {\n type BarChartLayout,\n type BarChartOptions,\n barChartLayout,\n rankedBarLayout,\n renderBarChartSvg,\n seriesBarLayout,\n} from \"../../content/chart-bar\";\nexport {\n renderStateTimelineSvg,\n type StateTimelineChartOptions,\n type StateTimelineDomain,\n stateTimelineDomain,\n stateTimelineHeight,\n} from \"../../content/chart-state-timeline\";\nexport { type ChartTimeAxis } from \"../../content/chart-time-axis\";\nexport { type AreaOptions, areaLayout, renderAreaSvg } from \"./area\";\nexport * from \"./bubble\";\nexport * from \"./calendar\";\nexport { type FunnelLayout, type FunnelOptions, funnelLayout, renderFunnelLayoutSvg, renderFunnelSvg } from \"./funnel\";\nexport { type HorizontalBarLayout, type HorizontalBarOptions, hbarLayout, renderHbarLayoutSvg, renderHbarSvg } from \"./hbar\";\nexport * from \"./inspection\";\nexport { map } from \"./map\";\nexport * from \"./pareto\";\n\nexport * from \"./radar\";\nexport * from \"./render\";\nexport { chartRenderHeight, preservesAspectRatio } from \"./render-size\";\nexport * from \"./snapshot\";\nexport { charts } from \"./svg\";\nexport {\n type AxisOptions,\n arcPathD,\n autoBin,\n type BarItem,\n bar,\n barGauge,\n boxplot,\n type ChartOptions,\n chartDatumSvg,\n computeBoxStats,\n computeDomain,\n donut,\n escapeXml,\n extendDomainToNice,\n gauge,\n heatmap,\n histogram,\n type LineStyle,\n line,\n linearRegression,\n linePathD,\n type MapOptions,\n type MapPoint,\n type MapSeries,\n type MapViewport,\n type MarkerShape,\n mapLog,\n mapRange,\n markerPath,\n niceLogTicks,\n niceStep,\n normalizePadding,\n type Padding,\n type Point,\n pie,\n type ReferenceLine,\n type Series,\n type SliceItem,\n scatter,\n smoothPathD,\n sparkline,\n stat,\n stateTimeline,\n stepPathD,\n svgRoot,\n} from \"./svg-renderers\";\nexport * from \"./treemap\";\nexport {\n type ChartDateFormat,\n type ChartDatum,\n type ChartDatumRole,\n type ChartFormat,\n type ChartKind,\n type ChartNumberFormat,\n chartDatumRoles,\n} from \"./types\";\n\nexport { renderWaterfallLayoutSvg, renderWaterfallSvg, type WaterfallLayout, type WaterfallOptions, waterfallLayout } from \"./waterfall\";\n"],"mappings":"AAAA;;AAEA,SAGE,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,eAAe,QACV,yBAAyB;AAChC,SACE,sBAAsB,EAGtB,mBAAmB,EACnB,mBAAmB,QACd,oCAAoC;AAE3C,SAA2B,UAAU,EAAE,aAAa,QAAQ,QAAQ;AACpE,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,SAAgD,YAAY,EAAE,qBAAqB,EAAE,eAAe,QAAQ,UAAU;AACtH,SAA8D,UAAU,EAAE,mBAAmB,EAAE,aAAa,QAAQ,QAAQ;AAC5H,cAAc,cAAc;AAC5B,SAAS,GAAG,QAAQ,OAAO;AAC3B,cAAc,UAAU;AAExB,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,SAAS,iBAAiB,EAAE,oBAAoB,QAAQ,eAAe;AACvE,cAAc,YAAY;AAC1B,SAAS,MAAM,QAAQ,OAAO;AAC9B,SAEE,QAAQ,EACR,OAAO,EAEP,GAAG,EACH,QAAQ,EACR,OAAO,EAEP,aAAa,EACb,eAAe,EACf,aAAa,EACb,KAAK,EACL,SAAS,EACT,kBAAkB,EAClB,KAAK,EACL,OAAO,EACP,SAAS,EAET,IAAI,EACJ,gBAAgB,EAChB,SAAS,EAMT,MAAM,EACN,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAGhB,GAAG,EAIH,OAAO,EACP,WAAW,EACX,SAAS,EACT,IAAI,EACJ,aAAa,EACb,SAAS,EACT,OAAO,QACF,iBAAiB;AACxB,cAAc,WAAW;AACzB,SAOE,eAAe,QACV,SAAS;AAEhB,SAAS,wBAAwB,EAAE,kBAAkB,EAA+C,eAAe,QAAQ,aAAa","ignoreList":[]}
@@ -0,0 +1,120 @@
1
+ import { chartDatumSvg, escapeXml, niceStep, renderHeader, svgRoot } from "./svg";
2
+ export function paretoLayout(spec, size = {
3
+ width: spec.width ?? 480,
4
+ height: spec.height ?? 280
5
+ }) {
6
+ const width = spec.displayWidth ?? size.width,
7
+ header = renderHeader(width, spec.title, spec.subtitle),
8
+ top = header.height + 24,
9
+ bottom = 48,
10
+ height = Math.max(size.height, spec.data.length * 34 + top + bottom);
11
+ const data = spec.data.map((d, index) => {
12
+ if (![d.value, d.prev].every(v => Number.isFinite(v) && v >= 0)) throw new RangeError("Pareto values must be finite and nonnegative.");
13
+ return {
14
+ ...d,
15
+ index
16
+ };
17
+ }).sort((a, b) => Number(a.label.toLowerCase() === "rest") - Number(b.label.toLowerCase() === "rest") || b.value - a.value);
18
+ const total = data.reduce((s, d) => s + d.value, 0),
19
+ rawMax = Math.max(0, ...data.flatMap(d => [d.value, d.prev])) || 1;
20
+ const step = niceStep(rawMax, 3),
21
+ roundedMax = Math.ceil(rawMax / step) * step;
22
+ const max = Number.isFinite(roundedMax) && roundedMax > 0 ? roundedMax : rawMax;
23
+ const ticks = Number.isFinite(step) && step > 0 && max / step <= 6 ? Array.from({
24
+ length: Math.round(max / step) + 1
25
+ }, (_, i) => i * step) : [0, max / 2, max];
26
+ if (!Number.isFinite(total)) throw new RangeError("Pareto total must be finite.");
27
+ const left = Math.min(112, width * 0.25),
28
+ plot = width - left - 30,
29
+ rowHeight = (height - top - bottom) / Math.max(1, data.length);
30
+ let sum = 0;
31
+ return {
32
+ width,
33
+ height,
34
+ total,
35
+ max,
36
+ ticks,
37
+ left,
38
+ plot,
39
+ rowHeight,
40
+ header,
41
+ top,
42
+ bottom,
43
+ rows: data.map((d, index) => {
44
+ sum += d.value;
45
+ return {
46
+ ...d,
47
+ y: top + rowHeight * (index + 0.5),
48
+ cumulative: total ? sum / total : 0
49
+ };
50
+ })
51
+ };
52
+ }
53
+ export function renderParetoSvg(spec) {
54
+ const s = paretoLayout(spec);
55
+ const number = spec.format ?? new Intl.NumberFormat(spec.locale ?? "en", {
56
+ maximumSignificantDigits: 15
57
+ }).format;
58
+ const percent = new Intl.NumberFormat(spec.locale ?? "en", {
59
+ style: "percent",
60
+ maximumFractionDigits: 1
61
+ });
62
+ const color = "var(--stdlib-chart-c1,#3b82f6)";
63
+ const body = [s.header.svg.replace(/<text class="stdlib-chart-title"/g, '<text fill="var(--k2b-text,#27272a)" font-size="14" class="stdlib-chart-title"').replace(/<text class="stdlib-chart-subtitle"/g, '<text fill="var(--k2b-text-muted,#45454e)" font-size="11" class="stdlib-chart-subtitle"')];
64
+ const axisNumber = spec.format ?? new Intl.NumberFormat(spec.locale ?? "en", {
65
+ maximumFractionDigits: 2,
66
+ notation: s.max >= 1e9 || s.max < 0.001 ? "scientific" : "standard"
67
+ }).format;
68
+ for (const tick of s.ticks) body.push(`<line x1="${s.left + tick / s.max * s.plot}" x2="${s.left + tick / s.max * s.plot}" y1="${s.top}" y2="${s.height - s.bottom}" stroke="var(--k2b-border,#e4e4e7)" stroke-opacity="0.5" pointer-events="none"/><text x="${s.left + tick / s.max * s.plot}" y="${s.top - 8}" text-anchor="${tick === s.max ? "end" : tick === 0 ? "start" : "middle"}" font-size="11" fill="var(--k2b-text-muted,#45454e)">${escapeXml(axisNumber(tick))}</text>`);
69
+ let line = `${s.left},${s.top}`;
70
+ for (const row of s.rows) {
71
+ const change = row.prev ? row.value / row.prev - 1 : Number.NaN;
72
+ const bh = Math.min(s.rowHeight * 0.36, 12),
73
+ valueWidth = row.value / s.max * s.plot,
74
+ prevWidth = row.prev / s.max * s.plot;
75
+ const hatch = `<path class="k2b-chart-pareto-hatch" d="${Array.from({
76
+ length: Math.floor(prevWidth / 5)
77
+ }, (_, i) => `M${s.left + i * 5},${row.y + 1 + bh}l${Math.min(4, prevWidth - i * 5)},-${bh}`).join(" ")}" fill="none" stroke="${color}" stroke-width="1" pointer-events="none"/>`;
78
+ body.push(chartDatumSvg(`<rect class="k2b-chart-pareto-current" x="${s.left}" y="${row.y - bh - 1}" width="${valueWidth}" height="${bh}" rx="2" fill="${color}" stroke="none"/><rect class="k2b-chart-pareto-previous" x="${s.left}" y="${row.y + 1}" width="${prevWidth}" height="${bh}" rx="2" fill="${color}" fill-opacity="0.14" stroke="${color}" stroke-width="0.8"/>${hatch}<rect class="k2b-chart-category-band" x="0" y="${row.y - s.rowHeight / 2}" width="${s.width}" height="${s.rowHeight}" fill="transparent" pointer-events="none"/><text x="${s.left - 8}" y="${row.y + 4}" text-anchor="end" font-size="12" fill="var(--k2b-text,#27272a)">${escapeXml(row.label.length > Math.floor(s.left * (spec.displayWidth ?? 296) / s.width / 7) - 1 ? row.label.slice(0, Math.max(1, Math.floor(s.left * (spec.displayWidth ?? 296) / s.width / 7) - 2)) + "…" : row.label)}</text>`, {
79
+ role: "item",
80
+ index: row.index,
81
+ label: row.label,
82
+ anchor: [s.left + valueWidth, row.y],
83
+ grid: [0, s.rows.indexOf(row)],
84
+ values: [{
85
+ key: "value",
86
+ value: row.value,
87
+ formatted: number(row.value)
88
+ }, {
89
+ key: "previous",
90
+ value: row.prev,
91
+ formatted: number(row.prev)
92
+ }, {
93
+ key: "change",
94
+ value: Number.isFinite(change) ? change : 0,
95
+ formatted: Number.isFinite(change) ? percent.format(change) : "–"
96
+ }, {
97
+ key: "cumulative",
98
+ value: row.cumulative,
99
+ formatted: s.total ? percent.format(row.cumulative) : "–"
100
+ }]
101
+ }, spec.inspect));
102
+ line += ` ${s.left + row.cumulative * s.plot},${row.y}`;
103
+ }
104
+ body.push(`<line x1="${s.left + 0.8 * s.plot}" x2="${s.left + 0.8 * s.plot}" y1="${s.top}" y2="${s.height - s.bottom}" stroke="var(--k2b-warning-text,#92400e)" stroke-dasharray="5 4"/><text x="${s.left + 0.8 * s.plot + 4}" y="${s.height - s.bottom - 4}" font-size="11" fill="var(--k2b-warning-text,#92400e)">80 %</text><polyline points="${line}" fill="none" stroke="var(--k2b-text-muted,#45454e)" stroke-width="1.5" pointer-events="none"/>`);
105
+ for (let p = 0; p <= 5; p++) body.push(`<text x="${s.left + p / 5 * s.plot}" y="${s.height - s.bottom + 17}" text-anchor="middle" font-size="11" fill="var(--k2b-text-muted,#45454e)">${escapeXml(percent.format(p / 5))}</text>`);
106
+ for (const row of s.rows) body.push(`<circle cx="${s.left + row.cumulative * s.plot}" cy="${row.y}" r="3" fill="var(--k2b-surface,#fff)" stroke="var(--k2b-text-muted,#45454e)" stroke-width="1.5" pointer-events="none"/>`);
107
+ const names = [...spec.labels, (spec.locale ?? "en").startsWith("de") ? "Kumuliert" : "Cumulative"];
108
+ let lx = 0;
109
+ names.forEach((name, index) => {
110
+ const x = lx;
111
+ lx += Math.min(s.width / 3, name.length * 12 + 32);
112
+ const display = name.slice(0, Math.max(1, Math.floor(((spec.displayWidth ?? 296) / 3 - 28) / 7)));
113
+ body.push(`${index === 2 ? `<line x1="${x}" x2="${x + 12}" y1="${s.height - 10}" y2="${s.height - 10}" stroke="var(--k2b-text-muted,#45454e)"/>` : `<rect x="${x}" y="${s.height - 15}" width="10" height="10" rx="2" fill="${color}" fill-opacity="${index === 1 ? 0.2 : 1}"/>${index === 1 ? `<path d="M${x},${s.height - 6}l8,-8" stroke="${color}"/>` : ""}`}<text x="${x + 16}" y="${s.height - 6}" font-size="11" fill="var(--k2b-text-muted,#45454e)">${escapeXml(display)}</text>`);
114
+ });
115
+ return svgRoot({
116
+ ...s,
117
+ className: spec.className
118
+ }, body.join(""));
119
+ }
120
+ //# sourceMappingURL=pareto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["charts/core/pareto.ts"],"sourcesContent":["import { type ChartOptions, chartDatumSvg, escapeXml, niceStep, renderHeader, svgRoot } from \"./svg\";\nexport type ParetoOptions = ChartOptions & {\n labels: [string, string];\n data: { label: string; value: number; prev: number }[];\n locale?: string;\n format?: (value: number) => string;\n displayWidth?: number;\n};\nexport function paretoLayout(spec: ParetoOptions, size = { width: spec.width ?? 480, height: spec.height ?? 280 }) {\n const width = spec.displayWidth ?? size.width,\n header = renderHeader(width, spec.title, spec.subtitle),\n top = header.height + 24,\n bottom = 48,\n height = Math.max(size.height, spec.data.length * 34 + top + bottom);\n const data = spec.data\n .map((d, index) => {\n if (![d.value, d.prev].every((v) => Number.isFinite(v) && v >= 0))\n throw new RangeError(\"Pareto values must be finite and nonnegative.\");\n return { ...d, index };\n })\n .sort((a, b) => Number(a.label.toLowerCase() === \"rest\") - Number(b.label.toLowerCase() === \"rest\") || b.value - a.value);\n const total = data.reduce((s, d) => s + d.value, 0),\n rawMax = Math.max(0, ...data.flatMap((d) => [d.value, d.prev])) || 1;\n const step = niceStep(rawMax, 3),\n roundedMax = Math.ceil(rawMax / step) * step;\n const max = Number.isFinite(roundedMax) && roundedMax > 0 ? roundedMax : rawMax;\n const ticks =\n Number.isFinite(step) && step > 0 && max / step <= 6\n ? Array.from({ length: Math.round(max / step) + 1 }, (_, i) => i * step)\n : [0, max / 2, max];\n if (!Number.isFinite(total)) throw new RangeError(\"Pareto total must be finite.\");\n const left = Math.min(112, width * 0.25),\n plot = width - left - 30,\n rowHeight = (height - top - bottom) / Math.max(1, data.length);\n let sum = 0;\n return {\n width,\n height,\n total,\n max,\n ticks,\n left,\n plot,\n rowHeight,\n header,\n top,\n bottom,\n rows: data.map((d, index) => {\n sum += d.value;\n return { ...d, y: top + rowHeight * (index + 0.5), cumulative: total ? sum / total : 0 };\n }),\n };\n}\nexport function renderParetoSvg(spec: ParetoOptions): string {\n const s = paretoLayout(spec);\n const number = spec.format ?? new Intl.NumberFormat(spec.locale ?? \"en\", { maximumSignificantDigits: 15 }).format;\n const percent = new Intl.NumberFormat(spec.locale ?? \"en\", { style: \"percent\", maximumFractionDigits: 1 });\n const color = \"var(--stdlib-chart-c1,#3b82f6)\";\n const body: string[] = [\n s.header.svg\n .replace(/<text class=\"stdlib-chart-title\"/g, '<text fill=\"var(--k2b-text,#27272a)\" font-size=\"14\" class=\"stdlib-chart-title\"')\n .replace(\n /<text class=\"stdlib-chart-subtitle\"/g,\n '<text fill=\"var(--k2b-text-muted,#45454e)\" font-size=\"11\" class=\"stdlib-chart-subtitle\"',\n ),\n ];\n const axisNumber =\n spec.format ??\n new Intl.NumberFormat(spec.locale ?? \"en\", {\n maximumFractionDigits: 2,\n notation: s.max >= 1e9 || s.max < 0.001 ? \"scientific\" : \"standard\",\n }).format;\n for (const tick of s.ticks)\n body.push(\n `<line x1=\"${s.left + (tick / s.max) * s.plot}\" x2=\"${s.left + (tick / s.max) * s.plot}\" y1=\"${s.top}\" y2=\"${s.height - s.bottom}\" stroke=\"var(--k2b-border,#e4e4e7)\" stroke-opacity=\"0.5\" pointer-events=\"none\"/><text x=\"${s.left + (tick / s.max) * s.plot}\" y=\"${s.top - 8}\" text-anchor=\"${tick === s.max ? \"end\" : tick === 0 ? \"start\" : \"middle\"}\" font-size=\"11\" fill=\"var(--k2b-text-muted,#45454e)\">${escapeXml(axisNumber(tick))}</text>`,\n );\n let line = `${s.left},${s.top}`;\n for (const row of s.rows) {\n const change = row.prev ? row.value / row.prev - 1 : Number.NaN;\n const bh = Math.min(s.rowHeight * 0.36, 12),\n valueWidth = (row.value / s.max) * s.plot,\n prevWidth = (row.prev / s.max) * s.plot;\n const hatch = `<path class=\"k2b-chart-pareto-hatch\" d=\"${Array.from({ length: Math.floor(prevWidth / 5) }, (_, i) => `M${s.left + i * 5},${row.y + 1 + bh}l${Math.min(4, prevWidth - i * 5)},-${bh}`).join(\" \")}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1\" pointer-events=\"none\"/>`;\n body.push(\n chartDatumSvg(\n `<rect class=\"k2b-chart-pareto-current\" x=\"${s.left}\" y=\"${row.y - bh - 1}\" width=\"${valueWidth}\" height=\"${bh}\" rx=\"2\" fill=\"${color}\" stroke=\"none\"/><rect class=\"k2b-chart-pareto-previous\" x=\"${s.left}\" y=\"${row.y + 1}\" width=\"${prevWidth}\" height=\"${bh}\" rx=\"2\" fill=\"${color}\" fill-opacity=\"0.14\" stroke=\"${color}\" stroke-width=\"0.8\"/>${hatch}<rect class=\"k2b-chart-category-band\" x=\"0\" y=\"${row.y - s.rowHeight / 2}\" width=\"${s.width}\" height=\"${s.rowHeight}\" fill=\"transparent\" pointer-events=\"none\"/><text x=\"${s.left - 8}\" y=\"${row.y + 4}\" text-anchor=\"end\" font-size=\"12\" fill=\"var(--k2b-text,#27272a)\">${escapeXml(row.label.length > Math.floor((s.left * (spec.displayWidth ?? 296)) / s.width / 7) - 1 ? row.label.slice(0, Math.max(1, Math.floor((s.left * (spec.displayWidth ?? 296)) / s.width / 7) - 2)) + \"…\" : row.label)}</text>`,\n {\n role: \"item\",\n index: row.index,\n label: row.label,\n anchor: [s.left + valueWidth, row.y],\n grid: [0, s.rows.indexOf(row)],\n values: [\n { key: \"value\", value: row.value, formatted: number(row.value) },\n { key: \"previous\", value: row.prev, formatted: number(row.prev) },\n {\n key: \"change\",\n value: Number.isFinite(change) ? change : 0,\n formatted: Number.isFinite(change) ? percent.format(change) : \"–\",\n },\n { key: \"cumulative\", value: row.cumulative, formatted: s.total ? percent.format(row.cumulative) : \"–\" },\n ],\n },\n spec.inspect,\n ),\n );\n line += ` ${s.left + row.cumulative * s.plot},${row.y}`;\n }\n body.push(\n `<line x1=\"${s.left + 0.8 * s.plot}\" x2=\"${s.left + 0.8 * s.plot}\" y1=\"${s.top}\" y2=\"${s.height - s.bottom}\" stroke=\"var(--k2b-warning-text,#92400e)\" stroke-dasharray=\"5 4\"/><text x=\"${s.left + 0.8 * s.plot + 4}\" y=\"${s.height - s.bottom - 4}\" font-size=\"11\" fill=\"var(--k2b-warning-text,#92400e)\">80 %</text><polyline points=\"${line}\" fill=\"none\" stroke=\"var(--k2b-text-muted,#45454e)\" stroke-width=\"1.5\" pointer-events=\"none\"/>`,\n );\n for (let p = 0; p <= 5; p++)\n body.push(\n `<text x=\"${s.left + (p / 5) * s.plot}\" y=\"${s.height - s.bottom + 17}\" text-anchor=\"middle\" font-size=\"11\" fill=\"var(--k2b-text-muted,#45454e)\">${escapeXml(percent.format(p / 5))}</text>`,\n );\n for (const row of s.rows)\n body.push(\n `<circle cx=\"${s.left + row.cumulative * s.plot}\" cy=\"${row.y}\" r=\"3\" fill=\"var(--k2b-surface,#fff)\" stroke=\"var(--k2b-text-muted,#45454e)\" stroke-width=\"1.5\" pointer-events=\"none\"/>`,\n );\n const names = [...spec.labels, (spec.locale ?? \"en\").startsWith(\"de\") ? \"Kumuliert\" : \"Cumulative\"];\n let lx = 0;\n names.forEach((name, index) => {\n const x = lx;\n lx += Math.min(s.width / 3, name.length * 12 + 32);\n const display = name.slice(0, Math.max(1, Math.floor(((spec.displayWidth ?? 296) / 3 - 28) / 7)));\n body.push(\n `${index === 2 ? `<line x1=\"${x}\" x2=\"${x + 12}\" y1=\"${s.height - 10}\" y2=\"${s.height - 10}\" stroke=\"var(--k2b-text-muted,#45454e)\"/>` : `<rect x=\"${x}\" y=\"${s.height - 15}\" width=\"10\" height=\"10\" rx=\"2\" fill=\"${color}\" fill-opacity=\"${index === 1 ? 0.2 : 1}\"/>${index === 1 ? `<path d=\"M${x},${s.height - 6}l8,-8\" stroke=\"${color}\"/>` : \"\"}`}<text x=\"${x + 16}\" y=\"${s.height - 6}\" font-size=\"11\" fill=\"var(--k2b-text-muted,#45454e)\">${escapeXml(display)}</text>`,\n );\n });\n return svgRoot({ ...s, className: spec.className }, body.join(\"\"));\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,101 @@
1
+ import { chartDatumSvg, escapeXml, renderHeader, svgRoot } from "./svg";
2
+ const palette = ["#3b82f6", "#10b981", "#f59e0b", "#8b5cf6"];
3
+ const color = index => `var(--stdlib-chart-c${index + 1},${palette[index]})`;
4
+ export function radarLayout(spec, size = {
5
+ width: spec.width ?? 480,
6
+ height: spec.height ?? 280
7
+ }) {
8
+ if (spec.axes.length < 3 || spec.axes.length > 8 || !Number.isFinite(spec.max) || spec.max <= 0 || spec.series.length > 4) throw new RangeError("Radar needs 3 to 8 axes, at most 4 series and one positive maximum.");
9
+ for (const series of spec.series) if (series.data.length !== spec.axes.length || series.data.some(value => !Number.isFinite(value) || value < 0 || value > spec.max)) throw new RangeError("Radar series need one value per axis, between zero and the common maximum.");
10
+ const width = spec.displayWidth ?? Math.min(size.width, 296),
11
+ height = size.height,
12
+ header = renderHeader(width, spec.title, spec.subtitle);
13
+ const legend = [];
14
+ let lx = 0,
15
+ row = 0;
16
+ if (spec.legend !== false) spec.series.forEach((series, index) => {
17
+ const space = Math.min(width, series.label.length * 12 + 28);
18
+ if (lx && lx + space > width) {
19
+ lx = 0;
20
+ row++;
21
+ }
22
+ legend.push({
23
+ label: series.label,
24
+ index,
25
+ x: lx,
26
+ row
27
+ });
28
+ lx += space;
29
+ });
30
+ const bottom = legend.length ? (row + 1) * 20 + 4 : 4,
31
+ plotHeight = height - header.height - bottom,
32
+ cx = width / 2,
33
+ cy = header.height + plotHeight / 2;
34
+ const labelRoom = Math.min(width * 0.28, Math.max(0, ...spec.axes.map((label, index) => Math.abs(Math.cos(-Math.PI / 2 + index * Math.PI * 2 / spec.axes.length)) > 0.2 ? label.length * 7 : 0))) + 18;
35
+ const radius = Math.max(0, Math.min(width / 2 - labelRoom, plotHeight / 2 - 24));
36
+ const point = (axis, value) => {
37
+ const angle = -Math.PI / 2 + axis * Math.PI * 2 / spec.axes.length;
38
+ return [cx + Math.cos(angle) * radius * (value / spec.max), cy + Math.sin(angle) * radius * (value / spec.max)];
39
+ };
40
+ const axes = spec.axes.map((label, index) => {
41
+ const angle = -Math.PI / 2 + index * Math.PI * 2 / spec.axes.length,
42
+ c = Math.cos(angle),
43
+ x = cx + (radius + 12) * c,
44
+ y = cy + (radius + 12) * Math.sin(angle) + 4,
45
+ anchor = Math.abs(c) < 0.2 ? "middle" : c > 0 ? "start" : "end";
46
+ const room = anchor === "middle" ? width - 16 : anchor === "start" ? width - x - 6 : x - 6;
47
+ const length = Math.max(1, Math.floor(room / 7));
48
+ return {
49
+ label,
50
+ index,
51
+ x,
52
+ y,
53
+ anchor,
54
+ text: label.length > length ? label.slice(0, Math.max(1, length - 1)) + "…" : label,
55
+ end: point(index, spec.max),
56
+ points: spec.series.map(series => point(index, series.data[index]))
57
+ };
58
+ });
59
+ return {
60
+ width,
61
+ height,
62
+ header,
63
+ cx,
64
+ cy,
65
+ radius,
66
+ axes,
67
+ point,
68
+ legend,
69
+ bottom
70
+ };
71
+ }
72
+ export function renderRadarSvg(spec) {
73
+ const s = radarLayout(spec),
74
+ number = spec.format ?? new Intl.NumberFormat(spec.locale ?? "en", {
75
+ maximumSignificantDigits: 15
76
+ }).format;
77
+ const text = "var(--k2b-text-muted,#45454e)",
78
+ border = "var(--k2b-border,#e4e4e7)";
79
+ const body = [s.header.svg.replace(/<text class="stdlib-chart-title"/g, '<text fill="var(--k2b-text,#27272a)" font-size="14" class="stdlib-chart-title"').replace(/<text class="stdlib-chart-subtitle"/g, '<text fill="var(--k2b-text-muted,#45454e)" font-size="11" class="stdlib-chart-subtitle"')];
80
+ for (let ring = 1; ring <= 4; ring++) body.push(`<polygon points="${s.axes.map(axis => s.point(axis.index, spec.max * (ring / 4)).join(",")).join(" ")}" fill="none" stroke="${border}"/>`);
81
+ for (const axis of s.axes) body.push(`<line x1="${s.cx}" y1="${s.cy}" x2="${axis.end[0]}" y2="${axis.end[1]}" stroke="${border}"/><text class="k2b-chart-radar-label" x="${axis.x}" y="${axis.y}" text-anchor="${axis.anchor}" font-size="12" fill="${text}">${escapeXml(axis.text)}</text>`);
82
+ body.push(`<text x="${s.cx + 5}" y="${s.cy - s.radius + 13}" font-size="10" fill="${text}">${escapeXml(number(spec.max))}${spec.unit ? " " + escapeXml(spec.unit) : ""}</text>`);
83
+ spec.series.forEach((series, index) => body.push(`<polygon points="${series.data.map((value, axis) => s.point(axis, value).join(",")).join(" ")}" fill="${color(index)}" fill-opacity="0.18" stroke="${color(index)}" stroke-width="2" stroke-linejoin="round"/>`));
84
+ for (const axis of s.axes) body.push(chartDatumSvg(axis.points.map((point, index) => `<circle cx="${point[0]}" cy="${point[1]}" r="3" fill="${color(index)}" style="--k2b-chart-inspection-color:${color(index)};--k2b-chart-selection-color:${color(index)}" stroke="none"/>`).join("") + `<path pointer-events="stroke" class="k2b-chart-category-band k2b-chart-radar-axis" d="M${s.cx},${s.cy}L${axis.end[0]},${axis.end[1]}" fill="none" stroke="transparent" stroke-width="16"/>`, {
85
+ role: "item",
86
+ index: axis.index,
87
+ label: axis.label,
88
+ anchor: axis.end,
89
+ values: spec.series.map((series, index) => ({
90
+ key: `series:${index}`,
91
+ value: series.data[axis.index],
92
+ formatted: `${number(series.data[axis.index])} / ${number(spec.max)}${spec.unit ? " " + spec.unit : ""}`
93
+ }))
94
+ }, spec.inspect));
95
+ for (const item of s.legend) body.push(`<rect x="${item.x}" y="${s.height - (s.legend.at(-1).row - item.row) * 20 - 14}" width="8" height="8" rx="2" fill="${color(item.index)}"/><text x="${item.x + 13}" y="${s.height - (s.legend.at(-1).row - item.row) * 20 - 6}" font-size="11" fill="${text}">${escapeXml(item.label.slice(0, Math.floor((s.width - 28) / 12)))}</text>`);
96
+ return svgRoot({
97
+ ...s,
98
+ className: spec.className
99
+ }, body.join(""));
100
+ }
101
+ //# sourceMappingURL=radar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["charts/core/radar.ts"],"sourcesContent":["import { type ChartOptions, chartDatumSvg, escapeXml, renderHeader, svgRoot } from \"./svg\";\nexport type RadarOptions = ChartOptions & {\n axes: string[];\n max: number;\n unit?: string;\n series: { label: string; data: number[] }[];\n legend?: boolean;\n locale?: string;\n format?: (value: number) => string;\n displayWidth?: number;\n};\nconst palette = [\"#3b82f6\", \"#10b981\", \"#f59e0b\", \"#8b5cf6\"];\nconst color = (index: number) => `var(--stdlib-chart-c${index + 1},${palette[index]})`;\nexport function radarLayout(spec: RadarOptions, size = { width: spec.width ?? 480, height: spec.height ?? 280 }) {\n if (spec.axes.length < 3 || spec.axes.length > 8 || !Number.isFinite(spec.max) || spec.max <= 0 || spec.series.length > 4)\n throw new RangeError(\"Radar needs 3 to 8 axes, at most 4 series and one positive maximum.\");\n for (const series of spec.series)\n if (series.data.length !== spec.axes.length || series.data.some((value) => !Number.isFinite(value) || value < 0 || value > spec.max))\n throw new RangeError(\"Radar series need one value per axis, between zero and the common maximum.\");\n const width = spec.displayWidth ?? Math.min(size.width, 296),\n height = size.height,\n header = renderHeader(width, spec.title, spec.subtitle);\n const legend: { label: string; index: number; x: number; row: number }[] = [];\n let lx = 0,\n row = 0;\n if (spec.legend !== false)\n spec.series.forEach((series, index) => {\n const space = Math.min(width, series.label.length * 12 + 28);\n if (lx && lx + space > width) {\n lx = 0;\n row++;\n }\n legend.push({ label: series.label, index, x: lx, row });\n lx += space;\n });\n const bottom = legend.length ? (row + 1) * 20 + 4 : 4,\n plotHeight = height - header.height - bottom,\n cx = width / 2,\n cy = header.height + plotHeight / 2;\n const labelRoom =\n Math.min(\n width * 0.28,\n Math.max(\n 0,\n ...spec.axes.map((label, index) =>\n Math.abs(Math.cos(-Math.PI / 2 + (index * Math.PI * 2) / spec.axes.length)) > 0.2 ? label.length * 7 : 0,\n ),\n ),\n ) + 18;\n const radius = Math.max(0, Math.min(width / 2 - labelRoom, plotHeight / 2 - 24));\n const point = (axis: number, value: number) => {\n const angle = -Math.PI / 2 + (axis * Math.PI * 2) / spec.axes.length;\n return [cx + Math.cos(angle) * radius * (value / spec.max), cy + Math.sin(angle) * radius * (value / spec.max)] as [number, number];\n };\n const axes = spec.axes.map((label, index) => {\n const angle = -Math.PI / 2 + (index * Math.PI * 2) / spec.axes.length,\n c = Math.cos(angle),\n x = cx + (radius + 12) * c,\n y = cy + (radius + 12) * Math.sin(angle) + 4,\n anchor = Math.abs(c) < 0.2 ? \"middle\" : c > 0 ? \"start\" : \"end\";\n const room = anchor === \"middle\" ? width - 16 : anchor === \"start\" ? width - x - 6 : x - 6;\n const length = Math.max(1, Math.floor(room / 7));\n return {\n label,\n index,\n x,\n y,\n anchor,\n text: label.length > length ? label.slice(0, Math.max(1, length - 1)) + \"…\" : label,\n end: point(index, spec.max),\n points: spec.series.map((series) => point(index, series.data[index]!)),\n };\n });\n return { width, height, header, cx, cy, radius, axes, point, legend, bottom };\n}\nexport function renderRadarSvg(spec: RadarOptions): string {\n const s = radarLayout(spec),\n number = spec.format ?? new Intl.NumberFormat(spec.locale ?? \"en\", { maximumSignificantDigits: 15 }).format;\n const text = \"var(--k2b-text-muted,#45454e)\",\n border = \"var(--k2b-border,#e4e4e7)\";\n const body = [\n s.header.svg\n .replace(/<text class=\"stdlib-chart-title\"/g, '<text fill=\"var(--k2b-text,#27272a)\" font-size=\"14\" class=\"stdlib-chart-title\"')\n .replace(\n /<text class=\"stdlib-chart-subtitle\"/g,\n '<text fill=\"var(--k2b-text-muted,#45454e)\" font-size=\"11\" class=\"stdlib-chart-subtitle\"',\n ),\n ];\n for (let ring = 1; ring <= 4; ring++)\n body.push(\n `<polygon points=\"${s.axes.map((axis) => s.point(axis.index, spec.max * (ring / 4)).join(\",\")).join(\" \")}\" fill=\"none\" stroke=\"${border}\"/>`,\n );\n for (const axis of s.axes)\n body.push(\n `<line x1=\"${s.cx}\" y1=\"${s.cy}\" x2=\"${axis.end[0]}\" y2=\"${axis.end[1]}\" stroke=\"${border}\"/><text class=\"k2b-chart-radar-label\" x=\"${axis.x}\" y=\"${axis.y}\" text-anchor=\"${axis.anchor}\" font-size=\"12\" fill=\"${text}\">${escapeXml(axis.text)}</text>`,\n );\n body.push(\n `<text x=\"${s.cx + 5}\" y=\"${s.cy - s.radius + 13}\" font-size=\"10\" fill=\"${text}\">${escapeXml(number(spec.max))}${spec.unit ? \" \" + escapeXml(spec.unit) : \"\"}</text>`,\n );\n spec.series.forEach((series, index) =>\n body.push(\n `<polygon points=\"${series.data.map((value, axis) => s.point(axis, value).join(\",\")).join(\" \")}\" fill=\"${color(index)}\" fill-opacity=\"0.18\" stroke=\"${color(index)}\" stroke-width=\"2\" stroke-linejoin=\"round\"/>`,\n ),\n );\n for (const axis of s.axes)\n body.push(\n chartDatumSvg(\n axis.points\n .map(\n (point, index) =>\n `<circle cx=\"${point[0]}\" cy=\"${point[1]}\" r=\"3\" fill=\"${color(index)}\" style=\"--k2b-chart-inspection-color:${color(index)};--k2b-chart-selection-color:${color(index)}\" stroke=\"none\"/>`,\n )\n .join(\"\") +\n `<path pointer-events=\"stroke\" class=\"k2b-chart-category-band k2b-chart-radar-axis\" d=\"M${s.cx},${s.cy}L${axis.end[0]},${axis.end[1]}\" fill=\"none\" stroke=\"transparent\" stroke-width=\"16\"/>`,\n {\n role: \"item\",\n index: axis.index,\n label: axis.label,\n anchor: axis.end,\n values: spec.series.map((series, index) => ({\n key: `series:${index}`,\n value: series.data[axis.index]!,\n formatted: `${number(series.data[axis.index]!)} / ${number(spec.max)}${spec.unit ? \" \" + spec.unit : \"\"}`,\n })),\n },\n spec.inspect,\n ),\n );\n for (const item of s.legend)\n body.push(\n `<rect x=\"${item.x}\" y=\"${s.height - (s.legend.at(-1)!.row - item.row) * 20 - 14}\" width=\"8\" height=\"8\" rx=\"2\" fill=\"${color(item.index)}\"/><text x=\"${item.x + 13}\" y=\"${s.height - (s.legend.at(-1)!.row - item.row) * 20 - 6}\" font-size=\"11\" fill=\"${text}\">${escapeXml(item.label.slice(0, Math.floor((s.width - 28) / 12)))}</text>`,\n );\n return svgRoot({ ...s, className: spec.className }, body.join(\"\"));\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,10 +1,15 @@
1
1
  import { renderBarChartSvg } from "../../content/chart-bar";
2
2
  import { renderStateTimelineSvg } from "../../content/chart-state-timeline";
3
3
  import { renderAreaSvg } from "./area";
4
+ import { renderBubbleSvg } from "./bubble";
4
5
  import { renderHeatmapSvg } from "./calendar";
6
+ import { renderFunnelSvg } from "./funnel";
5
7
  import { renderHbarSvg } from "./hbar";
6
8
  import { map } from "./map";
9
+ import { renderParetoSvg } from "./pareto";
10
+ import { renderRadarSvg } from "./radar";
7
11
  import { barGauge, boxplot, donut, gauge, histogram, line, pie, scatter, sparkline, stat } from "./svg-renderers";
12
+ import { renderTreemapSvg } from "./treemap";
8
13
  import { renderWaterfallSvg } from "./waterfall";
9
14
 
10
15
  // Add one renderer here: its key defines the discriminator, ChartKind and the capitalized Chart namespace member.
@@ -15,6 +20,7 @@ const createChartRenderers = () => ({
15
20
  line: line,
16
21
  bar: renderBarChartSvg,
17
22
  hbar: renderHbarSvg,
23
+ funnel: renderFunnelSvg,
18
24
  pie: pie,
19
25
  donut: donut,
20
26
  scatter: scatter,
@@ -26,7 +32,11 @@ const createChartRenderers = () => ({
26
32
  stat: stat,
27
33
  heatmap: renderHeatmapSvg,
28
34
  map: map,
29
- stateTimeline: renderStateTimelineSvg
35
+ stateTimeline: renderStateTimelineSvg,
36
+ treemap: renderTreemapSvg,
37
+ pareto: renderParetoSvg,
38
+ bubble: renderBubbleSvg,
39
+ radar: renderRadarSvg
30
40
  });
31
41
  export const chartRenderers = /* @__PURE__ */createChartRenderers();
32
42
  // Object.entries loses literal keys; names are constructed from those same keys here.
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["charts/core/registry.ts"],"sourcesContent":["import { renderBarChartSvg } from \"../../content/chart-bar\";\nimport { renderStateTimelineSvg } from \"../../content/chart-state-timeline\";\nimport { renderAreaSvg } from \"./area\";\nimport { renderHeatmapSvg } from \"./calendar\";\nimport { renderHbarSvg } from \"./hbar\";\nimport { map } from \"./map\";\nimport { barGauge, boxplot, donut, gauge, histogram, line, pie, scatter, sparkline, stat } from \"./svg-renderers\";\nimport { renderWaterfallSvg } from \"./waterfall\";\n\n// Add one renderer here: its key defines the discriminator, ChartKind and the capitalized Chart namespace member.\n// Keep kind-specific adaptations in renderChartSvg and add a fixture to the namespace parity test.\nconst createChartRenderers = () => ({\n waterfall: renderWaterfallSvg,\n area: renderAreaSvg,\n line: line,\n bar: renderBarChartSvg,\n hbar: renderHbarSvg,\n pie: pie,\n donut: donut,\n scatter: scatter,\n sparkline: sparkline,\n histogram: histogram,\n boxplot: boxplot,\n gauge: gauge,\n barGauge: barGauge,\n stat: stat,\n heatmap: renderHeatmapSvg,\n map: map,\n stateTimeline: renderStateTimelineSvg,\n});\nexport const chartRenderers = /* @__PURE__ */ createChartRenderers();\ntype Kind = keyof typeof chartRenderers;\ntype ChartKinds = { [K in Kind as Capitalize<K>]: K };\n// Object.entries loses literal keys; names are constructed from those same keys here.\nconst kinds = () =>\n Object.fromEntries(Object.keys(chartRenderers).map((kind) => [kind[0]!.toUpperCase() + kind.slice(1), kind])) as ChartKinds;\nexport const chartKinds = /* @__PURE__ */ kinds();\n"],"mappings":"AAAA,SAAS,iBAAiB,QAAQ,yBAAyB;AAC3D,SAAS,sBAAsB,QAAQ,oCAAoC;AAC3E,SAAS,aAAa,QAAQ,QAAQ;AACtC,SAAS,gBAAgB,QAAQ,YAAY;AAC7C,SAAS,aAAa,QAAQ,QAAQ;AACtC,SAAS,GAAG,QAAQ,OAAO;AAC3B,SAAS,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,QAAQ,iBAAiB;AACjH,SAAS,kBAAkB,QAAQ,aAAa;;AAEhD;AACA;AACA,MAAM,oBAAoB,GAAG,OAAO;EAClC,SAAS,EAAE,kBAAkB;EAC7B,IAAI,EAAE,aAAa;EACnB,IAAI,EAAE,IAAI;EACV,GAAG,EAAE,iBAAiB;EACtB,IAAI,EAAE,aAAa;EACnB,GAAG,EAAE,GAAG;EACR,KAAK,EAAE,KAAK;EACZ,OAAO,EAAE,OAAO;EAChB,SAAS,EAAE,SAAS;EACpB,SAAS,EAAE,SAAS;EACpB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,KAAK;EACZ,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,IAAI;EACV,OAAO,EAAE,gBAAgB;EACzB,GAAG,EAAE,GAAG;EACR,aAAa,EAAE;AACjB,CAAC,CAAC;AACF,OAAO,MAAM,cAAc,GAAG,eAAgB,oBAAoB,CAAC,CAAC;AAGpE;AACA,MAAM,KAAK,GAAG,MACZ,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,CAAE,IAAI,IAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAe;AAC7H,OAAO,MAAM,UAAU,GAAG,eAAgB,KAAK,CAAC,CAAC","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["charts/core/registry.ts"],"sourcesContent":["import { renderBarChartSvg } from \"../../content/chart-bar\";\nimport { renderStateTimelineSvg } from \"../../content/chart-state-timeline\";\nimport { renderAreaSvg } from \"./area\";\nimport { renderBubbleSvg } from \"./bubble\";\nimport { renderHeatmapSvg } from \"./calendar\";\nimport { renderFunnelSvg } from \"./funnel\";\nimport { renderHbarSvg } from \"./hbar\";\nimport { map } from \"./map\";\nimport { renderParetoSvg } from \"./pareto\";\n\nimport { renderRadarSvg } from \"./radar\";\nimport { barGauge, boxplot, donut, gauge, histogram, line, pie, scatter, sparkline, stat } from \"./svg-renderers\";\nimport { renderTreemapSvg } from \"./treemap\";\nimport { renderWaterfallSvg } from \"./waterfall\";\n\n// Add one renderer here: its key defines the discriminator, ChartKind and the capitalized Chart namespace member.\n// Keep kind-specific adaptations in renderChartSvg and add a fixture to the namespace parity test.\nconst createChartRenderers = () => ({\n waterfall: renderWaterfallSvg,\n area: renderAreaSvg,\n line: line,\n bar: renderBarChartSvg,\n hbar: renderHbarSvg,\n funnel: renderFunnelSvg,\n pie: pie,\n donut: donut,\n scatter: scatter,\n sparkline: sparkline,\n histogram: histogram,\n boxplot: boxplot,\n gauge: gauge,\n barGauge: barGauge,\n stat: stat,\n heatmap: renderHeatmapSvg,\n map: map,\n stateTimeline: renderStateTimelineSvg,\n treemap: renderTreemapSvg,\n pareto: renderParetoSvg,\n\n bubble: renderBubbleSvg,\n radar: renderRadarSvg,\n});\nexport const chartRenderers = /* @__PURE__ */ createChartRenderers();\ntype Kind = keyof typeof chartRenderers;\ntype ChartKinds = { [K in Kind as Capitalize<K>]: K };\n// Object.entries loses literal keys; names are constructed from those same keys here.\nconst kinds = () =>\n Object.fromEntries(Object.keys(chartRenderers).map((kind) => [kind[0]!.toUpperCase() + kind.slice(1), kind])) as ChartKinds;\nexport const chartKinds = /* @__PURE__ */ kinds();\n"],"mappings":"AAAA,SAAS,iBAAiB,QAAQ,yBAAyB;AAC3D,SAAS,sBAAsB,QAAQ,oCAAoC;AAC3E,SAAS,aAAa,QAAQ,QAAQ;AACtC,SAAS,eAAe,QAAQ,UAAU;AAC1C,SAAS,gBAAgB,QAAQ,YAAY;AAC7C,SAAS,eAAe,QAAQ,UAAU;AAC1C,SAAS,aAAa,QAAQ,QAAQ;AACtC,SAAS,GAAG,QAAQ,OAAO;AAC3B,SAAS,eAAe,QAAQ,UAAU;AAE1C,SAAS,cAAc,QAAQ,SAAS;AACxC,SAAS,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,QAAQ,iBAAiB;AACjH,SAAS,gBAAgB,QAAQ,WAAW;AAC5C,SAAS,kBAAkB,QAAQ,aAAa;;AAEhD;AACA;AACA,MAAM,oBAAoB,GAAG,OAAO;EAClC,SAAS,EAAE,kBAAkB;EAC7B,IAAI,EAAE,aAAa;EACnB,IAAI,EAAE,IAAI;EACV,GAAG,EAAE,iBAAiB;EACtB,IAAI,EAAE,aAAa;EACnB,MAAM,EAAE,eAAe;EACvB,GAAG,EAAE,GAAG;EACR,KAAK,EAAE,KAAK;EACZ,OAAO,EAAE,OAAO;EAChB,SAAS,EAAE,SAAS;EACpB,SAAS,EAAE,SAAS;EACpB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,KAAK;EACZ,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,IAAI;EACV,OAAO,EAAE,gBAAgB;EACzB,GAAG,EAAE,GAAG;EACR,aAAa,EAAE,sBAAsB;EACrC,OAAO,EAAE,gBAAgB;EACzB,MAAM,EAAE,eAAe;EAEvB,MAAM,EAAE,eAAe;EACvB,KAAK,EAAE;AACT,CAAC,CAAC;AACF,OAAO,MAAM,cAAc,GAAG,eAAgB,oBAAoB,CAAC,CAAC;AAGpE;AACA,MAAM,KAAK,GAAG,MACZ,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,CAAE,IAAI,IAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,WAAW,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAe;AAC7H,OAAO,MAAM,UAAU,GAAG,eAAgB,KAAK,CAAC,CAAC","ignoreList":[]}
@@ -1,13 +1,15 @@
1
1
  import { barChartLayout } from "../../content/chart-bar";
2
2
  import { stateTimelineHeight } from "../../content/chart-state-timeline";
3
3
  import { hbarLayout } from "./hbar";
4
+ import { renderHeader } from "./svg-renderers";
4
5
  /** Standard logical height, or compact bar-gauge rows for a host without an explicit height. */
5
6
  export const chartRenderHeight = (props, sizing = {}) => {
6
7
  if (props.kind === "stateTimeline") return stateTimelineHeight(props.rows.length, props.legend !== false);
8
+ if (props.kind === "pareto") return Math.max(280, props.data.length * 34 + renderHeader(480, props.title, props.subtitle).height + 72);
7
9
  if (props.kind === "bar") return barChartLayout(props).height;
8
10
  if (props.kind === "hbar") return hbarLayout(props).height;
9
11
  if (props.kind === "barGauge") return Math.max(sizing.contentHeight ? 80 : 280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);
10
12
  return 280;
11
13
  };
12
- export const preservesAspectRatio = kind => kind === "map" || kind === "pie" || kind === "donut" || kind === "gauge";
14
+ export const preservesAspectRatio = kind => kind === "map" || kind === "pie" || kind === "donut" || kind === "gauge" || kind === "radar";
13
15
  //# sourceMappingURL=render-size.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["charts/core/render-size.ts"],"sourcesContent":["import { barChartLayout } from \"../../content/chart-bar\";\nimport { stateTimelineHeight } from \"../../content/chart-state-timeline\";\nimport { hbarLayout } from \"./hbar\";\nimport type { ChartRenderOptions } from \"./render\";\nimport type { ChartKind } from \"./types\";\n\n/** Standard logical height, or compact bar-gauge rows for a host without an explicit height. */\nexport const chartRenderHeight = (props: ChartRenderOptions, sizing: { contentHeight?: boolean } = {}): number => {\n if (props.kind === \"stateTimeline\") return stateTimelineHeight(props.rows.length, props.legend !== false);\n if (props.kind === \"bar\") return barChartLayout(props).height;\n if (props.kind === \"hbar\") return hbarLayout(props).height;\n if (props.kind === \"barGauge\")\n return Math.max(sizing.contentHeight ? 80 : 280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);\n return 280;\n};\n\nexport const preservesAspectRatio = (kind: ChartKind) => kind === \"map\" || kind === \"pie\" || kind === \"donut\" || kind === \"gauge\";\n"],"mappings":"AAAA,SAAS,cAAc,QAAQ,yBAAyB;AACxD,SAAS,mBAAmB,QAAQ,oCAAoC;AACxE,SAAS,UAAU,QAAQ,QAAQ;AAInC;AACA,OAAO,MAAM,iBAAiB,GAAG,CAAC,KAAyB,EAAE,MAAmC,GAAG,CAAC,CAAC,KAAa;EAChH,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,OAAO,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC;EACzG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,MAAM;EAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM;EAC1D,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC;EAC3H,OAAO,GAAG;AACZ,CAAC;AAED,OAAO,MAAM,oBAAoB,GAAI,IAAe,IAAK,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["charts/core/render-size.ts"],"sourcesContent":["import { barChartLayout } from \"../../content/chart-bar\";\nimport { stateTimelineHeight } from \"../../content/chart-state-timeline\";\nimport { hbarLayout } from \"./hbar\";\nimport type { ChartRenderOptions } from \"./render\";\nimport { renderHeader } from \"./svg-renderers\";\nimport type { ChartKind } from \"./types\";\n\n/** Standard logical height, or compact bar-gauge rows for a host without an explicit height. */\nexport const chartRenderHeight = (props: ChartRenderOptions, sizing: { contentHeight?: boolean } = {}): number => {\n if (props.kind === \"stateTimeline\") return stateTimelineHeight(props.rows.length, props.legend !== false);\n if (props.kind === \"pareto\") return Math.max(280, props.data.length * 34 + renderHeader(480, props.title, props.subtitle).height + 72);\n if (props.kind === \"bar\") return barChartLayout(props).height;\n if (props.kind === \"hbar\") return hbarLayout(props).height;\n if (props.kind === \"barGauge\")\n return Math.max(sizing.contentHeight ? 80 : 280, (props.title || props.subtitle ? 42 : 16) + props.data.length * 28 + 14);\n return 280;\n};\n\nexport const preservesAspectRatio = (kind: ChartKind) =>\n kind === \"map\" || kind === \"pie\" || kind === \"donut\" || kind === \"gauge\" || kind === \"radar\";\n"],"mappings":"AAAA,SAAS,cAAc,QAAQ,yBAAyB;AACxD,SAAS,mBAAmB,QAAQ,oCAAoC;AACxE,SAAS,UAAU,QAAQ,QAAQ;AAEnC,SAAS,YAAY,QAAQ,iBAAiB;AAG9C;AACA,OAAO,MAAM,iBAAiB,GAAG,CAAC,KAAyB,EAAE,MAAmC,GAAG,CAAC,CAAC,KAAa;EAChH,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,OAAO,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC;EACzG,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;EACtI,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,MAAM;EAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM;EAC1D,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,CAAC;EAC3H,OAAO,GAAG;AACZ,CAAC;AAED,OAAO,MAAM,oBAAoB,GAAI,IAAe,IAClD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO","ignoreList":[]}
@@ -5,6 +5,7 @@ import { renderStateTimelineSvg } from "../../content/chart-state-timeline";
5
5
  import { responsiveChartSvg, responsiveMapSvg } from "../../content/chart-svg";
6
6
  import { timeAxisSvg } from "../../content/chart-time-axis";
7
7
  import { renderAreaSvg } from "./area";
8
+ import { renderFunnelSvg } from "./funnel";
8
9
  import { renderHbarSvg } from "./hbar";
9
10
  import { chartRenderers } from "./registry";
10
11
  import { renderWaterfallSvg } from "./waterfall";
@@ -13,6 +14,17 @@ import { preservesAspectRatio } from "./render-size";
13
14
 
14
15
  /** Shared logical SVG renderer; callbacks and browser interaction stay with the Solid host. */
15
16
  export const renderChartSvg = (props, width, height, mapViewport, timelineViewport, renderLocale) => {
17
+ if (props.kind === "treemap" || props.kind === "pareto") return responsiveChartSvg(props.kind === "treemap" ? chartRenderers.treemap({
18
+ ...props,
19
+ width,
20
+ height,
21
+ inspect: true
22
+ }) : chartRenderers.pareto({
23
+ ...props,
24
+ width,
25
+ height,
26
+ inspect: true
27
+ }));
16
28
  if (props.kind === "heatmap" && props.layout === "calendar") return chartRenderers.heatmap({
17
29
  ...props,
18
30
  width,
@@ -35,6 +47,13 @@ export const renderChartSvg = (props, width, height, mapViewport, timelineViewpo
35
47
  interactive: true
36
48
  }));
37
49
  }
50
+ if (kind === "funnel") return responsiveChartSvg(renderFunnelSvg({
51
+ ...opts,
52
+ locale: opts.locale ?? renderLocale,
53
+ width,
54
+ height,
55
+ inspect: true
56
+ }));
38
57
  if (kind === "hbar") return responsiveChartSvg(renderHbarSvg({
39
58
  ...opts,
40
59
  width,