src/services/chartConfig.ts
Rama main · réplica de lectura del repositorio original.
/**
* Shared Chart.js configuration utilities for consistent styling across all dashboard charts
*/
interface AxisConfig {
grid?: {
color: string
drawBorder?: boolean
borderColor?: string
}
border?: {
display?: boolean
color?: string
}
ticks?: {
color: string
maxRotation?: number
autoSkip?: boolean
callback?: (value: string | number) => string
}
beginAtZero?: boolean
stacked?: boolean
suggestedMax?: number
max?: number
}
interface LegendConfig {
display: boolean
position?: 'top' | 'bottom' | 'left' | 'right'
labels?: {
color: string
padding?: number
font?: {
size?: number
}
}
}
/**
* Creates standardized x-axis configuration
*/
export function createXAxisConfig(isDark: boolean, options: { stacked?: boolean } = {}) {
const gridColor = isDark ? '#323e4e' : '#cad5e2'
const config: AxisConfig = {
grid: {
color: gridColor,
},
// Hide the axis border line (first vertical line) to match grid lines
border: {
display: false,
},
ticks: {
color: isDark ? 'white' : 'black',
maxRotation: 0,
autoSkip: true,
},
}
if (options.stacked !== undefined) {
config.stacked = options.stacked
}
return config
}
/**
* Creates standardized y-axis configuration
*/
export function createYAxisConfig(
isDark: boolean,
options: {
stacked?: boolean
suggestedMax?: number
max?: number
tickCallback?: (value: string | number) => string
} = {},
) {
const gridColor = isDark ? '#424e5f' : '#bfc9d6'
const config: AxisConfig = {
beginAtZero: true,
grid: {
color: gridColor,
},
// Hide the axis border line (bottom horizontal line) to match grid lines
border: {
display: false,
},
ticks: {
color: isDark ? 'white' : 'black',
},
}
if (options.stacked !== undefined) {
config.stacked = options.stacked
}
if (options.suggestedMax !== undefined) {
config.suggestedMax = options.suggestedMax
}
if (options.max !== undefined) {
config.max = options.max
}
if (options.tickCallback) {
config.ticks!.callback = options.tickCallback
}
return config
}
/**
* Creates chart scales configuration (x and y axes)
*/
export function createChartScales(
isDark: boolean,
options: {
xStacked?: boolean
yStacked?: boolean
suggestedMax?: number
max?: number
yTickCallback?: (value: string | number) => string
} = {},
) {
return {
x: createXAxisConfig(isDark, { stacked: options.xStacked }),
y: createYAxisConfig(isDark, {
stacked: options.yStacked,
suggestedMax: options.suggestedMax,
max: options.max,
tickCallback: options.yTickCallback,
}),
}
}
/**
* Creates stacked chart scales with conditional stacking
*/
export function createStackedChartScales(isDark: boolean, stacked: boolean) {
return createChartScales(isDark, {
xStacked: stacked,
yStacked: stacked,
})
}
/**
* Creates standardized legend configuration
*/
export function createLegendConfig(
isDark: boolean,
display: boolean,
options: {
position?: 'top' | 'bottom' | 'left' | 'right'
fontSize?: number
padding?: number
} = {},
): LegendConfig {
return {
display,
position: options.position ?? 'bottom',
labels: {
color: isDark ? 'white' : 'black',
padding: options.padding ?? 10,
font: {
size: options.fontSize ?? 11,
},
},
}
}