Fix x-axis tick interval calculation (there were too many, especially on mobile)
This commit is contained in:
@@ -53,16 +53,46 @@ const SimulationChart = ({
|
||||
const totalHours = (parseInt(simulationDays, 10) || 3) * 24;
|
||||
const dispDays = parseInt(displayedDays, 10) || 2;
|
||||
|
||||
// Dynamically calculate tick interval based on displayed days
|
||||
// Aim for ~40-50 pixels per tick for readability
|
||||
// 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;
|
||||
|
||||
// Dynamically calculate tick interval based on available pixel width
|
||||
// Aim for ~46px per label to avoid overlaps on narrow screens
|
||||
const xTickInterval = React.useMemo(() => {
|
||||
// Scale interval with displayed days: 1 day = 1h, 2 days = 2h, 3-4 days = 3h, 5+ days = 6h
|
||||
if (dispDays <= 1) return 1;
|
||||
if (dispDays <= 2) return 2;
|
||||
if (dispDays <= 4) return 3;
|
||||
if (dispDays <= 6) return 4;
|
||||
return 6;
|
||||
}, [dispDays]);
|
||||
const MIN_PX_PER_TICK = 46;
|
||||
const intervals = [1, 2, 3, 4, 6, 8, 12, 24];
|
||||
|
||||
const pxPerDay = scrollableWidth / Math.max(1, dispDays);
|
||||
const ticksPerDay = Math.floor(pxPerDay / MIN_PX_PER_TICK);
|
||||
|
||||
// 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
|
||||
const chartTicks = React.useMemo(() => {
|
||||
@@ -207,28 +237,6 @@ const SimulationChart = ({
|
||||
return Array.from(dataMap.values()).sort((a, b) => a.timeHours - b.timeHours);
|
||||
}, [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
|
||||
const chartWidth = simDays <= dispDays
|
||||
? scrollableWidth
|
||||
|
||||
Reference in New Issue
Block a user