Files
dees-catalog/ts_web/elements/00group-chart/dees-chart-echarts-theme.ts

92 lines
2.7 KiB
TypeScript

/**
* Shared theme utilities for ECharts-based chart components.
* Uses the centralized themeDefaults tokens so chart colors stay in sync
* with the rest of the dees-catalog design system.
*
* ECharts renders on <svg> and cannot read CSS custom properties,
* so we reference the TypeScript source-of-truth (themeDefaults) directly.
*
* IMPORTANT: All colors passed to ECharts for data series must be hex or rgb/rgba.
* ECharts cannot interpolate HSL strings during hover/emphasis animations,
* causing them to flash black.
*/
import { themeDefaults } from '../00theme.js';
const light = themeDefaults.colors.light;
const dark = themeDefaults.colors.dark;
/**
* Series color palette for ECharts charts.
* Aligned with the Tailwind/shadcn-inspired palette used throughout the codebase.
* All values are hex — ECharts requires this for animation interpolation.
*/
const SERIES_COLORS = {
dark: [
'#60a5fa', // blue-400 — softer in dark mode
'#2dd4bf', // teal-400
'#a78bfa', // violet-400
'#fbbf24', // amber-400
'#34d399', // emerald-400
'#fb7185', // rose-400
],
light: [
'#3b82f6', // blue-500
'#14b8a6', // teal-500
'#8b5cf6', // violet-500
'#f59e0b', // amber-500
'#10b981', // emerald-500
'#f43f5e', // rose-500
],
};
export function getEchartsSeriesColors(goBright: boolean): string[] {
return goBright ? SERIES_COLORS.light : SERIES_COLORS.dark;
}
/**
* Convert a hex color to an rgba string with the given alpha.
*/
export function hexToRgba(hex: string, alpha: number): string {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
export function getEchartsThemeOptions(goBright: boolean): Record<string, any> {
const colors = goBright ? light : dark;
return {
backgroundColor: 'transparent',
textStyle: {
color: colors.textSecondary,
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
fontSize: 12,
},
// No global `color` array — each component sets per-item/per-series
// colors explicitly to avoid conflicts during emphasis animations.
tooltip: {
backgroundColor: colors.bgPrimary,
borderColor: colors.borderDefault,
textStyle: {
color: colors.textPrimary,
fontSize: 12,
},
confine: true,
},
legend: {
textStyle: {
color: colors.textSecondary,
fontSize: 12,
},
},
};
}
/**
* Helper to get the resolved theme colors object for use in buildOption().
*/
export function getThemeColors(goBright: boolean) {
return goBright ? light : dark;
}