@databricks/appkit-ui 0.41.4 → 0.41.6

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.
@@ -1,6 +1,6 @@
1
1
  import { normalizeChartData, normalizeHeatmapData } from "./normalize.js";
2
2
  import { buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption } from "./options.js";
3
- import { useThemeColors } from "./theme.js";
3
+ import { useChartUITokens, useThemeColors } from "./theme.js";
4
4
  import ReactECharts from "echarts-for-react";
5
5
  import { useCallback, useMemo, useRef } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
@@ -24,6 +24,7 @@ function getDefaultPalette(chartType) {
24
24
  function BaseChart({ data, chartType, xKey, yKey, orientation, height = 300, title, showLegend = true, colorPalette, colors: customColors, showSymbol = false, smooth = true, stacked = false, symbolSize = 8, showArea = true, innerRadius = 0, showLabels = true, labelPosition = "outside", yAxisKey, min, max, options: customOptions, className }) {
25
25
  const themeColors = useThemeColors(colorPalette ?? getDefaultPalette(chartType));
26
26
  const colors = customColors ?? themeColors;
27
+ const ui = useChartUITokens();
27
28
  const echartsInstanceRef = useRef(null);
28
29
  const chartRefCallback = useCallback((node) => {
29
30
  if (echartsInstanceRef.current && !echartsInstanceRef.current.isDisposed()) echartsInstanceRef.current.dispose();
@@ -52,7 +53,8 @@ function BaseChart({ data, chartType, xKey, yKey, orientation, height = 300, tit
52
53
  colors,
53
54
  title,
54
55
  showLegend,
55
- xField
56
+ xField,
57
+ ui
56
58
  };
57
59
  const isPie = chartType === "pie" || chartType === "donut";
58
60
  const isRadar = chartType === "radar";
@@ -88,6 +90,7 @@ function BaseChart({ data, chartType, xKey, yKey, orientation, height = 300, tit
88
90
  }, [
89
91
  normalized,
90
92
  colors,
93
+ ui,
91
94
  title,
92
95
  showLegend,
93
96
  chartType,
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","names":[],"sources":["../../../src/react/charts/base.tsx"],"sourcesContent":["import type { ECharts } from \"echarts\";\nimport ReactECharts from \"echarts-for-react\";\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { normalizeChartData, normalizeHeatmapData } from \"./normalize\";\nimport {\n buildCartesianOption,\n buildHeatmapOption,\n buildHorizontalBarOption,\n buildPieOption,\n buildRadarOption,\n type OptionBuilderContext,\n} from \"./options\";\nimport { useThemeColors } from \"./theme\";\nimport type {\n ChartColorPalette,\n ChartData,\n ChartType,\n Orientation,\n} from \"./types\";\n\n// ============================================================================\n// Palette Selection\n// ============================================================================\n\n/**\n * Determines the appropriate color palette for a chart type.\n * - Heatmaps use sequential (low → high intensity)\n * - All other charts use categorical (distinct categories)\n */\nfunction getDefaultPalette(chartType: ChartType): ChartColorPalette {\n switch (chartType) {\n case \"heatmap\":\n return \"sequential\";\n default:\n return \"categorical\";\n }\n}\n\n// ============================================================================\n// Component Props\n// ============================================================================\n\nexport interface BaseChartProps {\n /** Chart data (Arrow Table or JSON array) - format is auto-detected */\n data: ChartData;\n /** Chart type */\n chartType: ChartType;\n /** X-axis field key (auto-detected from schema if not provided) */\n xKey?: string;\n /** Y-axis field key(s) (auto-detected from schema if not provided) */\n yKey?: string | string[];\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Chart height in pixels @default 300 */\n height?: number;\n /** Chart title */\n title?: string;\n /** Show legend @default true */\n showLegend?: boolean;\n /**\n * Color palette to use. Auto-selected based on chart type if not specified.\n * - \"categorical\": Distinct colors for different categories (bar, pie, line)\n * - \"sequential\": Gradient for magnitude (heatmap)\n * - \"diverging\": Two-tone for positive/negative (correlation)\n */\n colorPalette?: ChartColorPalette;\n /** Custom colors (overrides colorPalette) */\n colors?: string[];\n /** Show data point symbols (line/area charts) @default false */\n showSymbol?: boolean;\n /** Smooth line curves (line/area charts) @default true */\n smooth?: boolean;\n /** Stack series @default false */\n stacked?: boolean;\n /** Symbol size for scatter charts @default 8 */\n symbolSize?: number;\n /** Show area fill for radar charts @default true */\n showArea?: boolean;\n /** Inner radius for pie/donut (0-100) @default 0 */\n innerRadius?: number;\n /** Show labels on pie/donut slices @default true */\n showLabels?: boolean;\n /** Label position for pie/donut @default \"outside\" */\n labelPosition?: \"outside\" | \"inside\" | \"center\";\n /** Y-axis field key for heatmap (the row dimension) */\n yAxisKey?: string;\n /** Min value for heatmap color scale */\n min?: number;\n /** Max value for heatmap color scale */\n max?: number;\n /** Additional ECharts options to merge */\n options?: Record<string, unknown>;\n /** Additional CSS classes */\n className?: string;\n}\n\n// ============================================================================\n// Base Chart Component\n// ============================================================================\n\n/**\n * Base chart component that handles both Arrow and JSON data.\n * Renders using ECharts for consistent output across both formats.\n */\nexport function BaseChart({\n data,\n chartType,\n xKey,\n yKey,\n orientation,\n height = 300,\n title,\n showLegend = true,\n colorPalette,\n colors: customColors,\n showSymbol = false,\n smooth = true,\n stacked = false,\n symbolSize = 8,\n showArea = true,\n innerRadius = 0,\n showLabels = true,\n labelPosition = \"outside\",\n yAxisKey,\n min,\n max,\n options: customOptions,\n className,\n}: BaseChartProps) {\n // Determine the appropriate color palette based on chart type\n const resolvedPalette = colorPalette ?? getDefaultPalette(chartType);\n const themeColors = useThemeColors(resolvedPalette);\n const colors = customColors ?? themeColors;\n\n // Store ECharts instance directly to avoid stale ref issues on unmount\n const echartsInstanceRef = useRef<ECharts | null>(null);\n\n // Callback ref pattern: captures the ECharts instance when ReactECharts mounts\n // This ensures we always have a stable reference to the actual instance\n const chartRefCallback = useCallback((node: ReactECharts | null) => {\n // Dispose previous instance if component is being replaced\n if (\n echartsInstanceRef.current &&\n !echartsInstanceRef.current.isDisposed()\n ) {\n echartsInstanceRef.current.dispose();\n }\n\n // Store the new instance\n if (node) {\n echartsInstanceRef.current = node.getEchartsInstance();\n } else {\n // Component unmounting - dispose the stored instance\n if (\n echartsInstanceRef.current &&\n !echartsInstanceRef.current.isDisposed()\n ) {\n echartsInstanceRef.current.dispose();\n }\n echartsInstanceRef.current = null;\n }\n }, []);\n\n // Memoize data normalization\n const normalized = useMemo(\n () =>\n chartType === \"heatmap\"\n ? normalizeHeatmapData(data, xKey, yAxisKey, yKey)\n : normalizeChartData(data, xKey, yKey, orientation),\n [data, xKey, yKey, yAxisKey, orientation, chartType],\n );\n\n // Memoize option building\n const option = useMemo(() => {\n const { xData, yFields, xField, chartType: detectedChartType } = normalized;\n\n if (xData.length === 0) return null;\n\n // Determine chart mode first (needed to handle yDataMap)\n const isHeatmap = chartType === \"heatmap\";\n\n // Heatmaps use heatmapData instead of yDataMap\n // For other charts, yDataMap is required\n const yDataMap = \"yDataMap\" in normalized ? normalized.yDataMap : {};\n\n const baseCtx: OptionBuilderContext = {\n xData,\n yDataMap,\n yFields,\n colors,\n title,\n showLegend,\n xField,\n };\n const isPie = chartType === \"pie\" || chartType === \"donut\";\n const isRadar = chartType === \"radar\";\n const isHorizontal =\n !isPie &&\n !isRadar &&\n !isHeatmap &&\n (orientation === \"horizontal\" ||\n (detectedChartType === \"categorical\" &&\n !orientation &&\n chartType === \"bar\"));\n const isTimeSeries =\n detectedChartType === \"timeseries\" &&\n !isHorizontal &&\n !isRadar &&\n !isHeatmap;\n\n // Build option based on chart type\n let opt: Record<string, unknown>;\n\n if (isHeatmap && \"yAxisData\" in normalized && \"heatmapData\" in normalized) {\n const heatmapNorm = normalized as {\n yAxisData: (string | number)[];\n heatmapData: [number, number, number][];\n min: number;\n max: number;\n } & typeof normalized;\n opt = buildHeatmapOption({\n ...baseCtx,\n yAxisData: heatmapNorm.yAxisData,\n heatmapData: heatmapNorm.heatmapData,\n min: min ?? heatmapNorm.min,\n max: max ?? heatmapNorm.max,\n showLabels,\n });\n } else if (isRadar) {\n opt = buildRadarOption(baseCtx, showArea);\n } else if (isPie) {\n opt = buildPieOption(\n baseCtx,\n chartType as \"pie\" | \"donut\",\n innerRadius,\n showLabels,\n labelPosition,\n );\n } else if (isHorizontal) {\n opt = buildHorizontalBarOption(baseCtx, stacked);\n } else {\n opt = buildCartesianOption({\n ...baseCtx,\n chartType,\n isTimeSeries,\n stacked,\n smooth,\n showSymbol,\n symbolSize,\n });\n }\n\n // Merge custom options\n return customOptions ? { ...opt, ...customOptions } : opt;\n }, [\n normalized,\n colors,\n title,\n showLegend,\n chartType,\n orientation,\n innerRadius,\n showLabels,\n labelPosition,\n stacked,\n smooth,\n showSymbol,\n symbolSize,\n showArea,\n min,\n max,\n customOptions,\n ]);\n\n if (!option) {\n return (\n <div className=\"flex items-center justify-center h-full text-muted-foreground\">\n No data\n </div>\n );\n }\n\n return (\n <ReactECharts\n ref={chartRefCallback}\n option={option}\n style={{ height }}\n className={className}\n opts={{ renderer: \"canvas\" }}\n notMerge={false}\n lazyUpdate={true}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;AA6BA,SAAS,kBAAkB,WAAyC;AAClE,SAAQ,WAAR;EACE,KAAK,UACH,QAAO;EACT,QACE,QAAO;;;;;;;AAsEb,SAAgB,UAAU,EACxB,MACA,WACA,MACA,MACA,aACA,SAAS,KACT,OACA,aAAa,MACb,cACA,QAAQ,cACR,aAAa,OACb,SAAS,MACT,UAAU,OACV,aAAa,GACb,WAAW,MACX,cAAc,GACd,aAAa,MACb,gBAAgB,WAChB,UACA,KACA,KACA,SAAS,eACT,aACiB;CAGjB,MAAM,cAAc,eADI,gBAAgB,kBAAkB,UAAU,CACjB;CACnD,MAAM,SAAS,gBAAgB;CAG/B,MAAM,qBAAqB,OAAuB,KAAK;CAIvD,MAAM,mBAAmB,aAAa,SAA8B;AAElE,MACE,mBAAmB,WACnB,CAAC,mBAAmB,QAAQ,YAAY,CAExC,oBAAmB,QAAQ,SAAS;AAItC,MAAI,KACF,oBAAmB,UAAU,KAAK,oBAAoB;OACjD;AAEL,OACE,mBAAmB,WACnB,CAAC,mBAAmB,QAAQ,YAAY,CAExC,oBAAmB,QAAQ,SAAS;AAEtC,sBAAmB,UAAU;;IAE9B,EAAE,CAAC;CAGN,MAAM,aAAa,cAEf,cAAc,YACV,qBAAqB,MAAM,MAAM,UAAU,KAAK,GAChD,mBAAmB,MAAM,MAAM,MAAM,YAAY,EACvD;EAAC;EAAM;EAAM;EAAM;EAAU;EAAa;EAAU,CACrD;CAGD,MAAM,SAAS,cAAc;EAC3B,MAAM,EAAE,OAAO,SAAS,QAAQ,WAAW,sBAAsB;AAEjE,MAAI,MAAM,WAAW,EAAG,QAAO;EAG/B,MAAM,YAAY,cAAc;EAMhC,MAAM,UAAgC;GACpC;GACA,UAJe,cAAc,aAAa,WAAW,WAAW,EAAE;GAKlE;GACA;GACA;GACA;GACA;GACD;EACD,MAAM,QAAQ,cAAc,SAAS,cAAc;EACnD,MAAM,UAAU,cAAc;EAC9B,MAAM,eACJ,CAAC,SACD,CAAC,WACD,CAAC,cACA,gBAAgB,gBACd,sBAAsB,iBACrB,CAAC,eACD,cAAc;EACpB,MAAM,eACJ,sBAAsB,gBACtB,CAAC,gBACD,CAAC,WACD,CAAC;EAGH,IAAI;AAEJ,MAAI,aAAa,eAAe,cAAc,iBAAiB,YAAY;GACzE,MAAM,cAAc;AAMpB,SAAM,mBAAmB;IACvB,GAAG;IACH,WAAW,YAAY;IACvB,aAAa,YAAY;IACzB,KAAK,OAAO,YAAY;IACxB,KAAK,OAAO,YAAY;IACxB;IACD,CAAC;aACO,QACT,OAAM,iBAAiB,SAAS,SAAS;WAChC,MACT,OAAM,eACJ,SACA,WACA,aACA,YACA,cACD;WACQ,aACT,OAAM,yBAAyB,SAAS,QAAQ;MAEhD,OAAM,qBAAqB;GACzB,GAAG;GACH;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;AAIJ,SAAO,gBAAgB;GAAE,GAAG;GAAK,GAAG;GAAe,GAAG;IACrD;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,CAAC,OACH,QACE,oBAAC;EAAI,WAAU;YAAgE;GAEzE;AAIV,QACE,oBAAC;EACC,KAAK;EACG;EACR,OAAO,EAAE,QAAQ;EACN;EACX,MAAM,EAAE,UAAU,UAAU;EAC5B,UAAU;EACV,YAAY;GACZ"}
1
+ {"version":3,"file":"base.js","names":[],"sources":["../../../src/react/charts/base.tsx"],"sourcesContent":["import type { ECharts } from \"echarts\";\nimport ReactECharts from \"echarts-for-react\";\nimport { useCallback, useMemo, useRef } from \"react\";\nimport { normalizeChartData, normalizeHeatmapData } from \"./normalize\";\nimport {\n buildCartesianOption,\n buildHeatmapOption,\n buildHorizontalBarOption,\n buildPieOption,\n buildRadarOption,\n type OptionBuilderContext,\n} from \"./options\";\nimport { useChartUITokens, useThemeColors } from \"./theme\";\nimport type {\n ChartColorPalette,\n ChartData,\n ChartType,\n Orientation,\n} from \"./types\";\n\n// ============================================================================\n// Palette Selection\n// ============================================================================\n\n/**\n * Determines the appropriate color palette for a chart type.\n * - Heatmaps use sequential (low → high intensity)\n * - All other charts use categorical (distinct categories)\n */\nfunction getDefaultPalette(chartType: ChartType): ChartColorPalette {\n switch (chartType) {\n case \"heatmap\":\n return \"sequential\";\n default:\n return \"categorical\";\n }\n}\n\n// ============================================================================\n// Component Props\n// ============================================================================\n\nexport interface BaseChartProps {\n /** Chart data (Arrow Table or JSON array) - format is auto-detected */\n data: ChartData;\n /** Chart type */\n chartType: ChartType;\n /** X-axis field key (auto-detected from schema if not provided) */\n xKey?: string;\n /** Y-axis field key(s) (auto-detected from schema if not provided) */\n yKey?: string | string[];\n /** Chart orientation @default \"vertical\" */\n orientation?: Orientation;\n /** Chart height in pixels @default 300 */\n height?: number;\n /** Chart title */\n title?: string;\n /** Show legend @default true */\n showLegend?: boolean;\n /**\n * Color palette to use. Auto-selected based on chart type if not specified.\n * - \"categorical\": Distinct colors for different categories (bar, pie, line)\n * - \"sequential\": Gradient for magnitude (heatmap)\n * - \"diverging\": Two-tone for positive/negative (correlation)\n */\n colorPalette?: ChartColorPalette;\n /** Custom colors (overrides colorPalette) */\n colors?: string[];\n /** Show data point symbols (line/area charts) @default false */\n showSymbol?: boolean;\n /** Smooth line curves (line/area charts) @default true */\n smooth?: boolean;\n /** Stack series @default false */\n stacked?: boolean;\n /** Symbol size for scatter charts @default 8 */\n symbolSize?: number;\n /** Show area fill for radar charts @default true */\n showArea?: boolean;\n /** Inner radius for pie/donut (0-100) @default 0 */\n innerRadius?: number;\n /** Show labels on pie/donut slices @default true */\n showLabels?: boolean;\n /** Label position for pie/donut @default \"outside\" */\n labelPosition?: \"outside\" | \"inside\" | \"center\";\n /** Y-axis field key for heatmap (the row dimension) */\n yAxisKey?: string;\n /** Min value for heatmap color scale */\n min?: number;\n /** Max value for heatmap color scale */\n max?: number;\n /** Additional ECharts options to merge */\n options?: Record<string, unknown>;\n /** Additional CSS classes */\n className?: string;\n}\n\n// ============================================================================\n// Base Chart Component\n// ============================================================================\n\n/**\n * Base chart component that handles both Arrow and JSON data.\n * Renders using ECharts for consistent output across both formats.\n */\nexport function BaseChart({\n data,\n chartType,\n xKey,\n yKey,\n orientation,\n height = 300,\n title,\n showLegend = true,\n colorPalette,\n colors: customColors,\n showSymbol = false,\n smooth = true,\n stacked = false,\n symbolSize = 8,\n showArea = true,\n innerRadius = 0,\n showLabels = true,\n labelPosition = \"outside\",\n yAxisKey,\n min,\n max,\n options: customOptions,\n className,\n}: BaseChartProps) {\n // Determine the appropriate color palette based on chart type\n const resolvedPalette = colorPalette ?? getDefaultPalette(chartType);\n const themeColors = useThemeColors(resolvedPalette);\n const colors = customColors ?? themeColors;\n\n const ui = useChartUITokens();\n\n // Store ECharts instance directly to avoid stale ref issues on unmount\n const echartsInstanceRef = useRef<ECharts | null>(null);\n\n // Callback ref pattern: captures the ECharts instance when ReactECharts mounts\n // This ensures we always have a stable reference to the actual instance\n const chartRefCallback = useCallback((node: ReactECharts | null) => {\n // Dispose previous instance if component is being replaced\n if (\n echartsInstanceRef.current &&\n !echartsInstanceRef.current.isDisposed()\n ) {\n echartsInstanceRef.current.dispose();\n }\n\n // Store the new instance\n if (node) {\n echartsInstanceRef.current = node.getEchartsInstance();\n } else {\n // Component unmounting - dispose the stored instance\n if (\n echartsInstanceRef.current &&\n !echartsInstanceRef.current.isDisposed()\n ) {\n echartsInstanceRef.current.dispose();\n }\n echartsInstanceRef.current = null;\n }\n }, []);\n\n // Memoize data normalization\n const normalized = useMemo(\n () =>\n chartType === \"heatmap\"\n ? normalizeHeatmapData(data, xKey, yAxisKey, yKey)\n : normalizeChartData(data, xKey, yKey, orientation),\n [data, xKey, yKey, yAxisKey, orientation, chartType],\n );\n\n // Memoize option building\n const option = useMemo(() => {\n const { xData, yFields, xField, chartType: detectedChartType } = normalized;\n\n if (xData.length === 0) return null;\n\n // Determine chart mode first (needed to handle yDataMap)\n const isHeatmap = chartType === \"heatmap\";\n\n // Heatmaps use heatmapData instead of yDataMap\n // For other charts, yDataMap is required\n const yDataMap = \"yDataMap\" in normalized ? normalized.yDataMap : {};\n\n const baseCtx: OptionBuilderContext = {\n xData,\n yDataMap,\n yFields,\n colors,\n title,\n showLegend,\n xField,\n ui,\n };\n const isPie = chartType === \"pie\" || chartType === \"donut\";\n const isRadar = chartType === \"radar\";\n const isHorizontal =\n !isPie &&\n !isRadar &&\n !isHeatmap &&\n (orientation === \"horizontal\" ||\n (detectedChartType === \"categorical\" &&\n !orientation &&\n chartType === \"bar\"));\n const isTimeSeries =\n detectedChartType === \"timeseries\" &&\n !isHorizontal &&\n !isRadar &&\n !isHeatmap;\n\n // Build option based on chart type\n let opt: Record<string, unknown>;\n\n if (isHeatmap && \"yAxisData\" in normalized && \"heatmapData\" in normalized) {\n const heatmapNorm = normalized as {\n yAxisData: (string | number)[];\n heatmapData: [number, number, number][];\n min: number;\n max: number;\n } & typeof normalized;\n opt = buildHeatmapOption({\n ...baseCtx,\n yAxisData: heatmapNorm.yAxisData,\n heatmapData: heatmapNorm.heatmapData,\n min: min ?? heatmapNorm.min,\n max: max ?? heatmapNorm.max,\n showLabels,\n });\n } else if (isRadar) {\n opt = buildRadarOption(baseCtx, showArea);\n } else if (isPie) {\n opt = buildPieOption(\n baseCtx,\n chartType as \"pie\" | \"donut\",\n innerRadius,\n showLabels,\n labelPosition,\n );\n } else if (isHorizontal) {\n opt = buildHorizontalBarOption(baseCtx, stacked);\n } else {\n opt = buildCartesianOption({\n ...baseCtx,\n chartType,\n isTimeSeries,\n stacked,\n smooth,\n showSymbol,\n symbolSize,\n });\n }\n\n // Merge custom options\n return customOptions ? { ...opt, ...customOptions } : opt;\n }, [\n normalized,\n colors,\n ui,\n title,\n showLegend,\n chartType,\n orientation,\n innerRadius,\n showLabels,\n labelPosition,\n stacked,\n smooth,\n showSymbol,\n symbolSize,\n showArea,\n min,\n max,\n customOptions,\n ]);\n\n if (!option) {\n return (\n <div className=\"flex items-center justify-center h-full text-muted-foreground\">\n No data\n </div>\n );\n }\n\n return (\n <ReactECharts\n ref={chartRefCallback}\n option={option}\n style={{ height }}\n className={className}\n opts={{ renderer: \"canvas\" }}\n notMerge={false}\n lazyUpdate={true}\n />\n );\n}\n"],"mappings":";;;;;;;;;;;;;AA6BA,SAAS,kBAAkB,WAAyC;AAClE,SAAQ,WAAR;EACE,KAAK,UACH,QAAO;EACT,QACE,QAAO;;;;;;;AAsEb,SAAgB,UAAU,EACxB,MACA,WACA,MACA,MACA,aACA,SAAS,KACT,OACA,aAAa,MACb,cACA,QAAQ,cACR,aAAa,OACb,SAAS,MACT,UAAU,OACV,aAAa,GACb,WAAW,MACX,cAAc,GACd,aAAa,MACb,gBAAgB,WAChB,UACA,KACA,KACA,SAAS,eACT,aACiB;CAGjB,MAAM,cAAc,eADI,gBAAgB,kBAAkB,UAAU,CACjB;CACnD,MAAM,SAAS,gBAAgB;CAE/B,MAAM,KAAK,kBAAkB;CAG7B,MAAM,qBAAqB,OAAuB,KAAK;CAIvD,MAAM,mBAAmB,aAAa,SAA8B;AAElE,MACE,mBAAmB,WACnB,CAAC,mBAAmB,QAAQ,YAAY,CAExC,oBAAmB,QAAQ,SAAS;AAItC,MAAI,KACF,oBAAmB,UAAU,KAAK,oBAAoB;OACjD;AAEL,OACE,mBAAmB,WACnB,CAAC,mBAAmB,QAAQ,YAAY,CAExC,oBAAmB,QAAQ,SAAS;AAEtC,sBAAmB,UAAU;;IAE9B,EAAE,CAAC;CAGN,MAAM,aAAa,cAEf,cAAc,YACV,qBAAqB,MAAM,MAAM,UAAU,KAAK,GAChD,mBAAmB,MAAM,MAAM,MAAM,YAAY,EACvD;EAAC;EAAM;EAAM;EAAM;EAAU;EAAa;EAAU,CACrD;CAGD,MAAM,SAAS,cAAc;EAC3B,MAAM,EAAE,OAAO,SAAS,QAAQ,WAAW,sBAAsB;AAEjE,MAAI,MAAM,WAAW,EAAG,QAAO;EAG/B,MAAM,YAAY,cAAc;EAMhC,MAAM,UAAgC;GACpC;GACA,UAJe,cAAc,aAAa,WAAW,WAAW,EAAE;GAKlE;GACA;GACA;GACA;GACA;GACA;GACD;EACD,MAAM,QAAQ,cAAc,SAAS,cAAc;EACnD,MAAM,UAAU,cAAc;EAC9B,MAAM,eACJ,CAAC,SACD,CAAC,WACD,CAAC,cACA,gBAAgB,gBACd,sBAAsB,iBACrB,CAAC,eACD,cAAc;EACpB,MAAM,eACJ,sBAAsB,gBACtB,CAAC,gBACD,CAAC,WACD,CAAC;EAGH,IAAI;AAEJ,MAAI,aAAa,eAAe,cAAc,iBAAiB,YAAY;GACzE,MAAM,cAAc;AAMpB,SAAM,mBAAmB;IACvB,GAAG;IACH,WAAW,YAAY;IACvB,aAAa,YAAY;IACzB,KAAK,OAAO,YAAY;IACxB,KAAK,OAAO,YAAY;IACxB;IACD,CAAC;aACO,QACT,OAAM,iBAAiB,SAAS,SAAS;WAChC,MACT,OAAM,eACJ,SACA,WACA,aACA,YACA,cACD;WACQ,aACT,OAAM,yBAAyB,SAAS,QAAQ;MAEhD,OAAM,qBAAqB;GACzB,GAAG;GACH;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;AAIJ,SAAO,gBAAgB;GAAE,GAAG;GAAK,GAAG;GAAe,GAAG;IACrD;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,CAAC,OACH,QACE,oBAAC;EAAI,WAAU;YAAgE;GAEzE;AAIV,QACE,oBAAC;EACC,KAAK;EACG;EACR,OAAO,EAAE,QAAQ;EACN;EACX,MAAM,EAAE,UAAU,UAAU;EAC5B,UAAU;EACV,YAAY;GACZ"}
@@ -1,4 +1,5 @@
1
1
  import { DATE_FIELD_PATTERNS, METADATA_DATE_PATTERNS, NAME_FIELD_PATTERNS } from "../../js/constants.js";
2
+ import "./types.js";
2
3
 
3
4
  //#region src/react/charts/constants.d.ts
4
5
  /** CSS variable names for categorical chart colors (distinct categories) */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","names":[],"sources":["../../../src/react/charts/constants.ts"],"mappings":";;;;cAgBa,4BAAA;AAAb;AAAA,cAYa,2BAAA;;cAYA,0BAAA;;cAYA,gBAAA;;cAgBA,2BAAA;;cAYA,0BAAA;AAxCb;AAAA,cAoDa,yBAAA"}
1
+ {"version":3,"file":"constants.d.ts","names":[],"sources":["../../../src/react/charts/constants.ts"],"mappings":";;;;;cAkBa,4BAAA;AAAb;AAAA,cAYa,2BAAA;;cAYA,0BAAA;;cAYA,gBAAA;;cAgBA,2BAAA;;cAYA,0BAAA;AAxCb;AAAA,cAoDa,yBAAA"}
@@ -78,7 +78,21 @@ const FALLBACK_COLORS_DIVERGING = [
78
78
  "hsla(10, 72%, 50%, 1)",
79
79
  "hsla(10, 80%, 40%, 1)"
80
80
  ];
81
+ /** CSS variable names for the chart UI tokens (read at runtime like the palettes) */
82
+ const CHART_UI_VARS = {
83
+ axisLabel: "--chart-axis-label",
84
+ axisTitle: "--chart-axis-title",
85
+ grid: "--chart-grid",
86
+ tooltipBg: "--chart-tooltip-bg"
87
+ };
88
+ /** Fallback chart UI tokens (light values). */
89
+ const FALLBACK_UI_TOKENS = {
90
+ axisLabel: "hsla(240, 4%, 46%, 1)",
91
+ axisTitle: "hsla(240, 6%, 10%, 1)",
92
+ grid: "hsla(240, 5%, 90%, 1)",
93
+ tooltipBg: "hsla(0, 0%, 100%, 1)"
94
+ };
81
95
 
82
96
  //#endregion
83
- export { CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL };
97
+ export { CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, CHART_UI_VARS, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL, FALLBACK_UI_TOKENS };
84
98
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../../../src/react/charts/constants.ts"],"sourcesContent":["// ============================================================================\n// Shared Constants for Chart Components\n// ============================================================================\n\n// Re-export field patterns from shared constants\nexport {\n DATE_FIELD_PATTERNS,\n METADATA_DATE_PATTERNS,\n NAME_FIELD_PATTERNS,\n} from \"@/js/constants\";\n\n// ============================================================================\n// Chart Color Palettes\n// ============================================================================\n\n/** CSS variable names for categorical chart colors (distinct categories) */\nexport const CHART_COLOR_VARS_CATEGORICAL = [\n \"--chart-cat-1\",\n \"--chart-cat-2\",\n \"--chart-cat-3\",\n \"--chart-cat-4\",\n \"--chart-cat-5\",\n \"--chart-cat-6\",\n \"--chart-cat-7\",\n \"--chart-cat-8\",\n] as const;\n\n/** CSS variable names for sequential chart colors (low → high) */\nexport const CHART_COLOR_VARS_SEQUENTIAL = [\n \"--chart-seq-1\",\n \"--chart-seq-2\",\n \"--chart-seq-3\",\n \"--chart-seq-4\",\n \"--chart-seq-5\",\n \"--chart-seq-6\",\n \"--chart-seq-7\",\n \"--chart-seq-8\",\n] as const;\n\n/** CSS variable names for diverging chart colors (negative ↔ positive) */\nexport const CHART_COLOR_VARS_DIVERGING = [\n \"--chart-div-1\",\n \"--chart-div-2\",\n \"--chart-div-3\",\n \"--chart-div-4\",\n \"--chart-div-5\",\n \"--chart-div-6\",\n \"--chart-div-7\",\n \"--chart-div-8\",\n] as const;\n\n/** Legacy: CSS variable names for chart colors (aliases to categorical) */\nexport const CHART_COLOR_VARS = [\n \"--chart-1\",\n \"--chart-2\",\n \"--chart-3\",\n \"--chart-4\",\n \"--chart-5\",\n \"--chart-6\",\n \"--chart-7\",\n \"--chart-8\",\n] as const;\n\n// ============================================================================\n// Fallback Colors (when CSS variables unavailable)\n// ============================================================================\n\n/** Fallback categorical colors */\nexport const FALLBACK_COLORS_CATEGORICAL = [\n \"hsla(221, 83%, 53%, 1)\", // Blue\n \"hsla(160, 60%, 45%, 1)\", // Teal\n \"hsla(291, 47%, 51%, 1)\", // Purple\n \"hsla(35, 92%, 55%, 1)\", // Amber\n \"hsla(349, 72%, 52%, 1)\", // Rose\n \"hsla(189, 75%, 42%, 1)\", // Cyan\n \"hsla(271, 55%, 60%, 1)\", // Lavender\n \"hsla(142, 55%, 45%, 1)\", // Emerald\n];\n\n/** Fallback sequential colors (light → dark blue) */\nexport const FALLBACK_COLORS_SEQUENTIAL = [\n \"hsla(221, 70%, 94%, 1)\",\n \"hsla(221, 72%, 85%, 1)\",\n \"hsla(221, 74%, 74%, 1)\",\n \"hsla(221, 76%, 63%, 1)\",\n \"hsla(221, 78%, 52%, 1)\",\n \"hsla(221, 80%, 42%, 1)\",\n \"hsla(221, 82%, 32%, 1)\",\n \"hsla(221, 84%, 24%, 1)\",\n];\n\n/** Fallback diverging colors (blue → red) */\nexport const FALLBACK_COLORS_DIVERGING = [\n \"hsla(221, 80%, 35%, 1)\", // Strong negative\n \"hsla(221, 70%, 50%, 1)\",\n \"hsla(221, 55%, 65%, 1)\",\n \"hsla(221, 35%, 82%, 1)\", // Weak negative\n \"hsla(10, 35%, 82%, 1)\", // Weak positive\n \"hsla(10, 60%, 65%, 1)\",\n \"hsla(10, 72%, 50%, 1)\",\n \"hsla(10, 80%, 40%, 1)\", // Strong positive\n];\n"],"mappings":";;;;AAgBA,MAAa,+BAA+B;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,8BAA8B;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,6BAA6B;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAOD,MAAa,8BAA8B;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,6BAA6B;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,4BAA4B;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../../../src/react/charts/constants.ts"],"sourcesContent":["// ============================================================================\n// Shared Constants for Chart Components\n// ============================================================================\n\nimport type { ChartUITokens } from \"./types\";\n\n// Re-export field patterns from shared constants\nexport {\n DATE_FIELD_PATTERNS,\n METADATA_DATE_PATTERNS,\n NAME_FIELD_PATTERNS,\n} from \"@/js/constants\";\n\n// ============================================================================\n// Chart Color Palettes\n// ============================================================================\n\n/** CSS variable names for categorical chart colors (distinct categories) */\nexport const CHART_COLOR_VARS_CATEGORICAL = [\n \"--chart-cat-1\",\n \"--chart-cat-2\",\n \"--chart-cat-3\",\n \"--chart-cat-4\",\n \"--chart-cat-5\",\n \"--chart-cat-6\",\n \"--chart-cat-7\",\n \"--chart-cat-8\",\n] as const;\n\n/** CSS variable names for sequential chart colors (low → high) */\nexport const CHART_COLOR_VARS_SEQUENTIAL = [\n \"--chart-seq-1\",\n \"--chart-seq-2\",\n \"--chart-seq-3\",\n \"--chart-seq-4\",\n \"--chart-seq-5\",\n \"--chart-seq-6\",\n \"--chart-seq-7\",\n \"--chart-seq-8\",\n] as const;\n\n/** CSS variable names for diverging chart colors (negative ↔ positive) */\nexport const CHART_COLOR_VARS_DIVERGING = [\n \"--chart-div-1\",\n \"--chart-div-2\",\n \"--chart-div-3\",\n \"--chart-div-4\",\n \"--chart-div-5\",\n \"--chart-div-6\",\n \"--chart-div-7\",\n \"--chart-div-8\",\n] as const;\n\n/** Legacy: CSS variable names for chart colors (aliases to categorical) */\nexport const CHART_COLOR_VARS = [\n \"--chart-1\",\n \"--chart-2\",\n \"--chart-3\",\n \"--chart-4\",\n \"--chart-5\",\n \"--chart-6\",\n \"--chart-7\",\n \"--chart-8\",\n] as const;\n\n// ============================================================================\n// Fallback Colors (when CSS variables unavailable)\n// ============================================================================\n\n/** Fallback categorical colors */\nexport const FALLBACK_COLORS_CATEGORICAL = [\n \"hsla(221, 83%, 53%, 1)\", // Blue\n \"hsla(160, 60%, 45%, 1)\", // Teal\n \"hsla(291, 47%, 51%, 1)\", // Purple\n \"hsla(35, 92%, 55%, 1)\", // Amber\n \"hsla(349, 72%, 52%, 1)\", // Rose\n \"hsla(189, 75%, 42%, 1)\", // Cyan\n \"hsla(271, 55%, 60%, 1)\", // Lavender\n \"hsla(142, 55%, 45%, 1)\", // Emerald\n];\n\n/** Fallback sequential colors (light → dark blue) */\nexport const FALLBACK_COLORS_SEQUENTIAL = [\n \"hsla(221, 70%, 94%, 1)\",\n \"hsla(221, 72%, 85%, 1)\",\n \"hsla(221, 74%, 74%, 1)\",\n \"hsla(221, 76%, 63%, 1)\",\n \"hsla(221, 78%, 52%, 1)\",\n \"hsla(221, 80%, 42%, 1)\",\n \"hsla(221, 82%, 32%, 1)\",\n \"hsla(221, 84%, 24%, 1)\",\n];\n\n/** Fallback diverging colors (blue → red) */\nexport const FALLBACK_COLORS_DIVERGING = [\n \"hsla(221, 80%, 35%, 1)\", // Strong negative\n \"hsla(221, 70%, 50%, 1)\",\n \"hsla(221, 55%, 65%, 1)\",\n \"hsla(221, 35%, 82%, 1)\", // Weak negative\n \"hsla(10, 35%, 82%, 1)\", // Weak positive\n \"hsla(10, 60%, 65%, 1)\",\n \"hsla(10, 72%, 50%, 1)\",\n \"hsla(10, 80%, 40%, 1)\", // Strong positive\n];\n\n// ============================================================================\n// Chart UI tokens (axis text, titles, grid lines)\n// ============================================================================\n\n/** CSS variable names for the chart UI tokens (read at runtime like the palettes) */\nexport const CHART_UI_VARS: Record<keyof ChartUITokens, string> = {\n axisLabel: \"--chart-axis-label\",\n axisTitle: \"--chart-axis-title\",\n grid: \"--chart-grid\",\n tooltipBg: \"--chart-tooltip-bg\",\n};\n\n/** Fallback chart UI tokens (light values). */\nexport const FALLBACK_UI_TOKENS: ChartUITokens = {\n axisLabel: \"hsla(240, 4%, 46%, 1)\", // ≈ --muted-foreground\n axisTitle: \"hsla(240, 6%, 10%, 1)\", // ≈ --foreground\n grid: \"hsla(240, 5%, 90%, 1)\", // ≈ --border\n tooltipBg: \"hsla(0, 0%, 100%, 1)\", // ≈ --popover\n};\n"],"mappings":";;;;AAkBA,MAAa,+BAA+B;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,8BAA8B;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,6BAA6B;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAOD,MAAa,8BAA8B;CACzC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,6BAA6B;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAa,4BAA4B;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;AAOD,MAAa,gBAAqD;CAChE,WAAW;CACX,WAAW;CACX,MAAM;CACN,WAAW;CACZ;;AAGD,MAAa,qBAAoC;CAC/C,WAAW;CACX,WAAW;CACX,MAAM;CACN,WAAW;CACZ"}
@@ -1,5 +1,5 @@
1
1
  import { DATE_FIELD_PATTERNS, METADATA_DATE_PATTERNS, NAME_FIELD_PATTERNS } from "../../js/constants.js";
2
- import { AreaChartProps, AreaChartSpecificProps, BarChartProps, BarChartSpecificProps, ChartBaseProps, ChartColorPalette, ChartData, ChartType, DataFormat, DataProps, DonutChartProps, HeatmapChartProps, HeatmapChartSpecificProps, LineChartProps, LineChartSpecificProps, NormalizedChartData, NormalizedChartDataBase, Orientation, PieChartProps, PieChartSpecificProps, QueryProps, RadarChartProps, RadarChartSpecificProps, ScatterChartProps, ScatterChartSpecificProps, UnifiedChartProps, isArrowTable, isDataProps, isQueryProps } from "./types.js";
2
+ import { AreaChartProps, AreaChartSpecificProps, BarChartProps, BarChartSpecificProps, ChartBaseProps, ChartColorPalette, ChartData, ChartType, ChartUITokens, DataFormat, DataProps, DonutChartProps, HeatmapChartProps, HeatmapChartSpecificProps, LineChartProps, LineChartSpecificProps, NormalizedChartData, NormalizedChartDataBase, Orientation, PieChartProps, PieChartSpecificProps, QueryProps, RadarChartProps, RadarChartSpecificProps, ScatterChartProps, ScatterChartSpecificProps, UnifiedChartProps, isArrowTable, isDataProps, isQueryProps } from "./types.js";
3
3
  import { AreaChart } from "./area/index.js";
4
4
  import { BarChart } from "./bar/index.js";
5
5
  import { HeatmapChart } from "./heatmap/index.js";
@@ -14,6 +14,6 @@ import { LoadingSkeleton, ResourceWaitingPlaceholder } from "./loading.js";
14
14
  import { ChartWrapper, ChartWrapperProps } from "./wrapper.js";
15
15
  import { NormalizedHeatmapData, normalizeChartData, normalizeHeatmapData } from "./normalize.js";
16
16
  import { CHART_COLOR_VARS, CHART_COLOR_VARS_CATEGORICAL, CHART_COLOR_VARS_DIVERGING, CHART_COLOR_VARS_SEQUENTIAL, FALLBACK_COLORS_CATEGORICAL, FALLBACK_COLORS_DIVERGING, FALLBACK_COLORS_SEQUENTIAL } from "./constants.js";
17
- import { useAllThemeColors, useThemeColors } from "./theme.js";
17
+ import { useAllThemeColors, useChartUITokens, useThemeColors } from "./theme.js";
18
18
  import { createTimeSeriesData, formatLabel, sortTimeSeriesAscending, toChartArray, toChartValue, truncateLabel } from "./utils.js";
19
19
  import { CartesianContext, HeatmapContext, OptionBuilderContext, buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption } from "./options.js";
@@ -4,7 +4,7 @@ import { isArrowTable, isDataProps, isQueryProps } from "./types.js";
4
4
  import { createTimeSeriesData, formatLabel, sortTimeSeriesAscending, toChartArray, toChartValue, truncateLabel } from "./utils.js";
5
5
  import { normalizeChartData, normalizeHeatmapData } from "./normalize.js";
6
6
  import { buildCartesianOption, buildHeatmapOption, buildHorizontalBarOption, buildPieOption, buildRadarOption } from "./options.js";
7
- import { useAllThemeColors, useThemeColors } from "./theme.js";
7
+ import { useAllThemeColors, useChartUITokens, useThemeColors } from "./theme.js";
8
8
  import { BaseChart } from "./base.js";
9
9
  import { useChartData } from "../hooks/use-chart-data.js";
10
10
  import { LoadingSkeleton, ResourceWaitingPlaceholder } from "./loading.js";
@@ -1,4 +1,4 @@
1
- import { ChartType } from "./types.js";
1
+ import { ChartType, ChartUITokens } from "./types.js";
2
2
 
3
3
  //#region src/react/charts/options.d.ts
4
4
  interface OptionBuilderContext {
@@ -9,6 +9,7 @@ interface OptionBuilderContext {
9
9
  title?: string;
10
10
  showLegend: boolean;
11
11
  xField?: string;
12
+ ui?: ChartUITokens;
12
13
  }
13
14
  interface CartesianContext extends OptionBuilderContext {
14
15
  chartType: ChartType;
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","names":[],"sources":["../../../src/react/charts/options.ts"],"mappings":";;;UAYiB,oBAAA;EACf,KAAA;EACA,QAAA,EAAU,MAAA;EACV,OAAA;EACA,MAAA;EACA,KAAA;EACA,UAAA;EACA,MAAA;AAAA;AAAA,UAGe,gBAAA,SAAyB,oBAAA;EACxC,SAAA,EAAW,SAAA;EACX,YAAA;EACA,OAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;AAAA;AAAA,iBAkBc,gBAAA,CACd,GAAA,EAAK,oBAAA,EACL,QAAA,aACC,MAAA;AAAA,iBAmCa,cAAA,CACd,GAAA,EAAK,oBAAA,EACL,SAAA,mBACA,WAAA,UACA,UAAA,WACA,aAAA,WACC,MAAA;AAAA,iBA2Ca,wBAAA,CACd,GAAA,EAAK,oBAAA,EACL,OAAA,YACC,MAAA;AAAA,UAsCc,cAAA,SAAuB,oBAAA;EAvJtC;EAyJA,SAAA;EAxJA;EA0JA,WAAA;EAxJA;EA0JA,GAAA;EAxJA;EA0JA,GAAA;EA1JU;EA4JV,UAAA;AAAA;AAAA,iBAGc,kBAAA,CACd,GAAA,EAAK,cAAA,GACJ,MAAA;AAAA,iBAwEa,oBAAA,CACd,GAAA,EAAK,gBAAA,GACJ,MAAA"}
1
+ {"version":3,"file":"options.d.ts","names":[],"sources":["../../../src/react/charts/options.ts"],"mappings":";;;UAaiB,oBAAA;EACf,KAAA;EACA,QAAA,EAAU,MAAA;EACV,OAAA;EACA,MAAA;EACA,KAAA;EACA,UAAA;EACA,MAAA;EACA,EAAA,GAAK,aAAA;AAAA;AAAA,UAGU,gBAAA,SAAyB,oBAAA;EACxC,SAAA,EAAW,SAAA;EACX,YAAA;EACA,OAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;AAAA;AAAA,iBAyDc,gBAAA,CACd,GAAA,EAAK,oBAAA,EACL,QAAA,aACC,MAAA;AAAA,iBAyCa,cAAA,CACd,GAAA,EAAK,oBAAA,EACL,SAAA,mBACA,WAAA,UACA,UAAA,WACA,aAAA,WACC,MAAA;AAAA,iBAqDa,wBAAA,CACd,GAAA,EAAK,oBAAA,EACL,OAAA,YACC,MAAA;AAAA,UA8Cc,cAAA,SAAuB,oBAAA;EAvNE;EAyNxC,SAAA;EAxNW;EA0NX,WAAA;EAxNA;EA0NA,GAAA;EAxNA;EA0NA,GAAA;EAzNU;EA2NV,UAAA;AAAA;AAAA,iBAGc,kBAAA,CACd,GAAA,EAAK,cAAA,GACJ,MAAA;AAAA,iBA2Ea,oBAAA,CACd,GAAA,EAAK,gBAAA,GACJ,MAAA"}
@@ -1,27 +1,68 @@
1
+ import { FALLBACK_UI_TOKENS } from "./constants.js";
1
2
  import { createTimeSeriesData, escapeHtml, formatLabel, truncateLabel } from "./utils.js";
2
3
 
3
4
  //#region src/react/charts/options.ts
4
5
  function buildBaseOption(ctx) {
6
+ const ui = ctx.ui ?? FALLBACK_UI_TOKENS;
5
7
  return {
6
8
  title: ctx.title ? {
7
9
  text: ctx.title,
8
- left: "center"
10
+ left: "center",
11
+ textStyle: { color: ui.axisTitle }
9
12
  } : void 0,
10
13
  color: ctx.colors
11
14
  };
12
15
  }
16
+ function axisCommon(ui) {
17
+ return {
18
+ axisLabel: { color: ui.axisLabel },
19
+ axisLine: { lineStyle: { color: ui.grid } },
20
+ axisTick: { lineStyle: { color: ui.grid } },
21
+ splitLine: { lineStyle: { color: ui.grid } },
22
+ nameTextStyle: { color: ui.axisTitle }
23
+ };
24
+ }
25
+ function mergeAxisLabel(ui, axisLabel) {
26
+ return {
27
+ ...axisCommon(ui),
28
+ axisLabel: {
29
+ color: ui.axisLabel,
30
+ ...axisLabel
31
+ }
32
+ };
33
+ }
34
+ function legendTextStyle(ui) {
35
+ return { textStyle: { color: ui.axisTitle } };
36
+ }
37
+ function tooltipTokens(ui) {
38
+ return {
39
+ backgroundColor: ui.tooltipBg,
40
+ borderColor: ui.grid,
41
+ textStyle: { color: ui.axisTitle }
42
+ };
43
+ }
13
44
  function buildRadarOption(ctx, showArea = true) {
45
+ const ui = ctx.ui ?? FALLBACK_UI_TOKENS;
14
46
  const maxValue = Math.max(...ctx.yFields.flatMap((f) => ctx.yDataMap[f].map((v) => Number(v) || 0)));
15
47
  return {
16
48
  ...buildBaseOption(ctx),
17
- tooltip: { trigger: "item" },
18
- legend: ctx.showLegend && ctx.yFields.length > 1 ? { top: "bottom" } : void 0,
49
+ tooltip: {
50
+ ...tooltipTokens(ui),
51
+ trigger: "item"
52
+ },
53
+ legend: ctx.showLegend && ctx.yFields.length > 1 ? {
54
+ top: "bottom",
55
+ ...legendTextStyle(ui)
56
+ } : void 0,
19
57
  radar: {
20
58
  indicator: ctx.xData.map((name) => ({
21
59
  name: String(name),
22
60
  max: maxValue * 1.2
23
61
  })),
24
- shape: "polygon"
62
+ shape: "polygon",
63
+ axisName: { color: ui.axisTitle },
64
+ axisLine: { lineStyle: { color: ui.grid } },
65
+ splitLine: { lineStyle: { color: ui.grid } }
25
66
  },
26
67
  series: [{
27
68
  type: "radar",
@@ -35,6 +76,7 @@ function buildRadarOption(ctx, showArea = true) {
35
76
  };
36
77
  }
37
78
  function buildPieOption(ctx, chartType, innerRadius, showLabels, labelPosition) {
79
+ const ui = ctx.ui ?? FALLBACK_UI_TOKENS;
38
80
  const pieData = ctx.xData.map((name, i) => ({
39
81
  name: String(name),
40
82
  value: ctx.yDataMap[ctx.yFields[0]]?.[i] ?? 0
@@ -43,13 +85,15 @@ function buildPieOption(ctx, chartType, innerRadius, showLabels, labelPosition)
43
85
  return {
44
86
  ...buildBaseOption(ctx),
45
87
  tooltip: {
88
+ ...tooltipTokens(ui),
46
89
  trigger: "item",
47
90
  formatter: "{b}: {c} ({d}%)"
48
91
  },
49
92
  legend: ctx.showLegend ? {
50
93
  orient: "vertical",
51
94
  left: "left",
52
- top: "middle"
95
+ top: "middle",
96
+ ...legendTextStyle(ui)
53
97
  } : void 0,
54
98
  series: [{
55
99
  type: "pie",
@@ -72,29 +116,37 @@ function buildPieOption(ctx, chartType, innerRadius, showLabels, labelPosition)
72
116
  };
73
117
  }
74
118
  function buildHorizontalBarOption(ctx, stacked) {
119
+ const ui = ctx.ui ?? FALLBACK_UI_TOKENS;
75
120
  const hasMultipleSeries = ctx.yFields.length > 1;
76
121
  return {
77
122
  ...buildBaseOption(ctx),
78
123
  tooltip: {
124
+ ...tooltipTokens(ui),
79
125
  trigger: "axis",
80
126
  axisPointer: { type: "shadow" }
81
127
  },
82
- legend: ctx.showLegend && hasMultipleSeries ? { top: "bottom" } : void 0,
128
+ legend: ctx.showLegend && hasMultipleSeries ? {
129
+ top: "bottom",
130
+ ...legendTextStyle(ui)
131
+ } : void 0,
83
132
  grid: {
84
133
  left: "20%",
85
134
  right: "10%",
86
135
  top: ctx.title ? "15%" : "5%",
87
136
  bottom: ctx.showLegend && hasMultipleSeries ? "15%" : "5%"
88
137
  },
89
- xAxis: { type: "value" },
138
+ xAxis: {
139
+ type: "value",
140
+ ...axisCommon(ui)
141
+ },
90
142
  yAxis: {
91
143
  type: "category",
92
144
  data: ctx.xData,
93
- axisLabel: {
145
+ ...mergeAxisLabel(ui, {
94
146
  width: 100,
95
147
  overflow: "truncate",
96
148
  formatter: (value) => truncateLabel(String(value))
97
- }
149
+ })
98
150
  },
99
151
  series: ctx.yFields.map((key, idx) => ({
100
152
  name: formatLabel(key),
@@ -112,9 +164,11 @@ function buildHorizontalBarOption(ctx, stacked) {
112
164
  };
113
165
  }
114
166
  function buildHeatmapOption(ctx) {
167
+ const ui = ctx.ui ?? FALLBACK_UI_TOKENS;
115
168
  return {
116
169
  ...buildBaseOption(ctx),
117
170
  tooltip: {
171
+ ...tooltipTokens(ui),
118
172
  trigger: "item",
119
173
  formatter: (params) => {
120
174
  const [xIdx, yIdx, value] = params.data;
@@ -131,16 +185,16 @@ function buildHeatmapOption(ctx) {
131
185
  type: "category",
132
186
  data: ctx.xData,
133
187
  splitArea: { show: true },
134
- axisLabel: {
188
+ ...mergeAxisLabel(ui, {
135
189
  rotate: ctx.xData.length > 10 ? 45 : 0,
136
190
  formatter: (v) => truncateLabel(String(v), 10)
137
- }
191
+ })
138
192
  },
139
193
  yAxis: {
140
194
  type: "category",
141
195
  data: ctx.yAxisData,
142
196
  splitArea: { show: true },
143
- axisLabel: { formatter: (v) => truncateLabel(String(v), 12) }
197
+ ...mergeAxisLabel(ui, { formatter: (v) => truncateLabel(String(v), 12) })
144
198
  },
145
199
  visualMap: {
146
200
  min: ctx.min,
@@ -149,6 +203,7 @@ function buildHeatmapOption(ctx) {
149
203
  orient: "vertical",
150
204
  right: "2%",
151
205
  top: "center",
206
+ textStyle: { color: ui.axisTitle },
152
207
  inRange: { color: ctx.colors.length >= 2 ? ctx.colors : ["#f0f0f0", ctx.colors[0]] }
153
208
  },
154
209
  series: [{
@@ -166,14 +221,21 @@ function buildHeatmapOption(ctx) {
166
221
  };
167
222
  }
168
223
  function buildCartesianOption(ctx) {
224
+ const ui = ctx.ui ?? FALLBACK_UI_TOKENS;
169
225
  const { chartType, isTimeSeries, stacked, smooth, showSymbol, symbolSize } = ctx;
170
226
  const hasMultipleSeries = ctx.yFields.length > 1;
171
227
  const seriesType = chartType === "area" ? "line" : chartType;
172
228
  const isScatter = chartType === "scatter";
173
229
  return {
174
230
  ...buildBaseOption(ctx),
175
- tooltip: { trigger: isScatter ? "item" : "axis" },
176
- legend: ctx.showLegend && hasMultipleSeries ? { top: "bottom" } : void 0,
231
+ tooltip: {
232
+ ...tooltipTokens(ui),
233
+ trigger: isScatter ? "item" : "axis"
234
+ },
235
+ legend: ctx.showLegend && hasMultipleSeries ? {
236
+ top: "bottom",
237
+ ...legendTextStyle(ui)
238
+ } : void 0,
177
239
  grid: {
178
240
  left: "10%",
179
241
  right: "10%",
@@ -185,14 +247,15 @@ function buildCartesianOption(ctx) {
185
247
  type: isScatter ? "value" : isTimeSeries ? "time" : "category",
186
248
  data: isScatter || isTimeSeries ? void 0 : ctx.xData,
187
249
  name: ctx.xField ? formatLabel(ctx.xField) : void 0,
188
- axisLabel: isScatter || isTimeSeries ? { show: true } : {
250
+ ...mergeAxisLabel(ui, isScatter || isTimeSeries ? { show: true } : {
189
251
  rotate: ctx.xData.length > 10 ? 45 : 0,
190
252
  formatter: (v) => truncateLabel(String(v), 10)
191
- }
253
+ })
192
254
  },
193
255
  yAxis: {
194
256
  type: "value",
195
- name: ctx.yFields.length === 1 ? formatLabel(ctx.yFields[0]) : void 0
257
+ name: ctx.yFields.length === 1 ? formatLabel(ctx.yFields[0]) : void 0,
258
+ ...axisCommon(ui)
196
259
  },
197
260
  series: ctx.yFields.map((key, idx) => ({
198
261
  name: formatLabel(key),
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","names":[],"sources":["../../../src/react/charts/options.ts"],"sourcesContent":["import type { ChartType } from \"./types\";\nimport {\n createTimeSeriesData,\n escapeHtml,\n formatLabel,\n truncateLabel,\n} from \"./utils\";\n\n// ============================================================================\n// Option Builder Types\n// ============================================================================\n\nexport interface OptionBuilderContext {\n xData: (string | number)[];\n yDataMap: Record<string, (string | number)[]>;\n yFields: string[];\n colors: string[];\n title?: string;\n showLegend: boolean;\n xField?: string;\n}\n\nexport interface CartesianContext extends OptionBuilderContext {\n chartType: ChartType;\n isTimeSeries: boolean;\n stacked: boolean;\n smooth: boolean;\n showSymbol: boolean;\n symbolSize: number;\n}\n\n// ============================================================================\n// Base Option Builder\n// ============================================================================\n\nfunction buildBaseOption(ctx: OptionBuilderContext): Record<string, unknown> {\n return {\n title: ctx.title ? { text: ctx.title, left: \"center\" } : undefined,\n color: ctx.colors,\n };\n}\n\n// ============================================================================\n// Radar Chart Option\n// ============================================================================\n\nexport function buildRadarOption(\n ctx: OptionBuilderContext,\n showArea = true,\n): Record<string, unknown> {\n const maxValue = Math.max(\n ...ctx.yFields.flatMap((f) => ctx.yDataMap[f].map((v) => Number(v) || 0)),\n );\n\n return {\n ...buildBaseOption(ctx),\n tooltip: { trigger: \"item\" },\n legend:\n ctx.showLegend && ctx.yFields.length > 1 ? { top: \"bottom\" } : undefined,\n radar: {\n indicator: ctx.xData.map((name) => ({\n name: String(name),\n max: maxValue * 1.2,\n })),\n shape: \"polygon\",\n },\n series: [\n {\n type: \"radar\",\n data: ctx.yFields.map((key, idx) => ({\n name: formatLabel(key),\n value: ctx.yDataMap[key],\n itemStyle: { color: ctx.colors[idx % ctx.colors.length] },\n areaStyle: showArea ? { opacity: 0.3 } : undefined,\n })),\n },\n ],\n };\n}\n\n// ============================================================================\n// Pie/Donut Chart Option\n// ============================================================================\n\nexport function buildPieOption(\n ctx: OptionBuilderContext,\n chartType: \"pie\" | \"donut\",\n innerRadius: number,\n showLabels: boolean,\n labelPosition: string,\n): Record<string, unknown> {\n const pieData = ctx.xData.map((name, i) => ({\n name: String(name),\n value: ctx.yDataMap[ctx.yFields[0]]?.[i] ?? 0,\n }));\n\n const isDonut = chartType === \"donut\" || innerRadius > 0;\n\n return {\n ...buildBaseOption(ctx),\n tooltip: { trigger: \"item\", formatter: \"{b}: {c} ({d}%)\" },\n legend: ctx.showLegend\n ? { orient: \"vertical\", left: \"left\", top: \"middle\" }\n : undefined,\n series: [\n {\n type: \"pie\",\n radius: isDonut ? [`${innerRadius || 40}%`, \"70%\"] : \"70%\",\n center: [\"60%\", \"50%\"],\n data: pieData,\n label: {\n show: showLabels,\n position: labelPosition,\n formatter: \"{b}: {d}%\",\n color: \"inherit\",\n textBorderWidth: 0,\n },\n emphasis: {\n itemStyle: {\n shadowBlur: 10,\n shadowOffsetX: 0,\n shadowColor: \"rgba(0, 0, 0, 0.5)\",\n },\n },\n },\n ],\n };\n}\n\n// ============================================================================\n// Horizontal Bar Chart Option\n// ============================================================================\n\nexport function buildHorizontalBarOption(\n ctx: OptionBuilderContext,\n stacked: boolean,\n): Record<string, unknown> {\n const hasMultipleSeries = ctx.yFields.length > 1;\n\n return {\n ...buildBaseOption(ctx),\n tooltip: { trigger: \"axis\", axisPointer: { type: \"shadow\" } },\n legend: ctx.showLegend && hasMultipleSeries ? { top: \"bottom\" } : undefined,\n grid: {\n left: \"20%\",\n right: \"10%\",\n top: ctx.title ? \"15%\" : \"5%\",\n bottom: ctx.showLegend && hasMultipleSeries ? \"15%\" : \"5%\",\n },\n xAxis: { type: \"value\" },\n yAxis: {\n type: \"category\",\n data: ctx.xData,\n axisLabel: {\n width: 100,\n overflow: \"truncate\",\n formatter: (value: string) => truncateLabel(String(value)),\n },\n },\n series: ctx.yFields.map((key, idx) => ({\n name: formatLabel(key),\n type: \"bar\",\n data: ctx.yDataMap[key],\n stack: stacked ? \"total\" : undefined,\n itemStyle: { borderRadius: [0, 4, 4, 0] },\n color: ctx.colors[idx % ctx.colors.length],\n })),\n };\n}\n\n// ============================================================================\n// Heatmap Chart Option\n// ============================================================================\n\nexport interface HeatmapContext extends OptionBuilderContext {\n /** Y-axis categories (rows) */\n yAxisData: (string | number)[];\n /** Heatmap data as [xIndex, yIndex, value] tuples */\n heatmapData: [number, number, number][];\n /** Min value for color scale */\n min: number;\n /** Max value for color scale */\n max: number;\n /** Show value labels on cells */\n showLabels: boolean;\n}\n\nexport function buildHeatmapOption(\n ctx: HeatmapContext,\n): Record<string, unknown> {\n return {\n ...buildBaseOption(ctx),\n tooltip: {\n trigger: \"item\",\n formatter: (params: { data: [number, number, number] }) => {\n const [xIdx, yIdx, value] = params.data;\n // Function formatter output is injected as raw HTML into the\n // tooltip DOM, so data-derived labels must be escaped.\n const xLabel = escapeHtml(String(ctx.xData[xIdx] ?? xIdx));\n const yLabel = escapeHtml(String(ctx.yAxisData[yIdx] ?? yIdx));\n return `${xLabel}, ${yLabel}: ${escapeHtml(String(value))}`;\n },\n },\n grid: {\n left: \"15%\",\n right: \"15%\",\n top: ctx.title ? \"15%\" : \"10%\",\n bottom: \"15%\",\n },\n xAxis: {\n type: \"category\",\n data: ctx.xData,\n splitArea: { show: true },\n axisLabel: {\n rotate: ctx.xData.length > 10 ? 45 : 0,\n formatter: (v: string) => truncateLabel(String(v), 10),\n },\n },\n yAxis: {\n type: \"category\",\n data: ctx.yAxisData,\n splitArea: { show: true },\n axisLabel: {\n formatter: (v: string) => truncateLabel(String(v), 12),\n },\n },\n visualMap: {\n min: ctx.min,\n max: ctx.max,\n calculable: true,\n orient: \"vertical\",\n right: \"2%\",\n top: \"center\",\n inRange: {\n color: ctx.colors.length >= 2 ? ctx.colors : [\"#f0f0f0\", ctx.colors[0]],\n },\n },\n series: [\n {\n type: \"heatmap\",\n data: ctx.heatmapData,\n label: {\n show: ctx.showLabels,\n formatter: (params: { data: [number, number, number] }) =>\n String(params.data[2]),\n },\n emphasis: {\n itemStyle: {\n shadowBlur: 10,\n shadowColor: \"rgba(0, 0, 0, 0.5)\",\n },\n },\n },\n ],\n };\n}\n\n// ============================================================================\n// Cartesian Chart Option (line, bar, area, scatter)\n// ============================================================================\n\nexport function buildCartesianOption(\n ctx: CartesianContext,\n): Record<string, unknown> {\n const { chartType, isTimeSeries, stacked, smooth, showSymbol, symbolSize } =\n ctx;\n const hasMultipleSeries = ctx.yFields.length > 1;\n const seriesType = chartType === \"area\" ? \"line\" : chartType;\n const isScatter = chartType === \"scatter\";\n\n return {\n ...buildBaseOption(ctx),\n tooltip: { trigger: isScatter ? \"item\" : \"axis\" },\n legend: ctx.showLegend && hasMultipleSeries ? { top: \"bottom\" } : undefined,\n grid: {\n left: \"10%\",\n right: \"10%\",\n top: ctx.title ? \"15%\" : \"10%\",\n bottom: ctx.showLegend && hasMultipleSeries ? \"20%\" : \"15%\",\n containLabel: true,\n },\n xAxis: {\n type: isScatter ? \"value\" : isTimeSeries ? \"time\" : \"category\",\n data: isScatter || isTimeSeries ? undefined : ctx.xData,\n name: ctx.xField ? formatLabel(ctx.xField) : undefined,\n axisLabel:\n isScatter || isTimeSeries\n ? { show: true }\n : {\n rotate: ctx.xData.length > 10 ? 45 : 0,\n formatter: (v: string) => truncateLabel(String(v), 10),\n },\n },\n yAxis: {\n type: \"value\",\n name: ctx.yFields.length === 1 ? formatLabel(ctx.yFields[0]) : undefined,\n },\n series: ctx.yFields.map((key, idx) => ({\n name: formatLabel(key),\n type: seriesType,\n data: isScatter\n ? ctx.xData.map((x, i) => [x, ctx.yDataMap[key][i]])\n : isTimeSeries\n ? createTimeSeriesData(ctx.xData, ctx.yDataMap[key])\n : ctx.yDataMap[key],\n smooth: chartType === \"line\" || chartType === \"area\" ? smooth : undefined,\n showSymbol:\n chartType === \"line\" || chartType === \"area\" ? showSymbol : undefined,\n symbol: isScatter ? \"circle\" : undefined,\n symbolSize: isScatter ? symbolSize : undefined,\n areaStyle: chartType === \"area\" ? { opacity: 0.3 } : undefined,\n stack: stacked && chartType === \"area\" ? \"total\" : undefined,\n itemStyle:\n chartType === \"bar\" ? { borderRadius: [4, 4, 0, 0] } : undefined,\n color: ctx.colors[idx % ctx.colors.length],\n })),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"options.js","names":[],"sources":["../../../src/react/charts/options.ts"],"sourcesContent":["import { FALLBACK_UI_TOKENS } from \"./constants\";\nimport type { ChartType, ChartUITokens } from \"./types\";\nimport {\n createTimeSeriesData,\n escapeHtml,\n formatLabel,\n truncateLabel,\n} from \"./utils\";\n\n// ============================================================================\n// Option Builder Types\n// ============================================================================\n\nexport interface OptionBuilderContext {\n xData: (string | number)[];\n yDataMap: Record<string, (string | number)[]>;\n yFields: string[];\n colors: string[];\n title?: string;\n showLegend: boolean;\n xField?: string;\n ui?: ChartUITokens;\n}\n\nexport interface CartesianContext extends OptionBuilderContext {\n chartType: ChartType;\n isTimeSeries: boolean;\n stacked: boolean;\n smooth: boolean;\n showSymbol: boolean;\n symbolSize: number;\n}\n\n// ============================================================================\n// Base Option Builder\n// ============================================================================\n\nfunction buildBaseOption(ctx: OptionBuilderContext): Record<string, unknown> {\n const ui = ctx.ui ?? FALLBACK_UI_TOKENS;\n return {\n title: ctx.title\n ? {\n text: ctx.title,\n left: \"center\",\n textStyle: { color: ui.axisTitle },\n }\n : undefined,\n color: ctx.colors,\n };\n}\n\nfunction axisCommon(ui: ChartUITokens) {\n return {\n axisLabel: { color: ui.axisLabel },\n axisLine: { lineStyle: { color: ui.grid } },\n axisTick: { lineStyle: { color: ui.grid } },\n splitLine: { lineStyle: { color: ui.grid } },\n nameTextStyle: { color: ui.axisTitle },\n };\n}\n\nfunction mergeAxisLabel(\n ui: ChartUITokens,\n axisLabel: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n ...axisCommon(ui),\n axisLabel: { color: ui.axisLabel, ...axisLabel },\n };\n}\n\nfunction legendTextStyle(ui: ChartUITokens) {\n return { textStyle: { color: ui.axisTitle } };\n}\n\nfunction tooltipTokens(ui: ChartUITokens) {\n return {\n backgroundColor: ui.tooltipBg,\n borderColor: ui.grid,\n textStyle: { color: ui.axisTitle },\n };\n}\n\n// ============================================================================\n// Radar Chart Option\n// ============================================================================\n\nexport function buildRadarOption(\n ctx: OptionBuilderContext,\n showArea = true,\n): Record<string, unknown> {\n const ui = ctx.ui ?? FALLBACK_UI_TOKENS;\n const maxValue = Math.max(\n ...ctx.yFields.flatMap((f) => ctx.yDataMap[f].map((v) => Number(v) || 0)),\n );\n\n return {\n ...buildBaseOption(ctx),\n tooltip: { ...tooltipTokens(ui), trigger: \"item\" },\n legend:\n ctx.showLegend && ctx.yFields.length > 1\n ? { top: \"bottom\", ...legendTextStyle(ui) }\n : undefined,\n radar: {\n indicator: ctx.xData.map((name) => ({\n name: String(name),\n max: maxValue * 1.2,\n })),\n shape: \"polygon\",\n axisName: { color: ui.axisTitle },\n axisLine: { lineStyle: { color: ui.grid } },\n splitLine: { lineStyle: { color: ui.grid } },\n },\n series: [\n {\n type: \"radar\",\n data: ctx.yFields.map((key, idx) => ({\n name: formatLabel(key),\n value: ctx.yDataMap[key],\n itemStyle: { color: ctx.colors[idx % ctx.colors.length] },\n areaStyle: showArea ? { opacity: 0.3 } : undefined,\n })),\n },\n ],\n };\n}\n\n// ============================================================================\n// Pie/Donut Chart Option\n// ============================================================================\n\nexport function buildPieOption(\n ctx: OptionBuilderContext,\n chartType: \"pie\" | \"donut\",\n innerRadius: number,\n showLabels: boolean,\n labelPosition: string,\n): Record<string, unknown> {\n const ui = ctx.ui ?? FALLBACK_UI_TOKENS;\n const pieData = ctx.xData.map((name, i) => ({\n name: String(name),\n value: ctx.yDataMap[ctx.yFields[0]]?.[i] ?? 0,\n }));\n\n const isDonut = chartType === \"donut\" || innerRadius > 0;\n\n return {\n ...buildBaseOption(ctx),\n tooltip: {\n ...tooltipTokens(ui),\n trigger: \"item\",\n formatter: \"{b}: {c} ({d}%)\",\n },\n legend: ctx.showLegend\n ? {\n orient: \"vertical\",\n left: \"left\",\n top: \"middle\",\n ...legendTextStyle(ui),\n }\n : undefined,\n series: [\n {\n type: \"pie\",\n radius: isDonut ? [`${innerRadius || 40}%`, \"70%\"] : \"70%\",\n center: [\"60%\", \"50%\"],\n data: pieData,\n label: {\n show: showLabels,\n position: labelPosition,\n formatter: \"{b}: {d}%\",\n color: \"inherit\",\n textBorderWidth: 0,\n },\n emphasis: {\n itemStyle: {\n shadowBlur: 10,\n shadowOffsetX: 0,\n shadowColor: \"rgba(0, 0, 0, 0.5)\",\n },\n },\n },\n ],\n };\n}\n\n// ============================================================================\n// Horizontal Bar Chart Option\n// ============================================================================\n\nexport function buildHorizontalBarOption(\n ctx: OptionBuilderContext,\n stacked: boolean,\n): Record<string, unknown> {\n const ui = ctx.ui ?? FALLBACK_UI_TOKENS;\n const hasMultipleSeries = ctx.yFields.length > 1;\n\n return {\n ...buildBaseOption(ctx),\n tooltip: {\n ...tooltipTokens(ui),\n trigger: \"axis\",\n axisPointer: { type: \"shadow\" },\n },\n legend:\n ctx.showLegend && hasMultipleSeries\n ? { top: \"bottom\", ...legendTextStyle(ui) }\n : undefined,\n grid: {\n left: \"20%\",\n right: \"10%\",\n top: ctx.title ? \"15%\" : \"5%\",\n bottom: ctx.showLegend && hasMultipleSeries ? \"15%\" : \"5%\",\n },\n xAxis: { type: \"value\", ...axisCommon(ui) },\n yAxis: {\n type: \"category\",\n data: ctx.xData,\n ...mergeAxisLabel(ui, {\n width: 100,\n overflow: \"truncate\",\n formatter: (value: string) => truncateLabel(String(value)),\n }),\n },\n series: ctx.yFields.map((key, idx) => ({\n name: formatLabel(key),\n type: \"bar\",\n data: ctx.yDataMap[key],\n stack: stacked ? \"total\" : undefined,\n itemStyle: { borderRadius: [0, 4, 4, 0] },\n color: ctx.colors[idx % ctx.colors.length],\n })),\n };\n}\n\n// ============================================================================\n// Heatmap Chart Option\n// ============================================================================\n\nexport interface HeatmapContext extends OptionBuilderContext {\n /** Y-axis categories (rows) */\n yAxisData: (string | number)[];\n /** Heatmap data as [xIndex, yIndex, value] tuples */\n heatmapData: [number, number, number][];\n /** Min value for color scale */\n min: number;\n /** Max value for color scale */\n max: number;\n /** Show value labels on cells */\n showLabels: boolean;\n}\n\nexport function buildHeatmapOption(\n ctx: HeatmapContext,\n): Record<string, unknown> {\n const ui = ctx.ui ?? FALLBACK_UI_TOKENS;\n return {\n ...buildBaseOption(ctx),\n tooltip: {\n ...tooltipTokens(ui),\n trigger: \"item\",\n formatter: (params: { data: [number, number, number] }) => {\n const [xIdx, yIdx, value] = params.data;\n // Function formatter output is injected as raw HTML into the\n // tooltip DOM, so data-derived labels must be escaped.\n const xLabel = escapeHtml(String(ctx.xData[xIdx] ?? xIdx));\n const yLabel = escapeHtml(String(ctx.yAxisData[yIdx] ?? yIdx));\n return `${xLabel}, ${yLabel}: ${escapeHtml(String(value))}`;\n },\n },\n grid: {\n left: \"15%\",\n right: \"15%\",\n top: ctx.title ? \"15%\" : \"10%\",\n bottom: \"15%\",\n },\n xAxis: {\n type: \"category\",\n data: ctx.xData,\n splitArea: { show: true },\n ...mergeAxisLabel(ui, {\n rotate: ctx.xData.length > 10 ? 45 : 0,\n formatter: (v: string) => truncateLabel(String(v), 10),\n }),\n },\n yAxis: {\n type: \"category\",\n data: ctx.yAxisData,\n splitArea: { show: true },\n ...mergeAxisLabel(ui, {\n formatter: (v: string) => truncateLabel(String(v), 12),\n }),\n },\n visualMap: {\n min: ctx.min,\n max: ctx.max,\n calculable: true,\n orient: \"vertical\",\n right: \"2%\",\n top: \"center\",\n textStyle: { color: ui.axisTitle },\n inRange: {\n color: ctx.colors.length >= 2 ? ctx.colors : [\"#f0f0f0\", ctx.colors[0]],\n },\n },\n series: [\n {\n type: \"heatmap\",\n data: ctx.heatmapData,\n label: {\n show: ctx.showLabels,\n formatter: (params: { data: [number, number, number] }) =>\n String(params.data[2]),\n },\n emphasis: {\n itemStyle: {\n shadowBlur: 10,\n shadowColor: \"rgba(0, 0, 0, 0.5)\",\n },\n },\n },\n ],\n };\n}\n\n// ============================================================================\n// Cartesian Chart Option (line, bar, area, scatter)\n// ============================================================================\n\nexport function buildCartesianOption(\n ctx: CartesianContext,\n): Record<string, unknown> {\n const ui = ctx.ui ?? FALLBACK_UI_TOKENS;\n const { chartType, isTimeSeries, stacked, smooth, showSymbol, symbolSize } =\n ctx;\n const hasMultipleSeries = ctx.yFields.length > 1;\n const seriesType = chartType === \"area\" ? \"line\" : chartType;\n const isScatter = chartType === \"scatter\";\n\n return {\n ...buildBaseOption(ctx),\n tooltip: { ...tooltipTokens(ui), trigger: isScatter ? \"item\" : \"axis\" },\n legend:\n ctx.showLegend && hasMultipleSeries\n ? { top: \"bottom\", ...legendTextStyle(ui) }\n : undefined,\n grid: {\n left: \"10%\",\n right: \"10%\",\n top: ctx.title ? \"15%\" : \"10%\",\n bottom: ctx.showLegend && hasMultipleSeries ? \"20%\" : \"15%\",\n containLabel: true,\n },\n xAxis: {\n type: isScatter ? \"value\" : isTimeSeries ? \"time\" : \"category\",\n data: isScatter || isTimeSeries ? undefined : ctx.xData,\n name: ctx.xField ? formatLabel(ctx.xField) : undefined,\n ...mergeAxisLabel(\n ui,\n isScatter || isTimeSeries\n ? { show: true }\n : {\n rotate: ctx.xData.length > 10 ? 45 : 0,\n formatter: (v: string) => truncateLabel(String(v), 10),\n },\n ),\n },\n yAxis: {\n type: \"value\",\n name: ctx.yFields.length === 1 ? formatLabel(ctx.yFields[0]) : undefined,\n ...axisCommon(ui),\n },\n series: ctx.yFields.map((key, idx) => ({\n name: formatLabel(key),\n type: seriesType,\n data: isScatter\n ? ctx.xData.map((x, i) => [x, ctx.yDataMap[key][i]])\n : isTimeSeries\n ? createTimeSeriesData(ctx.xData, ctx.yDataMap[key])\n : ctx.yDataMap[key],\n smooth: chartType === \"line\" || chartType === \"area\" ? smooth : undefined,\n showSymbol:\n chartType === \"line\" || chartType === \"area\" ? showSymbol : undefined,\n symbol: isScatter ? \"circle\" : undefined,\n symbolSize: isScatter ? symbolSize : undefined,\n areaStyle: chartType === \"area\" ? { opacity: 0.3 } : undefined,\n stack: stacked && chartType === \"area\" ? \"total\" : undefined,\n itemStyle:\n chartType === \"bar\" ? { borderRadius: [4, 4, 0, 0] } : undefined,\n color: ctx.colors[idx % ctx.colors.length],\n })),\n };\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ChartColorPalette } from "./types.js";
1
+ import { ChartColorPalette, ChartUITokens } from "./types.js";
2
2
 
3
3
  //#region src/react/charts/theme.d.ts
4
4
  /**
@@ -8,6 +8,12 @@ import { ChartColorPalette } from "./types.js";
8
8
  * @param palette - Color palette type: "categorical" (default), "sequential", or "diverging"
9
9
  */
10
10
  declare function useThemeColors(palette?: ChartColorPalette): string[];
11
+ /**
12
+ * Hook to get the chart UI tokens (axis text, titles, grid lines) with automatic
13
+ * updates on theme change. Pass the result into the ECharts option builders so
14
+ * axis labels, lines, legends, and titles follow the active theme.
15
+ */
16
+ declare function useChartUITokens(): ChartUITokens;
11
17
  /**
12
18
  * Hook to get all three color palettes at once.
13
19
  * Useful when a component needs access to multiple palette types.
@@ -18,5 +24,5 @@ declare function useAllThemeColors(): {
18
24
  diverging: string[];
19
25
  };
20
26
  //#endregion
21
- export { useAllThemeColors, useThemeColors };
27
+ export { useAllThemeColors, useChartUITokens, useThemeColors };
22
28
  //# sourceMappingURL=theme.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","names":[],"sources":["../../../src/react/charts/theme.ts"],"mappings":";;;;AAkIA;;;;;iBAxCgB,cAAA,CACd,OAAA,GAAS,iBAAA;;;;;iBAuCK,iBAAA,CAAA;EACd,WAAA;EACA,UAAA;EACA,SAAA;AAAA"}
1
+ {"version":3,"file":"theme.d.ts","names":[],"sources":["../../../src/react/charts/theme.ts"],"mappings":";;;AAyNA;;;;;AAmBA;AAnBA,iBAxBgB,cAAA,CACd,OAAA,GAAS,iBAAA;;;;;;iBAuBK,gBAAA,CAAA,GAAoB,aAAA;;;;;iBAmBpB,iBAAA,CAAA;EACd,WAAA;EACA,UAAA;EACA,SAAA;AAAA"}