mviz 1.4.2

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 (194) hide show
  1. package/README.md +174 -0
  2. package/dist/charts/area.d.ts +14 -0
  3. package/dist/charts/area.d.ts.map +1 -0
  4. package/dist/charts/area.js +137 -0
  5. package/dist/charts/area.js.map +1 -0
  6. package/dist/charts/bar.d.ts +14 -0
  7. package/dist/charts/bar.d.ts.map +1 -0
  8. package/dist/charts/bar.js +191 -0
  9. package/dist/charts/bar.js.map +1 -0
  10. package/dist/charts/boxplot.d.ts +14 -0
  11. package/dist/charts/boxplot.d.ts.map +1 -0
  12. package/dist/charts/boxplot.js +79 -0
  13. package/dist/charts/boxplot.js.map +1 -0
  14. package/dist/charts/bubble.d.ts +14 -0
  15. package/dist/charts/bubble.d.ts.map +1 -0
  16. package/dist/charts/bubble.js +127 -0
  17. package/dist/charts/bubble.js.map +1 -0
  18. package/dist/charts/calendar.d.ts +14 -0
  19. package/dist/charts/calendar.d.ts.map +1 -0
  20. package/dist/charts/calendar.js +94 -0
  21. package/dist/charts/calendar.js.map +1 -0
  22. package/dist/charts/combo.d.ts +14 -0
  23. package/dist/charts/combo.d.ts.map +1 -0
  24. package/dist/charts/combo.js +163 -0
  25. package/dist/charts/combo.js.map +1 -0
  26. package/dist/charts/dumbbell.d.ts +17 -0
  27. package/dist/charts/dumbbell.d.ts.map +1 -0
  28. package/dist/charts/dumbbell.js +368 -0
  29. package/dist/charts/dumbbell.js.map +1 -0
  30. package/dist/charts/funnel.d.ts +14 -0
  31. package/dist/charts/funnel.d.ts.map +1 -0
  32. package/dist/charts/funnel.js +145 -0
  33. package/dist/charts/funnel.js.map +1 -0
  34. package/dist/charts/heatmap.d.ts +14 -0
  35. package/dist/charts/heatmap.d.ts.map +1 -0
  36. package/dist/charts/heatmap.js +202 -0
  37. package/dist/charts/heatmap.js.map +1 -0
  38. package/dist/charts/histogram.d.ts +14 -0
  39. package/dist/charts/histogram.d.ts.map +1 -0
  40. package/dist/charts/histogram.js +103 -0
  41. package/dist/charts/histogram.js.map +1 -0
  42. package/dist/charts/index.d.ts +40 -0
  43. package/dist/charts/index.d.ts.map +1 -0
  44. package/dist/charts/index.js +42 -0
  45. package/dist/charts/index.js.map +1 -0
  46. package/dist/charts/line.d.ts +14 -0
  47. package/dist/charts/line.d.ts.map +1 -0
  48. package/dist/charts/line.js +134 -0
  49. package/dist/charts/line.js.map +1 -0
  50. package/dist/charts/pie.d.ts +14 -0
  51. package/dist/charts/pie.d.ts.map +1 -0
  52. package/dist/charts/pie.js +75 -0
  53. package/dist/charts/pie.js.map +1 -0
  54. package/dist/charts/registry.d.ts +36 -0
  55. package/dist/charts/registry.d.ts.map +1 -0
  56. package/dist/charts/registry.js +55 -0
  57. package/dist/charts/registry.js.map +1 -0
  58. package/dist/charts/sankey.d.ts +14 -0
  59. package/dist/charts/sankey.d.ts.map +1 -0
  60. package/dist/charts/sankey.js +74 -0
  61. package/dist/charts/sankey.js.map +1 -0
  62. package/dist/charts/scatter.d.ts +14 -0
  63. package/dist/charts/scatter.d.ts.map +1 -0
  64. package/dist/charts/scatter.js +130 -0
  65. package/dist/charts/scatter.js.map +1 -0
  66. package/dist/charts/sparkline.d.ts +19 -0
  67. package/dist/charts/sparkline.d.ts.map +1 -0
  68. package/dist/charts/sparkline.js +154 -0
  69. package/dist/charts/sparkline.js.map +1 -0
  70. package/dist/charts/waterfall.d.ts +14 -0
  71. package/dist/charts/waterfall.d.ts.map +1 -0
  72. package/dist/charts/waterfall.js +232 -0
  73. package/dist/charts/waterfall.js.map +1 -0
  74. package/dist/charts/xmr.d.ts +14 -0
  75. package/dist/charts/xmr.d.ts.map +1 -0
  76. package/dist/charts/xmr.js +456 -0
  77. package/dist/charts/xmr.js.map +1 -0
  78. package/dist/cli.d.ts +12 -0
  79. package/dist/cli.d.ts.map +1 -0
  80. package/dist/cli.js +120 -0
  81. package/dist/cli.js.map +1 -0
  82. package/dist/components/alert.d.ts +10 -0
  83. package/dist/components/alert.d.ts.map +1 -0
  84. package/dist/components/alert.js +65 -0
  85. package/dist/components/alert.js.map +1 -0
  86. package/dist/components/big_value.d.ts +10 -0
  87. package/dist/components/big_value.d.ts.map +1 -0
  88. package/dist/components/big_value.js +78 -0
  89. package/dist/components/big_value.js.map +1 -0
  90. package/dist/components/delta.d.ts +10 -0
  91. package/dist/components/delta.d.ts.map +1 -0
  92. package/dist/components/delta.js +83 -0
  93. package/dist/components/delta.js.map +1 -0
  94. package/dist/components/empty_space.d.ts +10 -0
  95. package/dist/components/empty_space.d.ts.map +1 -0
  96. package/dist/components/empty_space.js +29 -0
  97. package/dist/components/empty_space.js.map +1 -0
  98. package/dist/components/index.d.ts +21 -0
  99. package/dist/components/index.d.ts.map +1 -0
  100. package/dist/components/index.js +23 -0
  101. package/dist/components/index.js.map +1 -0
  102. package/dist/components/note.d.ts +10 -0
  103. package/dist/components/note.d.ts.map +1 -0
  104. package/dist/components/note.js +66 -0
  105. package/dist/components/note.js.map +1 -0
  106. package/dist/components/registry.d.ts +24 -0
  107. package/dist/components/registry.d.ts.map +1 -0
  108. package/dist/components/registry.js +36 -0
  109. package/dist/components/registry.js.map +1 -0
  110. package/dist/components/table.d.ts +90 -0
  111. package/dist/components/table.d.ts.map +1 -0
  112. package/dist/components/table.js +610 -0
  113. package/dist/components/table.js.map +1 -0
  114. package/dist/components/text.d.ts +10 -0
  115. package/dist/components/text.d.ts.map +1 -0
  116. package/dist/components/text.js +46 -0
  117. package/dist/components/text.js.map +1 -0
  118. package/dist/components/textarea.d.ts +10 -0
  119. package/dist/components/textarea.d.ts.map +1 -0
  120. package/dist/components/textarea.js +79 -0
  121. package/dist/components/textarea.js.map +1 -0
  122. package/dist/core/colors.d.ts +45 -0
  123. package/dist/core/colors.d.ts.map +1 -0
  124. package/dist/core/colors.js +93 -0
  125. package/dist/core/colors.js.map +1 -0
  126. package/dist/core/css.d.ts +20 -0
  127. package/dist/core/css.d.ts.map +1 -0
  128. package/dist/core/css.js +97 -0
  129. package/dist/core/css.js.map +1 -0
  130. package/dist/core/exceptions.d.ts +59 -0
  131. package/dist/core/exceptions.d.ts.map +1 -0
  132. package/dist/core/exceptions.js +100 -0
  133. package/dist/core/exceptions.js.map +1 -0
  134. package/dist/core/formatting.d.ts +53 -0
  135. package/dist/core/formatting.d.ts.map +1 -0
  136. package/dist/core/formatting.js +491 -0
  137. package/dist/core/formatting.js.map +1 -0
  138. package/dist/core/index.d.ts +10 -0
  139. package/dist/core/index.d.ts.map +1 -0
  140. package/dist/core/index.js +10 -0
  141. package/dist/core/index.js.map +1 -0
  142. package/dist/core/serializer.d.ts +29 -0
  143. package/dist/core/serializer.d.ts.map +1 -0
  144. package/dist/core/serializer.js +84 -0
  145. package/dist/core/serializer.js.map +1 -0
  146. package/dist/core/themes.d.ts +138 -0
  147. package/dist/core/themes.d.ts.map +1 -0
  148. package/dist/core/themes.js +484 -0
  149. package/dist/core/themes.js.map +1 -0
  150. package/dist/core/version-check.d.ts +23 -0
  151. package/dist/core/version-check.d.ts.map +1 -0
  152. package/dist/core/version-check.js +163 -0
  153. package/dist/core/version-check.js.map +1 -0
  154. package/dist/generate_test_harness.d.ts +13 -0
  155. package/dist/generate_test_harness.d.ts.map +1 -0
  156. package/dist/generate_test_harness.js +35 -0
  157. package/dist/generate_test_harness.js.map +1 -0
  158. package/dist/index.d.ts +17 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +19 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/layout/converter.d.ts +22 -0
  163. package/dist/layout/converter.d.ts.map +1 -0
  164. package/dist/layout/converter.js +46 -0
  165. package/dist/layout/converter.js.map +1 -0
  166. package/dist/layout/csv.d.ts +15 -0
  167. package/dist/layout/csv.d.ts.map +1 -0
  168. package/dist/layout/csv.js +88 -0
  169. package/dist/layout/csv.js.map +1 -0
  170. package/dist/layout/dispatcher.d.ts +13 -0
  171. package/dist/layout/dispatcher.d.ts.map +1 -0
  172. package/dist/layout/dispatcher.js +47 -0
  173. package/dist/layout/dispatcher.js.map +1 -0
  174. package/dist/layout/index.d.ts +8 -0
  175. package/dist/layout/index.d.ts.map +1 -0
  176. package/dist/layout/index.js +8 -0
  177. package/dist/layout/index.js.map +1 -0
  178. package/dist/layout/parser.d.ts +19 -0
  179. package/dist/layout/parser.d.ts.map +1 -0
  180. package/dist/layout/parser.js +888 -0
  181. package/dist/layout/parser.js.map +1 -0
  182. package/dist/layout/templates.d.ts +32 -0
  183. package/dist/layout/templates.d.ts.map +1 -0
  184. package/dist/layout/templates.js +1016 -0
  185. package/dist/layout/templates.js.map +1 -0
  186. package/dist/types.d.ts +144 -0
  187. package/dist/types.d.ts.map +1 -0
  188. package/dist/types.js +5 -0
  189. package/dist/types.js.map +1 -0
  190. package/dist/vitest.config.d.ts +3 -0
  191. package/dist/vitest.config.d.ts.map +1 -0
  192. package/dist/vitest.config.js +14 -0
  193. package/dist/vitest.config.js.map +1 -0
  194. package/package.json +79 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Pie chart generator
