Skip to content

Commit c542414

Browse files
added year in X-axis
1 parent 4b7b9c1 commit c542414

2 files changed

Lines changed: 44 additions & 35 deletions

File tree

src/components/BMDashboard/InjuriesOverTime/InjuriesOverTimeChart.jsx

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,7 @@ import styles from './InjuriesOverTimeChart.module.css';
2020
const { Option } = Select;
2121
const { RangePicker } = DatePicker;
2222

23-
const MONTHS = [
24-
'January',
25-
'February',
26-
'March',
27-
'April',
28-
'May',
29-
'June',
30-
'July',
31-
'August',
32-
'September',
33-
'October',
34-
'November',
35-
'December',
36-
];
37-
3823
const shortId = id => (id ? String(id).slice(-6) : 'unknown');
39-
4024
const generateColors = n =>
4125
Array.from({ length: n }, (_, i) => `hsl(${Math.round((360 / Math.max(n, 1)) * i)},60%,55%)`);
4226

@@ -46,7 +30,7 @@ function CustomTooltip({ active, payload, label, darkMode }) {
4630
<div className={`${styles.tooltip} ${darkMode ? styles.tooltipDark : ''}`}>
4731
<div style={{ fontWeight: 600, marginBottom: 6 }}>{label}</div>
4832
{payload
49-
.filter(p => p.value != null && Number(p.value) > 0)
33+
.filter(p => p?.value != null && Number(p.value) > 0)
5034
.map(p => (
5135
<div key={p.dataKey} style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
5236
<span
@@ -144,38 +128,59 @@ function InjuriesOverTimeLine({ darkMode = false }) {
144128
);
145129

146130
const chartData = useMemo(() => {
131+
const keysSet = new Set(filtered.map(r => dayjs(r.date).format('YYYY-MM')));
132+
const monthKeys = Array.from(keysSet).sort();
133+
147134
const totals = new Map();
148135
filtered.forEach(r => {
149-
const monthIdx = dayjs(r.date).month();
136+
const k = dayjs(r.date).format('YYYY-MM');
150137
const pid = String(r.projectId);
151-
const key = `${monthIdx}|${pid}`;
152-
totals.set(key, (totals.get(key) || 0) + (Number(r.count) || 0));
138+
const mapKey = `${k}|${pid}`;
139+
totals.set(mapKey, (totals.get(mapKey) || 0) + (Number(r.count) || 0));
153140
});
154141

155-
const rows = MONTHS.map((month, idx) => {
156-
const row = { month };
142+
return monthKeys.map(k => {
143+
const label = dayjs(k + '-01').format('MMM YYYY');
144+
const row = { month: label, _k: k };
157145
visibleProjects.forEach(({ id }) => {
158-
const v = totals.get(`${idx}|${id}`) || 0;
146+
const v = totals.get(`${k}|${id}`) || 0;
159147
row[id] = v > 0 ? v : null;
160148
});
161149
return row;
162150
});
163-
164-
return rows;
165151
}, [filtered, visibleProjects]);
166152

153+
const { yTicks, yDomain } = useMemo(() => {
154+
let dataMax = 0;
155+
for (const row of chartData) {
156+
for (const { id } of visibleProjects) {
157+
const v = row[id];
158+
if (typeof v === 'number' && v > dataMax) dataMax = v;
159+
}
160+
}
161+
162+
const divisions = 5;
163+
if (dataMax <= 0) {
164+
return {
165+
yTicks: Array.from({ length: divisions + 1 }, (_, i) => i),
166+
yDomain: [0, divisions],
167+
};
168+
}
169+
170+
const rawStep = Math.ceil(dataMax / divisions);
171+
const step = Math.max(1, rawStep);
172+
const niceMax = step * divisions;
173+
const ticks = Array.from({ length: divisions + 1 }, (_, i) => i * step);
174+
return { yTicks: ticks, yDomain: [0, niceMax] };
175+
}, [chartData, visibleProjects]);
176+
167177
const lineColors = useMemo(() => generateColors(visibleProjects.length || 1), [
168178
visibleProjects.length,
169179
]);
170180

171-
const maxY = Math.max(...chartData.flatMap(row => visibleProjects.map(p => row[p.id] || 0)), 0);
172-
173-
const step = Math.ceil(maxY / 5);
174-
const ticks = Array.from({ length: 6 }, (_, i) => i * step);
175-
176181
return (
177182
<div className={`${styles.wrapper} ${darkMode ? styles.wrapperDark : ''}`}>
178-
<h2 className={styles.title}>Injuries over time</h2>
183+
<h2 className={styles.title}>Injuries over time (Jan 1 2024 - Dec 31 2024)</h2>
179184

180185
<div className={styles.filters}>
181186
<Select
@@ -261,13 +266,17 @@ function InjuriesOverTimeLine({ darkMode = false }) {
261266
<div className={`${styles.chartCard} ${darkMode ? styles.chartCardDark : ''}`}>
262267
<ResponsiveContainer width="100%" height="100%">
263268
<LineChart data={chartData} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}>
264-
<CartesianGrid strokeDasharray="3 3" strokeOpacity={darkMode ? 0.2 : 1} />
269+
<CartesianGrid
270+
stroke={darkMode ? '#2f3b4a' : '#e5e7eb'}
271+
strokeDasharray="3 3"
272+
strokeOpacity={darkMode ? 0.2 : 1}
273+
/>
265274
<XAxis dataKey="month" height={60} angle={-25} textAnchor="end" interval={0} />
266275
<YAxis
267276
label={{ value: 'Injury Count', angle: -90, position: 'insideLeft' }}
268277
allowDecimals={false}
269-
domain={[0, maxY]}
270-
ticks={ticks}
278+
domain={yDomain}
279+
ticks={yTicks}
271280
/>
272281
<Tooltip content={<CustomTooltip darkMode={darkMode} />} />
273282
<Legend verticalAlign="top" align="left" wrapperStyle={{ paddingBottom: 20 }} />

src/components/BMDashboard/InjuriesOverTime/InjuriesOverTimeChart.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
.title {
1313
margin: 0;
1414
padding: 16px 0 8px;
15-
font-size: 20px;
15+
font-size: 25px;
1616
font-weight: 700;
1717
line-height: 1.3;
1818
}

0 commit comments

Comments
 (0)