@scality/core-ui 0.169.0 → 0.171.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/uuid.js +11 -0
- package/dist/components/barchartv2/Barchart.component.js +2 -2
- package/dist/components/buttonv2/Buttonv2.component.js +1 -1
- package/dist/components/chartlegend/ChartLegend.d.ts +3 -1
- package/dist/components/chartlegend/ChartLegend.d.ts.map +1 -1
- package/dist/components/chartlegend/ChartLegend.js +2 -2
- package/dist/components/chartlegend/ChartLegendWrapper.d.ts +3 -1
- package/dist/components/chartlegend/ChartLegendWrapper.d.ts.map +1 -1
- package/dist/components/chartlegend/ChartLegendWrapper.js +43 -9
- package/dist/components/date/FormattedDateTime.d.ts +41 -2
- package/dist/components/date/FormattedDateTime.d.ts.map +1 -1
- package/dist/components/date/FormattedDateTime.js +55 -8
- package/dist/components/date/FormattedDateTime.spec.js +12 -3
- package/dist/components/icon/Icon.component.d.ts +2 -0
- package/dist/components/icon/Icon.component.d.ts.map +1 -1
- package/dist/components/icon/Icon.component.js +2 -0
- package/dist/components/layout/v2/index.d.ts +2 -1
- package/dist/components/layout/v2/index.d.ts.map +1 -1
- package/dist/components/layout/v2/index.js +3 -3
- package/dist/components/linetemporalchart/ChartUtil.d.ts.map +1 -1
- package/dist/components/linetemporalchart/ChartUtil.js +12 -0
- package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts +10 -5
- package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts.map +1 -1
- package/dist/components/linetimeseriechart/linetimeseriechart.component.js +84 -49
- package/dist/components/text/Text.component.d.ts +2 -1
- package/dist/components/text/Text.component.d.ts.map +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.d.ts.map +1 -1
- package/dist/next.js +1 -1
- package/dist/style/theme.js +1 -1
- package/package.json +3 -1
- package/src/lib/components/barchartv2/Barchart.component.tsx +2 -2
- package/src/lib/components/barchartv2/ChartTooltip.test.tsx +1 -1
- package/src/lib/components/buttonv2/Buttonv2.component.tsx +1 -1
- package/src/lib/components/chartlegend/ChartLegend.tsx +4 -2
- package/src/lib/components/chartlegend/ChartLegendWrapper.test.tsx +197 -0
- package/src/lib/components/chartlegend/ChartLegendWrapper.tsx +65 -9
- package/src/lib/components/date/FormattedDateTime.spec.tsx +27 -2
- package/src/lib/components/date/FormattedDateTime.tsx +61 -11
- package/src/lib/components/icon/Icon.component.tsx +2 -0
- package/src/lib/components/layout/v2/index.tsx +5 -3
- package/src/lib/components/linetemporalchart/ChartUtil.ts +26 -0
- package/src/lib/components/linetimeseriechart/linetimeseriechart.component.tsx +227 -157
- package/src/lib/components/text/Text.component.tsx +8 -1
- package/src/lib/next.ts +4 -1
- package/src/lib/style/theme.ts +1 -1
- package/stories/BarChart/barchart.stories.tsx +7 -1
- package/stories/formattedate.stories.tsx +7 -0
- package/stories/layout.stories.tsx +19 -0
- package/stories/linetimeseriechart.stories.tsx +217 -1
|
@@ -5,9 +5,22 @@ import {
|
|
|
5
5
|
ReactNode,
|
|
6
6
|
useMemo,
|
|
7
7
|
useCallback,
|
|
8
|
+
useEffect,
|
|
9
|
+
useRef,
|
|
8
10
|
} from 'react';
|
|
11
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
12
|
import { ChartColors } from '../../style/theme';
|
|
10
13
|
|
|
14
|
+
export const useChartId = (): string => {
|
|
15
|
+
const idRef = useRef<string | null>(null);
|
|
16
|
+
|
|
17
|
+
if (idRef.current === null) {
|
|
18
|
+
idRef.current = uuidv4();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return idRef.current;
|
|
22
|
+
};
|
|
23
|
+
|
|
11
24
|
export type ChartLegendState = {
|
|
12
25
|
selectedResources: string[];
|
|
13
26
|
addSelectedResource: (resource: string) => void;
|
|
@@ -18,23 +31,65 @@ export type ChartLegendState = {
|
|
|
18
31
|
getColor: (resource: string) => string | undefined;
|
|
19
32
|
listResources: () => string[];
|
|
20
33
|
isOnlyOneSelected: () => boolean;
|
|
34
|
+
register: (chartId: string, seriesNames: string[]) => void;
|
|
21
35
|
};
|
|
22
36
|
|
|
23
37
|
const ChartLegendContext = createContext<ChartLegendState | null>(null);
|
|
24
38
|
|
|
25
39
|
export type ChartLegendWrapperProps = {
|
|
26
40
|
children: ReactNode;
|
|
27
|
-
colorSet:
|
|
41
|
+
colorSet:
|
|
42
|
+
| Record<string, ChartColors | string>
|
|
43
|
+
| ((seriesNames: string[]) => Record<string, ChartColors | string>);
|
|
28
44
|
};
|
|
29
45
|
|
|
30
46
|
export const ChartLegendWrapper = ({
|
|
31
47
|
children,
|
|
32
48
|
colorSet,
|
|
33
49
|
}: ChartLegendWrapperProps) => {
|
|
34
|
-
const
|
|
50
|
+
const [registeredColorSets, setRegisteredColorSets] = useState<
|
|
51
|
+
Record<string, string[]>
|
|
52
|
+
>({});
|
|
53
|
+
|
|
54
|
+
const [internalColorSet, setInternalColorSet] = useState<
|
|
55
|
+
Record<string, ChartColors | string>
|
|
56
|
+
>(() => {
|
|
57
|
+
return typeof colorSet === 'function' ? {} : colorSet;
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (typeof colorSet === 'function') {
|
|
62
|
+
const allUniqueSeriesNames = Array.from(
|
|
63
|
+
new Set(Object.values(registeredColorSets).flat()),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
if (allUniqueSeriesNames.length > 0) {
|
|
67
|
+
const newColorSet = colorSet(allUniqueSeriesNames);
|
|
68
|
+
setInternalColorSet(newColorSet);
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
setInternalColorSet(colorSet);
|
|
72
|
+
}
|
|
73
|
+
}, [registeredColorSets, colorSet]);
|
|
74
|
+
|
|
75
|
+
const allResources = useMemo(
|
|
76
|
+
() => Object.keys(internalColorSet),
|
|
77
|
+
[internalColorSet],
|
|
78
|
+
);
|
|
35
79
|
const [selectedResources, setSelectedResources] =
|
|
36
80
|
useState<string[]>(allResources);
|
|
37
81
|
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
setSelectedResources(allResources);
|
|
84
|
+
}, [allResources]);
|
|
85
|
+
|
|
86
|
+
const register = useCallback((chartId: string, seriesNames: string[]) => {
|
|
87
|
+
setRegisteredColorSets((prev) => ({
|
|
88
|
+
...prev,
|
|
89
|
+
[chartId]: seriesNames,
|
|
90
|
+
}));
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
38
93
|
const addSelectedResource = useCallback((resource: string) => {
|
|
39
94
|
setSelectedResources((prev) =>
|
|
40
95
|
prev.includes(resource) ? prev : [...prev, resource],
|
|
@@ -46,8 +101,8 @@ export const ChartLegendWrapper = ({
|
|
|
46
101
|
}, []);
|
|
47
102
|
|
|
48
103
|
const selectAllResources = useCallback(() => {
|
|
49
|
-
setSelectedResources(
|
|
50
|
-
}, [
|
|
104
|
+
setSelectedResources(Object.keys(internalColorSet));
|
|
105
|
+
}, [internalColorSet]);
|
|
51
106
|
|
|
52
107
|
const selectOnlyResource = useCallback((resource: string) => {
|
|
53
108
|
setSelectedResources([resource]);
|
|
@@ -65,7 +120,7 @@ export const ChartLegendWrapper = ({
|
|
|
65
120
|
|
|
66
121
|
const getColor = useCallback(
|
|
67
122
|
(resource: string) => {
|
|
68
|
-
const color =
|
|
123
|
+
const color = internalColorSet[resource];
|
|
69
124
|
if (!color) {
|
|
70
125
|
console.warn(
|
|
71
126
|
`ChartLegendWrapper: No color defined for resource "${resource}"`,
|
|
@@ -74,12 +129,12 @@ export const ChartLegendWrapper = ({
|
|
|
74
129
|
}
|
|
75
130
|
return color;
|
|
76
131
|
},
|
|
77
|
-
[
|
|
132
|
+
[internalColorSet],
|
|
78
133
|
);
|
|
79
134
|
|
|
80
135
|
const listResources = useCallback(() => {
|
|
81
|
-
return Object.keys(
|
|
82
|
-
}, [
|
|
136
|
+
return Object.keys(internalColorSet);
|
|
137
|
+
}, [internalColorSet]);
|
|
83
138
|
|
|
84
139
|
const chartLegendState = useMemo(
|
|
85
140
|
() => ({
|
|
@@ -92,6 +147,7 @@ export const ChartLegendWrapper = ({
|
|
|
92
147
|
getColor,
|
|
93
148
|
listResources,
|
|
94
149
|
isOnlyOneSelected,
|
|
150
|
+
register,
|
|
95
151
|
}),
|
|
96
152
|
[
|
|
97
153
|
selectedResources,
|
|
@@ -103,6 +159,7 @@ export const ChartLegendWrapper = ({
|
|
|
103
159
|
getColor,
|
|
104
160
|
listResources,
|
|
105
161
|
isOnlyOneSelected,
|
|
162
|
+
register,
|
|
106
163
|
],
|
|
107
164
|
);
|
|
108
165
|
|
|
@@ -113,7 +170,6 @@ export const ChartLegendWrapper = ({
|
|
|
113
170
|
);
|
|
114
171
|
};
|
|
115
172
|
|
|
116
|
-
// Hook for accessing legend state in custom components
|
|
117
173
|
export const useChartLegend = () => {
|
|
118
174
|
const context = useContext(ChartLegendContext);
|
|
119
175
|
if (!context) {
|
|
@@ -224,7 +224,7 @@ describe('FormatttedDateTime', () => {
|
|
|
224
224
|
/>,
|
|
225
225
|
);
|
|
226
226
|
//V
|
|
227
|
-
expect(screen.getByText('
|
|
227
|
+
expect(screen.getByText('06 Oct 18:33')).toBeInTheDocument();
|
|
228
228
|
});
|
|
229
229
|
|
|
230
230
|
it('should display the date in the expected format of date in the chart', () => {
|
|
@@ -236,6 +236,31 @@ describe('FormatttedDateTime', () => {
|
|
|
236
236
|
/>,
|
|
237
237
|
);
|
|
238
238
|
//V
|
|
239
|
-
expect(screen.getByText('
|
|
239
|
+
expect(screen.getByText('06 Oct 18:33:00')).toBeInTheDocument();
|
|
240
|
+
});
|
|
241
|
+
it('should display 3 letter month for September date', () => {
|
|
242
|
+
//S
|
|
243
|
+
render(
|
|
244
|
+
<>
|
|
245
|
+
<FormattedDateTime
|
|
246
|
+
format="day-month-abbreviated-hour-minute"
|
|
247
|
+
value={new Date('2022-09-06T18:33:00Z')}
|
|
248
|
+
/>
|
|
249
|
+
<FormattedDateTime
|
|
250
|
+
format="day-month-abbreviated-hour-minute-second"
|
|
251
|
+
value={new Date('2022-09-06T18:33:00Z')}
|
|
252
|
+
/>
|
|
253
|
+
|
|
254
|
+
<FormattedDateTime
|
|
255
|
+
format="chart-date"
|
|
256
|
+
value={new Date('2022-09-06T18:33:00Z')}
|
|
257
|
+
/>
|
|
258
|
+
</>,
|
|
259
|
+
);
|
|
260
|
+
//V
|
|
261
|
+
expect(screen.getByText(/06 Sep 18:33/)).toBeInTheDocument();
|
|
262
|
+
expect(screen.getByText(/06 Sep 18:33:00/)).toBeInTheDocument();
|
|
263
|
+
expect(screen.getByText(/Tue06Sep/)).toBeInTheDocument();
|
|
264
|
+
expect(screen.queryByText(/Sept/)).not.toBeInTheDocument();
|
|
240
265
|
});
|
|
241
266
|
});
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { getDateDaysDiff } from './dateDiffer';
|
|
2
2
|
import { Tooltip } from '../tooltip/Tooltip.component';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @description Long date formatter, with weekday, year, month and day. Used for describing long term date.
|
|
6
|
+
* @example Wednesday 6 October 2025
|
|
7
|
+
*/
|
|
4
8
|
export const LONG_DATE_FORMATER = Intl.DateTimeFormat('en-GB', {
|
|
5
9
|
weekday: 'long',
|
|
6
10
|
year: 'numeric',
|
|
7
11
|
month: 'long',
|
|
8
|
-
day: '
|
|
12
|
+
day: '2-digit',
|
|
9
13
|
});
|
|
10
14
|
|
|
11
15
|
/**
|
|
@@ -18,6 +22,10 @@ export const LONG_DATE_FORMATER_WITHOUT_WEEKDAY = Intl.DateTimeFormat('en-GB', {
|
|
|
18
22
|
day: '2-digit',
|
|
19
23
|
});
|
|
20
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @description Date formatter, with year, month and day. Used for describing long term date.
|
|
27
|
+
* @example 2025-01-01
|
|
28
|
+
*/
|
|
21
29
|
export const DATE_FORMATER = Intl.DateTimeFormat('fr-CA', {
|
|
22
30
|
year: 'numeric',
|
|
23
31
|
month: '2-digit',
|
|
@@ -25,12 +33,20 @@ export const DATE_FORMATER = Intl.DateTimeFormat('fr-CA', {
|
|
|
25
33
|
hour12: false,
|
|
26
34
|
});
|
|
27
35
|
|
|
36
|
+
/**
|
|
37
|
+
* @description Day month formatter, with weekday, day and month. Used for describing long term date.
|
|
38
|
+
* @example Wed 6 Oct
|
|
39
|
+
*/
|
|
28
40
|
export const DAY_MONTH_FORMATER = Intl.DateTimeFormat('en-GB', {
|
|
29
41
|
weekday: 'short',
|
|
30
42
|
day: '2-digit',
|
|
31
43
|
month: 'short',
|
|
32
44
|
});
|
|
33
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @description Time formatter, with hour, minute and second. Used for describing long term date.
|
|
48
|
+
* @example 18:33:00
|
|
49
|
+
*/
|
|
34
50
|
export const TIME_SECOND_FORMATER = Intl.DateTimeFormat('en-GB', {
|
|
35
51
|
hour12: false,
|
|
36
52
|
hour: '2-digit',
|
|
@@ -38,16 +54,24 @@ export const TIME_SECOND_FORMATER = Intl.DateTimeFormat('en-GB', {
|
|
|
38
54
|
second: '2-digit',
|
|
39
55
|
});
|
|
40
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @description Time formatter, with hour and minute. Used for describing long term date.
|
|
59
|
+
* @example 18:33
|
|
60
|
+
*/
|
|
41
61
|
export const TIME_FORMATER = Intl.DateTimeFormat('en-GB', {
|
|
42
62
|
hour12: false,
|
|
43
63
|
hour: '2-digit',
|
|
44
64
|
minute: '2-digit',
|
|
45
65
|
});
|
|
46
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @description Day month abbreviated hour minute second formatter. Used for describing long term date.
|
|
69
|
+
* @example 6 Oct 18:33:00
|
|
70
|
+
*/
|
|
47
71
|
export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND = Intl.DateTimeFormat(
|
|
48
72
|
'en-GB',
|
|
49
73
|
{
|
|
50
|
-
day: '
|
|
74
|
+
day: '2-digit',
|
|
51
75
|
month: 'short',
|
|
52
76
|
hour: '2-digit',
|
|
53
77
|
minute: '2-digit',
|
|
@@ -57,11 +81,11 @@ export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND = Intl.DateTimeFormat(
|
|
|
57
81
|
);
|
|
58
82
|
|
|
59
83
|
/**
|
|
60
|
-
* @description Day month abbreviated hour minute formatter
|
|
61
|
-
* @example
|
|
84
|
+
* @description Day month abbreviated hour minute formatter. Used for describing long term date.
|
|
85
|
+
* @example 6 Oct 18:33
|
|
62
86
|
*/
|
|
63
87
|
export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE = Intl.DateTimeFormat('en-GB', {
|
|
64
|
-
day: '
|
|
88
|
+
day: '2-digit',
|
|
65
89
|
month: 'short',
|
|
66
90
|
hour: '2-digit',
|
|
67
91
|
minute: '2-digit',
|
|
@@ -117,6 +141,21 @@ const isItFutureOrIsItPast = (
|
|
|
117
141
|
}
|
|
118
142
|
};
|
|
119
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @description Formats the date and time according to the format specified.
|
|
146
|
+
* @example
|
|
147
|
+
* date: '2025-01-01'
|
|
148
|
+
* 'date-time': '2025-01-01 00:00'
|
|
149
|
+
* 'date-time-second': '2025-01-01 00:00:00'
|
|
150
|
+
* time: '00:00'
|
|
151
|
+
* 'time-second': '00:00:00'
|
|
152
|
+
* relative: '1 month ago'
|
|
153
|
+
* 'day-month-abbreviated-hour-minute': '6 Oct 18:33'
|
|
154
|
+
* 'day-month-abbreviated-hour-minute-second': '6 Oct 18:33:00'
|
|
155
|
+
* 'long-date': 'Wednesday 6 October 2025'
|
|
156
|
+
* 'chart-date': '6 Oct'
|
|
157
|
+
* 'year-month-day': '2025-10-06'
|
|
158
|
+
*/
|
|
120
159
|
export const FormattedDateTime = ({
|
|
121
160
|
format,
|
|
122
161
|
value,
|
|
@@ -219,15 +258,19 @@ export const FormattedDateTime = ({
|
|
|
219
258
|
);
|
|
220
259
|
case 'day-month-abbreviated-hour-minute':
|
|
221
260
|
return (
|
|
222
|
-
<>
|
|
261
|
+
<>
|
|
262
|
+
{DAY_MONTH_ABBREVIATED_HOUR_MINUTE.format(value)
|
|
263
|
+
.replace(',', '')
|
|
264
|
+
.replace(/Sept/g, 'Sep')}
|
|
265
|
+
</>
|
|
223
266
|
);
|
|
224
267
|
case 'day-month-abbreviated-hour-minute-second':
|
|
225
268
|
return (
|
|
226
269
|
<>
|
|
227
|
-
{DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND.format(value)
|
|
228
|
-
',',
|
|
229
|
-
|
|
230
|
-
|
|
270
|
+
{DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND.format(value)
|
|
271
|
+
.replace(',', '')
|
|
272
|
+
// replace Sept with Sep to keep 3 letter month
|
|
273
|
+
.replace(/Sept/g, 'Sep')}
|
|
231
274
|
</>
|
|
232
275
|
);
|
|
233
276
|
case 'long-date':
|
|
@@ -235,7 +278,14 @@ export const FormattedDateTime = ({
|
|
|
235
278
|
case 'long-date-without-weekday':
|
|
236
279
|
return <>{LONG_DATE_FORMATER_WITHOUT_WEEKDAY.format(value)}</>;
|
|
237
280
|
case 'chart-date':
|
|
238
|
-
return
|
|
281
|
+
return (
|
|
282
|
+
<>
|
|
283
|
+
{DAY_MONTH_FORMATER.format(value)
|
|
284
|
+
.replace(/[ ,]/g, '')
|
|
285
|
+
// replace Sept with Sep to keep 3 letter month
|
|
286
|
+
.replace(/Sept/g, 'Sep')}
|
|
287
|
+
</>
|
|
288
|
+
);
|
|
239
289
|
case 'year-month-day':
|
|
240
290
|
return <>{YEAR_MONTH_DAY_FORMATTER.format(value)}</>;
|
|
241
291
|
case 'month-day':
|
|
@@ -2,12 +2,12 @@ import { ReactElement } from 'react';
|
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import { navbarHeight } from '../../../style/theme';
|
|
4
4
|
|
|
5
|
-
const LayoutContainer = styled.div
|
|
5
|
+
const LayoutContainer = styled.div<{ variant?: 'transparent' }>`
|
|
6
6
|
display: flex;
|
|
7
7
|
flex-direction: column;
|
|
8
8
|
height: 100vh;
|
|
9
9
|
box-sizing: border-box;
|
|
10
|
-
background: ${
|
|
10
|
+
background: ${props => props.variant === 'transparent' ? 'transparent' : props.theme.backgroundLevel1};
|
|
11
11
|
`;
|
|
12
12
|
|
|
13
13
|
const Navigation = styled.div`
|
|
@@ -17,12 +17,14 @@ const Navigation = styled.div`
|
|
|
17
17
|
export function Layout({
|
|
18
18
|
children: app,
|
|
19
19
|
headerNavigation,
|
|
20
|
+
variant,
|
|
20
21
|
}: {
|
|
21
22
|
children: ReactElement | ReactElement[];
|
|
22
23
|
headerNavigation: ReactElement;
|
|
24
|
+
variant?: 'transparent';
|
|
23
25
|
}) {
|
|
24
26
|
return (
|
|
25
|
-
<LayoutContainer className="layout-container">
|
|
27
|
+
<LayoutContainer className="layout-container" variant={variant}>
|
|
26
28
|
<Navigation>{headerNavigation}</Navigation>
|
|
27
29
|
{app}
|
|
28
30
|
</LayoutContainer>
|
|
@@ -148,8 +148,24 @@ export function addMissingDataPoint(
|
|
|
148
148
|
|
|
149
149
|
const newValues: [number, number | string | null][] = [];
|
|
150
150
|
|
|
151
|
+
// add missing data points for the starting time
|
|
152
|
+
for (
|
|
153
|
+
let i = startingTimeStamp;
|
|
154
|
+
i < orginalValues[0][0];
|
|
155
|
+
i += sampleInterval
|
|
156
|
+
) {
|
|
157
|
+
newValues.push([i, NAN_STRING]);
|
|
158
|
+
}
|
|
159
|
+
|
|
151
160
|
// Process all but the last element
|
|
152
161
|
for (let i = 0; i < orginalValues.length - 1; i++) {
|
|
162
|
+
if (
|
|
163
|
+
orginalValues[i][0] < startingTimeStamp ||
|
|
164
|
+
orginalValues[i][0] > startingTimeStamp + sampleDuration
|
|
165
|
+
) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
|
|
153
169
|
// Always add the current data point
|
|
154
170
|
newValues.push(orginalValues[i]);
|
|
155
171
|
|
|
@@ -170,8 +186,18 @@ export function addMissingDataPoint(
|
|
|
170
186
|
// Add the last element
|
|
171
187
|
newValues.push(orginalValues[orginalValues.length - 1]);
|
|
172
188
|
|
|
189
|
+
// add missing data points for the ending time
|
|
190
|
+
for (
|
|
191
|
+
let i = orginalValues[orginalValues.length - 1][0] + sampleInterval;
|
|
192
|
+
i < startingTimeStamp + sampleDuration;
|
|
193
|
+
i += sampleInterval
|
|
194
|
+
) {
|
|
195
|
+
newValues.push([i, NAN_STRING]);
|
|
196
|
+
}
|
|
197
|
+
|
|
173
198
|
return newValues;
|
|
174
199
|
}
|
|
200
|
+
|
|
175
201
|
// get the value for the based value
|
|
176
202
|
// TODO: We need to handle the negative value in the future
|
|
177
203
|
export const getRelativeValue = (value: number, base: number) => {
|