@fluentui/react-charts 9.3.12 → 9.3.13

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 (35) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/dist/index.d.ts +852 -0
  3. package/lib/VegaDeclarativeChart.js +1 -0
  4. package/lib/VegaDeclarativeChart.js.map +1 -0
  5. package/lib/components/VegaDeclarativeChart/VegaDeclarativeChart.js +386 -0
  6. package/lib/components/VegaDeclarativeChart/VegaDeclarativeChart.js.map +1 -0
  7. package/lib/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js +20 -0
  8. package/lib/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js.map +1 -0
  9. package/lib/components/VegaDeclarativeChart/VegaLiteColorAdapter.js +415 -0
  10. package/lib/components/VegaDeclarativeChart/VegaLiteColorAdapter.js.map +1 -0
  11. package/lib/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js +3284 -0
  12. package/lib/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js.map +1 -0
  13. package/lib/components/VegaDeclarativeChart/VegaLiteTypes.js +28 -0
  14. package/lib/components/VegaDeclarativeChart/VegaLiteTypes.js.map +1 -0
  15. package/lib/components/VegaDeclarativeChart/index.js +1 -0
  16. package/lib/components/VegaDeclarativeChart/index.js.map +1 -0
  17. package/lib/index.js +1 -0
  18. package/lib/index.js.map +1 -1
  19. package/lib-commonjs/VegaDeclarativeChart.js +6 -0
  20. package/lib-commonjs/VegaDeclarativeChart.js.map +1 -0
  21. package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChart.js +255 -0
  22. package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChart.js.map +1 -0
  23. package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js +35 -0
  24. package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js.map +1 -0
  25. package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteColorAdapter.js +412 -0
  26. package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteColorAdapter.js.map +1 -0
  27. package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js +3219 -0
  28. package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js.map +1 -0
  29. package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteTypes.js +31 -0
  30. package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteTypes.js.map +1 -0
  31. package/lib-commonjs/components/VegaDeclarativeChart/index.js +6 -0
  32. package/lib-commonjs/components/VegaDeclarativeChart/index.js.map +1 -0
  33. package/lib-commonjs/index.js +1 -0
  34. package/lib-commonjs/index.js.map +1 -1
  35. package/package.json +3 -3
