Update dark mode improvements for chart

This commit is contained in:
2026-02-04 15:18:58 +00:00
parent efa45ab288
commit b7a585a223

View File

@@ -85,6 +85,26 @@ const SimulationChart = ({
return () => window.removeEventListener('resize', updateWidth); return () => window.removeEventListener('resize', updateWidth);
}, []); }, []);
// Track current theme for chart styling
const [isDarkTheme, setIsDarkTheme] = React.useState(false);
React.useEffect(() => {
const checkTheme = () => {
setIsDarkTheme(document.documentElement.classList.contains('dark'));
};
checkTheme();
// Use MutationObserver to detect theme changes
const observer = new MutationObserver(checkTheme);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
return () => observer.disconnect();
}, []);
// Y-axis takes ~80px, scrollable area gets the rest // Y-axis takes ~80px, scrollable area gets the rest
const yAxisWidth = 80; const yAxisWidth = 80;
const scrollableWidth = containerWidth - yAxisWidth; const scrollableWidth = containerWidth - yAxisWidth;
@@ -161,7 +181,7 @@ const SimulationChart = ({
return ticks; return ticks;
}, [totalHours, xTickInterval]); }, [totalHours, xTickInterval]);
// Custom tick renderer for x-axis to handle 12h/24h/continuous formats // Custom tick renderer for x-axis to handle 12h/24h/continuous formats and dark mode
const XAxisTick = (props: any) => { const XAxisTick = (props: any) => {
const { x, y, payload } = props; const { x, y, payload } = props;
const h = payload.value as number; const h = payload.value as number;
@@ -173,7 +193,7 @@ const SimulationChart = ({
if (hour12 === 12) { if (hour12 === 12) {
label = t('tickNoon'); label = t('tickNoon');
return ( return (
<text x={x} y={y + 12} textAnchor="middle" fontStyle="italic" fill="#666"> <text x={x} y={y + 12} textAnchor="middle" fontStyle="italic" fill={isDarkTheme ? '#ccc' : '#666'}>
{label} {label}
</text> </text>
); );
@@ -185,12 +205,22 @@ const SimulationChart = ({
label = `${h}`; label = `${h}`;
} }
return ( return (
<text x={x} y={y + 12} textAnchor="middle" fill="#666"> <text x={x} y={y + 12} textAnchor="middle" fill={isDarkTheme ? '#ccc' : '#666'}>
{label} {label}
</text> </text>
); );
}; };
// Custom tick renderre for y-axis to handle dark mode
const YAxisTick = (props: any) => {
const { x, y, payload } = props;
return (
<text x={x} y={y + 4} textAnchor="end" fill={isDarkTheme ? '#ccc' : '#666'}>
{payload.value}
</text>
);
};
// Calculate Y-axis domain based on data and user settings // Calculate Y-axis domain based on data and user settings
const yAxisDomain = React.useMemo(() => { const yAxisDomain = React.useMemo(() => {
const numMin = parseFloat(yAxisMin); const numMin = parseFloat(yAxisMin);
@@ -454,6 +484,7 @@ const SimulationChart = ({
dataKey="timeHours" dataKey="timeHours"
type="number" type="number"
domain={[0, totalHours]} domain={[0, totalHours]}
axisLine={{ stroke: isDarkTheme ? '#ccc' : '#666' }}
tick={<XAxisTick />} tick={<XAxisTick />}
ticks={xAxisTicks} ticks={xAxisTicks}
tickCount={xAxisTicks.length} tickCount={xAxisTicks.length}
@@ -467,6 +498,8 @@ const SimulationChart = ({
// FIXME // FIXME
//label={{ value: t('axisLabelConcentration'), angle: -90, position: 'insideLeft', style: { fontStyle: 'italic', color: '#666' } }} //label={{ value: t('axisLabelConcentration'), angle: -90, position: 'insideLeft', style: { fontStyle: 'italic', color: '#666' } }}
domain={yAxisDomain as any} domain={yAxisDomain as any}
axisLine={{ stroke: isDarkTheme ? '#ccc' : '#666' }}
tick={<YAxisTick />}
tickCount={16} tickCount={16}
interval={0} interval={0}
allowDecimals={false} allowDecimals={false}
@@ -527,8 +560,10 @@ const SimulationChart = ({
allowEscapeViewBox={{ x: false, y: false }} allowEscapeViewBox={{ x: false, y: false }}
cursor={{ stroke: CHART_COLORS.cursor, strokeWidth: 1, strokeDasharray: '1 1' }} cursor={{ stroke: CHART_COLORS.cursor, strokeWidth: 1, strokeDasharray: '1 1' }}
position={{ y: 0 }} position={{ y: 0 }}
/> />
<CartesianGrid strokeDasharray="1 1" xAxisId="hours" yAxisId="concentration" /> <CartesianGrid strokeDasharray="1 1" xAxisId="hours" yAxisId="concentration"
style={{ stroke: isDarkTheme ? '#666' : '#ccc' }}
/>
{showDayReferenceLines !== false && [...Array(dispDays + 1).keys()].map(day => { {showDayReferenceLines !== false && [...Array(dispDays + 1).keys()].map(day => {
// Determine whether to use compact day labels to avoid overlap on narrow screens // Determine whether to use compact day labels to avoid overlap on narrow screens