mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
/**
|
|
* Vega-Lite chart config per UI theme (docs/architecture/05 §3, 09 §6).
|
|
*
|
|
* Portable core: a Vega-Lite `Config` styles every chart globally so charts
|
|
* visually belong to the app rather than looking like stock Vega-Lite. This is
|
|
* the single source of truth mapping a `UiTheme` to a config; it is applied at
|
|
* embed time (never baked into the user's stored spec). Adding a UI theme = one
|
|
* config object plus one map entry here.
|
|
*
|
|
* Values track the design language: IBM Plex font, axis/grid colors from the
|
|
* Carbon neutral ramp (matching `--text-secondary` / `--border`), and a
|
|
* categorical `range.category` palette transcribed from Carbon's data-viz
|
|
* 14-color pairing (white theme for light, g100 for dark — see
|
|
* carbon-charts `packages/core/scss/_color-palette.scss`). This is the
|
|
* expressive "free color" layer (doc §3.5, §5).
|
|
*/
|
|
|
|
import type { Config } from 'vega-lite';
|
|
import type { UiTheme } from './theme';
|
|
|
|
const PLEX = '"IBM Plex Sans", system-ui, -apple-system, sans-serif';
|
|
|
|
/** Carbon data-viz 14-color categorical palette — white (light) theme. */
|
|
const lightCategory = [
|
|
'#6929c4', // purple 70
|
|
'#1192e8', // cyan 50
|
|
'#005d5d', // teal 70
|
|
'#9f1853', // magenta 70
|
|
'#fa4d56', // red 50
|
|
'#520408', // red 90
|
|
'#198038', // green 60
|
|
'#002d9c', // blue 80
|
|
'#ee5396', // magenta 50
|
|
'#b28600', // yellow 50
|
|
'#009d9a', // teal 50
|
|
'#012749', // cyan 90
|
|
'#8a3800', // orange 70
|
|
'#a56eff', // purple 50
|
|
];
|
|
|
|
/** Carbon data-viz 14-color categorical palette — g100 (dark) theme. */
|
|
const darkCategory = [
|
|
'#8a3ffc', // purple 60
|
|
'#33b1ff', // cyan 40
|
|
'#007d79', // teal 60
|
|
'#ff7eb6', // magenta 40
|
|
'#fa4d56', // red 50
|
|
'#fff1f1', // red 10
|
|
'#6fdc8c', // green 30
|
|
'#4589ff', // blue 50
|
|
'#d02670', // magenta 60
|
|
'#d2a106', // yellow 40
|
|
'#08bdba', // teal 40
|
|
'#bae6ff', // cyan 20
|
|
'#ba4e00', // orange 60
|
|
'#d4bbff', // purple 30
|
|
];
|
|
|
|
export const lightChartConfig: Config = {
|
|
background: 'transparent',
|
|
font: PLEX,
|
|
title: { fontSize: 16, fontWeight: 600, color: '#161616' },
|
|
axis: {
|
|
domainColor: '#c6c6c6', // --border-strong (light)
|
|
gridColor: '#e0e0e0', // --border (light)
|
|
gridDash: [2, 2],
|
|
labelColor: '#525252', // --text-secondary (light)
|
|
titleColor: '#161616', // --text (light)
|
|
labelFontSize: 11,
|
|
titleFontSize: 12,
|
|
titleFontWeight: 600,
|
|
},
|
|
range: { category: lightCategory },
|
|
view: { stroke: 'transparent' },
|
|
};
|
|
|
|
export const darkChartConfig: Config = {
|
|
background: 'transparent',
|
|
font: PLEX,
|
|
title: { fontSize: 16, fontWeight: 600, color: '#f4f4f4' },
|
|
axis: {
|
|
domainColor: '#525252', // --border-strong (dark)
|
|
gridColor: '#393939', // --border (dark)
|
|
gridDash: [2, 2],
|
|
labelColor: '#a8a8a8', // --text-secondary (dark)
|
|
titleColor: '#f4f4f4', // --text (dark)
|
|
labelFontSize: 11,
|
|
titleFontSize: 12,
|
|
titleFontWeight: 600,
|
|
},
|
|
range: { category: darkCategory },
|
|
view: { stroke: 'transparent' },
|
|
};
|
|
|
|
const CHART_CONFIG: Record<UiTheme, Config> = {
|
|
light: lightChartConfig,
|
|
dark: darkChartConfig,
|
|
};
|
|
|
|
/** The Vega-Lite config for a UI theme — the only theme → config mapping. */
|
|
export function chartConfigFor(theme: UiTheme): Config {
|
|
return CHART_CONFIG[theme];
|
|
}
|