@centreon/ui 23.10.18-MON-17793-create-graph-component-centreon-ui.21 → 23.10.18-MON-17793-create-graph-component-centreon-ui.23
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/package.json +1 -1
- package/src/Graph/BasicComponents/Axes/index.tsx +2 -2
- package/src/Graph/BasicComponents/Axes/useAxisY.ts +5 -5
- package/src/Graph/BasicComponents/Lines/RegularLines/index.tsx +2 -2
- package/src/Graph/BasicComponents/Lines/StackedLines/index.tsx +2 -16
- package/src/Graph/BasicComponents/Lines/index.tsx +15 -6
- package/src/Graph/BasicComponents/useFilterLines.ts +4 -2
- package/src/Graph/Graph.tsx +18 -4
- package/src/Graph/Header/index.tsx +4 -2
- package/src/Graph/{icons → Icons}/Downtime.tsx +1 -1
- package/src/Graph/InteractiveComponents/AnchorPoint/AnchorPoint.styles.ts +52 -0
- package/src/Graph/InteractiveComponents/AnchorPoint/GuidingLines.tsx +45 -0
- package/src/Graph/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +4 -12
- package/src/Graph/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +16 -10
- package/src/Graph/InteractiveComponents/AnchorPoint/TooltipAnchorPoint.tsx +68 -0
- package/src/Graph/InteractiveComponents/AnchorPoint/index.tsx +9 -37
- package/src/Graph/InteractiveComponents/AnchorPoint/models.ts +38 -1
- package/src/Graph/InteractiveComponents/AnchorPoint/useTickGraph.ts +44 -7
- package/src/Graph/InteractiveComponents/AnchorPoint/useTooltipAnchorPoint.ts +107 -0
- package/src/Graph/InteractiveComponents/Annotations/Area/Downtime.tsx +1 -1
- package/src/Graph/InteractiveComponents/TimeShiftZones/TimeShiftIcon.tsx +6 -2
- package/src/Graph/InteractiveComponents/TimeShiftZones/index.tsx +1 -0
- package/src/Graph/InteractiveComponents/Tooltip/useGraphTooltip.ts +4 -14
- package/src/Graph/Legend/useLegend.ts +5 -2
- package/src/Graph/helpers/doc.ts +29 -4
- package/src/Graph/helpers/index.ts +12 -2
- package/src/Graph/index.stories.tsx +1 -1
- package/src/Graph/mockedData/lastDay.json +1282 -614
- package/src/Graph/models.ts +14 -1
- package/src/Graph/useGraphData.ts +2 -2
- package/src/api/useRequest/index.ts +9 -6
- package/src/utils/useIntersectionObserver.ts +4 -2
- /package/src/{Graph → @assets}/icons/downtime.icon.svg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ScaleLinear, ScaleTime } from 'd3-scale';
|
|
2
2
|
|
|
3
|
-
import { TimeValue } from '../../timeSeries/models';
|
|
3
|
+
import { Line, TimeValue } from '../../timeSeries/models';
|
|
4
4
|
|
|
5
5
|
interface AnchorPoint {
|
|
6
6
|
areaColor: string;
|
|
@@ -23,3 +23,40 @@ export interface StackData {
|
|
|
23
23
|
data: TimeValue;
|
|
24
24
|
}
|
|
25
25
|
export type StackValue = [number, number, StackData];
|
|
26
|
+
|
|
27
|
+
export interface GuidingLines {
|
|
28
|
+
graphHeight: number;
|
|
29
|
+
graphWidth: number;
|
|
30
|
+
timeSeries: Array<TimeValue>;
|
|
31
|
+
xScale: ScaleLinear<number, number>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface GetYAnchorPoint {
|
|
35
|
+
metric: string;
|
|
36
|
+
timeSeries: Array<TimeValue>;
|
|
37
|
+
timeTick: Date;
|
|
38
|
+
yScale: ScaleLinear<number, number>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface UseTooltipAnchorPointResult {
|
|
42
|
+
tooltipDataAxisX?: string | null;
|
|
43
|
+
tooltipDataAxisYLeft?: number | null;
|
|
44
|
+
tooltipDataAxisYRight?: number | null;
|
|
45
|
+
tooltipLeftAxisX?: number;
|
|
46
|
+
tooltipLeftAxisYLeft?: number;
|
|
47
|
+
tooltipLeftAxisYRight?: number;
|
|
48
|
+
tooltipTopAxisX?: number;
|
|
49
|
+
tooltipTopAxisYLeft?: number;
|
|
50
|
+
tooltipTopAxisYRight?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface TooltipAnchorModel {
|
|
54
|
+
baseAxis: number;
|
|
55
|
+
graphHeight: number;
|
|
56
|
+
graphWidth?: number;
|
|
57
|
+
leftScale?: ScaleLinear<number, number>;
|
|
58
|
+
lines: Array<Line>;
|
|
59
|
+
rightScale?: ScaleLinear<number, number>;
|
|
60
|
+
timeSeries: Array<TimeValue>;
|
|
61
|
+
xScale: ScaleLinear<number, number>;
|
|
62
|
+
}
|
|
@@ -4,24 +4,43 @@ import { ScaleLinear } from 'd3-scale';
|
|
|
4
4
|
import { useAtomValue } from 'jotai';
|
|
5
5
|
import { isEmpty, isNil, not } from 'ramda';
|
|
6
6
|
|
|
7
|
+
import useAxisY from '../../BasicComponents/Axes/useAxisY';
|
|
7
8
|
import { margin } from '../../common';
|
|
8
9
|
import { getMetrics, getTimeValue } from '../../timeSeries';
|
|
9
|
-
import { TimeValue } from '../../timeSeries/models';
|
|
10
|
+
import { Line, TimeValue } from '../../timeSeries/models';
|
|
10
11
|
import { mousePositionAtom, timeValueAtom } from '../interactionWithGraphAtoms';
|
|
11
12
|
|
|
12
13
|
interface AnchorPointResult {
|
|
13
14
|
positionX?: number;
|
|
14
15
|
positionY?: number;
|
|
15
|
-
|
|
16
|
+
tickAxisBottom: Date | null;
|
|
17
|
+
tickAxisLeft: string | null;
|
|
18
|
+
tickAxisRight: string | null;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
interface Props {
|
|
22
|
+
baseAxis?: number;
|
|
23
|
+
leftScale?: ScaleLinear<number, number>;
|
|
24
|
+
lines?: Array<Line>;
|
|
25
|
+
rightScale?: ScaleLinear<number, number>;
|
|
19
26
|
timeSeries: Array<TimeValue>;
|
|
20
27
|
xScale: ScaleLinear<number, number>;
|
|
21
28
|
}
|
|
22
29
|
|
|
23
|
-
const useTickGraph = ({
|
|
24
|
-
|
|
30
|
+
const useTickGraph = ({
|
|
31
|
+
timeSeries,
|
|
32
|
+
xScale,
|
|
33
|
+
leftScale,
|
|
34
|
+
rightScale,
|
|
35
|
+
lines = [],
|
|
36
|
+
baseAxis = 1000
|
|
37
|
+
}: Props): AnchorPointResult => {
|
|
38
|
+
const [tickAxisBottom, setTickAxisBottom] = useState<Date | null>(null);
|
|
39
|
+
const [tickAxisLeft, setTickAxisLeft] = useState<string | null>(null);
|
|
40
|
+
const [tickAxisRight, setTickAxisRight] = useState<string | null>(null);
|
|
41
|
+
|
|
42
|
+
const { axisRight, axisLeft } = useAxisY({ data: { baseAxis, lines } });
|
|
43
|
+
|
|
25
44
|
const mousePosition = useAtomValue(mousePositionAtom);
|
|
26
45
|
const timeValueData = useAtomValue(timeValueAtom);
|
|
27
46
|
|
|
@@ -34,7 +53,9 @@ const useTickGraph = ({ timeSeries, xScale }: Props): AnchorPointResult => {
|
|
|
34
53
|
|
|
35
54
|
useEffect(() => {
|
|
36
55
|
if (!mousePosition) {
|
|
37
|
-
|
|
56
|
+
setTickAxisBottom(null);
|
|
57
|
+
setTickAxisLeft(null);
|
|
58
|
+
setTickAxisRight(null);
|
|
38
59
|
|
|
39
60
|
return;
|
|
40
61
|
}
|
|
@@ -45,13 +66,29 @@ const useTickGraph = ({ timeSeries, xScale }: Props): AnchorPointResult => {
|
|
|
45
66
|
? new Date(mousePositionTimeTick)
|
|
46
67
|
: null;
|
|
47
68
|
|
|
48
|
-
|
|
69
|
+
setTickAxisBottom(timeTickValue);
|
|
70
|
+
|
|
71
|
+
const valueTickAxisLeft = leftScale?.invert(positionY);
|
|
72
|
+
const formattedTickAxisLeft = axisLeft?.tickFormat?.(valueTickAxisLeft);
|
|
73
|
+
|
|
74
|
+
setTickAxisLeft(formattedTickAxisLeft);
|
|
75
|
+
|
|
76
|
+
if (!axisRight.display) {
|
|
77
|
+
setTickAxisRight(null);
|
|
78
|
+
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const valueTickAxisRight = rightScale?.invert(positionY);
|
|
82
|
+
const formattedTickAxisRight = axisRight?.tickFormat?.(valueTickAxisRight);
|
|
83
|
+
setTickAxisRight(formattedTickAxisRight);
|
|
49
84
|
}, [mousePosition]);
|
|
50
85
|
|
|
51
86
|
return {
|
|
52
87
|
positionX,
|
|
53
88
|
positionY,
|
|
54
|
-
|
|
89
|
+
tickAxisBottom,
|
|
90
|
+
tickAxisLeft,
|
|
91
|
+
tickAxisRight
|
|
55
92
|
};
|
|
56
93
|
};
|
|
57
94
|
export default useTickGraph;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Tooltip } from '@visx/visx';
|
|
4
|
+
import { isNil } from 'ramda';
|
|
5
|
+
|
|
6
|
+
import { useLocaleDateTimeFormat } from '@centreon/ui';
|
|
7
|
+
|
|
8
|
+
import { margin, timeFormat } from '../../common/index';
|
|
9
|
+
|
|
10
|
+
import { TooltipAnchorModel, UseTooltipAnchorPointResult } from './models';
|
|
11
|
+
import useTickGraph from './useTickGraph';
|
|
12
|
+
|
|
13
|
+
const useTooltipAnchorPoint = ({
|
|
14
|
+
timeSeries,
|
|
15
|
+
xScale,
|
|
16
|
+
graphHeight,
|
|
17
|
+
leftScale,
|
|
18
|
+
rightScale,
|
|
19
|
+
graphWidth,
|
|
20
|
+
lines,
|
|
21
|
+
baseAxis
|
|
22
|
+
}: TooltipAnchorModel): UseTooltipAnchorPointResult => {
|
|
23
|
+
const { format } = useLocaleDateTimeFormat();
|
|
24
|
+
|
|
25
|
+
const { positionX, positionY, tickAxisBottom, tickAxisLeft, tickAxisRight } =
|
|
26
|
+
useTickGraph({
|
|
27
|
+
baseAxis,
|
|
28
|
+
leftScale,
|
|
29
|
+
lines,
|
|
30
|
+
rightScale,
|
|
31
|
+
timeSeries,
|
|
32
|
+
xScale
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const {
|
|
36
|
+
showTooltip: showTooltipAxisYLeft,
|
|
37
|
+
tooltipData: tooltipDataAxisYLeft,
|
|
38
|
+
tooltipLeft: tooltipLeftAxisYLeft,
|
|
39
|
+
tooltipTop: tooltipTopAxisYLeft
|
|
40
|
+
} = Tooltip.useTooltip();
|
|
41
|
+
const {
|
|
42
|
+
showTooltip: showTooltipAxisX,
|
|
43
|
+
tooltipData: tooltipDataAxisX,
|
|
44
|
+
tooltipLeft: tooltipLeftAxisX,
|
|
45
|
+
tooltipTop: tooltipTopAxisX
|
|
46
|
+
} = Tooltip.useTooltip();
|
|
47
|
+
|
|
48
|
+
const {
|
|
49
|
+
showTooltip: showTooltipAxisYRight,
|
|
50
|
+
tooltipData: tooltipDataAxisYRight,
|
|
51
|
+
tooltipLeft: tooltipLeftAxisYRight,
|
|
52
|
+
tooltipTop: tooltipTopAxisYRight
|
|
53
|
+
} = Tooltip.useTooltip();
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (!positionX || !positionY || !tickAxisBottom) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const dataAxisX = format({
|
|
61
|
+
date: tickAxisBottom,
|
|
62
|
+
formatString: timeFormat
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
showTooltipAxisX({
|
|
66
|
+
tooltipData: dataAxisX,
|
|
67
|
+
tooltipLeft: positionX + margin.left / 2,
|
|
68
|
+
tooltipTop: graphHeight + margin.top / 2
|
|
69
|
+
});
|
|
70
|
+
}, [positionX, positionY, tickAxisBottom]);
|
|
71
|
+
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (!positionX || !positionY || !tickAxisLeft) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
showTooltipAxisYLeft({
|
|
77
|
+
tooltipData: tickAxisLeft,
|
|
78
|
+
tooltipLeft: 40,
|
|
79
|
+
tooltipTop: positionY + margin.top / 2
|
|
80
|
+
});
|
|
81
|
+
}, [tickAxisLeft, positionX, positionY]);
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!positionX || !positionY || !tickAxisRight) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
showTooltipAxisYRight({
|
|
88
|
+
tooltipData: tickAxisRight,
|
|
89
|
+
tooltipLeft: graphWidth ? graphWidth + 40 : 0,
|
|
90
|
+
tooltipTop: positionY + margin.top / 2
|
|
91
|
+
});
|
|
92
|
+
}, [positionX, positionY, tickAxisRight]);
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
tooltipDataAxisX: !isNil(tickAxisBottom) ? tooltipDataAxisX : null,
|
|
96
|
+
tooltipDataAxisYLeft: !isNil(tickAxisLeft) ? tooltipDataAxisYLeft : null,
|
|
97
|
+
tooltipDataAxisYRight: !isNil(tickAxisRight) ? tooltipDataAxisYRight : null,
|
|
98
|
+
tooltipLeftAxisX,
|
|
99
|
+
tooltipLeftAxisYLeft,
|
|
100
|
+
tooltipLeftAxisYRight,
|
|
101
|
+
tooltipTopAxisX,
|
|
102
|
+
tooltipTopAxisYLeft,
|
|
103
|
+
tooltipTopAxisYRight
|
|
104
|
+
} as UseTooltipAnchorPointResult;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export default useTooltipAnchorPoint;
|
|
@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
2
2
|
|
|
3
3
|
import { useTheme } from '@mui/material';
|
|
4
4
|
|
|
5
|
-
import IconDowntime from '../../../
|
|
5
|
+
import IconDowntime from '../../../Icons/Downtime';
|
|
6
6
|
import { labelDowntime } from '../../../translatedLabels';
|
|
7
7
|
import EventAnnotations from '../EventAnnotations';
|
|
8
8
|
import { Args } from '../models';
|
|
@@ -5,11 +5,14 @@ import { makeStyles } from 'tss-react/mui';
|
|
|
5
5
|
|
|
6
6
|
import { useMemoComponent } from '@centreon/ui';
|
|
7
7
|
|
|
8
|
+
import { TimeShiftDirection } from './models';
|
|
9
|
+
|
|
8
10
|
export const timeShiftIconSize = 20;
|
|
9
11
|
|
|
10
12
|
interface Props {
|
|
11
13
|
Icon: ReactNode;
|
|
12
14
|
ariaLabel: string;
|
|
15
|
+
directionHovered: TimeShiftDirection;
|
|
13
16
|
xIcon: number;
|
|
14
17
|
yIcon: number;
|
|
15
18
|
}
|
|
@@ -24,7 +27,8 @@ const TimeShiftIcon = ({
|
|
|
24
27
|
xIcon,
|
|
25
28
|
yIcon,
|
|
26
29
|
Icon,
|
|
27
|
-
ariaLabel
|
|
30
|
+
ariaLabel,
|
|
31
|
+
directionHovered
|
|
28
32
|
}: Props): JSX.Element => {
|
|
29
33
|
const { classes } = useStyles();
|
|
30
34
|
const { t } = useTranslation();
|
|
@@ -51,7 +55,7 @@ const TimeShiftIcon = ({
|
|
|
51
55
|
</svg>
|
|
52
56
|
</g>
|
|
53
57
|
),
|
|
54
|
-
memoProps: [xIcon, ariaLabel]
|
|
58
|
+
memoProps: [xIcon, ariaLabel, directionHovered]
|
|
55
59
|
});
|
|
56
60
|
};
|
|
57
61
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
import { ScaleLinear } from 'd3-scale';
|
|
4
3
|
import { Event, Tooltip } from '@visx/visx';
|
|
4
|
+
import { ScaleLinear } from 'd3-scale';
|
|
5
5
|
import { useAtomValue } from 'jotai';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import { eventMouseUpAtom } from '../interactionWithGraphAtoms';
|
|
7
|
+
import { getDate } from '../../helpers/index';
|
|
9
8
|
import { TimeValue } from '../../timeSeries/models';
|
|
10
9
|
import { applyingZoomAtomAtom } from '../ZoomPreview/zoomPreviewAtoms';
|
|
10
|
+
import { eventMouseUpAtom } from '../interactionWithGraphAtoms';
|
|
11
11
|
|
|
12
12
|
import { GraphTooltip, width } from './models';
|
|
13
13
|
|
|
@@ -36,16 +36,6 @@ const useGraphTooltip = ({
|
|
|
36
36
|
const mouseUpEvent = useAtomValue(eventMouseUpAtom);
|
|
37
37
|
const isZoomApplied = useAtomValue(applyingZoomAtomAtom);
|
|
38
38
|
|
|
39
|
-
const getDate = (positionX): Date => {
|
|
40
|
-
const { timeTick } = getTimeValue({
|
|
41
|
-
timeSeries,
|
|
42
|
-
x: positionX,
|
|
43
|
-
xScale
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
return new Date(timeTick);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
39
|
useEffect(() => {
|
|
50
40
|
if (!mouseUpEvent || isZoomApplied) {
|
|
51
41
|
return;
|
|
@@ -59,7 +49,7 @@ const useGraphTooltip = ({
|
|
|
59
49
|
const displayLeft = graphWidth - x < tooltipWidth;
|
|
60
50
|
|
|
61
51
|
showTooltip({
|
|
62
|
-
tooltipData: getDate(x),
|
|
52
|
+
tooltipData: getDate({ positionX: x, timeSeries, xScale }),
|
|
63
53
|
tooltipLeft: displayLeft ? x - tooltipWidth : x,
|
|
64
54
|
tooltipTop: y
|
|
65
55
|
});
|
|
@@ -12,7 +12,9 @@ import {
|
|
|
12
12
|
prop,
|
|
13
13
|
propEq,
|
|
14
14
|
reject,
|
|
15
|
-
sortBy
|
|
15
|
+
sortBy,
|
|
16
|
+
compose,
|
|
17
|
+
toLower
|
|
16
18
|
} from 'ramda';
|
|
17
19
|
|
|
18
20
|
import { linesGraphAtom } from '../graphAtoms';
|
|
@@ -52,7 +54,8 @@ const useLegend = ({ lines }: Props): LegendActions => {
|
|
|
52
54
|
{ ...getLineByMetric(metric), highlight: true }
|
|
53
55
|
];
|
|
54
56
|
|
|
55
|
-
const sortedData = sortBy(prop('name'), data);
|
|
57
|
+
const sortedData = sortBy(compose(toLower, prop('name')), data);
|
|
58
|
+
|
|
56
59
|
setLines(sortedData);
|
|
57
60
|
};
|
|
58
61
|
|
package/src/Graph/helpers/doc.ts
CHANGED
|
@@ -201,13 +201,38 @@ export const argTypes = {
|
|
|
201
201
|
category: 'Graph data'
|
|
202
202
|
}
|
|
203
203
|
},
|
|
204
|
+
|
|
204
205
|
displayAnchor: {
|
|
205
|
-
control: '
|
|
206
|
-
description:
|
|
207
|
-
|
|
206
|
+
control: 'object',
|
|
207
|
+
description: getDescription({
|
|
208
|
+
sections: [
|
|
209
|
+
{
|
|
210
|
+
name: '',
|
|
211
|
+
props: [
|
|
212
|
+
{
|
|
213
|
+
displayGuidingLines: {
|
|
214
|
+
description: 'displays the guiding lines',
|
|
215
|
+
type: 'boolean'
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
displayTooltipsGuidingLines: {
|
|
220
|
+
description:
|
|
221
|
+
'displays the tooltips (labels) on the axis bottom/left/right',
|
|
222
|
+
type: 'boolean'
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
],
|
|
226
|
+
type: 'object'
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}),
|
|
208
230
|
table: {
|
|
209
231
|
category: 'Graph interaction',
|
|
210
|
-
type: {
|
|
232
|
+
type: {
|
|
233
|
+
summary:
|
|
234
|
+
'displays or not the guiding lines and the dots for each point of the corresponding graph (line) according to the interaction of the mouse with the graph'
|
|
235
|
+
}
|
|
211
236
|
}
|
|
212
237
|
},
|
|
213
238
|
end: {
|
|
@@ -3,8 +3,8 @@ import { gt, gte, isEmpty, isNil, prop, propEq, reject, sortBy } from 'ramda';
|
|
|
3
3
|
|
|
4
4
|
import { LinesData } from '../BasicComponents/Lines/models';
|
|
5
5
|
import { dateFormat, timeFormat } from '../common';
|
|
6
|
-
import { GraphData, GraphInterval } from '../models';
|
|
7
|
-
import { getLineData, getTimeSeries } from '../timeSeries';
|
|
6
|
+
import { GetDate, GraphData, GraphInterval } from '../models';
|
|
7
|
+
import { getLineData, getTimeSeries, getTimeValue } from '../timeSeries';
|
|
8
8
|
|
|
9
9
|
export const adjustGraphData = (graphData: GraphData): LinesData => {
|
|
10
10
|
const lines = getLineData(graphData);
|
|
@@ -46,3 +46,13 @@ export const truncate = (content?: string): string => {
|
|
|
46
46
|
|
|
47
47
|
export const displayArea = (data: unknown): boolean =>
|
|
48
48
|
!isEmpty(data) && !isNil(data);
|
|
49
|
+
|
|
50
|
+
export const getDate = ({ positionX, xScale, timeSeries }: GetDate): Date => {
|
|
51
|
+
const { timeTick } = getTimeValue({
|
|
52
|
+
timeSeries,
|
|
53
|
+
x: positionX,
|
|
54
|
+
xScale
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return new Date(timeTick);
|
|
58
|
+
};
|