2026-04-04 11:05:01 +00:00
|
|
|
/**
|
|
|
|
|
* Shared theme utilities for ECharts-based chart components.
|
2026-04-04 11:25:19 +00:00
|
|
|
* Uses the centralized themeDefaults tokens so chart colors stay in sync
|
|
|
|
|
* with the rest of the dees-catalog design system.
|
|
|
|
|
*
|
2026-04-04 12:29:39 +00:00
|
|
|
* ECharts renders on <svg> and cannot read CSS custom properties,
|
2026-04-04 11:25:19 +00:00
|
|
|
* so we reference the TypeScript source-of-truth (themeDefaults) directly.
|
2026-04-04 12:29:39 +00:00
|
|
|
*
|
|
|
|
|
* 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.
|
2026-04-04 11:05:01 +00:00
|
|
|
*/
|
|
|
|
|
|
2026-04-04 11:25:19 +00:00
|
|
|
import { themeDefaults } from '../00theme.js';
|
|
|
|
|
|
|
|
|
|
const light = themeDefaults.colors.light;
|
|
|
|
|
const dark = themeDefaults.colors.dark;
|
|
|
|
|
|
2026-04-04 12:29:39 +00:00
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2026-04-04 11:05:01 +00:00
|
|
|
const SERIES_COLORS = {
|
|
|
|
|
dark: [
|
2026-04-04 12:29:39 +00:00
|
|
|
'#60a5fa', // blue-400 — softer in dark mode
|
|
|
|
|
'#2dd4bf', // teal-400
|
|
|
|
|
'#a78bfa', // violet-400
|
|
|
|
|
'#fbbf24', // amber-400
|
|
|
|
|
'#34d399', // emerald-400
|
|
|
|
|
'#fb7185', // rose-400
|
2026-04-04 11:05:01 +00:00
|
|
|
],
|
|
|
|
|
light: [
|
2026-04-04 12:29:39 +00:00
|
|
|
'#3b82f6', // blue-500
|
|
|
|
|
'#14b8a6', // teal-500
|
|
|
|
|
'#8b5cf6', // violet-500
|
|
|
|
|
'#f59e0b', // amber-500
|
|
|
|
|
'#10b981', // emerald-500
|
|
|
|
|
'#f43f5e', // rose-500
|
2026-04-04 11:05:01 +00:00
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function getEchartsSeriesColors(goBright: boolean): string[] {
|
|
|
|
|
return goBright ? SERIES_COLORS.light : SERIES_COLORS.dark;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-04 12:29:39 +00:00
|
|
|
/**
|
|
|
|
|
* 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})`;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-04 11:05:01 +00:00
|
|
|
export function getEchartsThemeOptions(goBright: boolean): Record<string, any> {
|
2026-04-04 11:25:19 +00:00
|
|
|
const colors = goBright ? light : dark;
|
2026-04-04 11:05:01 +00:00
|
|
|
return {
|
|
|
|
|
backgroundColor: 'transparent',
|
|
|
|
|
textStyle: {
|
2026-04-04 11:25:19 +00:00
|
|
|
color: colors.textSecondary,
|
2026-04-04 11:05:01 +00:00
|
|
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
},
|
2026-04-04 12:29:39 +00:00
|
|
|
// No global `color` array — each component sets per-item/per-series
|
|
|
|
|
// colors explicitly to avoid conflicts during emphasis animations.
|
2026-04-04 11:05:01 +00:00
|
|
|
tooltip: {
|
2026-04-04 11:25:19 +00:00
|
|
|
backgroundColor: colors.bgPrimary,
|
|
|
|
|
borderColor: colors.borderDefault,
|
2026-04-04 11:05:01 +00:00
|
|
|
textStyle: {
|
2026-04-04 11:25:19 +00:00
|
|
|
color: colors.textPrimary,
|
2026-04-04 11:05:01 +00:00
|
|
|
fontSize: 12,
|
|
|
|
|
},
|
|
|
|
|
confine: true,
|
|
|
|
|
},
|
|
|
|
|
legend: {
|
|
|
|
|
textStyle: {
|
2026-04-04 11:25:19 +00:00
|
|
|
color: colors.textSecondary,
|
2026-04-04 11:05:01 +00:00
|
|
|
fontSize: 12,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
2026-04-04 11:25:19 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper to get the resolved theme colors object for use in buildOption().
|
|
|
|
|
*/
|
|
|
|
|
export function getThemeColors(goBright: boolean) {
|
|
|
|
|
return goBright ? light : dark;
|
|
|
|
|
}
|