@fluentui/react-charts 9.3.12 → 9.3.14
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.
- package/CHANGELOG.md +25 -2
- package/dist/index.d.ts +859 -0
- package/lib/VegaDeclarativeChart.js +1 -0
- package/lib/VegaDeclarativeChart.js.map +1 -0
- package/lib/components/LineChart/LineChart.js +47 -7
- package/lib/components/LineChart/LineChart.js.map +1 -1
- package/lib/components/ScatterChart/ScatterChart.js +12 -12
- package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChart.js +405 -0
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChart.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js +20 -0
- package/lib/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteColorAdapter.js +415 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteColorAdapter.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js +537 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js +3279 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteTypes.js +28 -0
- package/lib/components/VegaDeclarativeChart/VegaLiteTypes.js.map +1 -0
- package/lib/components/VegaDeclarativeChart/index.js +1 -0
- package/lib/components/VegaDeclarativeChart/index.js.map +1 -0
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +5 -2
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/utilities/utilities.js +41 -0
- package/lib/utilities/utilities.js.map +1 -1
- package/lib-commonjs/VegaDeclarativeChart.js +6 -0
- package/lib-commonjs/VegaDeclarativeChart.js.map +1 -0
- package/lib-commonjs/components/LineChart/LineChart.js +46 -6
- package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/ScatterChart.js +11 -11
- package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChart.js +274 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChart.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js +35 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaDeclarativeChartHooks.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteColorAdapter.js +412 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteColorAdapter.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js +533 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteExpressionEvaluator.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js +3214 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteSchemaAdapter.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteTypes.js +31 -0
- package/lib-commonjs/components/VegaDeclarativeChart/VegaLiteTypes.js.map +1 -0
- package/lib-commonjs/components/VegaDeclarativeChart/index.js +6 -0
- package/lib-commonjs/components/VegaDeclarativeChart/index.js.map +1 -0
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +4 -1
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib-commonjs/index.js +1 -0
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/utilities/utilities.js +33 -0
- package/lib-commonjs/utilities/utilities.js.map +1 -1
- package/package.json +3 -3
|
@@ -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 * Maximum allowed nesting depth for incoming JSON specs.\n * Matches the Plotly adapter's MAX_DEPTH to prevent stack overflow / memory exhaustion.\n */\nconst MAX_DEPTH = 15;\n\n/**\n * Validates that a JSON value does not exceed the maximum nesting depth.\n * Throws if the depth limit is exceeded (same behavior as Plotly's sanitizeJson).\n */\nfunction validateJsonDepth(value: unknown, depth: number = 0): void {\n if (depth > MAX_DEPTH) {\n throw new Error('VegaDeclarativeChart: Maximum JSON depth exceeded');\n }\n if (value !== null && typeof value === 'object') {\n for (const key of Object.keys(value as Record<string, unknown>)) {\n validateJsonDepth((value as Record<string, unknown>)[key], depth + 1);\n }\n }\n}\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 // Guard against excessively deep JSON specs that could cause stack overflow / memory exhaustion\n validateJsonDepth(vegaLiteSpec);\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","MAX_DEPTH","validateJsonDepth","value","depth","Error","key","Object","keys","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","ChartRenderer","chartProps","_hideLegend","hideLegend","VegaDeclarativeChart","forwardRef","props","forwardedRef","vegaLiteSpec","selectedLegends","chartSchema","chartRef","useRef","activeLegends","setActiveLegends","useState","onActiveLegendsChange","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","gridRowStart","gridRowEnd","gridColumnStart","gridColumnEnd","minWidth","legends","layer","marks","mark","hasBar","includes","hasLine","isBarLineCombo","chartComponent","error","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
function _export(target, all) {
|
|
7
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: all[name]
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
_export(exports, {
|
|
13
|
+
useColorMapping: function() {
|
|
14
|
+
return useColorMapping;
|
|
15
|
+
},
|
|
16
|
+
useIsDarkTheme: function() {
|
|
17
|
+
return useIsDarkTheme;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
|
21
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
22
|
+
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
|
|
23
|
+
const _tokens = require("@fluentui/tokens");
|
|
24
|
+
const _d3color = require("d3-color");
|
|
25
|
+
function useIsDarkTheme() {
|
|
26
|
+
const parentV9Theme = _react.useContext(_reactsharedcontexts.ThemeContext_unstable);
|
|
27
|
+
const v9Theme = parentV9Theme ? parentV9Theme : _tokens.webLightTheme;
|
|
28
|
+
const backgroundColor = (0, _d3color.hsl)(v9Theme.colorNeutralBackground1);
|
|
29
|
+
const foregroundColor = (0, _d3color.hsl)(v9Theme.colorNeutralForeground1);
|
|
30
|
+
const isDarkTheme = backgroundColor.l < foregroundColor.l;
|
|
31
|
+
return isDarkTheme;
|
|
32
|
+
}
|
|
33
|
+
function useColorMapping() {
|
|
34
|
+
return _react.useRef(new Map());
|
|
35
|
+
}
|
|
@@ -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;;;;;;;;;;;;IAyBgBgB,eAAAA;;;kBAfAV;;;;;iEARO,QAAQ;qCACyB,kCAAkC;wBACrD,mBAAmB;yBAC3B,WAAW;AAKjC,SAASA;IACd,MAAMC,gBAAgBP,OAAMQ,UAAU,CAACN,0CAAAA;IACvC,MAAMO,UAAiBF,gBAAgBA,gBAAgBJ,qBAAAA;IAEvD,MAAMO,sBAAkBL,YAAAA,EAAMI,QAAQE,uBAAuB;IAC7D,MAAMC,sBAAkBP,YAAAA,EAAMI,QAAQI,uBAAuB;IAE7D,MAAMC,cAAcJ,gBAAgBK,CAAC,GAAGH,gBAAgBG,CAAC;IAEzD,OAAOD;AACT;AAKO;IACL,OAAOd,OAAMiB,MAAM,CAAsB,IAAIC;AAC/C"}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
getSequentialSchemeColors: function() {
|
|
13
|
+
return getSequentialSchemeColors;
|
|
14
|
+
},
|
|
15
|
+
getVegaColor: function() {
|
|
16
|
+
return getVegaColor;
|
|
17
|
+
},
|
|
18
|
+
getVegaColorFromMap: function() {
|
|
19
|
+
return getVegaColorFromMap;
|
|
20
|
+
},
|
|
21
|
+
isStandardVegaScheme: function() {
|
|
22
|
+
return isStandardVegaScheme;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const _colors = require("../../utilities/colors");
|
|
26
|
+
const _utilities = require("../../utilities/utilities");
|
|
27
|
+
/**
|
|
28
|
+
* Vega-Lite Color Scheme to Fluent DataViz Palette Adapter
|
|
29
|
+
*
|
|
30
|
+
* Maps standard Vega-Lite color schemes to Fluent UI DataViz colors
|
|
31
|
+
* Similar to PlotlyColorAdapter but for Vega-Lite specifications
|
|
32
|
+
*/ // Vega's category10 scheme (D3 Category10)
|
|
33
|
+
// https://vega.github.io/vega/docs/schemes/#categorical
|
|
34
|
+
const VEGA_CATEGORY10 = [
|
|
35
|
+
'#1f77b4',
|
|
36
|
+
'#ff7f0e',
|
|
37
|
+
'#2ca02c',
|
|
38
|
+
'#d62728',
|
|
39
|
+
'#9467bd',
|
|
40
|
+
'#8c564b',
|
|
41
|
+
'#e377c2',
|
|
42
|
+
'#7f7f7f',
|
|
43
|
+
'#bcbd22',
|
|
44
|
+
'#17becf'
|
|
45
|
+
];
|
|
46
|
+
// Vega's category20 scheme
|
|
47
|
+
const VEGA_CATEGORY20 = [
|
|
48
|
+
'#1f77b4',
|
|
49
|
+
'#aec7e8',
|
|
50
|
+
'#ff7f0e',
|
|
51
|
+
'#ffbb78',
|
|
52
|
+
'#2ca02c',
|
|
53
|
+
'#98df8a',
|
|
54
|
+
'#d62728',
|
|
55
|
+
'#ff9896',
|
|
56
|
+
'#9467bd',
|
|
57
|
+
'#c5b0d5',
|
|
58
|
+
'#8c564b',
|
|
59
|
+
'#c49c94',
|
|
60
|
+
'#e377c2',
|
|
61
|
+
'#f7b6d2',
|
|
62
|
+
'#7f7f7f',
|
|
63
|
+
'#c7c7c7',
|
|
64
|
+
'#bcbd22',
|
|
65
|
+
'#dbdb8d',
|
|
66
|
+
'#17becf',
|
|
67
|
+
'#9edae5'
|
|
68
|
+
];
|
|
69
|
+
// Tableau10 scheme (commonly used in Vega-Lite)
|
|
70
|
+
const VEGA_TABLEAU10 = [
|
|
71
|
+
'#4e79a7',
|
|
72
|
+
'#f28e2c',
|
|
73
|
+
'#e15759',
|
|
74
|
+
'#76b7b2',
|
|
75
|
+
'#59a14f',
|
|
76
|
+
'#edc949',
|
|
77
|
+
'#af7aa1',
|
|
78
|
+
'#ff9da7',
|
|
79
|
+
'#9c755f',
|
|
80
|
+
'#bab0ab'
|
|
81
|
+
];
|
|
82
|
+
// Tableau20 scheme
|
|
83
|
+
const VEGA_TABLEAU20 = [
|
|
84
|
+
'#4e79a7',
|
|
85
|
+
'#a0cbe8',
|
|
86
|
+
'#f28e2c',
|
|
87
|
+
'#ffbe7d',
|
|
88
|
+
'#59a14f',
|
|
89
|
+
'#8cd17d',
|
|
90
|
+
'#b6992d',
|
|
91
|
+
'#f1ce63',
|
|
92
|
+
'#499894',
|
|
93
|
+
'#86bcb6',
|
|
94
|
+
'#e15759',
|
|
95
|
+
'#ff9d9a',
|
|
96
|
+
'#79706e',
|
|
97
|
+
'#bab0ab',
|
|
98
|
+
'#d37295',
|
|
99
|
+
'#fabfd2',
|
|
100
|
+
'#b07aa1',
|
|
101
|
+
'#d4a6c8',
|
|
102
|
+
'#9d7660',
|
|
103
|
+
'#d7b5a6'
|
|
104
|
+
];
|
|
105
|
+
// Mapping from Vega category10 to Fluent DataViz tokens
|
|
106
|
+
const CATEGORY10_FLUENT_MAPPING = [
|
|
107
|
+
_colors.DataVizPalette.color26,
|
|
108
|
+
_colors.DataVizPalette.warning,
|
|
109
|
+
_colors.DataVizPalette.color5,
|
|
110
|
+
_colors.DataVizPalette.error,
|
|
111
|
+
_colors.DataVizPalette.color4,
|
|
112
|
+
_colors.DataVizPalette.color17,
|
|
113
|
+
_colors.DataVizPalette.color22,
|
|
114
|
+
_colors.DataVizPalette.disabled,
|
|
115
|
+
_colors.DataVizPalette.color10,
|
|
116
|
+
_colors.DataVizPalette.color3
|
|
117
|
+
];
|
|
118
|
+
// Mapping from Vega category20 to Fluent DataViz tokens
|
|
119
|
+
const CATEGORY20_FLUENT_MAPPING = [
|
|
120
|
+
_colors.DataVizPalette.color26,
|
|
121
|
+
_colors.DataVizPalette.color36,
|
|
122
|
+
_colors.DataVizPalette.warning,
|
|
123
|
+
_colors.DataVizPalette.color27,
|
|
124
|
+
_colors.DataVizPalette.color5,
|
|
125
|
+
_colors.DataVizPalette.color15,
|
|
126
|
+
_colors.DataVizPalette.error,
|
|
127
|
+
_colors.DataVizPalette.color32,
|
|
128
|
+
_colors.DataVizPalette.color4,
|
|
129
|
+
_colors.DataVizPalette.color24,
|
|
130
|
+
_colors.DataVizPalette.color17,
|
|
131
|
+
_colors.DataVizPalette.color37,
|
|
132
|
+
_colors.DataVizPalette.color22,
|
|
133
|
+
_colors.DataVizPalette.color12,
|
|
134
|
+
_colors.DataVizPalette.disabled,
|
|
135
|
+
_colors.DataVizPalette.color31,
|
|
136
|
+
_colors.DataVizPalette.color10,
|
|
137
|
+
_colors.DataVizPalette.color30,
|
|
138
|
+
_colors.DataVizPalette.color3,
|
|
139
|
+
_colors.DataVizPalette.color13
|
|
140
|
+
];
|
|
141
|
+
// Mapping from Tableau10 to Fluent DataViz tokens
|
|
142
|
+
const TABLEAU10_FLUENT_MAPPING = [
|
|
143
|
+
_colors.DataVizPalette.color1,
|
|
144
|
+
_colors.DataVizPalette.color7,
|
|
145
|
+
_colors.DataVizPalette.error,
|
|
146
|
+
_colors.DataVizPalette.color3,
|
|
147
|
+
_colors.DataVizPalette.color5,
|
|
148
|
+
_colors.DataVizPalette.color10,
|
|
149
|
+
_colors.DataVizPalette.color4,
|
|
150
|
+
_colors.DataVizPalette.color2,
|
|
151
|
+
_colors.DataVizPalette.color17,
|
|
152
|
+
_colors.DataVizPalette.disabled
|
|
153
|
+
];
|
|
154
|
+
// Mapping from Tableau20 to Fluent DataViz tokens
|
|
155
|
+
const TABLEAU20_FLUENT_MAPPING = [
|
|
156
|
+
_colors.DataVizPalette.color1,
|
|
157
|
+
_colors.DataVizPalette.color11,
|
|
158
|
+
_colors.DataVizPalette.color7,
|
|
159
|
+
_colors.DataVizPalette.color27,
|
|
160
|
+
_colors.DataVizPalette.color5,
|
|
161
|
+
_colors.DataVizPalette.color15,
|
|
162
|
+
_colors.DataVizPalette.color10,
|
|
163
|
+
_colors.DataVizPalette.color30,
|
|
164
|
+
_colors.DataVizPalette.color3,
|
|
165
|
+
_colors.DataVizPalette.color13,
|
|
166
|
+
_colors.DataVizPalette.error,
|
|
167
|
+
_colors.DataVizPalette.color32,
|
|
168
|
+
_colors.DataVizPalette.disabled,
|
|
169
|
+
_colors.DataVizPalette.color31,
|
|
170
|
+
_colors.DataVizPalette.color2,
|
|
171
|
+
_colors.DataVizPalette.color12,
|
|
172
|
+
_colors.DataVizPalette.color4,
|
|
173
|
+
_colors.DataVizPalette.color24,
|
|
174
|
+
_colors.DataVizPalette.color17,
|
|
175
|
+
_colors.DataVizPalette.color37
|
|
176
|
+
];
|
|
177
|
+
/**
|
|
178
|
+
* Gets the Fluent color mapping for a given Vega-Lite color scheme
|
|
179
|
+
*/ function getSchemeMapping(scheme) {
|
|
180
|
+
if (!scheme) {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
const schemeLower = scheme.toLowerCase();
|
|
184
|
+
switch(schemeLower){
|
|
185
|
+
case 'category10':
|
|
186
|
+
return CATEGORY10_FLUENT_MAPPING;
|
|
187
|
+
case 'category20':
|
|
188
|
+
case 'category20b':
|
|
189
|
+
case 'category20c':
|
|
190
|
+
return CATEGORY20_FLUENT_MAPPING;
|
|
191
|
+
case 'tableau10':
|
|
192
|
+
return TABLEAU10_FLUENT_MAPPING;
|
|
193
|
+
case 'tableau20':
|
|
194
|
+
return TABLEAU20_FLUENT_MAPPING;
|
|
195
|
+
// For unsupported schemes, fall back to default Fluent palette
|
|
196
|
+
case 'accent':
|
|
197
|
+
case 'dark2':
|
|
198
|
+
case 'paired':
|
|
199
|
+
case 'pastel1':
|
|
200
|
+
case 'pastel2':
|
|
201
|
+
case 'set1':
|
|
202
|
+
case 'set2':
|
|
203
|
+
case 'set3':
|
|
204
|
+
// Color schemes not yet mapped to Fluent colors. Using default palette.
|
|
205
|
+
return undefined;
|
|
206
|
+
default:
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function getVegaColor(index, scheme, range, isDarkTheme = false) {
|
|
211
|
+
// Priority 1: Custom range (highest priority)
|
|
212
|
+
if (range && range.length > 0) {
|
|
213
|
+
return range[index % range.length];
|
|
214
|
+
}
|
|
215
|
+
// Priority 2: Named color scheme mapped to Fluent
|
|
216
|
+
const schemeMapping = getSchemeMapping(scheme);
|
|
217
|
+
if (schemeMapping) {
|
|
218
|
+
const token = schemeMapping[index % schemeMapping.length];
|
|
219
|
+
return (0, _colors.getColorFromToken)(token, isDarkTheme);
|
|
220
|
+
}
|
|
221
|
+
// Priority 3: Default Fluent qualitative palette
|
|
222
|
+
return (0, _colors.getNextColor)(index, 0, isDarkTheme);
|
|
223
|
+
}
|
|
224
|
+
function getVegaColorFromMap(legendLabel, colorMap, scheme, range, isDarkTheme = false) {
|
|
225
|
+
var _colorMap_current, _colorMap_current1, _colorMap_current2;
|
|
226
|
+
// Check if color is already assigned
|
|
227
|
+
if ((_colorMap_current = colorMap.current) === null || _colorMap_current === void 0 ? void 0 : _colorMap_current.has(legendLabel)) {
|
|
228
|
+
return colorMap.current.get(legendLabel);
|
|
229
|
+
}
|
|
230
|
+
var _colorMap_current_size;
|
|
231
|
+
// Assign new color based on current map size
|
|
232
|
+
const index = (_colorMap_current_size = (_colorMap_current1 = colorMap.current) === null || _colorMap_current1 === void 0 ? void 0 : _colorMap_current1.size) !== null && _colorMap_current_size !== void 0 ? _colorMap_current_size : 0;
|
|
233
|
+
const color = getVegaColor(index, scheme, range, isDarkTheme);
|
|
234
|
+
(_colorMap_current2 = colorMap.current) === null || _colorMap_current2 === void 0 ? void 0 : _colorMap_current2.set(legendLabel, color);
|
|
235
|
+
return color;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Sequential and diverging color scheme ramps for heatmaps and continuous color scales.
|
|
239
|
+
* Each ramp is a 5-point gradient matching D3/Vega defaults.
|
|
240
|
+
*/ const SEQUENTIAL_SCHEMES = {
|
|
241
|
+
blues: [
|
|
242
|
+
'#deebf7',
|
|
243
|
+
'#9ecae1',
|
|
244
|
+
'#4292c6',
|
|
245
|
+
'#2171b5',
|
|
246
|
+
'#084594'
|
|
247
|
+
],
|
|
248
|
+
greens: [
|
|
249
|
+
'#e5f5e0',
|
|
250
|
+
'#a1d99b',
|
|
251
|
+
'#41ab5d',
|
|
252
|
+
'#238b45',
|
|
253
|
+
'#005a32'
|
|
254
|
+
],
|
|
255
|
+
reds: [
|
|
256
|
+
'#fee0d2',
|
|
257
|
+
'#fc9272',
|
|
258
|
+
'#ef3b2c',
|
|
259
|
+
'#cb181d',
|
|
260
|
+
'#99000d'
|
|
261
|
+
],
|
|
262
|
+
oranges: [
|
|
263
|
+
'#feedde',
|
|
264
|
+
'#fdbe85',
|
|
265
|
+
'#fd8d3c',
|
|
266
|
+
'#e6550d',
|
|
267
|
+
'#a63603'
|
|
268
|
+
],
|
|
269
|
+
purples: [
|
|
270
|
+
'#efedf5',
|
|
271
|
+
'#bcbddc',
|
|
272
|
+
'#807dba',
|
|
273
|
+
'#6a51a3',
|
|
274
|
+
'#4a1486'
|
|
275
|
+
],
|
|
276
|
+
greys: [
|
|
277
|
+
'#f0f0f0',
|
|
278
|
+
'#bdbdbd',
|
|
279
|
+
'#969696',
|
|
280
|
+
'#636363',
|
|
281
|
+
'#252525'
|
|
282
|
+
],
|
|
283
|
+
viridis: [
|
|
284
|
+
'#440154',
|
|
285
|
+
'#3b528b',
|
|
286
|
+
'#21918c',
|
|
287
|
+
'#5ec962',
|
|
288
|
+
'#fde725'
|
|
289
|
+
],
|
|
290
|
+
inferno: [
|
|
291
|
+
'#000004',
|
|
292
|
+
'#57106e',
|
|
293
|
+
'#bc3754',
|
|
294
|
+
'#f98c0a',
|
|
295
|
+
'#fcffa4'
|
|
296
|
+
],
|
|
297
|
+
magma: [
|
|
298
|
+
'#000004',
|
|
299
|
+
'#51127c',
|
|
300
|
+
'#b73779',
|
|
301
|
+
'#fc8961',
|
|
302
|
+
'#fcfdbf'
|
|
303
|
+
],
|
|
304
|
+
plasma: [
|
|
305
|
+
'#0d0887',
|
|
306
|
+
'#7e03a8',
|
|
307
|
+
'#cc4778',
|
|
308
|
+
'#f89540',
|
|
309
|
+
'#f0f921'
|
|
310
|
+
],
|
|
311
|
+
greenblue: [
|
|
312
|
+
'#e0f3db',
|
|
313
|
+
'#a8ddb5',
|
|
314
|
+
'#4eb3d3',
|
|
315
|
+
'#2b8cbe',
|
|
316
|
+
'#08589e'
|
|
317
|
+
],
|
|
318
|
+
yellowgreen: [
|
|
319
|
+
'#ffffcc',
|
|
320
|
+
'#c2e699',
|
|
321
|
+
'#78c679',
|
|
322
|
+
'#31a354',
|
|
323
|
+
'#006837'
|
|
324
|
+
],
|
|
325
|
+
yellowgreenblue: [
|
|
326
|
+
'#ffffcc',
|
|
327
|
+
'#a1dab4',
|
|
328
|
+
'#41b6c4',
|
|
329
|
+
'#2c7fb8',
|
|
330
|
+
'#253494'
|
|
331
|
+
],
|
|
332
|
+
redyellowgreen: [
|
|
333
|
+
'#d73027',
|
|
334
|
+
'#fc8d59',
|
|
335
|
+
'#fee08b',
|
|
336
|
+
'#91cf60',
|
|
337
|
+
'#1a9850'
|
|
338
|
+
],
|
|
339
|
+
blueorange: [
|
|
340
|
+
'#2166ac',
|
|
341
|
+
'#67a9cf',
|
|
342
|
+
'#f7f7f7',
|
|
343
|
+
'#f4a582',
|
|
344
|
+
'#b2182b'
|
|
345
|
+
],
|
|
346
|
+
redblue: [
|
|
347
|
+
'#ca0020',
|
|
348
|
+
'#f4a582',
|
|
349
|
+
'#f7f7f7',
|
|
350
|
+
'#92c5de',
|
|
351
|
+
'#0571b0'
|
|
352
|
+
]
|
|
353
|
+
};
|
|
354
|
+
function getSequentialSchemeColors(scheme, steps = 5) {
|
|
355
|
+
const ramp = SEQUENTIAL_SCHEMES[scheme.toLowerCase()];
|
|
356
|
+
if (!ramp) {
|
|
357
|
+
return undefined;
|
|
358
|
+
}
|
|
359
|
+
if (steps === ramp.length) {
|
|
360
|
+
return [
|
|
361
|
+
...ramp
|
|
362
|
+
];
|
|
363
|
+
}
|
|
364
|
+
// Interpolate to requested number of steps
|
|
365
|
+
const result = [];
|
|
366
|
+
for(let i = 0; i < steps; i++){
|
|
367
|
+
const t = steps === 1 ? 0.5 : i / (steps - 1);
|
|
368
|
+
const pos = t * (ramp.length - 1);
|
|
369
|
+
const lo = Math.floor(pos);
|
|
370
|
+
const hi = Math.min(lo + 1, ramp.length - 1);
|
|
371
|
+
const frac = pos - lo;
|
|
372
|
+
if (frac === 0) {
|
|
373
|
+
result.push(ramp[lo]);
|
|
374
|
+
} else {
|
|
375
|
+
result.push(interpolateHexColor(ramp[lo], ramp[hi], frac));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return result;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Linearly interpolates between two hex colors
|
|
382
|
+
*/ function interpolateHexColor(c1, c2, t) {
|
|
383
|
+
const r1 = parseInt(c1.slice(1, 3), 16);
|
|
384
|
+
const g1 = parseInt(c1.slice(3, 5), 16);
|
|
385
|
+
const b1 = parseInt(c1.slice(5, 7), 16);
|
|
386
|
+
const r2 = parseInt(c2.slice(1, 3), 16);
|
|
387
|
+
const g2 = parseInt(c2.slice(3, 5), 16);
|
|
388
|
+
const b2 = parseInt(c2.slice(5, 7), 16);
|
|
389
|
+
const r = Math.round(r1 + (r2 - r1) * t);
|
|
390
|
+
const g = Math.round(g1 + (g2 - g1) * t);
|
|
391
|
+
const b = Math.round(b1 + (b2 - b1) * t);
|
|
392
|
+
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
393
|
+
}
|
|
394
|
+
function isStandardVegaScheme(range) {
|
|
395
|
+
if (!range || range.length === 0) {
|
|
396
|
+
return undefined;
|
|
397
|
+
}
|
|
398
|
+
const rangeLower = range.map((c)=>c.toLowerCase());
|
|
399
|
+
if ((0, _utilities.areArraysEqual)(rangeLower, VEGA_CATEGORY10)) {
|
|
400
|
+
return 'category10';
|
|
401
|
+
}
|
|
402
|
+
if ((0, _utilities.areArraysEqual)(rangeLower, VEGA_CATEGORY20)) {
|
|
403
|
+
return 'category20';
|
|
404
|
+
}
|
|
405
|
+
if ((0, _utilities.areArraysEqual)(rangeLower, VEGA_TABLEAU10)) {
|
|
406
|
+
return 'tableau10';
|
|
407
|
+
}
|
|
408
|
+
if ((0, _utilities.areArraysEqual)(rangeLower, VEGA_TABLEAU20)) {
|
|
409
|
+
return 'tableau20';
|
|
410
|
+
}
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/VegaDeclarativeChart/VegaLiteColorAdapter.ts"],"sourcesContent":["import { DataVizPalette, getColorFromToken, getNextColor } from '../../utilities/colors';\nimport { areArraysEqual } from '../../utilities/utilities';\n\n/**\n * A ref-like object holding a mutable Map of legend-label to color.\n * Structurally compatible with React.RefObject<Map<string, string>>.\n */\nexport type ColorMapRef = { readonly current: Map<string, string> | null };\n\n/**\n * Vega-Lite Color Scheme to Fluent DataViz Palette Adapter\n *\n * Maps standard Vega-Lite color schemes to Fluent UI DataViz colors\n * Similar to PlotlyColorAdapter but for Vega-Lite specifications\n */\n\n// Vega's category10 scheme (D3 Category10)\n// https://vega.github.io/vega/docs/schemes/#categorical\nconst VEGA_CATEGORY10 = [\n '#1f77b4', // blue\n '#ff7f0e', // orange\n '#2ca02c', // green\n '#d62728', // red\n '#9467bd', // purple\n '#8c564b', // brown\n '#e377c2', // pink\n '#7f7f7f', // gray\n '#bcbd22', // olive\n '#17becf', // cyan\n];\n\n// Vega's category20 scheme\nconst VEGA_CATEGORY20 = [\n '#1f77b4',\n '#aec7e8', // blue shades\n '#ff7f0e',\n '#ffbb78', // orange shades\n '#2ca02c',\n '#98df8a', // green shades\n '#d62728',\n '#ff9896', // red shades\n '#9467bd',\n '#c5b0d5', // purple shades\n '#8c564b',\n '#c49c94', // brown shades\n '#e377c2',\n '#f7b6d2', // pink shades\n '#7f7f7f',\n '#c7c7c7', // gray shades\n '#bcbd22',\n '#dbdb8d', // olive shades\n '#17becf',\n '#9edae5', // cyan shades\n];\n\n// Tableau10 scheme (commonly used in Vega-Lite)\nconst VEGA_TABLEAU10 = [\n '#4e79a7', // blue\n '#f28e2c', // orange\n '#e15759', // red\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc949', // yellow\n '#af7aa1', // purple\n '#ff9da7', // pink\n '#9c755f', // brown\n '#bab0ab', // gray\n];\n\n// Tableau20 scheme\nconst VEGA_TABLEAU20 = [\n '#4e79a7',\n '#a0cbe8', // blue shades\n '#f28e2c',\n '#ffbe7d', // orange shades\n '#59a14f',\n '#8cd17d', // green shades\n '#b6992d',\n '#f1ce63', // yellow shades\n '#499894',\n '#86bcb6', // teal shades\n '#e15759',\n '#ff9d9a', // red shades\n '#79706e',\n '#bab0ab', // gray shades\n '#d37295',\n '#fabfd2', // pink shades\n '#b07aa1',\n '#d4a6c8', // purple shades\n '#9d7660',\n '#d7b5a6', // brown shades\n];\n\n// Mapping from Vega category10 to Fluent DataViz tokens\nconst CATEGORY10_FLUENT_MAPPING: string[] = [\n DataVizPalette.color26, // blue -> lightBlue.shade10\n DataVizPalette.warning, // orange -> semantic warning\n DataVizPalette.color5, // green -> lightGreen.primary\n DataVizPalette.error, // red -> semantic error\n DataVizPalette.color4, // purple -> orchid.tint10\n DataVizPalette.color17, // brown -> pumpkin.shade20\n DataVizPalette.color22, // pink -> hotPink.tint20\n DataVizPalette.disabled, // gray -> semantic disabled\n DataVizPalette.color10, // olive/yellow-green -> gold.shade10\n DataVizPalette.color3, // cyan/teal -> teal.tint20\n];\n\n// Mapping from Vega category20 to Fluent DataViz tokens\nconst CATEGORY20_FLUENT_MAPPING: string[] = [\n DataVizPalette.color26,\n DataVizPalette.color36, // blue shades\n DataVizPalette.warning,\n DataVizPalette.color27, // orange shades\n DataVizPalette.color5,\n DataVizPalette.color15, // green shades\n DataVizPalette.error,\n DataVizPalette.color32, // red shades\n DataVizPalette.color4,\n DataVizPalette.color24, // purple shades\n DataVizPalette.color17,\n DataVizPalette.color37, // brown shades\n DataVizPalette.color22,\n DataVizPalette.color12, // pink shades\n DataVizPalette.disabled,\n DataVizPalette.color31, // gray shades\n DataVizPalette.color10,\n DataVizPalette.color30, // olive shades\n DataVizPalette.color3,\n DataVizPalette.color13, // cyan shades\n];\n\n// Mapping from Tableau10 to Fluent DataViz tokens\nconst TABLEAU10_FLUENT_MAPPING: string[] = [\n DataVizPalette.color1, // blue -> cornflower.tint10\n DataVizPalette.color7, // orange -> pumpkin.primary\n DataVizPalette.error, // red -> semantic error\n DataVizPalette.color3, // teal -> teal.tint20\n DataVizPalette.color5, // green -> lightGreen.primary\n DataVizPalette.color10, // yellow -> gold.shade10\n DataVizPalette.color4, // purple -> orchid.tint10\n DataVizPalette.color2, // pink -> hotPink.primary\n DataVizPalette.color17, // brown -> pumpkin.shade20\n DataVizPalette.disabled, // gray -> semantic disabled\n];\n\n// Mapping from Tableau20 to Fluent DataViz tokens\nconst TABLEAU20_FLUENT_MAPPING: string[] = [\n DataVizPalette.color1,\n DataVizPalette.color11, // blue shades\n DataVizPalette.color7,\n DataVizPalette.color27, // orange shades\n DataVizPalette.color5,\n DataVizPalette.color15, // green shades\n DataVizPalette.color10,\n DataVizPalette.color30, // yellow shades\n DataVizPalette.color3,\n DataVizPalette.color13, // teal shades\n DataVizPalette.error,\n DataVizPalette.color32, // red shades\n DataVizPalette.disabled,\n DataVizPalette.color31, // gray shades\n DataVizPalette.color2,\n DataVizPalette.color12, // pink shades\n DataVizPalette.color4,\n DataVizPalette.color24, // purple shades\n DataVizPalette.color17,\n DataVizPalette.color37, // brown shades\n];\n\n/**\n * Supported Vega-Lite color scheme names\n */\nexport type VegaColorScheme =\n | 'category10'\n | 'category20'\n | 'category20b'\n | 'category20c'\n | 'tableau10'\n | 'tableau20'\n | 'accent'\n | 'dark2'\n | 'paired'\n | 'pastel1'\n | 'pastel2'\n | 'set1'\n | 'set2'\n | 'set3';\n\n/**\n * Gets the Fluent color mapping for a given Vega-Lite color scheme\n */\nfunction getSchemeMapping(scheme: string | undefined): string[] | undefined {\n if (!scheme) {\n return undefined;\n }\n\n const schemeLower = scheme.toLowerCase();\n\n switch (schemeLower) {\n case 'category10':\n return CATEGORY10_FLUENT_MAPPING;\n case 'category20':\n case 'category20b':\n case 'category20c':\n return CATEGORY20_FLUENT_MAPPING;\n case 'tableau10':\n return TABLEAU10_FLUENT_MAPPING;\n case 'tableau20':\n return TABLEAU20_FLUENT_MAPPING;\n // For unsupported schemes, fall back to default Fluent palette\n case 'accent':\n case 'dark2':\n case 'paired':\n case 'pastel1':\n case 'pastel2':\n case 'set1':\n case 'set2':\n case 'set3':\n // Color schemes not yet mapped to Fluent colors. Using default palette.\n return undefined;\n default:\n return undefined;\n }\n}\n\n/**\n * Gets a color for a series based on Vega-Lite color encoding\n *\n * @param index - Series index\n * @param scheme - Vega-Lite color scheme name (e.g., 'category10', 'tableau10')\n * @param range - Custom color range array\n * @param isDarkTheme - Whether dark theme is active\n * @returns Color string (hex)\n */\nexport function getVegaColor(\n index: number,\n scheme: string | undefined,\n range: string[] | undefined,\n isDarkTheme: boolean = false,\n): string {\n // Priority 1: Custom range (highest priority)\n if (range && range.length > 0) {\n return range[index % range.length];\n }\n\n // Priority 2: Named color scheme mapped to Fluent\n const schemeMapping = getSchemeMapping(scheme);\n if (schemeMapping) {\n const token = schemeMapping[index % schemeMapping.length];\n return getColorFromToken(token, isDarkTheme);\n }\n\n // Priority 3: Default Fluent qualitative palette\n return getNextColor(index, 0, isDarkTheme);\n}\n\n/**\n * Gets a color from the color map or creates a new one based on Vega-Lite encoding\n *\n * @param legendLabel - Legend label for the series\n * @param colorMap - Color mapping ref for consistent coloring across charts\n * @param scheme - Vega-Lite color scheme name\n * @param range - Custom color range array\n * @param isDarkTheme - Whether dark theme is active\n * @returns Color string (hex)\n */\nexport function getVegaColorFromMap(\n legendLabel: string,\n colorMap: ColorMapRef,\n scheme: string | undefined,\n range: string[] | undefined,\n isDarkTheme: boolean = false,\n): string {\n // Check if color is already assigned\n if (colorMap.current?.has(legendLabel)) {\n return colorMap.current.get(legendLabel)!;\n }\n\n // Assign new color based on current map size\n const index = colorMap.current?.size ?? 0;\n const color = getVegaColor(index, scheme, range, isDarkTheme);\n\n colorMap.current?.set(legendLabel, color);\n return color;\n}\n\n/**\n * Sequential and diverging color scheme ramps for heatmaps and continuous color scales.\n * Each ramp is a 5-point gradient matching D3/Vega defaults.\n */\nconst SEQUENTIAL_SCHEMES: Record<string, string[]> = {\n blues: ['#deebf7', '#9ecae1', '#4292c6', '#2171b5', '#084594'],\n greens: ['#e5f5e0', '#a1d99b', '#41ab5d', '#238b45', '#005a32'],\n reds: ['#fee0d2', '#fc9272', '#ef3b2c', '#cb181d', '#99000d'],\n oranges: ['#feedde', '#fdbe85', '#fd8d3c', '#e6550d', '#a63603'],\n purples: ['#efedf5', '#bcbddc', '#807dba', '#6a51a3', '#4a1486'],\n greys: ['#f0f0f0', '#bdbdbd', '#969696', '#636363', '#252525'],\n viridis: ['#440154', '#3b528b', '#21918c', '#5ec962', '#fde725'],\n inferno: ['#000004', '#57106e', '#bc3754', '#f98c0a', '#fcffa4'],\n magma: ['#000004', '#51127c', '#b73779', '#fc8961', '#fcfdbf'],\n plasma: ['#0d0887', '#7e03a8', '#cc4778', '#f89540', '#f0f921'],\n greenblue: ['#e0f3db', '#a8ddb5', '#4eb3d3', '#2b8cbe', '#08589e'],\n yellowgreen: ['#ffffcc', '#c2e699', '#78c679', '#31a354', '#006837'],\n yellowgreenblue: ['#ffffcc', '#a1dab4', '#41b6c4', '#2c7fb8', '#253494'],\n redyellowgreen: ['#d73027', '#fc8d59', '#fee08b', '#91cf60', '#1a9850'],\n blueorange: ['#2166ac', '#67a9cf', '#f7f7f7', '#f4a582', '#b2182b'],\n redblue: ['#ca0020', '#f4a582', '#f7f7f7', '#92c5de', '#0571b0'],\n};\n\n/**\n * Gets a sequential or diverging color ramp for heatmap rendering.\n * Returns an array of `steps` interpolated colors for the given scheme name.\n *\n * @param scheme - Vega-Lite scheme name (e.g., 'blues', 'viridis', 'redyellowgreen')\n * @param steps - Number of color stops (default: 5)\n * @returns Array of hex/rgb color strings, or undefined if scheme is not recognized\n */\nexport function getSequentialSchemeColors(scheme: string, steps: number = 5): string[] | undefined {\n const ramp = SEQUENTIAL_SCHEMES[scheme.toLowerCase()];\n if (!ramp) {\n return undefined;\n }\n\n if (steps === ramp.length) {\n return [...ramp];\n }\n\n // Interpolate to requested number of steps\n const result: string[] = [];\n for (let i = 0; i < steps; i++) {\n const t = steps === 1 ? 0.5 : i / (steps - 1);\n const pos = t * (ramp.length - 1);\n const lo = Math.floor(pos);\n const hi = Math.min(lo + 1, ramp.length - 1);\n const frac = pos - lo;\n\n if (frac === 0) {\n result.push(ramp[lo]);\n } else {\n result.push(interpolateHexColor(ramp[lo], ramp[hi], frac));\n }\n }\n return result;\n}\n\n/**\n * Linearly interpolates between two hex colors\n */\nfunction interpolateHexColor(c1: string, c2: string, t: number): string {\n const r1 = parseInt(c1.slice(1, 3), 16);\n const g1 = parseInt(c1.slice(3, 5), 16);\n const b1 = parseInt(c1.slice(5, 7), 16);\n const r2 = parseInt(c2.slice(1, 3), 16);\n const g2 = parseInt(c2.slice(3, 5), 16);\n const b2 = parseInt(c2.slice(5, 7), 16);\n\n const r = Math.round(r1 + (r2 - r1) * t);\n const g = Math.round(g1 + (g2 - g1) * t);\n const b = Math.round(b1 + (b2 - b1) * t);\n\n return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;\n}\n\n/**\n * Checks if the provided range matches a standard Vega scheme\n * Useful for optimizing color assignment\n */\nexport function isStandardVegaScheme(range: string[] | undefined): VegaColorScheme | undefined {\n if (!range || range.length === 0) {\n return undefined;\n }\n\n const rangeLower = range.map(c => c.toLowerCase());\n\n if (areArraysEqual(rangeLower, VEGA_CATEGORY10)) {\n return 'category10';\n }\n if (areArraysEqual(rangeLower, VEGA_CATEGORY20)) {\n return 'category20';\n }\n if (areArraysEqual(rangeLower, VEGA_TABLEAU10)) {\n return 'tableau10';\n }\n if (areArraysEqual(rangeLower, VEGA_TABLEAU20)) {\n return 'tableau20';\n }\n\n return undefined;\n}\n"],"names":["DataVizPalette","getColorFromToken","getNextColor","areArraysEqual","VEGA_CATEGORY10","VEGA_CATEGORY20","VEGA_TABLEAU10","VEGA_TABLEAU20","CATEGORY10_FLUENT_MAPPING","color26","warning","color5","error","color4","color17","color22","disabled","color10","color3","CATEGORY20_FLUENT_MAPPING","color36","color27","color15","color32","color24","color37","color12","color31","color30","color13","TABLEAU10_FLUENT_MAPPING","color1","color7","color2","TABLEAU20_FLUENT_MAPPING","color11","getSchemeMapping","scheme","undefined","schemeLower","toLowerCase","getVegaColor","index","range","isDarkTheme","length","schemeMapping","token","getVegaColorFromMap","legendLabel","colorMap","current","has","get","size","color","set","SEQUENTIAL_SCHEMES","blues","greens","reds","oranges","purples","greys","viridis","inferno","magma","plasma","greenblue","yellowgreen","yellowgreenblue","redyellowgreen","blueorange","redblue","getSequentialSchemeColors","steps","ramp","result","i","t","pos","lo","Math","floor","hi","min","frac","push","interpolateHexColor","c1","c2","r1","parseInt","slice","g1","b1","r2","g2","b2","r","round","g","b","toString","padStart","isStandardVegaScheme","rangeLower","map","c"],"mappings":"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"}
|