3
+ */
4
+ import { FONT_SIZE_XXS, DEFAULT_CHART_HEIGHT, getThemeColors, getPalette } from '../core/themes.js';
5
+ import { wrapHtml } from '../core/serializer.js';
6
+ import { registerChart, registerOptions } from './registry.js';
7
+ /**
8
+ * Build ECharts options for a pie or donut chart
9
+ */
10
+ export function buildPieOptions(spec) {
11
+ const data = (spec.data ?? []);
12
+ const valueKey = spec.value ?? 'value';
13
+ const nameKey = spec.name ?? 'name';
14
+ const theme = (spec.theme ?? 'light');
15
+ const donut = spec.donut === true;
16
+ const colors = getThemeColors(theme);
17
+ const palette = getPalette(theme);
18
+ const pieData = data.map((d) => ({
19
+ name: String(d[nameKey] ?? ''),
20
+ value: d[valueKey] ?? 0,
21
+ }));
22
+ const option = {
23
+ backgroundColor: 'transparent',
24
+ animation: false,
25
+ color: palette,
26
+ tooltip: {
27
+ trigger: 'item',
28
+ formatter: '{b}: {c} ({d}%)',
29
+ backgroundColor: colors.paper,
30
+ borderColor: colors.border,
31
+ textStyle: { color: colors.text },
32
+ },
33
+ series: [
34
+ {
35
+ type: 'pie',
36
+ radius: donut ? ['50%', '78%'] : ['0%', '78%'],
37
+ center: ['50%', '50%'],
38
+ data: pieData,
39
+ label: {
40
+ show: true,
41
+ formatter: '{b} {d}%',
42
+ color: colors.textSecondary,
43
+ fontSize: FONT_SIZE_XXS,
44
+ overflow: 'truncate',
45
+ width: 80,
46
+ },
47
+ labelLine: {
48
+ length: 10,
49
+ length2: 15,
50
+ lineStyle: { color: colors.textSecondary, width: 1 },
51
+ },
52
+ itemStyle: {
53
+ borderColor: colors.background,
54
+ borderWidth: 1,
55
+ },
56
+ emphasis: {
57
+ scale: false,
58
+ },
59
+ },
60
+ ],
61
+ };
62
+ return option;
63
+ }
64
+ /**
65
+ * Generate a pie chart
66
+ */
67
+ function generatePieChart(spec) {
68
+ const height = typeof spec.height === 'number' ? spec.height : DEFAULT_CHART_HEIGHT;
69
+ return wrapHtml('chart', buildPieOptions(spec), '', '100%', height);
70
+ }
71
+ // Register the chart
72
+ registerChart('pie')(generatePieChart);
73
+ registerOptions('pie')(buildPieOptions);
74
+ export { generatePieChart };
75
+ //# sourceMappingURL=pie.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pie.js","sourceRoot":"","sources":["../../charts/pie.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Chart registry for mviz
3
+ *
4
+ * Charts register themselves using the @registerChart decorator.
5
+ * The dispatcher uses this registry to route specs to generators.
6
+ */
7
+ import type { ChartSpec, ChartGenerator } from '../types.js';
8
+ /**
9
+ * Registry of chart generators by type
10
+ */
11
+ export declare const CHART_REGISTRY: Map<string, ChartGenerator>;
12
+ /**
13
+ * Registry of option builders (for dashboard embedding)
14
+ */
15
+ export declare const OPTIONS_REGISTRY: Map<string, (spec: ChartSpec) => Record<string, unknown>>;
16
+ /**
17
+ * Decorator to register a chart generator
18
+ */
19
+ export declare function registerChart(type: string): (generator: ChartGenerator) => ChartGenerator;
20
+ /**
21
+ * Decorator to register an options builder
22
+ */
23
+ export declare function registerOptions(type: string): (builder: (spec: ChartSpec) => Record<string, unknown>) => (spec: ChartSpec) => Record<string, unknown>;
24
+ /**
25
+ * Get all registered chart types
26
+ */
27
+ export declare function getRegisteredChartTypes(): string[];
28
+ /**
29
+ * Check if a type is a registered chart
30
+ */
31
+ export declare function isChartType(type: string): boolean;
32
+ /**
33
+ * Get the options builder for a chart type
34
+ */
35
+ export declare function getOptionsBuilder(type: string): ((spec: ChartSpec) => Record<string, unknown> | null) | undefined;
36
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../charts/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,cAAc,6BAAoC,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,gBAAgB,qBAA0B,SAAS,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAG,CAAC;AAEhG;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,SAAS,EAAE,cAAc,KAAK,cAAc,CAKzF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,GACX,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKzG;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAElD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,SAAS,CAEjH"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Chart registry for mviz
3
+ *
4
+ * Charts register themselves using the @registerChart decorator.
5
+ * The dispatcher uses this registry to route specs to generators.
6
+ */
7
+ /**
8
+ * Registry of chart generators by type
9
+ */
10
+ export const CHART_REGISTRY = new Map();
11
+ /**
12
+ * Registry of option builders (for dashboard embedding)
13
+ */
14
+ export const OPTIONS_REGISTRY = new Map();
15
+ /**
16
+ * Decorator to register a chart generator
17
+ */
18
+ export function registerChart(type) {
19
+ return (generator) => {
20
+ CHART_REGISTRY.set(type, generator);
21
+ return generator;
22
+ };
23
+ }
24
+ /**
25
+ * Decorator to register an options builder
26
+ */
27
+ export function registerOptions(type) {
28
+ return (builder) => {
29
+ OPTIONS_REGISTRY.set(type, builder);
30
+ return builder;
31
+ };
32
+ }
33
+ /**
34
+ * Get all registered chart types
35
+ */
36
+ export function getRegisteredChartTypes() {
37
+ return Array.from(CHART_REGISTRY.keys());
38
+ }
39
+ /**
40
+ * Check if a type is a registered chart
41
+ */
42
+ export function isChartType(type) {
43
+ return CHART_REGISTRY.has(type);
44
+ }
45
+ /**
46
+ * Get the options builder for a chart type
47
+ */
48
+ export function getOptionsBuilder(type) {
49
+ return OPTIONS_REGISTRY.get(type);
50
+ }
51
+ // TODO: Import chart modules here to trigger registration
52
+ // import './bar.js';
53
+ // import './line.js';
54
+ // etc.
55
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../charts/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEhE;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAwD,CAAC;AAEhG;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,CAAC,SAAyB,EAAkB,EAAE;QACnD,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY;IAEZ,OAAO,CAAC,OAAqD,EAAkD,EAAE;QAC/G,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,0DAA0D;AAC1D,qBAAqB;AACrB,sBAAsB;AACtB,OAAO"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Sankey diagram generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for a Sankey diagram
7
+ */
8
+ export declare function buildSankeyOptions(spec: ChartSpec): Record<string, unknown>;
9
+ /**
10
+ * Generate a Sankey diagram
11
+ */
12
+ declare function generateSankey(spec: ChartSpec): string;
13
+ export { generateSankey };
14
+ //# sourceMappingURL=sankey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sankey.d.ts","sourceRoot":"","sources":["../../charts/sankey.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAqBpD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuD3E;AAED;;GAEG;AACH,iBAAS,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAG/C;AAMD,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Sankey diagram generator
3
+ */
4
+ import { FONT_SIZE_XXS, getThemeColors, PALETTE_SANKEY, PALETTE_SANKEY_DARK } from '../core/themes.js';
5
+ import { wrapHtml } from '../core/serializer.js';
6
+ import { registerChart, registerOptions } from './registry.js';
7
+ /**
8
+ * Build ECharts options for a Sankey diagram
9
+ */
10
+ export function buildSankeyOptions(spec) {
11
+ const data = (spec.data ?? []);
12
+ let nodes = spec.nodes;
13
+ const theme = (spec.theme ?? 'light');
14
+ const colors = getThemeColors(theme);
15
+ const palette = theme === 'dark' ? PALETTE_SANKEY_DARK : PALETTE_SANKEY;
16
+ // Auto-generate nodes if not provided
17
+ if (!nodes) {
18
+ const nodeNames = new Set();
19
+ for (const link of data) {
20
+ nodeNames.add(link.source ?? '');
21
+ nodeNames.add(link.target ?? '');
22
+ }
23
+ nodes = Array.from(nodeNames).map((n) => ({ name: n }));
24
+ }
25
+ return {
26
+ backgroundColor: 'transparent',
27
+ animation: false,
28
+ color: [...palette],
29
+ tooltip: {
30
+ trigger: 'item',
31
+ triggerOn: 'mousemove',
32
+ backgroundColor: colors.paper,
33
+ borderColor: colors.border,
34
+ textStyle: { color: colors.text },
35
+ },
36
+ series: [
37
+ {
38
+ type: 'sankey',
39
+ data: nodes,
40
+ links: data,
41
+ emphasis: { focus: 'adjacency' },
42
+ nodeWidth: 10,
43
+ nodeGap: 10,
44
+ layoutIterations: 32,
45
+ lineStyle: {
46
+ color: 'gradient',
47
+ curveness: 0.5,
48
+ opacity: 0.35,
49
+ },
50
+ itemStyle: {
51
+ borderWidth: 0,
52
+ },
53
+ label: {
54
+ color: theme === 'dark' ? '#ffffff' : colors.text,
55
+ fontSize: FONT_SIZE_XXS,
56
+ textShadowColor: theme === 'dark' ? 'rgba(0,0,0,0.5)' : 'transparent',
57
+ textShadowBlur: theme === 'dark' ? 2 : 0,
58
+ },
59
+ },
60
+ ],
61
+ };
62
+ }
63
+ /**
64
+ * Generate a Sankey diagram
65
+ */
66
+ function generateSankey(spec) {
67
+ const height = typeof spec.height === 'number' ? spec.height : 500;
68
+ return wrapHtml('chart', buildSankeyOptions(spec), '', '100%', height);
69
+ }
70
+ // Register the chart
71
+ registerChart('sankey')(generateSankey);
72
+ registerOptions('sankey')(buildSankeyOptions);
73
+ export { generateSankey };
74
+ //# sourceMappingURL=sankey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sankey.js","sourceRoot":"","sources":["../../charts/sankey.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Scatter chart generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for a scatter plot
7
+ */
8
+ export declare function buildScatterOptions(spec: ChartSpec): Record<string, unknown>;
9
+ /**
10
+ * Generate a scatter chart
11
+ */
12
+ declare function generateScatterChart(spec: ChartSpec): string;
13
+ export { generateScatterChart };
14
+ //# sourceMappingURL=scatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scatter.d.ts","sourceRoot":"","sources":["../../charts/scatter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,aAAa,CAAC;AAY3E;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkH5E;AAED;;GAEG;AACH,iBAAS,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGrD;AAMD,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Scatter chart generator
3
+ */
4
+ import { SCATTER_SYMBOL_SIZE, FONT_SIZE_TINY, DEFAULT_CHART_HEIGHT, getThemeColors, getPalette, } from '../core/themes.js';
5
+ import { wrapHtml } from '../core/serializer.js';
6
+ import { registerChart, registerOptions } from './registry.js';
7
+ import { inferFormat, getAxisFormatterJs } from '../core/formatting.js';
8
+ /**
9
+ * Build ECharts options for a scatter plot
10
+ */
11
+ export function buildScatterOptions(spec) {
12
+ const data = (spec.data ?? []);
13
+ const xField = spec.x ?? 'x';
14
+ const yField = spec.y ?? 'y';
15
+ const seriesField = spec.series;
16
+ const theme = (spec.theme ?? 'light');
17
+ const colors = getThemeColors(theme);
18
+ const palette = getPalette(theme);
19
+ // Infer formats for both axes (support separate xFormat/yFormat or shared format)
20
+ const xSample = data.length > 0 && data[0] ? data[0][xField] ?? 0 : 0;
21
+ const ySample = data.length > 0 && data[0] ? data[0][yField] ?? 0 : 0;
22
+ const xFormat = spec.xFormat ?? inferFormat(xField, xSample);
23
+ const yFormat = spec.yFormat ?? inferFormat(yField, ySample);
24
+ const xAxisFormatter = getAxisFormatterJs(xFormat);
25
+ const yAxisFormatter = getAxisFormatterJs(yFormat);
26
+ // Build series - either single series or grouped by seriesField
27
+ let seriesList;
28
+ let legendData = [];
29
+ if (seriesField) {
30
+ // Group data by the series field
31
+ const groups = new Map();
32
+ for (const d of data) {
33
+ const groupName = String(d[seriesField] ?? 'Unknown');
34
+ if (!groups.has(groupName)) {
35
+ groups.set(groupName, []);
36
+ }
37
+ groups.get(groupName).push([d[xField] ?? 0, d[yField] ?? 0]);
38
+ }
39
+ // Create a series for each group
40
+ legendData = [...groups.keys()];
41
+ seriesList = legendData.map((name, idx) => ({
42
+ type: 'scatter',
43
+ name,
44
+ data: groups.get(name),
45
+ symbolSize: SCATTER_SYMBOL_SIZE,
46
+ itemStyle: { color: palette[idx % palette.length], opacity: 0.75 },
47
+ }));
48
+ }
49
+ else {
50
+ // Single series (original behavior)
51
+ const scatterData = data.map((d) => [d[xField] ?? 0, d[yField] ?? 0]);
52
+ seriesList = [
53
+ {
54
+ type: 'scatter',
55
+ data: scatterData,
56
+ symbolSize: SCATTER_SYMBOL_SIZE,
57
+ itemStyle: { color: palette[0], opacity: 0.75 },
58
+ },
59
+ ];
60
+ }
61
+ const option = {
62
+ backgroundColor: 'transparent',
63
+ animation: false,
64
+ color: palette,
65
+ tooltip: {
66
+ trigger: 'item',
67
+ backgroundColor: colors.paper,
68
+ borderColor: colors.border,
69
+ textStyle: { color: colors.text },
70
+ },
71
+ grid: {
72
+ left: '2%',
73
+ right: '4%',
74
+ top: seriesField ? '12%' : '6%', // More top space for legend
75
+ bottom: '10%',
76
+ containLabel: true,
77
+ },
78
+ xAxis: {
79
+ type: 'value',
80
+ name: xField,
81
+ nameLocation: 'middle',
82
+ nameGap: 24,
83
+ nameTextStyle: { color: colors.textSecondary, fontSize: FONT_SIZE_TINY },
84
+ axisLine: { show: false },
85
+ axisTick: { show: false },
86
+ axisLabel: {
87
+ color: colors.textSecondary,
88
+ ...(xAxisFormatter && { formatter: xAxisFormatter }),
89
+ },
90
+ splitLine: { lineStyle: { color: colors.border, type: [2, 3], opacity: 0.6 } },
91
+ },
92
+ yAxis: {
93
+ type: 'value',
94
+ name: yField,
95
+ nameLocation: 'middle',
96
+ nameGap: 32,
97
+ nameTextStyle: { color: colors.textSecondary, fontSize: FONT_SIZE_TINY },
98
+ axisLine: { show: false },
99
+ axisTick: { show: false },
100
+ axisLabel: {
101
+ color: colors.textSecondary,
102
+ ...(yAxisFormatter && { formatter: yAxisFormatter }),
103
+ },
104
+ splitLine: { lineStyle: { color: colors.border, type: [2, 3], opacity: 0.6 } },
105
+ },
106
+ series: seriesList,
107
+ };
108
+ // Add legend for multi-series
109
+ if (seriesField && legendData.length > 1) {
110
+ option.legend = {
111
+ show: true,
112
+ data: legendData,
113
+ top: 0,
114
+ textStyle: { color: colors.textSecondary, fontSize: FONT_SIZE_TINY },
115
+ };
116
+ }
117
+ return option;
118
+ }
119
+ /**
120
+ * Generate a scatter chart
121
+ */
122
+ function generateScatterChart(spec) {
123
+ const height = typeof spec.height === 'number' ? spec.height : DEFAULT_CHART_HEIGHT;
124
+ return wrapHtml('chart', buildScatterOptions(spec), '', '100%', height);
125
+ }
126
+ // Register the chart
127
+ registerChart('scatter')(generateScatterChart);
128
+ registerOptions('scatter')(buildScatterOptions);
129
+ export { generateScatterChart };
130
+ //# sourceMappingURL=scatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scatter.js","sourceRoot":"","sources":["../../charts/scatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Sparkline chart generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for a sparkline chart
7
+ * Returns null for pct_bar type which uses HTML rendering
8
+ */
9
+ export declare function buildSparklineOptions(spec: ChartSpec): Record<string, unknown> | null;
10
+ /**
11
+ * Generate a percentage bar sparkline (no ECharts needed)
12
+ */
13
+ declare function generatePctBar(spec: ChartSpec): string;
14
+ /**
15
+ * Generate a sparkline chart
16
+ */
17
+ declare function generateSparkline(spec: ChartSpec): string;
18
+ export { generateSparkline, generatePctBar };
19
+ //# sourceMappingURL=sparkline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkline.d.ts","sourceRoot":"","sources":["../../charts/sparkline.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,aAAa,CAAC;AAQ3E;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAoDrF;AAED;;GAEG;AACH,iBAAS,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CA6C/C;AAED;;GAEG;AACH,iBAAS,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CA8ClD;AAMD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Sparkline chart generator
3
+ */
4
+ import { PALETTE, ECHARTS_CDN, FONT_STACK, getThemeColors } from '../core/themes.js';
5
+ import { formatNumber } from '../core/formatting.js';
6
+ import { serializeOption } from '../core/serializer.js';
7
+ import { registerChart, registerOptions } from './registry.js';
8
+ /**
9
+ * Build ECharts options for a sparkline chart
10
+ * Returns null for pct_bar type which uses HTML rendering
11
+ */
12
+ export function buildSparklineOptions(spec) {
13
+ const chartType = (spec.sparkType ?? 'line');
14
+ // pct_bar type renders as HTML, not ECharts
15
+ if (chartType === 'pct' || chartType === 'pct_bar') {
16
+ return null;
17
+ }
18
+ const data = (spec.data ?? []);
19
+ const valueField = spec.value ?? 'value';
20
+ const theme = (spec.theme ?? 'light');
21
+ // Extract values
22
+ let values;
23
+ if (data.length > 0 && typeof data[0] === 'object') {
24
+ values = data.map((d) => (typeof d[valueField] === 'number' ? d[valueField] : 0));
25
+ }
26
+ else {
27
+ values = data;
28
+ }
29
+ const colors = getThemeColors(theme);
30
+ return {
31
+ backgroundColor: 'transparent',
32
+ animation: false,
33
+ tooltip: {
34
+ trigger: 'axis',
35
+ backgroundColor: colors.paper,
36
+ borderColor: colors.border,
37
+ textStyle: { color: colors.text },
38
+ axisPointer: { type: 'line', lineStyle: { color: colors.textSecondary, width: 1 } },
39
+ },
40
+ grid: { left: 0, right: 0, top: 5, bottom: 5 },
41
+ xAxis: {
42
+ type: 'category',
43
+ show: false,
44
+ data: values.map((_, i) => i),
45
+ },
46
+ yAxis: { type: 'value', show: false },
47
+ series: [
48
+ {
49
+ type: chartType === 'bar' ? 'bar' : 'line',
50
+ data: values,
51
+ symbol: 'circle',
52
+ symbolSize: 0,
53
+ lineStyle: { width: 2, color: PALETTE[0] },
54
+ areaStyle: chartType === 'area' ? { opacity: 0.3, color: PALETTE[0] } : undefined,
55
+ itemStyle: { color: PALETTE[0] },
56
+ emphasis: { itemStyle: { borderWidth: 2 } },
57
+ },
58
+ ],
59
+ };
60
+ }
61
+ /**
62
+ * Generate a percentage bar sparkline (no ECharts needed)
63
+ */
64
+ function generatePctBar(spec) {
65
+ const title = spec.title ?? '';
66
+ const theme = (spec.theme ?? 'light');
67
+ const value = typeof spec.value === 'number' ? spec.value : 0;
68
+ const fmt = (spec.format ?? 'pct0');
69
+ const showValue = spec.showValue !== false;
70
+ const colors = getThemeColors(theme);
71
+ // Normalize value to 0-1 range
72
+ const pct = value <= 1 ? value : value / 100;
73
+ const clampedPct = Math.max(0, Math.min(1, pct));
74
+ const widthPct = clampedPct * 100;
75
+ // Format display value
76
+ const displayValue = showValue ? formatNumber(clampedPct, fmt) : '';
77
+ const titleUpper = title.toUpperCase();
78
+ const titleHtml = title ? `<span class="label">${titleUpper}</span>` : '';
79
+ const valueHtml = showValue ? `<span class="pct-value">${displayValue}</span>` : '';
80
+ return `<!DOCTYPE html>
81
+ <html lang="en">
82
+ <head>
83
+ <meta charset="utf-8">
84
+ <style>
85
+ * { box-sizing: border-box; }
86
+ html, body { margin: 0; padding: 0; width: 100%; height: 100%; background-color: ${colors.background}; font-family: ${FONT_STACK}; }
87
+ .container { display: flex; align-items: center; gap: 10px; padding: 8px; height: 100%; }
88
+ .label { font-size: 12px; color: ${colors.text}; white-space: nowrap; letter-spacing: 0.05em; min-width: 60px; }
89
+ .pct-bar-container { flex: 1; height: 12px; background-color: ${colors.border}; border-radius: 2px; overflow: hidden; min-width: 60px; }
90
+ .pct-bar-fill { height: 100%; background-color: ${PALETTE[0]}; border-radius: 2px 0 0 2px; }
91
+ .pct-value { font-size: 12px; color: ${colors.text}; font-weight: 700; min-width: 40px; text-align: right; }
92
+ </style>
93
+ </head>
94
+ <body>
95
+ <div class="container">
96
+ ${titleHtml}
97
+ <div class="pct-bar-container">
98
+ <div class="pct-bar-fill" style="width: ${widthPct}%;"></div>
99
+ </div>
100
+ ${valueHtml}
101
+ </div>
102
+ </body>
103
+ </html>`;
104
+ }
105
+ /**
106
+ * Generate a sparkline chart
107
+ */
108
+ function generateSparkline(spec) {
109
+ const chartType = (spec.sparkType ?? 'line');
110
+ // Handle pct_bar type separately
111
+ if (chartType === 'pct' || chartType === 'pct_bar') {
112
+ return generatePctBar(spec);
113
+ }
114
+ const title = spec.title ?? '';
115
+ const theme = (spec.theme ?? 'light');
116
+ const colors = getThemeColors(theme);
117
+ const option = buildSparklineOptions(spec);
118
+ if (!option) {
119
+ return generatePctBar(spec);
120
+ }
121
+ const titleUpper = title.toUpperCase();
122
+ const optionJson = serializeOption(option);
123
+ return `<!DOCTYPE html>
124
+ <html lang="en">
125
+ <head>
126
+ <meta charset="utf-8">
127
+ <script src="${ECHARTS_CDN}"></script>
128
+ <style>
129
+ * { box-sizing: border-box; }
130
+ html, body { margin: 0; padding: 0; width: 100%; height: 100%; background-color: ${colors.background}; font-family: ${FONT_STACK}; }
131
+ .container { display: flex; align-items: center; gap: 12px; padding: 8px; height: 100%; }
132
+ .label { font-size: 12px; color: ${colors.text}; white-space: nowrap; letter-spacing: 0.05em; }
133
+ #chart { flex: 1; height: 32px; min-width: 80px; }
134
+ </style>
135
+ </head>
136
+ <body>
137
+ <div class="container">
138
+ <span class="label">${titleUpper}</span>
139
+ <div id="chart"></div>
140
+ </div>
141
+ <script>
142
+ var chart = echarts.init(document.getElementById('chart'));
143
+ var option = ${optionJson};
144
+ chart.setOption(option);
145
+ window.addEventListener('resize', function() { chart.resize(); });
146
+ </script>
147
+ </body>
148
+ </html>`;
149
+ }
150
+ // Register the chart
151
+ registerChart('sparkline')(generateSparkline);
152
+ registerOptions('sparkline')(buildSparklineOptions);
153
+ export { generateSparkline, generatePctBar };
154
+ //# sourceMappingURL=sparkline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sparkline.js","sourceRoot":"","sources":["../../charts/sparkline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Waterfall chart generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for a waterfall chart showing cumulative effect
7
+ */
8
+ export declare function buildWaterfallOptions(spec: ChartSpec): Record<string, unknown>;
9
+ /**
10
+ * Generate a waterfall chart
11
+ */
12
+ declare function generateWaterfall(spec: ChartSpec): string;
13
+ export { generateWaterfall };
14
+ //# sourceMappingURL=waterfall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waterfall.d.ts","sourceRoot":"","sources":["../../charts/waterfall.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAuBpD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwN9E;AAED;;GAEG;AACH,iBAAS,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGlD;AAMD,OAAO,EAAE,iBAAiB,EAAE,CAAC"}