forked from SigNoz/signoz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xAxisConfig.ts
140 lines (128 loc) · 3.44 KB
/
xAxisConfig.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { Chart, TimeUnit } from 'chart.js';
import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
import { IAxisTimeConfig, IAxisTimeUintConfig, ITimeRange } from './types';
export const TIME_UNITS: Record<TimeUnit, TimeUnit> = {
millisecond: 'millisecond',
second: 'second',
minute: 'minute',
hour: 'hour',
day: 'day',
week: 'week',
month: 'month',
year: 'year',
quarter: 'quarter',
};
const TIME_UNITS_CONFIG: IAxisTimeUintConfig[] = [
{
unitName: TIME_UNITS.millisecond,
multiplier: 1,
},
{
unitName: TIME_UNITS.second,
multiplier: 1 / 1e3,
},
{
unitName: TIME_UNITS.minute,
multiplier: 1 / (1e3 * 60),
},
{
unitName: TIME_UNITS.hour,
multiplier: 1 / (1e3 * 60 * 60),
},
{
unitName: TIME_UNITS.day,
multiplier: 1 / (1e3 * 60 * 60 * 24),
},
{
unitName: TIME_UNITS.week,
multiplier: 1 / (1e3 * 60 * 60 * 24 * 7),
},
{
unitName: TIME_UNITS.month,
multiplier: 1 / (1e3 * 60 * 60 * 24 * 30),
},
{
unitName: TIME_UNITS.year,
multiplier: 1 / (1e3 * 60 * 60 * 24 * 365),
},
];
/**
* Finds the relevant time unit based on the input time stamps (in ms)
*/
export const convertTimeRange = (
start: number,
end: number,
): IAxisTimeConfig => {
const MIN_INTERVALS = 6;
const range = end - start;
let relevantTimeUnit = TIME_UNITS_CONFIG[1];
let stepSize = 1;
try {
for (let idx = TIME_UNITS_CONFIG.length - 1; idx >= 0; idx -= 1) {
const timeUnit = TIME_UNITS_CONFIG[idx];
const units = range * timeUnit.multiplier;
const steps = units / MIN_INTERVALS;
if (steps >= 1) {
relevantTimeUnit = timeUnit;
stepSize = steps;
break;
}
}
} catch (error) {
console.error(error);
}
return {
unitName: relevantTimeUnit.unitName,
stepSize: Math.floor(stepSize) || 1,
};
};
/**
* Accepts Chart.js data's data-structure and returns the relevant time unit for the axis based on the range of the data.
*/
export const useXAxisTimeUnit = (data: Chart['data']): IAxisTimeConfig => {
// Local time is the time range inferred from the input chart data.
let localTime: ITimeRange | null;
try {
let minTime = Number.POSITIVE_INFINITY;
let maxTime = Number.NEGATIVE_INFINITY;
data?.labels?.forEach((timeStamp: unknown): void => {
const getTimeStamp = (time: Date | number): Date | number | string => {
if (time instanceof Date) {
return Date.parse(time.toString());
}
return time;
};
const time = getTimeStamp(timeStamp as Date | number);
minTime = Math.min(parseInt(time.toString(), 10), minTime);
maxTime = Math.max(parseInt(time.toString(), 10), maxTime);
});
localTime = {
minTime: minTime === Number.POSITIVE_INFINITY ? null : minTime,
maxTime: maxTime === Number.NEGATIVE_INFINITY ? null : maxTime,
};
} catch (error) {
localTime = null;
console.error(error);
}
// Global time is the time selected from the global time selector menu.
const globalTime = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
// Use local time if valid else use the global time range
const { maxTime, minTime } = useMemo(() => {
if (localTime && localTime.maxTime && localTime.minTime) {
return {
minTime: localTime.minTime,
maxTime: localTime.maxTime,
};
}
return {
minTime: globalTime.minTime / 1e6,
maxTime: globalTime.maxTime / 1e6,
};
}, [globalTime, localTime]);
return convertTimeRange(minTime, maxTime);
};