@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
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["charts/core/render.ts"],"sourcesContent":["import { type BarChartOptions, renderBarChartSvg } from \"../../content/chart-bar\";\nimport { lineGapsSvg } from \"../../content/chart-line-gaps\";\nimport { DEFAULT_MAP_VIEWPORT, normalizeMapViewport } from \"../../content/chart-map-viewport\";\nimport { renderStateTimelineSvg, type StateTimelineChartOptions, type StateTimelineDomain } from \"../../content/chart-state-timeline\";\nimport { responsiveChartSvg, responsiveMapSvg } from \"../../content/chart-svg\";\nimport { type ChartTimeAxis, timeAxisSvg } from \"../../content/chart-time-axis\";\nimport { type AreaOptions, renderAreaSvg } from \"./area\";\nimport { type HorizontalBarOptions, renderHbarSvg } from \"./hbar\";\nimport { chartRenderers } from \"./registry\";\nimport type { MapViewport } from \"./svg\";\nimport type { ChartKind } from \"./types\";\nimport { renderWaterfallSvg, type WaterfallOptions } from \"./waterfall\";\n\ntype DrawingOptions<T> = T extends unknown ? Omit<T, \"width\" | \"height\" | \"inspect\" | \"interactive\"> : never;\ntype RenderOptions<T> = T extends unknown ? Omit<T, \"legendPlacement\"> : never;\n\nexport type ChartDrawingOptions = {\n [K in ChartKind]: { kind: K } & (K extends \"map\"\n ? {\n /** Target when zooming in from the world view. Defaults to Europe (50, 10). */\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n }\n : {}) &\n (K extends \"line\"\n ? {\n /** Largest connected X distance; positive, finite, without area/errorBand fills. */\n maxGap?: number;\n /** Wrap the legend above the plot inside the caller's total chart height. Requires legend=true. */\n legendPlacement?: \"top-start\";\n /** Round ticks for instant X values (Unix ms), in the supplied zone. xAxis.format labels them. */\n timeAxis?: ChartTimeAxis;\n }\n : {}) &\n DrawingOptions<Parameters<(typeof chartRenderers)[K]>[0]>;\n}[ChartKind];\nexport type ChartRenderOptions = RenderOptions<ChartDrawingOptions>;\n\nexport { chartRenderHeight, preservesAspectRatio } from \"./render-size\";\n\nimport { preservesAspectRatio } from \"./render-size\";\n\n/** Shared logical SVG renderer; callbacks and browser interaction stay with the Solid host. */\nexport const renderChartSvg = (\n props: ChartDrawingOptions,\n width: number,\n height: number,\n mapViewport?: MapViewport,\n timelineViewport?: StateTimelineDomain,\n renderLocale?: string,\n): string => {\n if (props.kind === \"heatmap\" && props.layout === \"calendar\") return chartRenderers.heatmap({ ...props, width, height, inspect: true });\n const {\n kind,\n zoomFocus: _zoomFocus,\n legendPlacement: _legendPlacement,\n timeAxis: _timeAxis,\n ...opts\n } = props as ChartDrawingOptions & {\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n legendPlacement?: \"top-start\";\n timeAxis?: ChartTimeAxis;\n };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: true,\n }),\n );\n }\n if (kind === \"hbar\") return responsiveChartSvg(renderHbarSvg({ ...(opts as HorizontalBarOptions), width, height, inspect: true }));\n if (kind === \"waterfall\")\n return responsiveChartSvg(\n renderWaterfallSvg(\n {\n ...(opts as WaterfallOptions),\n displayWidth: (opts as WaterfallOptions).displayWidth ?? 296,\n locale: (opts as WaterfallOptions).locale ?? renderLocale,\n width,\n height,\n inspect: true,\n },\n true,\n ),\n );\n if (kind === \"area\")\n return responsiveChartSvg(\n renderAreaSvg({\n ...(opts as AreaOptions),\n locale: (opts as AreaOptions).locale ?? renderLocale,\n legend: false,\n width,\n height,\n inspect: true,\n }),\n );\n if (kind === \"bar\") return responsiveChartSvg(renderBarChartSvg({ ...(opts as BarChartOptions), width, height, inspect: true }));\n // A time axis needs an explicit X domain: it maps its round ticks onto the axis the renderer drew over it.\n const timeAxis = props.kind === \"line\" ? props.timeAxis : undefined;\n const timeDomain = timeAxis && props.kind === \"line\" ? lineTimeDomain(props) : undefined;\n let svg = (chartRenderers[kind] as (o: unknown) => string)({\n ...opts,\n ...(timeDomain && props.kind === \"line\" ? { xAxis: { ...props.xAxis, domain: timeDomain, format: () => \"\" } } : {}),\n ...(props.kind === \"line\" && props.legend && props.legendPlacement === \"top-start\" ? { legend: false } : {}),\n ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: true,\n });\n if (props.kind === \"line\" && props.maxGap !== undefined) {\n if (props.area || props.errorBand) throw new Error(\"Chart maxGap does not support area or errorBand fills\");\n svg = lineGapsSvg(svg, props.maxGap, props);\n }\n if (timeAxis && timeDomain && props.kind === \"line\")\n svg = timeAxisSvg(svg, timeDomain, timeAxis, (props.xAxis?.ticks ?? 3) + 2, props.xAxis?.format);\n if (props.kind === \"map\") return responsiveMapSvg(svg, width, height, normalizeMapViewport(mapViewport ?? props.viewport));\n return preservesAspectRatio(kind) ? svg : responsiveChartSvg(svg);\n};\n\n/** The given X domain, or the span of the plotted instants. */\nconst lineTimeDomain = (props: Extract<ChartDrawingOptions, { kind: \"line\" }>): [number, number] | undefined => {\n if (props.xAxis?.domain) return props.xAxis.domain;\n const xs = props.series.flatMap((series) => series.data.map((point) => point.x)).filter(Number.isFinite);\n if (!xs.length) return undefined;\n const lo = Math.min(...xs),\n hi = Math.max(...xs);\n return lo < hi ? [lo, hi] : undefined;\n};\n\nexport type ChartSize = { width: number; height: number };\nexport type ChartScene = ChartSize & { kind: ChartKind; svg: string };\n/** Lay out a chart in a fixed logical coordinate space, without browser measurement. */\nexport const layout = (spec: ChartDrawingOptions, size: ChartSize): ChartScene => ({\n ...size,\n kind: spec.kind,\n svg: renderChartSvg(spec, size.width, size.height),\n});\nexport const toSvg = (scene: ChartScene): string => scene.svg;\n"],"mappings":"AAAA,SAA+B,iBAAiB,QAAQ,yBAAyB;AACjF,SAAS,WAAW,QAAQ,+BAA+B;AAC3D,SAAS,oBAAoB,EAAE,oBAAoB,QAAQ,kCAAkC;AAC7F,SAAS,sBAAsB,QAAkE,oCAAoC;AACrI,SAAS,kBAAkB,EAAE,gBAAgB,QAAQ,yBAAyB;AAC9E,SAA6B,WAAW,QAAQ,+BAA+B;AAC/E,SAA2B,aAAa,QAAQ,QAAQ;AACxD,SAAoC,aAAa,QAAQ,QAAQ;AACjE,SAAS,cAAc,QAAQ,YAAY;AAG3C,SAAS,kBAAkB,QAA+B,aAAa;AA0BvE,SAAS,iBAAiB,EAAE,oBAAoB,QAAQ,eAAe;AAEvE,SAAS,oBAAoB,QAAQ,eAAe;;AAEpD;AACA,OAAO,MAAM,cAAc,GAAG,CAC5B,KAA0B,EAC1B,KAAa,EACb,MAAc,EACd,WAAyB,EACzB,gBAAsC,EACtC,YAAqB,KACV;EACX,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAE,OAAO,cAAc,CAAC,OAAO,CAAC;IAAE,GAAG,KAAK;IAAE,KAAK;IAAE,MAAM;IAAE,OAAO,EAAE;EAAK,CAAC,CAAC;EACtI,MAAM;IACJ,IAAI;IACJ,SAAS,EAAE,UAAU;IACrB,eAAe,EAAE,gBAAgB;IACjC,QAAQ,EAAE,SAAS;IACnB,GAAG;EACL,CAAC,GAAG,KAIH;EACD,IAAI,IAAI,KAAK,eAAe,EAAE;IAC5B,OAAO,kBAAkB,CACvB,sBAAsB,CAAC;MACrB,GAAI,IAAkC;MACtC,KAAK;MACL,MAAM;MACN,QAAQ,EAAE,gBAAgB;MAC1B,WAAW,EAAE;IACf,CAAC,CACH,CAAC;EACH;EACA,IAAI,IAAI,KAAK,MAAM,EAAE,OAAO,kBAAkB,CAAC,aAAa,CAAC;IAAE,GAAI,IAA6B;IAAE,KAAK;IAAE,MAAM;IAAE,OAAO,EAAE;EAAK,CAAC,CAAC,CAAC;EAClI,IAAI,IAAI,KAAK,WAAW,EACtB,OAAO,kBAAkB,CACvB,kBAAkB,CAChB;IACE,GAAI,IAAyB;IAC7B,YAAY,EAAG,IAAI,CAAsB,YAAY,IAAI,GAAG;IAC5D,MAAM,EAAG,IAAI,CAAsB,MAAM,IAAI,YAAY;IACzD,KAAK;IACL,MAAM;IACN,OAAO,EAAE;EACX,CAAC,EACD,IACF,CACF,CAAC;EACH,IAAI,IAAI,KAAK,MAAM,EACjB,OAAO,kBAAkB,CACvB,aAAa,CAAC;IACZ,GAAI,IAAoB;IACxB,MAAM,EAAG,IAAI,CAAiB,MAAM,IAAI,YAAY;IACpD,MAAM,EAAE,KAAK;IACb,KAAK;IACL,MAAM;IACN,OAAO,EAAE;EACX,CAAC,CACH,CAAC;EACH,IAAI,IAAI,KAAK,KAAK,EAAE,OAAO,kBAAkB,CAAC,iBAAiB,CAAC;IAAE,GAAI,IAAwB;IAAE,KAAK;IAAE,MAAM;IAAE,OAAO,EAAE;EAAK,CAAC,CAAC,CAAC;EAChI;EACA,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,GAAG,KAAK,CAAC,QAAQ,GAAG,SAAS;EACnE,MAAM,UAAU,GAAG,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,SAAS;EACxF,IAAI,GAAG,GAAI,cAAc,CAAC,IAAI,CAAC,CAA4B;IACzD,GAAG,IAAI;IACP,IAAI,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,GAAG;MAAE,KAAK,EAAE;QAAE,GAAG,KAAK,CAAC,KAAK;QAAE,MAAM,EAAE,UAAU;QAAE,MAAM,EAAE,MAAM;MAAG;IAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACnH,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,WAAW,GAAG;MAAE,MAAM,EAAE;IAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5G,IAAI,IAAI,KAAK,KAAK,GAAG;MAAE,QAAQ,EAAE;IAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,KAAK;IACL,MAAM;IACN,OAAO,EAAE;EACX,CAAC,CAAC;EACF,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE;IACvD,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC;IAC3G,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;EAC7C;EACA,IAAI,QAAQ,IAAI,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EACjD,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;EAClG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,CAAC,WAAW,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EAC1H,OAAO,oBAAoB,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC;AACnE,CAAC;;AAED;AACA,MAAM,cAAc,GAAI,KAAqD,IAAmC;EAC9G,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM;EAClD,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAE,MAAM,IAAK,MAAM,CAAC,IAAI,CAAC,GAAG,CAAE,KAAK,IAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;EACxG,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,SAAS;EAChC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACxB,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;EACtB,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,SAAS;AACvC,CAAC;AAID;AACA,OAAO,MAAM,MAAM,GAAG,CAAC,IAAyB,EAAE,IAAe,MAAkB;EACjF,GAAG,IAAI;EACP,IAAI,EAAE,IAAI,CAAC,IAAI;EACf,GAAG,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM;AACnD,CAAC,CAAC;AACF,OAAO,MAAM,KAAK,GAAI,KAAiB,IAAa,KAAK,CAAC,GAAG","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["charts/core/render.ts"],"sourcesContent":["import { type BarChartOptions, renderBarChartSvg } from \"../../content/chart-bar\";\nimport { lineGapsSvg } from \"../../content/chart-line-gaps\";\nimport { DEFAULT_MAP_VIEWPORT, normalizeMapViewport } from \"../../content/chart-map-viewport\";\nimport { renderStateTimelineSvg, type StateTimelineChartOptions, type StateTimelineDomain } from \"../../content/chart-state-timeline\";\nimport { responsiveChartSvg, responsiveMapSvg } from \"../../content/chart-svg\";\nimport { type ChartTimeAxis, timeAxisSvg } from \"../../content/chart-time-axis\";\nimport { type AreaOptions, renderAreaSvg } from \"./area\";\nimport { type FunnelOptions, renderFunnelSvg } from \"./funnel\";\nimport { type HorizontalBarOptions, renderHbarSvg } from \"./hbar\";\nimport { chartRenderers } from \"./registry\";\nimport type { MapViewport } from \"./svg\";\nimport type { ChartKind } from \"./types\";\nimport { renderWaterfallSvg, type WaterfallOptions } from \"./waterfall\";\n\ntype DrawingOptions<T> = T extends unknown ? Omit<T, \"width\" | \"height\" | \"inspect\" | \"interactive\"> : never;\ntype RenderOptions<T> = T extends unknown ? Omit<T, \"legendPlacement\"> : never;\n\nexport type ChartDrawingOptions = {\n [K in ChartKind]: { kind: K } & (K extends \"map\"\n ? {\n /** Target when zooming in from the world view. Defaults to Europe (50, 10). */\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n }\n : {}) &\n (K extends \"line\"\n ? {\n /** Largest connected X distance; positive, finite, without area/errorBand fills. */\n maxGap?: number;\n /** Wrap the legend above the plot inside the caller's total chart height. Requires legend=true. */\n legendPlacement?: \"top-start\";\n /** Round ticks for instant X values (Unix ms), in the supplied zone. xAxis.format labels them. */\n timeAxis?: ChartTimeAxis;\n }\n : {}) &\n DrawingOptions<Parameters<(typeof chartRenderers)[K]>[0]>;\n}[ChartKind];\nexport type ChartRenderOptions = RenderOptions<ChartDrawingOptions>;\n\nexport { chartRenderHeight, preservesAspectRatio } from \"./render-size\";\n\nimport { preservesAspectRatio } from \"./render-size\";\n\n/** Shared logical SVG renderer; callbacks and browser interaction stay with the Solid host. */\nexport const renderChartSvg = (\n props: ChartDrawingOptions,\n width: number,\n height: number,\n mapViewport?: MapViewport,\n timelineViewport?: StateTimelineDomain,\n renderLocale?: string,\n): string => {\n if (props.kind === \"treemap\" || props.kind === \"pareto\")\n return responsiveChartSvg(\n props.kind === \"treemap\"\n ? chartRenderers.treemap({ ...props, width, height, inspect: true })\n : chartRenderers.pareto({ ...props, width, height, inspect: true }),\n );\n if (props.kind === \"heatmap\" && props.layout === \"calendar\") return chartRenderers.heatmap({ ...props, width, height, inspect: true });\n const {\n kind,\n zoomFocus: _zoomFocus,\n legendPlacement: _legendPlacement,\n timeAxis: _timeAxis,\n ...opts\n } = props as ChartDrawingOptions & {\n zoomFocus?: Pick<MapViewport, \"latitude\" | \"longitude\">;\n legendPlacement?: \"top-start\";\n timeAxis?: ChartTimeAxis;\n };\n if (kind === \"stateTimeline\") {\n return responsiveChartSvg(\n renderStateTimelineSvg({\n ...(opts as StateTimelineChartOptions),\n width,\n height,\n viewport: timelineViewport,\n interactive: true,\n }),\n );\n }\n if (kind === \"funnel\")\n return responsiveChartSvg(\n renderFunnelSvg({ ...(opts as FunnelOptions), locale: (opts as FunnelOptions).locale ?? renderLocale, width, height, inspect: true }),\n );\n if (kind === \"hbar\") return responsiveChartSvg(renderHbarSvg({ ...(opts as HorizontalBarOptions), width, height, inspect: true }));\n if (kind === \"waterfall\")\n return responsiveChartSvg(\n renderWaterfallSvg(\n {\n ...(opts as WaterfallOptions),\n displayWidth: (opts as WaterfallOptions).displayWidth ?? 296,\n locale: (opts as WaterfallOptions).locale ?? renderLocale,\n width,\n height,\n inspect: true,\n },\n true,\n ),\n );\n if (kind === \"area\")\n return responsiveChartSvg(\n renderAreaSvg({\n ...(opts as AreaOptions),\n locale: (opts as AreaOptions).locale ?? renderLocale,\n legend: false,\n width,\n height,\n inspect: true,\n }),\n );\n if (kind === \"bar\") return responsiveChartSvg(renderBarChartSvg({ ...(opts as BarChartOptions), width, height, inspect: true }));\n // A time axis needs an explicit X domain: it maps its round ticks onto the axis the renderer drew over it.\n const timeAxis = props.kind === \"line\" ? props.timeAxis : undefined;\n const timeDomain = timeAxis && props.kind === \"line\" ? lineTimeDomain(props) : undefined;\n let svg = (chartRenderers[kind] as (o: unknown) => string)({\n ...opts,\n ...(timeDomain && props.kind === \"line\" ? { xAxis: { ...props.xAxis, domain: timeDomain, format: () => \"\" } } : {}),\n ...(props.kind === \"line\" && props.legend && props.legendPlacement === \"top-start\" ? { legend: false } : {}),\n ...(kind === \"map\" ? { viewport: DEFAULT_MAP_VIEWPORT } : {}),\n width,\n height,\n inspect: true,\n });\n if (props.kind === \"line\" && props.maxGap !== undefined) {\n if (props.area || props.errorBand) throw new Error(\"Chart maxGap does not support area or errorBand fills\");\n svg = lineGapsSvg(svg, props.maxGap, props);\n }\n if (timeAxis && timeDomain && props.kind === \"line\")\n svg = timeAxisSvg(svg, timeDomain, timeAxis, (props.xAxis?.ticks ?? 3) + 2, props.xAxis?.format);\n if (props.kind === \"map\") return responsiveMapSvg(svg, width, height, normalizeMapViewport(mapViewport ?? props.viewport));\n return preservesAspectRatio(kind) ? svg : responsiveChartSvg(svg);\n};\n\n/** The given X domain, or the span of the plotted instants. */\nconst lineTimeDomain = (props: Extract<ChartDrawingOptions, { kind: \"line\" }>): [number, number] | undefined => {\n if (props.xAxis?.domain) return props.xAxis.domain;\n const xs = props.series.flatMap((series) => series.data.map((point) => point.x)).filter(Number.isFinite);\n if (!xs.length) return undefined;\n const lo = Math.min(...xs),\n hi = Math.max(...xs);\n return lo < hi ? [lo, hi] : undefined;\n};\n\nexport type ChartSize = { width: number; height: number };\nexport type ChartScene = ChartSize & { kind: ChartKind; svg: string };\n/** Lay out a chart in a fixed logical coordinate space, without browser measurement. */\nexport const layout = (spec: ChartDrawingOptions, size: ChartSize): ChartScene => ({\n ...size,\n kind: spec.kind,\n svg: renderChartSvg(spec, size.width, size.height),\n});\nexport const toSvg = (scene: ChartScene): string => scene.svg;\n"],"mappings":"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","ignoreList":[]}
@@ -58,7 +58,7 @@ export function prepareChartSnapshot(options, inspection, sizing = {}) {
58
58
  ...(calendar ? {
59
59
  minWidth: calendar.minWidth
60
60
  } : {}),
61
- stretch: !calendar && !["map", "pie", "donut", "gauge"].includes(options.kind),
61
+ stretch: !calendar && !["map", "pie", "donut", "gauge", "radar"].includes(options.kind),
62
62
  marks
63
63
  };
64
64
  }
@@ -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(/&quot;/g, '\"')\n .replace(/&apos;|&#39;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&amp;/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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","ignoreList":[]}
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(/&quot;/g, '\"')\n .replace(/&apos;|&#39;/g, \"'\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&amp;/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":[]}