@@ -0,0 +1 @@
1
+ export * from './components/VegaDeclarativeChart';
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/VegaDeclarativeChart.ts"],"sourcesContent":["export * from './components/VegaDeclarativeChart';\n"],"names":[],"mappings":"AAAA,cAAc,oCAAoC"}
@@ -0,0 +1,386 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import { transformVegaLiteToLineChartProps, transformVegaLiteToVerticalBarChartProps, transformVegaLiteToVerticalStackedBarChartProps, transformVegaLiteToGroupedVerticalBarChartProps, transformVegaLiteToHorizontalBarChartProps, transformVegaLiteToAreaChartProps, transformVegaLiteToScatterChartProps, transformVegaLiteToDonutChartProps, transformVegaLiteToHeatMapChartProps, transformVegaLiteToHistogramProps, transformVegaLiteToPolarChartProps, getChartType, getMarkType, getVegaLiteLegendsProps } from './VegaLiteSchemaAdapter';
4
+ import { Legends } from '../Legends/index';
5
+ import { withResponsiveContainer } from '../ResponsiveContainer/withResponsiveContainer';
6
+ import { LineChart } from '../LineChart/index';
7
+ import { VerticalBarChart } from '../VerticalBarChart/index';
8
+ import { VerticalStackedBarChart } from '../VerticalStackedBarChart/index';
9
+ import { GroupedVerticalBarChart } from '../GroupedVerticalBarChart/index';
10
+ import { HorizontalBarChartWithAxis } from '../HorizontalBarChartWithAxis/index';
11
+ import { AreaChart } from '../AreaChart/index';
12
+ import { ScatterChart } from '../ScatterChart/index';
13
+ import { DonutChart } from '../DonutChart/index';
14
+ import { HeatMapChart } from '../HeatMapChart/index';
15
+ import { PolarChart } from '../PolarChart/index';
16
+ import { useIsDarkTheme, useColorMapping } from './VegaDeclarativeChartHooks';
17
+ /**
18
+ * Check if spec is a horizontal concatenation
19
+ */ function isHConcatSpec(spec) {
20
+ return !!spec.hconcat && Array.isArray(spec.hconcat) && spec.hconcat.length > 0;
21
+ }
22
+ /**
23
+ * Check if spec is a vertical concatenation
24
+ */ function isVConcatSpec(spec) {
25
+ return !!spec.vconcat && Array.isArray(spec.vconcat) && spec.vconcat.length > 0;
26
+ }
27
+ /**
28
+ * Get grid properties for concat specs
29
+ */ function getVegaConcatGridProperties(spec) {
30
+ if (isHConcatSpec(spec)) {
31
+ return {
32
+ templateRows: 'auto',
33
+ templateColumns: `repeat(${spec.hconcat.length}, 1fr)`,
34
+ isHorizontal: true,
35
+ specs: spec.hconcat
36
+ };
37
+ }
38
+ if (isVConcatSpec(spec)) {
39
+ return {
40
+ templateRows: `repeat(${spec.vconcat.length}, auto)`,
41
+ templateColumns: '1fr',
42
+ isHorizontal: false,
43
+ specs: spec.vconcat
44
+ };
45
+ }
46
+ return {
47
+ templateRows: '1fr',
48
+ templateColumns: '1fr',
49
+ isHorizontal: false,
50
+ specs: [
51
+ spec
52
+ ]
53
+ };
54
+ }
55
+ const ResponsiveLineChart = withResponsiveContainer(LineChart);
56
+ const ResponsiveVerticalBarChart = withResponsiveContainer(VerticalBarChart);
57
+ const ResponsiveVerticalStackedBarChart = withResponsiveContainer(VerticalStackedBarChart);
58
+ const ResponsiveGroupedVerticalBarChart = withResponsiveContainer(GroupedVerticalBarChart);
59
+ const ResponsiveHorizontalBarChartWithAxis = withResponsiveContainer(HorizontalBarChartWithAxis);
60
+ const ResponsiveAreaChart = withResponsiveContainer(AreaChart);
61
+ const ResponsiveScatterChart = withResponsiveContainer(ScatterChart);
62
+ const ResponsiveDonutChart = withResponsiveContainer(DonutChart);
63
+ const ResponsiveHeatMapChart = withResponsiveContainer(HeatMapChart);
64
+ const ResponsivePolarChart = withResponsiveContainer(PolarChart);
65
+ const vegaChartMap = {
66
+ line: {
67
+ transformer: transformVegaLiteToLineChartProps,
68
+ renderer: ResponsiveLineChart
69
+ },
70
+ bar: {
71
+ transformer: transformVegaLiteToVerticalBarChartProps,
72
+ renderer: ResponsiveVerticalBarChart
73
+ },
74
+ 'stacked-bar': {
75
+ transformer: transformVegaLiteToVerticalStackedBarChartProps,
76
+ renderer: ResponsiveVerticalStackedBarChart
77
+ },
78
+ 'grouped-bar': {
79
+ transformer: transformVegaLiteToGroupedVerticalBarChartProps,
80
+ renderer: ResponsiveGroupedVerticalBarChart
81
+ },
82
+ 'horizontal-bar': {
83
+ transformer: transformVegaLiteToHorizontalBarChartProps,
84
+ renderer: ResponsiveHorizontalBarChartWithAxis
85
+ },
86
+ area: {
87
+ transformer: transformVegaLiteToAreaChartProps,
88
+ renderer: ResponsiveAreaChart
89
+ },
90
+ scatter: {
91
+ transformer: transformVegaLiteToScatterChartProps,
92
+ renderer: ResponsiveScatterChart
93
+ },
94
+ donut: {
95
+ transformer: transformVegaLiteToDonutChartProps,
96
+ renderer: ResponsiveDonutChart
97
+ },
98
+ heatmap: {
99
+ transformer: transformVegaLiteToHeatMapChartProps,
100
+ renderer: ResponsiveHeatMapChart
101
+ },
102
+ histogram: {
103
+ transformer: transformVegaLiteToHistogramProps,
104
+ renderer: ResponsiveVerticalBarChart
105
+ },
106
+ polar: {
107
+ transformer: transformVegaLiteToPolarChartProps,
108
+ renderer: ResponsivePolarChart
109
+ }
110
+ };
111
+ /**
112
+ * Renders a single Vega-Lite chart spec
113
+ */ function renderSingleChart(spec, colorMap, isDarkTheme, interactiveCommonProps) {
114
+ const chartType = getChartType(spec);
115
+ const chartConfig = vegaChartMap[chartType.type];
116
+ if (!chartConfig) {
117
+ throw new Error(`VegaDeclarativeChart: Unsupported chart type '${chartType.type}'`);
118
+ }
119
+ const { transformer, renderer: ChartRenderer } = chartConfig;
120
+ const chartProps = transformer(spec, colorMap, isDarkTheme);
121
+ // For hconcat/vconcat sub-charts, hide per-chart legends (shared legend rendered separately)
122
+ if (spec._hideLegend) {
123
+ chartProps.hideLegend = true;
124
+ }
125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
+ return /*#__PURE__*/ React.createElement(ChartRenderer, {
127
+ ...chartProps,
128
+ ...interactiveCommonProps
129
+ });
130
+ }
131
+ /**
132
+ * VegaDeclarativeChart - Render Vega-Lite specifications with Fluent UI styling
133
+ *
134
+ * Supported chart types:
135
+ * - Line charts: mark: 'line' or 'point'
136
+ * - Area charts: mark: 'area'
137
+ * - Scatter charts: mark: 'point', 'circle', or 'square'
138
+ * - Vertical bar charts: mark: 'bar' with nominal/ordinal x-axis
139
+ * - Stacked bar charts: mark: 'bar' with color encoding
140
+ * - Grouped bar charts: mark: 'bar' with color encoding (via configuration)
141
+ * - Horizontal bar charts: mark: 'bar' with nominal/ordinal y-axis
142
+ * - Donut/Pie charts: mark: 'arc' with theta encoding
143
+ * - Heatmaps: mark: 'rect' with x, y, and color (quantitative) encodings
144
+ * - Combo charts: Layered specs with bar + line marks render as VerticalStackedBarChart with line overlays
145
+ *
146
+ * Multi-plot Support:
147
+ * - Horizontal concatenation (hconcat): Multiple charts side-by-side
148
+ * - Vertical concatenation (vconcat): Multiple charts stacked vertically
149
+ * - Shared data and encoding are merged from parent spec to each subplot
150
+ *
151
+ * Limitations:
152
+ * - Most layered specifications (multiple chart types) are not fully supported
153
+ * - Bar + Line combinations ARE supported and will render properly
154
+ * - For other composite charts, only the first layer will be rendered
155
+ * - Faceting and repeat operators are not yet supported
156
+ * - Funnel charts are not a native Vega-Lite mark type. The conversion_funnel.json example
157
+ * uses a horizontal bar chart (y: nominal, x: quantitative) which is the standard way to
158
+ * represent funnel data in Vega-Lite. For specialized funnel visualizations with tapering
159
+ * shapes, consider using Plotly's native funnel chart type instead.
160
+ *
161
+ * Note: Sankey, Gantt, and Gauge charts are not standard Vega-Lite marks.
162
+ * These specialized visualizations would require custom extensions or alternative approaches.
163
+ *
164
+ * @example Line Chart
165
+ * ```tsx
166
+ * import { VegaDeclarativeChart } from '@fluentui/react-charts';
167
+ *
168
+ * const spec = {
169
+ * mark: 'line',
170
+ * data: { values: [{ x: 1, y: 10 }, { x: 2, y: 20 }] },
171
+ * encoding: {
172
+ * x: { field: 'x', type: 'quantitative' },
173
+ * y: { field: 'y', type: 'quantitative' }
174
+ * }
175
+ * };
176
+ *
177
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: spec }} />
178
+ * ```
179
+ *
180
+ * @example Area Chart
181
+ * ```tsx
182
+ * const areaSpec = {
183
+ * mark: 'area',
184
+ * data: { values: [{ date: '2023-01', value: 100 }, { date: '2023-02', value: 150 }] },
185
+ * encoding: {
186
+ * x: { field: 'date', type: 'temporal' },
187
+ * y: { field: 'value', type: 'quantitative' }
188
+ * }
189
+ * };
190
+ *
191
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: areaSpec }} />
192
+ * ```
193
+ *
194
+ * @example Scatter Chart
195
+ * ```tsx
196
+ * const scatterSpec = {
197
+ * mark: 'point',
198
+ * data: { values: [{ x: 10, y: 20, size: 100 }, { x: 15, y: 30, size: 200 }] },
199
+ * encoding: {
200
+ * x: { field: 'x', type: 'quantitative' },
201
+ * y: { field: 'y', type: 'quantitative' },
202
+ * size: { field: 'size', type: 'quantitative' }
203
+ * }
204
+ * };
205
+ *
206
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: scatterSpec }} />
207
+ * ```
208
+ *
209
+ * @example Vertical Bar Chart
210
+ * ```tsx
211
+ * const barSpec = {
212
+ * mark: 'bar',
213
+ * data: { values: [{ cat: 'A', val: 28 }, { cat: 'B', val: 55 }] },
214
+ * encoding: {
215
+ * x: { field: 'cat', type: 'nominal' },
216
+ * y: { field: 'val', type: 'quantitative' }
217
+ * }
218
+ * };
219
+ *
220
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: barSpec }} />
221
+ * ```
222
+ *
223
+ * @example Stacked Bar Chart
224
+ * ```tsx
225
+ * const stackedSpec = {
226
+ * mark: 'bar',
227
+ * data: { values: [
228
+ * { cat: 'A', group: 'G1', val: 28 },
229
+ * { cat: 'A', group: 'G2', val: 15 }
230
+ * ]},
231
+ * encoding: {
232
+ * x: { field: 'cat', type: 'nominal' },
233
+ * y: { field: 'val', type: 'quantitative' },
234
+ * color: { field: 'group', type: 'nominal' }
235
+ * }
236
+ * };
237
+ *
238
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: stackedSpec }} />
239
+ * ```
240
+ *
241
+ * @example Donut Chart
242
+ * ```tsx
243
+ * const donutSpec = {
244
+ * mark: 'arc',
245
+ * data: { values: [{ category: 'A', value: 30 }, { category: 'B', value: 70 }] },
246
+ * encoding: {
247
+ * theta: { field: 'value', type: 'quantitative' },
248
+ * color: { field: 'category', type: 'nominal' }
249
+ * }
250
+ * };
251
+ *
252
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: donutSpec }} />
253
+ * ```
254
+ *
255
+ * @example Heatmap
256
+ * ```tsx
257
+ * const heatmapSpec = {
258
+ * mark: 'rect',
259
+ * data: { values: [
260
+ * { x: 'A', y: 'Mon', value: 28 },
261
+ * { x: 'B', y: 'Mon', value: 55 },
262
+ * { x: 'A', y: 'Tue', value: 43 }
263
+ * ]},
264
+ * encoding: {
265
+ * x: { field: 'x', type: 'nominal' },
266
+ * y: { field: 'y', type: 'nominal' },
267
+ * color: { field: 'value', type: 'quantitative' }
268
+ * }
269
+ * };
270
+ *
271
+ * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: heatmapSpec }} />
272
+ * ```
273
+ */ export const VegaDeclarativeChart = /*#__PURE__*/ React.forwardRef((props, forwardedRef)=>{
274
+ const { vegaLiteSpec, selectedLegends = [] } = props.chartSchema;
275
+ if (!vegaLiteSpec) {
276
+ throw new Error('VegaDeclarativeChart: vegaLiteSpec is required in chartSchema');
277
+ }
278
+ const colorMap = useColorMapping();
279
+ const isDarkTheme = useIsDarkTheme();
280
+ const chartRef = React.useRef(null);
281
+ const [activeLegends, setActiveLegends] = React.useState(selectedLegends);
282
+ const onActiveLegendsChange = (keys)=>{
283
+ setActiveLegends(keys);
284
+ if (props.onSchemaChange) {
285
+ props.onSchemaChange({
286
+ vegaLiteSpec,
287
+ selectedLegends: keys
288
+ });
289
+ }
290
+ };
291
+ React.useEffect(()=>{
292
+ var _props_chartSchema_selectedLegends;
293
+ setActiveLegends((_props_chartSchema_selectedLegends = props.chartSchema.selectedLegends) !== null && _props_chartSchema_selectedLegends !== void 0 ? _props_chartSchema_selectedLegends : []);
294
+ }, [
295
+ props.chartSchema.selectedLegends
296
+ ]);
297
+ const multiSelectLegendProps = {
298
+ canSelectMultipleLegends: true,
299
+ onChange: onActiveLegendsChange,
300
+ selectedLegends: activeLegends
301
+ };
302
+ const interactiveCommonProps = {
303
+ componentRef: chartRef,
304
+ legendProps: multiSelectLegendProps
305
+ };
306
+ try {
307
+ // Check if this is a concat spec (multiple charts side-by-side or stacked)
308
+ if (isHConcatSpec(vegaLiteSpec) || isVConcatSpec(vegaLiteSpec)) {
309
+ const gridProps = getVegaConcatGridProperties(vegaLiteSpec);
310
+ // Build shared legend from the first sub-chart's color encoding
311
+ const firstSubSpec = {
312
+ ...gridProps.specs[0],
313
+ data: gridProps.specs[0].data || vegaLiteSpec.data,
314
+ encoding: {
315
+ ...vegaLiteSpec.encoding || {},
316
+ ...gridProps.specs[0].encoding || {}
317
+ }
318
+ };
319
+ const sharedLegendProps = getVegaLiteLegendsProps(firstSubSpec, colorMap, isDarkTheme);
320
+ return /*#__PURE__*/ React.createElement("div", {
321
+ ref: forwardedRef,
322
+ className: props.className,
323
+ style: props.style
324
+ }, /*#__PURE__*/ React.createElement("div", {
325
+ style: {
326
+ display: 'grid',
327
+ gridTemplateRows: gridProps.templateRows,
328
+ gridTemplateColumns: gridProps.templateColumns,
329
+ gap: '16px'
330
+ }
331
+ }, gridProps.specs.map((subSpec, index)=>{
332
+ // Compute default height for sub-charts
333
+ const defaultSubHeight = typeof vegaLiteSpec.height === 'number' ? vegaLiteSpec.height : typeof subSpec.height === 'number' ? subSpec.height : 300;
334
+ const mergedSpec = {
335
+ ...subSpec,
336
+ data: subSpec.data || vegaLiteSpec.data,
337
+ encoding: {
338
+ ...vegaLiteSpec.encoding || {},
339
+ ...subSpec.encoding || {}
340
+ },
341
+ height: typeof subSpec.height === 'number' ? subSpec.height : defaultSubHeight,
342
+ // Hide legends on ALL sub-charts — shared legend is rendered below
343
+ _hideLegend: true
344
+ };
345
+ const cellRow = gridProps.isHorizontal ? 1 : index + 1;
346
+ const cellColumn = gridProps.isHorizontal ? index + 1 : 1;
347
+ return /*#__PURE__*/ React.createElement("div", {
348
+ key: `chart_${index}`,
349
+ style: {
350
+ gridRowStart: cellRow,
351
+ gridRowEnd: cellRow + 1,
352
+ gridColumnStart: cellColumn,
353
+ gridColumnEnd: cellColumn + 1,
354
+ minWidth: 0
355
+ }
356
+ }, renderSingleChart(mergedSpec, colorMap, isDarkTheme, interactiveCommonProps));
357
+ })), sharedLegendProps.legends.length > 0 && /*#__PURE__*/ React.createElement(Legends, {
358
+ ...sharedLegendProps,
359
+ ...multiSelectLegendProps
360
+ }));
361
+ }
362
+ // Check if this is a layered spec (composite chart)
363
+ if (vegaLiteSpec.layer && vegaLiteSpec.layer.length > 1) {
364
+ // Check if it's a supported bar+line combo
365
+ const marks = vegaLiteSpec.layer.map((layer)=>getMarkType(layer.mark));
366
+ const hasBar = marks.includes('bar');
367
+ const hasLine = marks.includes('line') || marks.includes('point');
368
+ const isBarLineCombo = hasBar && hasLine;
369
+ // Only warn for unsupported layered specs
370
+ if (!isBarLineCombo) {
371
+ // Layered specifications with multiple chart types are not fully supported.
372
+ // Only the first layer will be rendered.
373
+ }
374
+ }
375
+ // Render single chart
376
+ const chartComponent = renderSingleChart(vegaLiteSpec, colorMap, isDarkTheme, interactiveCommonProps);
377
+ return /*#__PURE__*/ React.createElement("div", {
378
+ ref: forwardedRef,
379
+ className: props.className,
380
+ style: props.style
381
+ }, chartComponent);
382
+ } catch (error) {
383
+ throw new Error(`Failed to transform Vega-Lite spec: ${error}`);
384
+ }
385
+ });
386
+ VegaDeclarativeChart.displayName = 'VegaDeclarativeChart';
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/VegaDeclarativeChart/VegaDeclarativeChart.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n transformVegaLiteToLineChartProps,\n transformVegaLiteToVerticalBarChartProps,\n transformVegaLiteToVerticalStackedBarChartProps,\n transformVegaLiteToGroupedVerticalBarChartProps,\n transformVegaLiteToHorizontalBarChartProps,\n transformVegaLiteToAreaChartProps,\n transformVegaLiteToScatterChartProps,\n transformVegaLiteToDonutChartProps,\n transformVegaLiteToHeatMapChartProps,\n transformVegaLiteToHistogramProps,\n transformVegaLiteToPolarChartProps,\n getChartType,\n getMarkType,\n getVegaLiteLegendsProps,\n} from './VegaLiteSchemaAdapter';\nimport type { VegaLiteUnitSpec, VegaLiteSpec } from './VegaLiteTypes';\nimport { Legends } from '../Legends/index';\nimport { withResponsiveContainer } from '../ResponsiveContainer/withResponsiveContainer';\nimport { LineChart } from '../LineChart/index';\nimport { VerticalBarChart } from '../VerticalBarChart/index';\nimport { VerticalStackedBarChart } from '../VerticalStackedBarChart/index';\nimport { GroupedVerticalBarChart } from '../GroupedVerticalBarChart/index';\nimport { HorizontalBarChartWithAxis } from '../HorizontalBarChartWithAxis/index';\nimport { AreaChart } from '../AreaChart/index';\nimport { ScatterChart } from '../ScatterChart/index';\nimport { DonutChart } from '../DonutChart/index';\nimport { HeatMapChart } from '../HeatMapChart/index';\nimport { PolarChart } from '../PolarChart/index';\nimport { useIsDarkTheme, useColorMapping } from './VegaDeclarativeChartHooks';\nimport type { Chart } from '../../types/index';\n\n// Re-export the typed VegaLiteSpec for public API\nexport type { VegaLiteSpec } from './VegaLiteTypes';\n\n/**\n * Schema for VegaDeclarativeChart component\n */\nexport interface VegaSchema {\n /**\n * Vega-Lite specification\n *\n * @see https://vega.github.io/vega-lite/docs/spec.html\n */\n vegaLiteSpec: VegaLiteSpec;\n\n /**\n * Selected legends for filtering\n */\n selectedLegends?: string[];\n}\n\n/**\n * Props for VegaDeclarativeChart component\n */\nexport interface VegaDeclarativeChartProps {\n /**\n * Vega-Lite chart schema\n */\n chartSchema: VegaSchema;\n\n /**\n * Callback when schema changes (e.g., legend selection)\n */\n onSchemaChange?: (newSchema: VegaSchema) => void;\n\n /**\n * Additional CSS class name\n */\n className?: string;\n\n /**\n * Additional inline styles\n */\n style?: React.CSSProperties;\n}\n\n/**\n * Check if spec is a horizontal concatenation\n */\nfunction isHConcatSpec(spec: VegaLiteSpec): boolean {\n return !!spec.hconcat && Array.isArray(spec.hconcat) && spec.hconcat.length > 0;\n}\n\n/**\n * Check if spec is a vertical concatenation\n */\nfunction isVConcatSpec(spec: VegaLiteSpec): boolean {\n return !!spec.vconcat && Array.isArray(spec.vconcat) && spec.vconcat.length > 0;\n}\n\n/**\n * Get grid properties for concat specs\n */\nfunction getVegaConcatGridProperties(spec: VegaLiteSpec): {\n templateRows: string;\n templateColumns: string;\n isHorizontal: boolean;\n specs: VegaLiteSpec[];\n} {\n if (isHConcatSpec(spec)) {\n return {\n templateRows: 'auto',\n templateColumns: `repeat(${spec.hconcat!.length}, 1fr)`,\n isHorizontal: true,\n specs: spec.hconcat!,\n };\n }\n\n if (isVConcatSpec(spec)) {\n return {\n templateRows: `repeat(${spec.vconcat!.length}, auto)`,\n templateColumns: '1fr',\n isHorizontal: false,\n specs: spec.vconcat!,\n };\n }\n\n return {\n templateRows: '1fr',\n templateColumns: '1fr',\n isHorizontal: false,\n specs: [spec],\n };\n}\n\nconst ResponsiveLineChart = withResponsiveContainer(LineChart);\nconst ResponsiveVerticalBarChart = withResponsiveContainer(VerticalBarChart);\nconst ResponsiveVerticalStackedBarChart = withResponsiveContainer(VerticalStackedBarChart);\nconst ResponsiveGroupedVerticalBarChart = withResponsiveContainer(GroupedVerticalBarChart);\nconst ResponsiveHorizontalBarChartWithAxis = withResponsiveContainer(HorizontalBarChartWithAxis);\nconst ResponsiveAreaChart = withResponsiveContainer(AreaChart);\nconst ResponsiveScatterChart = withResponsiveContainer(ScatterChart);\nconst ResponsiveDonutChart = withResponsiveContainer(DonutChart);\nconst ResponsiveHeatMapChart = withResponsiveContainer(HeatMapChart);\nconst ResponsivePolarChart = withResponsiveContainer(PolarChart);\n\n/**\n * Chart type mapping with transformers and renderers\n * Follows the factory functor pattern from PlotlyDeclarativeChart\n */\ntype VegaChartTypeMap = {\n line: { transformer: typeof transformVegaLiteToLineChartProps; renderer: typeof ResponsiveLineChart };\n bar: { transformer: typeof transformVegaLiteToVerticalBarChartProps; renderer: typeof ResponsiveVerticalBarChart };\n 'stacked-bar': {\n transformer: typeof transformVegaLiteToVerticalStackedBarChartProps;\n renderer: typeof ResponsiveVerticalStackedBarChart;\n };\n 'grouped-bar': {\n transformer: typeof transformVegaLiteToGroupedVerticalBarChartProps;\n renderer: typeof ResponsiveGroupedVerticalBarChart;\n };\n 'horizontal-bar': {\n transformer: typeof transformVegaLiteToHorizontalBarChartProps;\n renderer: typeof ResponsiveHorizontalBarChartWithAxis;\n };\n area: { transformer: typeof transformVegaLiteToAreaChartProps; renderer: typeof ResponsiveAreaChart };\n scatter: { transformer: typeof transformVegaLiteToScatterChartProps; renderer: typeof ResponsiveScatterChart };\n donut: { transformer: typeof transformVegaLiteToDonutChartProps; renderer: typeof ResponsiveDonutChart };\n heatmap: { transformer: typeof transformVegaLiteToHeatMapChartProps; renderer: typeof ResponsiveHeatMapChart };\n histogram: { transformer: typeof transformVegaLiteToHistogramProps; renderer: typeof ResponsiveVerticalBarChart };\n polar: { transformer: typeof transformVegaLiteToPolarChartProps; renderer: typeof ResponsivePolarChart };\n};\n\nconst vegaChartMap: VegaChartTypeMap = {\n line: { transformer: transformVegaLiteToLineChartProps, renderer: ResponsiveLineChart },\n bar: { transformer: transformVegaLiteToVerticalBarChartProps, renderer: ResponsiveVerticalBarChart },\n 'stacked-bar': {\n transformer: transformVegaLiteToVerticalStackedBarChartProps,\n renderer: ResponsiveVerticalStackedBarChart,\n },\n 'grouped-bar': {\n transformer: transformVegaLiteToGroupedVerticalBarChartProps,\n renderer: ResponsiveGroupedVerticalBarChart,\n },\n 'horizontal-bar': {\n transformer: transformVegaLiteToHorizontalBarChartProps,\n renderer: ResponsiveHorizontalBarChartWithAxis,\n },\n area: { transformer: transformVegaLiteToAreaChartProps, renderer: ResponsiveAreaChart },\n scatter: { transformer: transformVegaLiteToScatterChartProps, renderer: ResponsiveScatterChart },\n donut: { transformer: transformVegaLiteToDonutChartProps, renderer: ResponsiveDonutChart },\n heatmap: { transformer: transformVegaLiteToHeatMapChartProps, renderer: ResponsiveHeatMapChart },\n histogram: { transformer: transformVegaLiteToHistogramProps, renderer: ResponsiveVerticalBarChart },\n polar: { transformer: transformVegaLiteToPolarChartProps, renderer: ResponsivePolarChart },\n};\n\ninterface MultiSelectLegendProps {\n canSelectMultipleLegends: boolean;\n onChange: (keys: string[]) => void;\n selectedLegends: string[];\n}\n\n/**\n * Renders a single Vega-Lite chart spec\n */\nfunction renderSingleChart(\n spec: VegaLiteSpec,\n colorMap: React.RefObject<Map<string, string>>,\n isDarkTheme: boolean,\n interactiveCommonProps: { componentRef: React.RefObject<Chart | null>; legendProps: MultiSelectLegendProps },\n): React.ReactElement {\n const chartType = getChartType(spec);\n const chartConfig = vegaChartMap[chartType.type];\n\n if (!chartConfig) {\n throw new Error(`VegaDeclarativeChart: Unsupported chart type '${chartType.type}'`);\n }\n\n const { transformer, renderer: ChartRenderer } = chartConfig;\n const chartProps = transformer(spec, colorMap, isDarkTheme) as Record<string, unknown>;\n\n // For hconcat/vconcat sub-charts, hide per-chart legends (shared legend rendered separately)\n if ((spec as Record<string, unknown>)._hideLegend) {\n chartProps.hideLegend = true;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return <ChartRenderer {...(chartProps as any)} {...interactiveCommonProps} />;\n}\n\n/**\n * VegaDeclarativeChart - Render Vega-Lite specifications with Fluent UI styling\n *\n * Supported chart types:\n * - Line charts: mark: 'line' or 'point'\n * - Area charts: mark: 'area'\n * - Scatter charts: mark: 'point', 'circle', or 'square'\n * - Vertical bar charts: mark: 'bar' with nominal/ordinal x-axis\n * - Stacked bar charts: mark: 'bar' with color encoding\n * - Grouped bar charts: mark: 'bar' with color encoding (via configuration)\n * - Horizontal bar charts: mark: 'bar' with nominal/ordinal y-axis\n * - Donut/Pie charts: mark: 'arc' with theta encoding\n * - Heatmaps: mark: 'rect' with x, y, and color (quantitative) encodings\n * - Combo charts: Layered specs with bar + line marks render as VerticalStackedBarChart with line overlays\n *\n * Multi-plot Support:\n * - Horizontal concatenation (hconcat): Multiple charts side-by-side\n * - Vertical concatenation (vconcat): Multiple charts stacked vertically\n * - Shared data and encoding are merged from parent spec to each subplot\n *\n * Limitations:\n * - Most layered specifications (multiple chart types) are not fully supported\n * - Bar + Line combinations ARE supported and will render properly\n * - For other composite charts, only the first layer will be rendered\n * - Faceting and repeat operators are not yet supported\n * - Funnel charts are not a native Vega-Lite mark type. The conversion_funnel.json example\n * uses a horizontal bar chart (y: nominal, x: quantitative) which is the standard way to\n * represent funnel data in Vega-Lite. For specialized funnel visualizations with tapering\n * shapes, consider using Plotly's native funnel chart type instead.\n *\n * Note: Sankey, Gantt, and Gauge charts are not standard Vega-Lite marks.\n * These specialized visualizations would require custom extensions or alternative approaches.\n *\n * @example Line Chart\n * ```tsx\n * import { VegaDeclarativeChart } from '@fluentui/react-charts';\n *\n * const spec = {\n * mark: 'line',\n * data: { values: [{ x: 1, y: 10 }, { x: 2, y: 20 }] },\n * encoding: {\n * x: { field: 'x', type: 'quantitative' },\n * y: { field: 'y', type: 'quantitative' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: spec }} />\n * ```\n *\n * @example Area Chart\n * ```tsx\n * const areaSpec = {\n * mark: 'area',\n * data: { values: [{ date: '2023-01', value: 100 }, { date: '2023-02', value: 150 }] },\n * encoding: {\n * x: { field: 'date', type: 'temporal' },\n * y: { field: 'value', type: 'quantitative' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: areaSpec }} />\n * ```\n *\n * @example Scatter Chart\n * ```tsx\n * const scatterSpec = {\n * mark: 'point',\n * data: { values: [{ x: 10, y: 20, size: 100 }, { x: 15, y: 30, size: 200 }] },\n * encoding: {\n * x: { field: 'x', type: 'quantitative' },\n * y: { field: 'y', type: 'quantitative' },\n * size: { field: 'size', type: 'quantitative' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: scatterSpec }} />\n * ```\n *\n * @example Vertical Bar Chart\n * ```tsx\n * const barSpec = {\n * mark: 'bar',\n * data: { values: [{ cat: 'A', val: 28 }, { cat: 'B', val: 55 }] },\n * encoding: {\n * x: { field: 'cat', type: 'nominal' },\n * y: { field: 'val', type: 'quantitative' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: barSpec }} />\n * ```\n *\n * @example Stacked Bar Chart\n * ```tsx\n * const stackedSpec = {\n * mark: 'bar',\n * data: { values: [\n * { cat: 'A', group: 'G1', val: 28 },\n * { cat: 'A', group: 'G2', val: 15 }\n * ]},\n * encoding: {\n * x: { field: 'cat', type: 'nominal' },\n * y: { field: 'val', type: 'quantitative' },\n * color: { field: 'group', type: 'nominal' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: stackedSpec }} />\n * ```\n *\n * @example Donut Chart\n * ```tsx\n * const donutSpec = {\n * mark: 'arc',\n * data: { values: [{ category: 'A', value: 30 }, { category: 'B', value: 70 }] },\n * encoding: {\n * theta: { field: 'value', type: 'quantitative' },\n * color: { field: 'category', type: 'nominal' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: donutSpec }} />\n * ```\n *\n * @example Heatmap\n * ```tsx\n * const heatmapSpec = {\n * mark: 'rect',\n * data: { values: [\n * { x: 'A', y: 'Mon', value: 28 },\n * { x: 'B', y: 'Mon', value: 55 },\n * { x: 'A', y: 'Tue', value: 43 }\n * ]},\n * encoding: {\n * x: { field: 'x', type: 'nominal' },\n * y: { field: 'y', type: 'nominal' },\n * color: { field: 'value', type: 'quantitative' }\n * }\n * };\n *\n * <VegaDeclarativeChart chartSchema={{ vegaLiteSpec: heatmapSpec }} />\n * ```\n */\nexport const VegaDeclarativeChart = React.forwardRef<HTMLDivElement, VegaDeclarativeChartProps>(\n (props, forwardedRef) => {\n const { vegaLiteSpec, selectedLegends = [] } = props.chartSchema;\n\n if (!vegaLiteSpec) {\n throw new Error('VegaDeclarativeChart: vegaLiteSpec is required in chartSchema');\n }\n\n const colorMap = useColorMapping();\n const isDarkTheme = useIsDarkTheme();\n const chartRef = React.useRef<Chart>(null);\n\n const [activeLegends, setActiveLegends] = React.useState<string[]>(selectedLegends);\n\n const onActiveLegendsChange = (keys: string[]) => {\n setActiveLegends(keys);\n if (props.onSchemaChange) {\n props.onSchemaChange({ vegaLiteSpec, selectedLegends: keys });\n }\n };\n\n React.useEffect(() => {\n setActiveLegends(props.chartSchema.selectedLegends ?? []);\n }, [props.chartSchema.selectedLegends]);\n\n const multiSelectLegendProps = {\n canSelectMultipleLegends: true,\n onChange: onActiveLegendsChange,\n selectedLegends: activeLegends,\n };\n\n const interactiveCommonProps = {\n componentRef: chartRef,\n legendProps: multiSelectLegendProps,\n };\n\n try {\n // Check if this is a concat spec (multiple charts side-by-side or stacked)\n if (isHConcatSpec(vegaLiteSpec) || isVConcatSpec(vegaLiteSpec)) {\n const gridProps = getVegaConcatGridProperties(vegaLiteSpec);\n\n // Build shared legend from the first sub-chart's color encoding\n const firstSubSpec = {\n ...gridProps.specs[0],\n data: gridProps.specs[0].data || vegaLiteSpec.data,\n encoding: {\n ...(vegaLiteSpec.encoding || {}),\n ...(gridProps.specs[0].encoding || {}),\n },\n };\n const sharedLegendProps = getVegaLiteLegendsProps(firstSubSpec, colorMap, isDarkTheme);\n\n return (\n <div ref={forwardedRef} className={props.className} style={props.style}>\n <div\n style={{\n display: 'grid',\n gridTemplateRows: gridProps.templateRows,\n gridTemplateColumns: gridProps.templateColumns,\n gap: '16px',\n }}\n >\n {gridProps.specs.map((subSpec: VegaLiteSpec, index: number) => {\n // Compute default height for sub-charts\n const defaultSubHeight =\n typeof vegaLiteSpec.height === 'number'\n ? vegaLiteSpec.height\n : typeof subSpec.height === 'number'\n ? subSpec.height\n : 300;\n\n const mergedSpec = {\n ...subSpec,\n data: subSpec.data || vegaLiteSpec.data,\n encoding: {\n ...(vegaLiteSpec.encoding || {}),\n ...(subSpec.encoding || {}),\n },\n height: typeof subSpec.height === 'number' ? subSpec.height : defaultSubHeight,\n // Hide legends on ALL sub-charts — shared legend is rendered below\n _hideLegend: true,\n };\n\n const cellRow = gridProps.isHorizontal ? 1 : index + 1;\n const cellColumn = gridProps.isHorizontal ? index + 1 : 1;\n\n return (\n <div\n key={`chart_${index}`}\n style={{\n gridRowStart: cellRow,\n gridRowEnd: cellRow + 1,\n gridColumnStart: cellColumn,\n gridColumnEnd: cellColumn + 1,\n minWidth: 0,\n }}\n >\n {renderSingleChart(mergedSpec, colorMap, isDarkTheme, interactiveCommonProps)}\n </div>\n );\n })}\n </div>\n {sharedLegendProps.legends.length > 0 && <Legends {...sharedLegendProps} {...multiSelectLegendProps} />}\n </div>\n );\n }\n\n // Check if this is a layered spec (composite chart)\n if (vegaLiteSpec.layer && vegaLiteSpec.layer.length > 1) {\n // Check if it's a supported bar+line combo\n const marks = vegaLiteSpec.layer.map((layer: VegaLiteUnitSpec) => getMarkType(layer.mark));\n const hasBar = marks.includes('bar');\n const hasLine = marks.includes('line') || marks.includes('point');\n const isBarLineCombo = hasBar && hasLine;\n\n // Only warn for unsupported layered specs\n if (!isBarLineCombo) {\n // Layered specifications with multiple chart types are not fully supported.\n // Only the first layer will be rendered.\n }\n }\n\n // Render single chart\n const chartComponent = renderSingleChart(vegaLiteSpec, colorMap, isDarkTheme, interactiveCommonProps);\n\n return (\n <div ref={forwardedRef} className={props.className} style={props.style}>\n {chartComponent}\n </div>\n );\n } catch (error) {\n throw new Error(`Failed to transform Vega-Lite spec: ${error}`);\n }\n },\n);\n\nVegaDeclarativeChart.displayName = 'VegaDeclarativeChart';\n"],"names":["React","transformVegaLiteToLineChartProps","transformVegaLiteToVerticalBarChartProps","transformVegaLiteToVerticalStackedBarChartProps","transformVegaLiteToGroupedVerticalBarChartProps","transformVegaLiteToHorizontalBarChartProps","transformVegaLiteToAreaChartProps","transformVegaLiteToScatterChartProps","transformVegaLiteToDonutChartProps","transformVegaLiteToHeatMapChartProps","transformVegaLiteToHistogramProps","transformVegaLiteToPolarChartProps","getChartType","getMarkType","getVegaLiteLegendsProps","Legends","withResponsiveContainer","LineChart","VerticalBarChart","VerticalStackedBarChart","GroupedVerticalBarChart","HorizontalBarChartWithAxis","AreaChart","ScatterChart","DonutChart","HeatMapChart","PolarChart","useIsDarkTheme","useColorMapping","isHConcatSpec","spec","hconcat","Array","isArray","length","isVConcatSpec","vconcat","getVegaConcatGridProperties","templateRows","templateColumns","isHorizontal","specs","ResponsiveLineChart","ResponsiveVerticalBarChart","ResponsiveVerticalStackedBarChart","ResponsiveGroupedVerticalBarChart","ResponsiveHorizontalBarChartWithAxis","ResponsiveAreaChart","ResponsiveScatterChart","ResponsiveDonutChart","ResponsiveHeatMapChart","ResponsivePolarChart","vegaChartMap","line","transformer","renderer","bar","area","scatter","donut","heatmap","histogram","polar","renderSingleChart","colorMap","isDarkTheme","interactiveCommonProps","chartType","chartConfig","type","Error","ChartRenderer","chartProps","_hideLegend","hideLegend","VegaDeclarativeChart","forwardRef","props","forwardedRef","vegaLiteSpec","selectedLegends","chartSchema","chartRef","useRef","activeLegends","setActiveLegends","useState","onActiveLegendsChange","keys","onSchemaChange","useEffect","multiSelectLegendProps","canSelectMultipleLegends","onChange","componentRef","legendProps","gridProps","firstSubSpec","data","encoding","sharedLegendProps","div","ref","className","style","display","gridTemplateRows","gridTemplateColumns","gap","map","subSpec","index","defaultSubHeight","height","mergedSpec","cellRow","cellColumn","key","gridRowStart","gridRowEnd","gridColumnStart","gridColumnEnd","minWidth","legends","layer","marks","mark","hasBar","includes","hasLine","isBarLineCombo","chartComponent","error","displayName"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import { ThemeContext_unstable as V9ThemeContext } from '@fluentui/react-shared-contexts';
4
+ import { webLightTheme } from '@fluentui/tokens';
5
+ import { hsl as d3Hsl } from 'd3-color';
6
+ /**
7
+ * Hook to determine if dark theme is active based on background/foreground luminance
8
+ */ export function useIsDarkTheme() {
9
+ const parentV9Theme = React.useContext(V9ThemeContext);
10
+ const v9Theme = parentV9Theme ? parentV9Theme : webLightTheme;
11
+ const backgroundColor = d3Hsl(v9Theme.colorNeutralBackground1);
12
+ const foregroundColor = d3Hsl(v9Theme.colorNeutralForeground1);
13
+ const isDarkTheme = backgroundColor.l < foregroundColor.l;
14
+ return isDarkTheme;
15
+ }
16
+ /**
17
+ * Hook for color mapping across charts - maintains persistent color assignments
18
+ */ export function useColorMapping() {
19
+ return React.useRef(new Map());
20
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ThemeContext_unstable as V9ThemeContext } from '@fluentui/react-shared-contexts';\nimport { Theme, webLightTheme } from '@fluentui/tokens';\nimport { hsl as d3Hsl } from 'd3-color';\n\n/**\n * Hook to determine if dark theme is active based on background/foreground luminance\n */\nexport function useIsDarkTheme(): boolean {\n const parentV9Theme = React.useContext(V9ThemeContext) as Theme;\n const v9Theme: Theme = parentV9Theme ? parentV9Theme : webLightTheme;\n\n const backgroundColor = d3Hsl(v9Theme.colorNeutralBackground1);\n const foregroundColor = d3Hsl(v9Theme.colorNeutralForeground1);\n\n const isDarkTheme = backgroundColor.l < foregroundColor.l;\n\n return isDarkTheme;\n}\n\n/**\n * Hook for color mapping across charts - maintains persistent color assignments\n */\nexport function useColorMapping(): React.RefObject<Map<string, string>> {\n return React.useRef<Map<string, string>>(new Map());\n}\n"],"names":["React","ThemeContext_unstable","V9ThemeContext","webLightTheme","hsl","d3Hsl","useIsDarkTheme","parentV9Theme","useContext","v9Theme","backgroundColor","colorNeutralBackground1","foregroundColor","colorNeutralForeground1","isDarkTheme","l","useColorMapping","useRef","Map"],"mappings":"AAAA;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,yBAAyBC,cAAc,QAAQ,kCAAkC;AAC1F,SAAgBC,aAAa,QAAQ,mBAAmB;AACxD,SAASC,OAAOC,KAAK,QAAQ,WAAW;AAExC;;CAEC,GACD,OAAO,SAASC;IACd,MAAMC,gBAAgBP,MAAMQ,UAAU,CAACN;IACvC,MAAMO,UAAiBF,gBAAgBA,gBAAgBJ;IAEvD,MAAMO,kBAAkBL,MAAMI,QAAQE,uBAAuB;IAC7D,MAAMC,kBAAkBP,MAAMI,QAAQI,uBAAuB;IAE7D,MAAMC,cAAcJ,gBAAgBK,CAAC,GAAGH,gBAAgBG,CAAC;IAEzD,OAAOD;AACT;AAEA;;CAEC,GACD,OAAO,SAASE;IACd,OAAOhB,MAAMiB,MAAM,CAAsB,IAAIC;AAC/C"}