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
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # mviz
2
+
3
+ Generate clean, data-focused charts and dashboards from compact JSON specs or markdown.
4
+
5
+ Maximizes data-ink ratio with minimal chartjunk, gridlines, and decorative elements. Uses ECharts for rendering and outputs standalone HTML.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Global install
11
+ npm install -g mviz
12
+
13
+ # Or use npx (no install)
14
+ npx mviz
15
+ ```
16
+
17
+ ## CLI Usage
18
+
19
+ ### Single Chart (JSON via stdin)
20
+
21
+ ```bash
22
+ echo '{"type": "bar", "x": "month", "y": "sales", "data": [{"month": "Jan", "sales": 120}, {"month": "Feb", "sales": 150}]}' | mviz > chart.html
23
+ ```
24
+
25
+ ### Dashboard from Markdown
26
+
27
+ ```bash
28
+ mviz dashboard.md > dashboard.html
29
+ ```
30
+
31
+ ### Dashboard from Folder
32
+
33
+ ```bash
34
+ mviz my-dashboard/ > dashboard.html
35
+ ```
36
+
37
+ ## Library Usage
38
+
39
+ ```typescript
40
+ import { generateChart, parseMarkdownToDashboard } from 'mviz';
41
+
42
+ // Generate a single chart
43
+ const chartHtml = generateChart({
44
+ type: 'bar',
45
+ x: 'month',
46
+ y: 'sales',
47
+ data: [
48
+ { month: 'Jan', sales: 120 },
49
+ { month: 'Feb', sales: 150 },
50
+ ],
51
+ });
52
+
53
+ // Generate a dashboard from markdown
54
+ const dashboardHtml = parseMarkdownToDashboard(markdownContent);
55
+ ```
56
+
57
+ ## Supported Chart Types
58
+
59
+ | Type | Description |
60
+ |------|-------------|
61
+ | `bar` | Vertical/horizontal bars, grouped, stacked |
62
+ | `line` | Time series, multi-series, smooth/angular |
63
+ | `area` | Filled line charts, stacked areas |
64
+ | `pie` | Pie and donut charts |
65
+ | `scatter` | Scatter plots with optional sizing (bubble) |
66
+ | `combo` | Bar + line combinations, dual axis |
67
+ | `dumbbell` | Before/after comparisons with directional coloring |
68
+ | `heatmap` | 2D matrix with color scale |
69
+ | `calendar` | GitHub-style contribution calendars |
70
+ | `funnel` | Conversion funnels |
71
+ | `sankey` | Flow diagrams |
72
+ | `waterfall` | Financial waterfall charts |
73
+ | `histogram` | Distribution analysis |
74
+ | `boxplot` | Statistical box plots |
75
+ | `xmr` | Process control charts with Nelson rules |
76
+ | `sparkline` | Inline mini-charts |
77
+
78
+ ## UI Components
79
+
80
+ | Type | Description |
81
+ |------|-------------|
82
+ | `big_value` | Large KPI display |
83
+ | `delta` | Change indicator with arrow |
84
+ | `table` | Data tables with sparklines, heatmap columns |
85
+ | `alert` | Notification banners |
86
+ | `note` | Callout boxes |
87
+ | `textarea` | Markdown text blocks |
88
+
89
+ ## JSON Spec Format
90
+
91
+ All charts require:
92
+ - `type` - Chart type
93
+ - `data` - Array of data objects
94
+
95
+ Common optional fields:
96
+ - `title` - Chart title
97
+ - `theme` - `"light"` (default) or `"dark"`
98
+ - `x` - Field name for x-axis
99
+ - `y` - Field name(s) for y-axis
100
+
101
+ Example:
102
+ ```json
103
+ {
104
+ "type": "line",
105
+ "title": "Revenue Trend",
106
+ "x": "month",
107
+ "y": "revenue",
108
+ "data": [
109
+ {"month": "Jan", "revenue": 1250000},
110
+ {"month": "Feb", "revenue": 1450000},
111
+ {"month": "Mar", "revenue": 1380000}
112
+ ]
113
+ }
114
+ ```
115
+
116
+ ## Markdown Dashboard Format
117
+
118
+ ```markdown
119
+ ---
120
+ theme: light
121
+ title: My Dashboard
122
+ ---
123
+
124
+ # Sales Report
125
+
126
+ ```big_value size=[4,2]
127
+ {"value": 1250000, "label": "Revenue", "format": "usd"}
128
+ ```
129
+
130
+ ```bar size=[8,5]
131
+ {"title": "Monthly Sales", "x": "month", "y": "sales", "data": [...]}
132
+ ```
133
+ ```
134
+
135
+ Layout rules:
136
+ - Multiple code blocks in sequence = grid columns (16-column grid)
137
+ - Empty lines = new rows
138
+ - `size=[cols,rows]` controls component dimensions
139
+
140
+ ## Format Options
141
+
142
+ - `auto` - Smart formatting based on magnitude (default)
143
+ - `usd_auto` - Currency with smart abbreviation ($1.25m)
144
+ - `usd` - Full currency ($1,250,000)
145
+ - `pct` / `pct0` - Percentages (15.0% / 15%)
146
+ - `num0` / `num1` - Numbers with 0/1 decimal places
147
+
148
+ ## Distribution Options
149
+
150
+ ### npm (CLI & Library)
151
+
152
+ ```bash
153
+ npm install -g mviz # Global CLI
154
+ npx mviz # No-install usage
155
+ npm install mviz # Library dependency
156
+ ```
157
+
158
+ ### Claude Skills
159
+
160
+ mviz is available as a Claude skill for use in Claude.ai, Claude Code, and the Claude API:
161
+
162
+ 1. **Claude.ai**: Upload `mviz.skill` at Settings > Capabilities
163
+ 2. **Claude Code**: `npm install -g mviz` then use in projects
164
+ 3. **Skills Directory**: Check [claude.com/connectors](https://claude.com/connectors)
165
+
166
+ Build the skill bundle:
167
+ ```bash
168
+ npm run build
169
+ python3 build_skill.py -o mviz.skill
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Area chart generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for an area chart
7
+ */
8
+ export declare function buildAreaOptions(spec: ChartSpec): Record<string, unknown>;
9
+ /**
10
+ * Generate an area chart
11
+ */
12
+ declare function generateAreaChart(spec: ChartSpec): string;
13
+ export { generateAreaChart };
14
+ //# sourceMappingURL=area.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area.d.ts","sourceRoot":"","sources":["../../charts/area.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,aAAa,CAAC;AAe3E;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA8HzE;AAED;;GAEG;AACH,iBAAS,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGlD;AAMD,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Area chart generator
3
+ */
4
+ import { FONT_SIZE_XXS, LEGEND_ITEM_WIDTH, LEGEND_ITEM_HEIGHT, LEGEND_ITEM_GAP, 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, inferAxisType } from '../core/formatting.js';
8
+ /**
9
+ * Build ECharts options for an area chart
10
+ */
11
+ export function buildAreaOptions(spec) {
12
+ const data = (spec.data ?? []);
13
+ const x = spec.x ?? 'name';
14
+ const y = spec.y ?? 'value';
15
+ const theme = (spec.theme ?? 'light');
16
+ const stacked = spec.stacked === true;
17
+ const smooth = spec.smooth === true;
18
+ const colors = getThemeColors(theme);
19
+ const yKeys = Array.isArray(y) ? y : [y];
20
+ const categories = data.map((d) => d[x]);
21
+ const palette = getPalette(theme);
22
+ // Infer format for value axis based on first y field name
23
+ const firstYKey = yKeys[0] ?? 'value';
24
+ const sampleValue = data.length > 0 && data[0] ? data[0][firstYKey] ?? 0 : 0;
25
+ const valueFormat = spec.format ?? inferFormat(firstYKey, sampleValue);
26
+ const axisFormatter = getAxisFormatterJs(valueFormat);
27
+ // Detect x-axis type: time, value, or category
28
+ const xAxisType = spec.xAxisType ?? inferAxisType(categories);
29
+ // Get axis label config based on axis type
30
+ const xAxisLabelConfig = xAxisType === 'category'
31
+ ? { interval: 0, rotate: 45, overflow: 'truncate', ellipsis: '...', width: 100 }
32
+ : xAxisType === 'time'
33
+ ? {
34
+ hideOverlap: true,
35
+ formatter: {
36
+ _js_: `function(value) {
37
+ var d = new Date(value);
38
+ var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
39
+ return months[d.getMonth()] + ' ' + d.getDate();
40
+ }`,
41
+ },
42
+ }
43
+ : { hideOverlap: true };
44
+ const option = {
45
+ backgroundColor: 'transparent',
46
+ animation: false,
47
+ color: palette,
48
+ tooltip: {
49
+ trigger: 'axis',
50
+ backgroundColor: colors.paper,
51
+ borderColor: colors.border,
52
+ textStyle: { color: colors.text },
53
+ },
54
+ grid: {
55
+ left: '2%',
56
+ right: '2%',
57
+ top: yKeys.length > 1 ? '14%' : '6%',
58
+ bottom: '8%',
59
+ containLabel: true,
60
+ },
61
+ xAxis: {
62
+ type: xAxisType,
63
+ data: xAxisType === 'category' ? categories.map(String) : undefined,
64
+ boundaryGap: false,
65
+ axisLine: { show: false },
66
+ axisTick: { show: false },
67
+ axisLabel: {
68
+ color: colors.textSecondary,
69
+ ...xAxisLabelConfig,
70
+ },
71
+ },
72
+ yAxis: {
73
+ type: 'value',
74
+ axisLine: { show: false },
75
+ axisTick: { show: false },
76
+ axisLabel: {
77
+ color: colors.textSecondary,
78
+ ...(axisFormatter && { formatter: axisFormatter }),
79
+ },
80
+ splitLine: { lineStyle: { color: colors.border, type: [2, 3], opacity: 0.6 } },
81
+ },
82
+ series: [],
83
+ };
84
+ // Apply yMin/yMax
85
+ if (spec.yMin !== undefined) {
86
+ option.yAxis.min = spec.yMin;
87
+ }
88
+ if (spec.yMax !== undefined) {
89
+ option.yAxis.max = spec.yMax;
90
+ }
91
+ // Add legend for multi-series
92
+ if (yKeys.length > 1) {
93
+ option.legend = {
94
+ data: yKeys,
95
+ top: 0,
96
+ textStyle: { color: colors.textSecondary, fontSize: FONT_SIZE_XXS },
97
+ itemWidth: LEGEND_ITEM_WIDTH,
98
+ itemHeight: LEGEND_ITEM_HEIGHT,
99
+ itemGap: LEGEND_ITEM_GAP,
100
+ };
101
+ }
102
+ // Build series
103
+ for (let i = 0; i < yKeys.length; i++) {
104
+ const key = yKeys[i];
105
+ // Format series data based on axis type
106
+ const seriesData = xAxisType === 'category'
107
+ ? data.map((d) => d[key] ?? 0) // Category axis: just y values
108
+ : data.map((d) => [d[x], d[key] ?? 0]); // Time/value axes: [x, y] pairs
109
+ const series = {
110
+ name: key,
111
+ type: 'line',
112
+ data: seriesData,
113
+ smooth,
114
+ areaStyle: { opacity: stacked ? 0.85 : 0.5 },
115
+ symbol: 'none',
116
+ lineStyle: { width: 0 },
117
+ itemStyle: { color: palette[i % palette.length] },
118
+ };
119
+ if (stacked) {
120
+ series.stack = 'total';
121
+ }
122
+ option.series.push(series);
123
+ }
124
+ return option;
125
+ }
126
+ /**
127
+ * Generate an area chart
128
+ */
129
+ function generateAreaChart(spec) {
130
+ const height = typeof spec.height === 'number' ? spec.height : DEFAULT_CHART_HEIGHT;
131
+ return wrapHtml('chart', buildAreaOptions(spec), '', '100%', height);
132
+ }
133
+ // Register the chart
134
+ registerChart('area')(generateAreaChart);
135
+ registerOptions('area')(buildAreaOptions);
136
+ export { generateAreaChart };
137
+ //# sourceMappingURL=area.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"area.js","sourceRoot":"","sources":["../../charts/area.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Bar chart generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for a bar chart
7
+ */
8
+ export declare function buildBarOptions(spec: ChartSpec): Record<string, unknown>;
9
+ /**
10
+ * Generate a bar chart
11
+ */
12
+ declare function generateBarChart(spec: ChartSpec): string;
13
+ export { generateBarChart };
14
+ //# sourceMappingURL=bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bar.d.ts","sourceRoot":"","sources":["../../charts/bar.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAgC,MAAM,aAAa,CAAC;AAiB3E;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0LxE;AAED;;GAEG;AACH,iBAAS,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGjD;AAMD,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Bar chart generator
3
+ */
4
+ import { BAR_MAX_WIDTH, LEGEND_ITEM_WIDTH, LEGEND_ITEM_HEIGHT, LEGEND_ITEM_GAP, FONT_SIZE_TINY, 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
+ import { inferFormat, getLabelFormatterJs, getAxisFormatterJs, inferAxisType } from '../core/formatting.js';
8
+ /**
9
+ * Build ECharts options for a bar chart
10
+ */
11
+ export function buildBarOptions(spec) {
12
+ const data = (spec.data ?? []);
13
+ const x = spec.x ?? 'name';
14
+ const y = spec.y ?? 'value';
15
+ const theme = (spec.theme ?? 'light');
16
+ const stacked = spec.stacked === true;
17
+ const horizontal = spec.horizontal === true;
18
+ const colors = getThemeColors(theme);
19
+ const yKeys = Array.isArray(y) ? y : [y];
20
+ const categories = data.map((d) => d[x]);
21
+ const palette = getPalette(theme);
22
+ // Infer format for value axis based on first y field name
23
+ const firstYKey = yKeys[0] ?? 'value';
24
+ const sampleValue = data.length > 0 && data[0] ? data[0][firstYKey] ?? 0 : 0;
25
+ const valueFormat = spec.format ?? inferFormat(firstYKey, sampleValue);
26
+ const labelFormatter = getLabelFormatterJs(valueFormat);
27
+ const axisFormatter = getAxisFormatterJs(valueFormat);
28
+ // Detect category axis type (this is x-axis for vertical, y-axis for horizontal)
29
+ const categoryAxisType = spec.xAxisType ?? inferAxisType(categories);
30
+ // For horizontal bars, x-axis is always 'value'; for vertical it's the category axis type
31
+ const xAxisType = horizontal ? 'value' : categoryAxisType;
32
+ // Determine if labels should be shown (based on category axis type, not x-axis for horizontal)
33
+ const showLabels = yKeys.length === 1 && !stacked && data.length <= 12 && categoryAxisType === 'category';
34
+ // Get axis label config based on axis type
35
+ const xAxisLabelConfig = xAxisType === 'category'
36
+ ? { interval: 0, rotate: 45, overflow: 'truncate', ellipsis: '...', width: 100 }
37
+ : { hideOverlap: true };
38
+ const option = {
39
+ backgroundColor: 'transparent',
40
+ animation: false,
41
+ tooltip: {
42
+ trigger: 'axis',
43
+ axisPointer: { type: 'shadow' },
44
+ backgroundColor: colors.paper,
45
+ borderColor: colors.border,
46
+ textStyle: { color: colors.text },
47
+ },
48
+ grid: {
49
+ left: '2%',
50
+ right: horizontal && showLabels ? '8%' : '2%',
51
+ top: yKeys.length > 1 ? '14%' : showLabels && !horizontal ? '14%' : '6%',
52
+ bottom: '8%',
53
+ containLabel: true,
54
+ },
55
+ xAxis: horizontal
56
+ ? {
57
+ type: 'value',
58
+ axisLine: { show: false },
59
+ axisTick: { show: false },
60
+ axisLabel: {
61
+ color: colors.textSecondary,
62
+ fontSize: FONT_SIZE_XXS,
63
+ margin: 10,
64
+ hideOverlap: true,
65
+ ...(axisFormatter && { formatter: axisFormatter }),
66
+ },
67
+ splitLine: { lineStyle: { color: colors.border, type: [2, 3], opacity: 0.6 } },
68
+ }
69
+ : {
70
+ type: xAxisType,
71
+ data: xAxisType === 'category' ? categories.map(String) : undefined,
72
+ axisLine: { show: false },
73
+ axisTick: { show: false },
74
+ axisLabel: {
75
+ color: colors.textSecondary,
76
+ ...xAxisLabelConfig,
77
+ },
78
+ },
79
+ yAxis: horizontal
80
+ ? {
81
+ type: 'category',
82
+ data: categories,
83
+ axisLine: { show: false },
84
+ axisTick: { show: false },
85
+ axisLabel: {
86
+ color: colors.textSecondary,
87
+ fontSize: FONT_SIZE_XXS,
88
+ margin: 10,
89
+ interval: 0,
90
+ rotate: 45,
91
+ overflow: 'truncate',
92
+ ellipsis: '...',
93
+ width: 100,
94
+ },
95
+ }
96
+ : {
97
+ type: 'value',
98
+ axisLine: { show: false },
99
+ axisTick: { show: false },
100
+ axisLabel: {
101
+ color: colors.textSecondary,
102
+ fontSize: FONT_SIZE_XXS,
103
+ margin: 10,
104
+ ...(axisFormatter && { formatter: axisFormatter }),
105
+ },
106
+ splitLine: { lineStyle: { color: colors.border, type: [2, 3], opacity: 0.6 } },
107
+ },
108
+ series: [],
109
+ };
110
+ // Apply yMin/yMax to value axis
111
+ const valueAxis = horizontal ? 'xAxis' : 'yAxis';
112
+ if (spec.yMin !== undefined) {
113
+ option[valueAxis].min = spec.yMin;
114
+ }
115
+ if (spec.yMax !== undefined) {
116
+ option[valueAxis].max = spec.yMax;
117
+ }
118
+ // Adjust y-axis gridlines based on x-axis category label length
119
+ // Long category labels (rotated 45°) take up vertical space at bottom
120
+ const chartHeight = typeof spec.height === 'number' ? spec.height : DEFAULT_CHART_HEIGHT;
121
+ if (chartHeight && categories.length > 0 && !horizontal) {
122
+ // Find longest category label
123
+ const maxLabelLen = Math.max(...categories.map((cat) => String(cat).length));
124
+ // Rotated 45° labels: height ≈ label_length * 5px (rough estimate)
125
+ // Short labels (< 8 chars) don't need adjustment
126
+ if (maxLabelLen > 8) {
127
+ const labelBottomSpace = maxLabelLen * 5; // px taken by rotated labels
128
+ const usableHeight = chartHeight - labelBottomSpace - 30; // minus top margin
129
+ // Each gridline needs ~20px vertical space
130
+ const maxSplits = Math.max(2, Math.floor(usableHeight / 20));
131
+ if (maxSplits < 5) {
132
+ option[valueAxis].splitNumber = maxSplits;
133
+ }
134
+ }
135
+ }
136
+ // Add legend for multi-series
137
+ if (yKeys.length > 1) {
138
+ option.legend = {
139
+ data: yKeys,
140
+ top: 0,
141
+ textStyle: { color: colors.textSecondary, fontSize: FONT_SIZE_XXS },
142
+ itemWidth: LEGEND_ITEM_WIDTH,
143
+ itemHeight: LEGEND_ITEM_HEIGHT,
144
+ itemGap: LEGEND_ITEM_GAP,
145
+ };
146
+ }
147
+ // Use lighter label color for dark theme for better visibility
148
+ const labelColor = theme === 'dark' ? colors.text : colors.textSecondary;
149
+ // Build series
150
+ for (let i = 0; i < yKeys.length; i++) {
151
+ const key = yKeys[i];
152
+ // Format series data based on axis type (for non-horizontal bars)
153
+ const seriesData = (xAxisType === 'category' || horizontal)
154
+ ? data.map((d) => d[key] ?? 0) // Category/horizontal: just y values
155
+ : data.map((d) => [d[x], d[key] ?? 0]); // Time/value axes: [x, y] pairs
156
+ const series = {
157
+ name: key,
158
+ type: 'bar',
159
+ data: seriesData,
160
+ barMaxWidth: BAR_MAX_WIDTH,
161
+ itemStyle: {
162
+ color: palette[i % palette.length],
163
+ },
164
+ label: {
165
+ show: showLabels,
166
+ position: horizontal ? 'right' : 'top',
167
+ color: labelColor,
168
+ fontSize: FONT_SIZE_TINY,
169
+ offset: horizontal ? [2, 0] : [0, -2],
170
+ ...(labelFormatter && { formatter: labelFormatter }),
171
+ },
172
+ };
173
+ if (stacked) {
174
+ series.stack = 'total';
175
+ }
176
+ option.series.push(series);
177
+ }
178
+ return option;
179
+ }
180
+ /**
181
+ * Generate a bar chart
182
+ */
183
+ function generateBarChart(spec) {
184
+ const height = typeof spec.height === 'number' ? spec.height : DEFAULT_CHART_HEIGHT;
185
+ return wrapHtml('chart', buildBarOptions(spec), '', '100%', height);
186
+ }
187
+ // Register the chart
188
+ registerChart('bar')(generateBarChart);
189
+ registerOptions('bar')(buildBarOptions);
190
+ export { generateBarChart };
191
+ //# sourceMappingURL=bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bar.js","sourceRoot":"","sources":["../../charts/bar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Box plot chart generator
3
+ */
4
+ import type { ChartSpec } from '../types.js';
5
+ /**
6
+ * Build ECharts options for a box plot
7
+ */
8
+ export declare function buildBoxplotOptions(spec: ChartSpec): Record<string, unknown>;
9
+ /**
10
+ * Generate a box plot chart
11
+ */
12
+ declare function generateBoxplot(spec: ChartSpec): string;
13
+ export { generateBoxplot };
14
+ //# sourceMappingURL=boxplot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boxplot.d.ts","sourceRoot":"","sources":["../../charts/boxplot.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAS,MAAM,aAAa,CAAC;AAKpD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA4D5E;AAED;;GAEG;AACH,iBAAS,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGhD;AAMD,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Box plot chart generator
3
+ */
4
+ import { 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 box plot
9
+ */
10
+ export function buildBoxplotOptions(spec) {
11
+ const data = spec.data ?? [];
12
+ const theme = (spec.theme ?? 'light');
13
+ const categories = spec.categories ?? [];
14
+ const colors = getThemeColors(theme);
15
+ const palette = getPalette(theme);
16
+ // Box data should be arrays of [min, Q1, median, Q3, max]
17
+ const boxData = Array.isArray(data[0]) ? data : data;
18
+ return {
19
+ backgroundColor: 'transparent',
20
+ animation: false,
21
+ color: palette,
22
+ tooltip: {
23
+ trigger: 'item',
24
+ backgroundColor: colors.paper,
25
+ borderColor: colors.border,
26
+ textStyle: { color: colors.text },
27
+ },
28
+ grid: {
29
+ left: '6%',
30
+ right: '6%',
31
+ top: '6%',
32
+ bottom: '18%',
33
+ containLabel: true,
34
+ },
35
+ xAxis: {
36
+ type: 'category',
37
+ data: categories,
38
+ boundaryGap: true,
39
+ axisLine: { show: false },
40
+ axisTick: { show: false },
41
+ axisLabel: {
42
+ color: colors.textSecondary,
43
+ interval: 0,
44
+ rotate: 45,
45
+ },
46
+ },
47
+ yAxis: {
48
+ type: 'value',
49
+ axisLine: { show: false },
50
+ axisTick: { show: false },
51
+ axisLabel: { color: colors.textSecondary },
52
+ splitLine: { lineStyle: { color: colors.border, type: [2, 3], opacity: 0.6 } },
53
+ },
54
+ series: [
55
+ {
56
+ type: 'boxplot',
57
+ data: boxData,
58
+ itemStyle: {
59
+ color: palette[0],
60
+ borderColor: palette[0],
61
+ borderWidth: 1,
62
+ opacity: 0.7,
63
+ },
64
+ },
65
+ ],
66
+ };
67
+ }
68
+ /**
69
+ * Generate a box plot chart
70
+ */
71
+ function generateBoxplot(spec) {
72
+ const height = typeof spec.height === 'number' ? spec.height : DEFAULT_CHART_HEIGHT;
73
+ return wrapHtml('chart', buildBoxplotOptions(spec), '', '100%', height);
74
+ }
75
+ // Register the chart
76
+ registerChart('boxplot')(generateBoxplot);
77
+ registerOptions('boxplot')(buildBoxplotOptions);
78
+ export { generateBoxplot };
79
+ //# sourceMappingURL=boxplot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boxplot.js","sourceRoot":"","sources":["../../charts/boxplot.ts"],"names":[],"mappings":"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"}