Fix x-axis tick interval calculation (there were too many, especially on mobile)

This commit is contained in:
2026-01-10 11:32:35 +00:00
parent 7ca41bc09e
commit 9235d9b9fb

View File

@@ -53,16 +53,46 @@ const SimulationChart = ({
const totalHours = (parseInt(simulationDays, 10) || 3) * 24; const totalHours = (parseInt(simulationDays, 10) || 3) * 24;
const dispDays = parseInt(displayedDays, 10) || 2; const dispDays = parseInt(displayedDays, 10) || 2;
// Dynamically calculate tick interval based on displayed days // Calculate chart dimensions
// Aim for ~40-50 pixels per tick for readability const [containerWidth, setContainerWidth] = React.useState(1000);
const containerRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const updateWidth = () => {
if (containerRef.current) {
setContainerWidth(containerRef.current.clientWidth);
}
};
updateWidth();
window.addEventListener('resize', updateWidth);
return () => window.removeEventListener('resize', updateWidth);
}, []);
const simDays = parseInt(simulationDays, 10) || 3;
// Y-axis takes ~80px, scrollable area gets the rest
const yAxisWidth = 80;
const scrollableWidth = containerWidth - yAxisWidth;
// Dynamically calculate tick interval based on available pixel width
// Aim for ~46px per label to avoid overlaps on narrow screens
const xTickInterval = React.useMemo(() => { const xTickInterval = React.useMemo(() => {
// Scale interval with displayed days: 1 day = 1h, 2 days = 2h, 3-4 days = 3h, 5+ days = 6h const MIN_PX_PER_TICK = 46;
if (dispDays <= 1) return 1; const intervals = [1, 2, 3, 4, 6, 8, 12, 24];
if (dispDays <= 2) return 2;
if (dispDays <= 4) return 3; const pxPerDay = scrollableWidth / Math.max(1, dispDays);
if (dispDays <= 6) return 4; const ticksPerDay = Math.floor(pxPerDay / MIN_PX_PER_TICK);
return 6;
}, [dispDays]); // Plenty of room: allow hourly ticks
if (ticksPerDay >= 16) return 1;
// Extremely tight: show one tick per day boundary
if (ticksPerDay <= 0) return 24;
const idealInterval = 24 / ticksPerDay;
const selected = intervals.find((value) => value >= idealInterval);
return selected ?? 24;
}, [dispDays, scrollableWidth]);
// Generate ticks for continuous time axis // Generate ticks for continuous time axis
const chartTicks = React.useMemo(() => { const chartTicks = React.useMemo(() => {
@@ -207,28 +237,6 @@ const SimulationChart = ({
return Array.from(dataMap.values()).sort((a, b) => a.timeHours - b.timeHours); return Array.from(dataMap.values()).sort((a, b) => a.timeHours - b.timeHours);
}, [combinedProfile, templateProfile, daysWithDeviations]); }, [combinedProfile, templateProfile, daysWithDeviations]);
// Calculate chart dimensions
const [containerWidth, setContainerWidth] = React.useState(1000);
const containerRef = React.useRef<HTMLDivElement>(null);
React.useEffect(() => {
const updateWidth = () => {
if (containerRef.current) {
setContainerWidth(containerRef.current.clientWidth);
}
};
updateWidth();
window.addEventListener('resize', updateWidth);
return () => window.removeEventListener('resize', updateWidth);
}, []);
const simDays = parseInt(simulationDays, 10) || 3;
// Y-axis takes ~80px, scrollable area gets the rest
const yAxisWidth = 80;
const scrollableWidth = containerWidth - yAxisWidth;
// Calculate chart width for scrollable area // Calculate chart width for scrollable area
const chartWidth = simDays <= dispDays const chartWidth = simDays <= dispDays
? scrollableWidth ? scrollableWidth