@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.
- package/dist/react/charts/base.js +5 -2
- package/dist/react/charts/base.js.map +1 -1
- package/dist/react/charts/constants.d.ts +1 -0
- package/dist/react/charts/constants.d.ts.map +1 -1
- package/dist/react/charts/constants.js +15 -1
- package/dist/react/charts/constants.js.map +1 -1
- package/dist/react/charts/index.d.ts +2 -2
- package/dist/react/charts/index.js +1 -1
- package/dist/react/charts/options.d.ts +2 -1
- package/dist/react/charts/options.d.ts.map +1 -1
- package/dist/react/charts/options.js +80 -17
- package/dist/react/charts/options.js.map +1 -1
- package/dist/react/charts/theme.d.ts +8 -2
- package/dist/react/charts/theme.d.ts.map +1 -1
- package/dist/react/charts/theme.js +89 -30
- package/dist/react/charts/theme.js.map +1 -1
- package/dist/react/charts/types.d.ts +12 -1
- package/dist/react/charts/types.d.ts.map +1 -1
- package/dist/react/charts/types.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +2 -2
- package/dist/styles.css +65 -5
- package/docs/development/type-generation.md +4 -0
- package/docs/plugins/analytics.md +15 -0
- package/package.json +1 -1
- package/sbom.cdx.json +1 -1
|
@@ -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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","names":[],"sources":["../../../src/react/charts/constants.ts"],"mappings":"
|
|
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":";;;;
|
|
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":";;;
|
|
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: {
|
|
18
|
-
|
|
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 ? {
|
|
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: {
|
|
138
|
+
xAxis: {
|
|
139
|
+
type: "value",
|
|
140
|
+
...axisCommon(ui)
|
|
141
|
+
},
|
|
90
142
|
yAxis: {
|
|
91
143
|
type: "category",
|
|
92
144
|
data: ctx.xData,
|
|
93
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: {
|
|
176
|
-
|
|
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
|
-
|
|
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":"
|
|
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"}
|