Skip to content

Commit b237ebe

Browse files
committed
Fix - Improve timeline format
1 parent 076c847 commit b237ebe

File tree

1 file changed

+87
-62
lines changed

1 file changed

+87
-62
lines changed

src/useTimeLabels.js

Lines changed: 87 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { useDateTime } from "./useDateTime";
22
import locales from "./locales/locales.json";
33

4+
const SECONDS_IN_DAY = 24 * 60 * 60;
5+
46
/**
57
* @param {Array<string|number>} values
68
* @param {number} maxDatapoints
79
* @param {{ enable:boolean, useUTC:boolean, locale:string, januaryAsYear:boolean, options:Record<string,string> }} formatter
8-
* @param {number} start // index de début (inclus)
9-
* @param {number} end // index de fin (exclus)
10+
* @param {number} start // start index (provided by Slicer)
11+
* @param {number} end // end index (provided by Slicer)
1012
*/
1113
export function useTimeLabels({
1214
values,
@@ -15,92 +17,115 @@ export function useTimeLabels({
1517
start: sliceStart,
1618
end: sliceEnd
1719
}) {
18-
const raw = values;
1920
const out = [];
20-
2121
if (!xl.enable) {
22-
for (let i = sliceStart; i < sliceEnd; i += 1) {
23-
out.push({ text: raw[i] ?? String(i), absoluteIndex: i });
22+
for (let i = sliceStart; i < sliceEnd; i++) {
23+
out.push({ text: String(values[i] ?? i), absoluteIndex: i });
2424
}
2525
return out;
2626
}
2727

28-
const windowValues = raw.slice(sliceStart, sliceEnd);
29-
28+
const window = values.slice(sliceStart, sliceEnd);
29+
if (window.length === 0) return [];
30+
const minX = window[0], maxX = window[window.length - 1];
3031
const dt = useDateTime({
3132
useUTC: xl.useUTC,
32-
min: windowValues[0],
33-
max: windowValues[windowValues.length - 1],
33+
min: minX,
34+
max: maxX,
3435
locale: locales[xl.locale],
3536
januaryAsYear: xl.januaryAsYear,
3637
});
3738

38-
const ws = new Date(windowValues[0]);
39-
const we = new Date(windowValues[windowValues.length - 1]);
40-
const getMonthFn = xl.useUTC ? "getUTCMonth" : "getMonth";
41-
const getYearFn = xl.useUTC ? "getUTCFullYear" : "getFullYear";
42-
const monthsDiff =
43-
(we[getYearFn]() - ws[getYearFn]()) * 12 +
44-
(we[getMonthFn]() - ws[getMonthFn]());
39+
const rangeMS = maxX - minX;
40+
const daysDiff = rangeMS / (1000 * SECONDS_IN_DAY);
41+
const hoursDiff = daysDiff * 24;
42+
const minutesDiff = hoursDiff * 60;
43+
const secondsDiff = minutesDiff * 60;
4544

46-
const u = dt.getTimeUnitsfromTimestamp(
47-
windowValues[0],
48-
windowValues[windowValues.length - 1]
49-
);
45+
let tickInterval;
46+
switch (true) {
47+
case (daysDiff / 365) > 5:
48+
tickInterval = 'years';
49+
break;
50+
case daysDiff > 800:
51+
tickInterval = 'half_year';
52+
break;
53+
case daysDiff > 180:
54+
tickInterval = 'months';
55+
break;
56+
case daysDiff > 90:
57+
tickInterval = 'months_fortnight';
58+
break;
59+
case daysDiff > 60:
60+
tickInterval = 'months_days';
61+
break;
62+
case daysDiff > 30:
63+
tickInterval = 'week_days';
64+
break;
65+
case daysDiff > 2:
66+
tickInterval = 'days';
67+
break;
68+
case hoursDiff > 2.4:
69+
tickInterval = 'hours';
70+
break;
71+
case minutesDiff > 15:
72+
tickInterval = 'minutes_fives';
73+
break;
74+
case minutesDiff > 5:
75+
tickInterval = 'minutes';
76+
break;
77+
case minutesDiff > 1:
78+
tickInterval = 'seconds_tens';
79+
break;
80+
case secondsDiff > 20:
81+
tickInterval = 'seconds_fives';
82+
break;
83+
default:
84+
tickInterval = 'seconds';
85+
break;
86+
}
5087

51-
let xUnit = "second";
52-
if (u.minMinute !== u.maxMinute) xUnit = "minute";
53-
else if (u.minHour !== u.maxHour) xUnit = "hour";
54-
else if (u.minDate !== u.maxDate) xUnit = "day";
55-
else if (monthsDiff >= 1) xUnit = "month";
88+
let xUnit;
89+
if (tickInterval === 'years') xUnit = 'year';
90+
else if (['half_year', 'months', 'months_fortnight', 'months_days', 'week_days'].includes(tickInterval)) xUnit = 'month';
91+
else if (tickInterval === 'days') xUnit = 'day';
92+
else if (tickInterval === 'hours') xUnit = 'hour';
93+
else if (['minutes_fives', 'minutes'].includes(tickInterval)) xUnit = 'minute';
94+
else xUnit = 'second';
5695

57-
const fmt = xl.options[xUnit];
96+
const fmt = xl.options[xUnit] ?? xl.options.hour;
5897
const yearFmt = xl.options.year;
5998
const monthFmt = xl.options.month;
6099
const dayFmt = xl.options.day;
61100

62-
windowValues.forEach((ts, idx) => {
101+
window.forEach((ts, idx) => {
63102
const d = new Date(ts);
64-
const hours = xl.useUTC ? d.getUTCHours() : d.getHours();
65-
const minutes = xl.useUTC ? d.getUTCMinutes() : d.getMinutes();
66-
67103
let text;
68-
if (idx === 0) {
69-
if (xUnit === "month" && (hours === 0 && minutes === 0) && ((xl.useUTC ? d.getUTCDate() : d.getDate()) === 1)) {
70-
text = dt.formatDate(d, monthFmt);
71-
} else if (hours === 0 && minutes === 0) {
72-
text = dt.formatDate(d, dayFmt);
73-
} else {
74-
text = dt.formatDate(d, fmt);
75-
}
76-
} else {
77-
const prev = new Date(windowValues[idx - 1]);
78-
const prevY = xl.useUTC ? prev.getUTCFullYear() : prev.getFullYear();
79-
const prevM = xl.useUTC ? prev.getUTCMonth() : prev.getMonth();
80-
const prevD = xl.useUTC ? prev.getUTCDate() : prev.getDate();
81-
const currY = xl.useUTC ? d.getUTCFullYear() : d.getFullYear();
82-
const currM = xl.useUTC ? d.getUTCMonth() : d.getMonth();
83-
const currD = xl.useUTC ? d.getUTCDate() : d.getDate();
84-
85-
if (currY !== prevY) {
104+
switch (xUnit) {
105+
case 'year':
86106
text = dt.formatDate(d, yearFmt);
87-
} else if (currM !== prevM) {
88-
text = xUnit === "month"
89-
? dt.formatDate(d, monthFmt)
90-
: dt.formatDate(d, dayFmt);
91-
} else if (currD !== prevD) {
92-
text = dt.formatDate(d, dayFmt);
93-
} else if (hours === 0 && minutes === 0) {
107+
break;
108+
case 'month': {
109+
const m = xl.useUTC ? d.getUTCMonth() : d.getMonth();
110+
text = (xl.januaryAsYear && m === 0) ? dt.formatDate(d, yearFmt) : dt.formatDate(d, monthFmt);
111+
break;
112+
}
113+
case 'day':
94114
text = dt.formatDate(d, dayFmt);
95-
} else if (xl.januaryAsYear && xUnit === "month" && currM === 0) {
96-
text = dt.formatDate(d, yearFmt);
97-
} else {
98-
text = dt.formatDate(d, fmt);
115+
break;
116+
default: {
117+
// For hour/minute/second: show day label if exact midnight
118+
const H = xl.useUTC ? d.getUTCHours() : d.getHours();
119+
const M = xl.useUTC ? d.getUTCMinutes() : d.getMinutes();
120+
if (H === 0 && M === 0) {
121+
text = dt.formatDate(d, dayFmt);
122+
} else {
123+
text = dt.formatDate(d, fmt);
124+
}
99125
}
100126
}
101-
102127
out.push({ text, absoluteIndex: sliceStart + idx });
103128
});
104129

105130
return out;
106-
}
131+
}

0 commit comments

Comments
 (0)