@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@centreon/ui",
|
|
3
|
-
"version": "23.10.18-MON-17793-create-graph-component-centreon-ui.
|
|
3
|
+
"version": "23.10.18-MON-17793-create-graph-component-centreon-ui.23",
|
|
4
4
|
"description": "Centreon UI Components",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
|
|
@@ -61,7 +61,7 @@ const Axes = ({
|
|
|
61
61
|
{axisLeft.displayUnit && <UnitLabel unit={firstUnit} x={-4} />}
|
|
62
62
|
|
|
63
63
|
<Axis.AxisLeft
|
|
64
|
-
numTicks={axisLeft
|
|
64
|
+
numTicks={axisLeft?.numTicks}
|
|
65
65
|
orientation="left"
|
|
66
66
|
scale={leftScale}
|
|
67
67
|
tickFormat={axisLeft.tickFormat}
|
|
@@ -72,7 +72,7 @@ const Axes = ({
|
|
|
72
72
|
{displayAxisRight && (
|
|
73
73
|
<Axis.AxisRight
|
|
74
74
|
left={width}
|
|
75
|
-
numTicks={axisRight
|
|
75
|
+
numTicks={axisRight?.numTicks}
|
|
76
76
|
orientation="right"
|
|
77
77
|
scale={rightScale}
|
|
78
78
|
tickFormat={axisRight.tickFormat}
|
|
@@ -10,8 +10,8 @@ import { Data, LabelProps } from './models';
|
|
|
10
10
|
|
|
11
11
|
interface AxisYData {
|
|
12
12
|
displayUnit: boolean;
|
|
13
|
-
numTicks
|
|
14
|
-
tickFormat:
|
|
13
|
+
numTicks?: number;
|
|
14
|
+
tickFormat: (value: unknown) => string;
|
|
15
15
|
tickLabelProps: Axis.TickLabelProps<unknown>;
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -25,8 +25,8 @@ interface AxisY {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
interface Props {
|
|
28
|
-
data: Data
|
|
29
|
-
graphHeight
|
|
28
|
+
data: Omit<Data, 'timeSeries'>;
|
|
29
|
+
graphHeight?: number;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
const useAxisY = ({ data, graphHeight }: Props): AxisY => {
|
|
@@ -35,7 +35,7 @@ const useAxisY = ({ data, graphHeight }: Props): AxisY => {
|
|
|
35
35
|
const { lines } = data;
|
|
36
36
|
const [firstUnit, secondUnit, thirdUnit] = getUnits(lines);
|
|
37
37
|
|
|
38
|
-
const numTicks = Math.ceil(graphHeight / 30);
|
|
38
|
+
const numTicks = graphHeight && Math.ceil(graphHeight / 30);
|
|
39
39
|
|
|
40
40
|
const hasMoreThanTwoUnits = !isNil(thirdUnit);
|
|
41
41
|
const hasTwoUnits = !isNil(secondUnit) && !hasMoreThanTwoUnits;
|
|
@@ -37,13 +37,13 @@ const RegularLine = ({
|
|
|
37
37
|
transparency,
|
|
38
38
|
graphHeight
|
|
39
39
|
}: Props): JSX.Element => {
|
|
40
|
-
const isHighlighted = highlight ?
|
|
40
|
+
const isHighlighted = highlight ? 3 : 1;
|
|
41
41
|
|
|
42
42
|
const props = {
|
|
43
43
|
curve: Curve.curveLinear,
|
|
44
44
|
data: timeSeries,
|
|
45
45
|
defined: (value): boolean => !isNil(value[metric]),
|
|
46
|
-
opacity: !highlight ?
|
|
46
|
+
opacity: !highlight ? 1 : 3,
|
|
47
47
|
stroke: lineColor,
|
|
48
48
|
strokeWidth: isHighlighted,
|
|
49
49
|
unit,
|
|
@@ -4,15 +4,12 @@ import { all, isNil, map, not, nth, path, pipe, prop } from 'ramda';
|
|
|
4
4
|
|
|
5
5
|
import StackedAnchorPoint from '../../../InteractiveComponents/AnchorPoint/StackedAnchorPoint';
|
|
6
6
|
import { StackValue } from '../../../InteractiveComponents/AnchorPoint/models';
|
|
7
|
-
import useTickGraph from '../../../InteractiveComponents/AnchorPoint/useTickGraph';
|
|
8
7
|
import { getFillColor } from '../../../common';
|
|
9
8
|
import { getTime } from '../../../timeSeries';
|
|
10
9
|
import { Line, TimeValue } from '../../../timeSeries/models';
|
|
11
10
|
|
|
12
11
|
interface Props {
|
|
13
12
|
displayAnchor: boolean;
|
|
14
|
-
graphHeight: number;
|
|
15
|
-
graphWidth: number;
|
|
16
13
|
lines: Array<Line>;
|
|
17
14
|
timeSeries: Array<TimeValue>;
|
|
18
15
|
xScale: ScaleTime<number, number>;
|
|
@@ -24,15 +21,8 @@ const StackLines = ({
|
|
|
24
21
|
lines,
|
|
25
22
|
yScale,
|
|
26
23
|
xScale,
|
|
27
|
-
displayAnchor
|
|
28
|
-
graphHeight,
|
|
29
|
-
graphWidth
|
|
24
|
+
displayAnchor
|
|
30
25
|
}: Props): JSX.Element => {
|
|
31
|
-
const { timeTick, positionX, positionY } = useTickGraph({
|
|
32
|
-
timeSeries,
|
|
33
|
-
xScale
|
|
34
|
-
});
|
|
35
|
-
|
|
36
26
|
return (
|
|
37
27
|
<Shape.AreaStack
|
|
38
28
|
curve={Curve.curveLinear}
|
|
@@ -60,13 +50,9 @@ const StackLines = ({
|
|
|
60
50
|
{displayAnchor && (
|
|
61
51
|
<StackedAnchorPoint
|
|
62
52
|
areaColor={areaColor}
|
|
63
|
-
graphHeight={graphHeight}
|
|
64
|
-
graphWidth={graphWidth}
|
|
65
53
|
lineColor={lineColor}
|
|
66
|
-
positionX={positionX}
|
|
67
|
-
positionY={positionY}
|
|
68
54
|
stackValues={stack as unknown as Array<StackValue>}
|
|
69
|
-
|
|
55
|
+
timeSeries={timeSeries}
|
|
70
56
|
transparency={transparency}
|
|
71
57
|
xScale={xScale}
|
|
72
58
|
yScale={yScale}
|
|
@@ -3,9 +3,10 @@ import { MutableRefObject } from 'react';
|
|
|
3
3
|
import { ScaleLinear } from 'd3-scale';
|
|
4
4
|
import { isNil } from 'ramda';
|
|
5
5
|
|
|
6
|
+
import GuidingLines from '../../InteractiveComponents/AnchorPoint/GuidingLines';
|
|
6
7
|
import RegularAnchorPoint from '../../InteractiveComponents/AnchorPoint/RegularAnchorPoint';
|
|
7
8
|
import { displayArea } from '../../helpers/index';
|
|
8
|
-
import { GlobalAreaLines } from '../../models';
|
|
9
|
+
import { DisplayAnchor, GlobalAreaLines } from '../../models';
|
|
9
10
|
import { getStackedYScale, getUnits, getYScale } from '../../timeSeries';
|
|
10
11
|
import { Line, TimeValue } from '../../timeSeries/models';
|
|
11
12
|
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
} from './Threshold/models';
|
|
21
22
|
|
|
22
23
|
interface Props extends GlobalAreaLines {
|
|
23
|
-
displayAnchor
|
|
24
|
+
displayAnchor?: DisplayAnchor;
|
|
24
25
|
displayedLines: Array<Line>;
|
|
25
26
|
graphSvgRef: MutableRefObject<SVGSVGElement | null>;
|
|
26
27
|
height: number;
|
|
@@ -64,8 +65,9 @@ const Lines = ({
|
|
|
64
65
|
rightScale
|
|
65
66
|
});
|
|
66
67
|
|
|
68
|
+
const displayGuidingLines = displayAnchor?.displayGuidingLines ?? true;
|
|
67
69
|
const commonStackedLinesProps = {
|
|
68
|
-
displayAnchor,
|
|
70
|
+
displayAnchor: displayGuidingLines,
|
|
69
71
|
graphHeight: height,
|
|
70
72
|
graphSvgRef,
|
|
71
73
|
graphWidth: width,
|
|
@@ -75,6 +77,15 @@ const Lines = ({
|
|
|
75
77
|
|
|
76
78
|
return (
|
|
77
79
|
<g>
|
|
80
|
+
{displayGuidingLines && (
|
|
81
|
+
<GuidingLines
|
|
82
|
+
graphHeight={height}
|
|
83
|
+
graphWidth={width}
|
|
84
|
+
timeSeries={timeSeries}
|
|
85
|
+
xScale={xScale}
|
|
86
|
+
/>
|
|
87
|
+
)}
|
|
88
|
+
|
|
78
89
|
{(areaStackedLines?.display ?? true) && (
|
|
79
90
|
<>
|
|
80
91
|
{displayArea(stackedLinesData.lines) && (
|
|
@@ -133,11 +144,9 @@ const Lines = ({
|
|
|
133
144
|
|
|
134
145
|
return (
|
|
135
146
|
<g key={metric}>
|
|
136
|
-
{
|
|
147
|
+
{displayGuidingLines && (
|
|
137
148
|
<RegularAnchorPoint
|
|
138
149
|
areaColor={areaColor}
|
|
139
|
-
graphHeight={height}
|
|
140
|
-
graphWidth={width}
|
|
141
150
|
lineColor={lineColor}
|
|
142
151
|
metric={metric}
|
|
143
152
|
timeSeries={timeSeries}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
import { useAtom } from 'jotai';
|
|
4
|
-
import { equals, propEq, reject } from 'ramda';
|
|
4
|
+
import { compose, equals, prop, propEq, reject, sortBy, toLower } from 'ramda';
|
|
5
5
|
|
|
6
6
|
import { linesGraphAtom } from '../graphAtoms';
|
|
7
7
|
import { Line } from '../timeSeries/models';
|
|
@@ -49,7 +49,9 @@ const useFilterLines = ({
|
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
const sortedLines = sortBy(compose(toLower, prop('name')), filteredLines);
|
|
53
|
+
|
|
54
|
+
setLinesGraph(sortedLines);
|
|
53
55
|
}, [lines, displayThreshold]);
|
|
54
56
|
|
|
55
57
|
return { displayedLines, newLines: linesGraph ?? lines };
|
package/src/Graph/Graph.tsx
CHANGED
|
@@ -8,11 +8,13 @@ import { ClickAwayListener, Skeleton } from '@mui/material';
|
|
|
8
8
|
import Axes from './BasicComponents/Axes';
|
|
9
9
|
import Grids from './BasicComponents/Grids';
|
|
10
10
|
import Lines from './BasicComponents/Lines';
|
|
11
|
+
import { canDisplayThreshold } from './BasicComponents/Lines/Threshold/models';
|
|
11
12
|
import LoadingProgress from './BasicComponents/LoadingProgress';
|
|
12
13
|
import useFilterLines from './BasicComponents/useFilterLines';
|
|
13
14
|
import { useStyles } from './Graph.styles';
|
|
14
15
|
import Header from './Header';
|
|
15
16
|
import InteractionWithGraph from './InteractiveComponents';
|
|
17
|
+
import TooltipAnchorPoint from './InteractiveComponents/AnchorPoint/TooltipAnchorPoint';
|
|
16
18
|
import GraphTooltip from './InteractiveComponents/Tooltip';
|
|
17
19
|
import useGraphTooltip from './InteractiveComponents/Tooltip/useGraphTooltip';
|
|
18
20
|
import Legend from './Legend';
|
|
@@ -26,7 +28,6 @@ import {
|
|
|
26
28
|
} from './models';
|
|
27
29
|
import { getLeftScale, getRightScale, getXScale } from './timeSeries';
|
|
28
30
|
import { useIntersection } from './useGraphIntersection';
|
|
29
|
-
import { canDisplayThreshold } from './BasicComponents/Lines/Threshold/models';
|
|
30
31
|
|
|
31
32
|
interface Props extends GraphProps {
|
|
32
33
|
graphData: Data;
|
|
@@ -42,7 +43,7 @@ const Graph = ({
|
|
|
42
43
|
width,
|
|
43
44
|
shapeLines,
|
|
44
45
|
axis,
|
|
45
|
-
displayAnchor
|
|
46
|
+
displayAnchor,
|
|
46
47
|
loading,
|
|
47
48
|
zoomPreview,
|
|
48
49
|
graphInterval,
|
|
@@ -119,7 +120,7 @@ const Graph = ({
|
|
|
119
120
|
return (
|
|
120
121
|
<>
|
|
121
122
|
<Header
|
|
122
|
-
displayTimeTick={displayAnchor}
|
|
123
|
+
displayTimeTick={displayAnchor?.displayGuidingLines ?? true}
|
|
123
124
|
header={header}
|
|
124
125
|
timeSeries={timeSeries}
|
|
125
126
|
title={title}
|
|
@@ -185,10 +186,23 @@ const Graph = ({
|
|
|
185
186
|
{displayTooltip && (
|
|
186
187
|
<GraphTooltip {...tooltip} {...graphTooltipData} />
|
|
187
188
|
)}
|
|
189
|
+
{(displayAnchor?.displayTooltipsGuidingLines ?? true) && (
|
|
190
|
+
<TooltipAnchorPoint
|
|
191
|
+
baseAxis={baseAxis}
|
|
192
|
+
graphHeight={graphHeight}
|
|
193
|
+
graphWidth={graphWidth}
|
|
194
|
+
leftScale={leftScale}
|
|
195
|
+
lines={displayedLines}
|
|
196
|
+
rightScale={rightScale}
|
|
197
|
+
timeSeries={timeSeries}
|
|
198
|
+
xScale={xScale}
|
|
199
|
+
/>
|
|
200
|
+
)}
|
|
201
|
+
|
|
188
202
|
{displayLegend && (
|
|
189
203
|
<Legend
|
|
190
204
|
base={baseAxis}
|
|
191
|
-
displayAnchor={displayAnchor}
|
|
205
|
+
displayAnchor={displayAnchor?.displayGuidingLines ?? true}
|
|
192
206
|
lines={newLines}
|
|
193
207
|
renderExtraComponent={legend?.renderExtraComponent}
|
|
194
208
|
timeSeries={timeSeries}
|
|
@@ -28,12 +28,14 @@ const Header = ({
|
|
|
28
28
|
const { classes } = useStyles();
|
|
29
29
|
const { toDateTime } = useLocaleDateTimeFormat();
|
|
30
30
|
|
|
31
|
-
const {
|
|
31
|
+
const { tickAxisBottom } = useTickGraph({
|
|
32
32
|
timeSeries,
|
|
33
33
|
xScale
|
|
34
34
|
});
|
|
35
35
|
const time =
|
|
36
|
-
displayTimeTick && !isNil(
|
|
36
|
+
displayTimeTick && !isNil(tickAxisBottom)
|
|
37
|
+
? toDateTime(tickAxisBottom)
|
|
38
|
+
: null;
|
|
37
39
|
|
|
38
40
|
const displayTitle = header?.displayTitle ?? true;
|
|
39
41
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SvgIcon, SvgIconProps } from '@mui/material';
|
|
2
2
|
|
|
3
|
-
import { ReactComponent as IconDowntime } from '
|
|
3
|
+
import { ReactComponent as IconDowntime } from '../../@assets/icons/downtime.icon.svg';
|
|
4
4
|
|
|
5
5
|
const Downtime = (props: SvgIconProps): JSX.Element => (
|
|
6
6
|
<SvgIcon component={IconDowntime} {...props} />
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
|
|
3
|
+
interface StylesProps {
|
|
4
|
+
tooltipLeftAxisX?: number;
|
|
5
|
+
tooltipLeftAxisYLeft?: number;
|
|
6
|
+
tooltipLeftAxisYRight?: number;
|
|
7
|
+
tooltipTopAxisX?: number;
|
|
8
|
+
tooltipTopAxisYLeft?: number;
|
|
9
|
+
tooltipTopAxisYRight?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const useStyles = makeStyles<StylesProps>()(
|
|
13
|
+
(
|
|
14
|
+
theme,
|
|
15
|
+
{
|
|
16
|
+
tooltipLeftAxisX,
|
|
17
|
+
tooltipTopAxisX,
|
|
18
|
+
tooltipLeftAxisYLeft,
|
|
19
|
+
tooltipTopAxisYLeft,
|
|
20
|
+
tooltipLeftAxisYRight,
|
|
21
|
+
tooltipTopAxisYRight
|
|
22
|
+
}
|
|
23
|
+
) => ({
|
|
24
|
+
tooltipAxisBottom: {
|
|
25
|
+
backgroundColor: theme.palette.background.listingHeader,
|
|
26
|
+
color: theme.palette.common.white,
|
|
27
|
+
left: tooltipLeftAxisX ?? 0,
|
|
28
|
+
minWidth: theme.spacing(5.5),
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
textAlign: 'center',
|
|
31
|
+
top: tooltipTopAxisX ?? 0
|
|
32
|
+
},
|
|
33
|
+
tooltipAxisLeftY: {
|
|
34
|
+
backgroundColor: theme.palette.background.listingHeader,
|
|
35
|
+
color: theme.palette.common.white,
|
|
36
|
+
left: tooltipLeftAxisYLeft ?? 0,
|
|
37
|
+
minWidth: theme.spacing(3),
|
|
38
|
+
position: 'absolute',
|
|
39
|
+
textAlign: 'center',
|
|
40
|
+
top: tooltipTopAxisYLeft ?? 0
|
|
41
|
+
},
|
|
42
|
+
tooltipLeftAxisRightY: {
|
|
43
|
+
backgroundColor: theme.palette.background.listingHeader,
|
|
44
|
+
color: theme.palette.common.white,
|
|
45
|
+
left: tooltipLeftAxisYRight ?? 0,
|
|
46
|
+
minWidth: theme.spacing(3),
|
|
47
|
+
position: 'absolute',
|
|
48
|
+
textAlign: 'center',
|
|
49
|
+
top: tooltipTopAxisYRight ?? 0
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Shape } from '@visx/visx';
|
|
2
|
+
|
|
3
|
+
import { grey } from '@mui/material/colors';
|
|
4
|
+
|
|
5
|
+
import { GuidingLines } from './models';
|
|
6
|
+
import useTickGraph from './useTickGraph';
|
|
7
|
+
|
|
8
|
+
const GuidingLines = ({
|
|
9
|
+
timeSeries,
|
|
10
|
+
xScale,
|
|
11
|
+
graphHeight,
|
|
12
|
+
graphWidth
|
|
13
|
+
}: GuidingLines): JSX.Element | null => {
|
|
14
|
+
const { positionX, positionY } = useTickGraph({
|
|
15
|
+
timeSeries,
|
|
16
|
+
xScale
|
|
17
|
+
});
|
|
18
|
+
if (!positionX || !positionY) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<>
|
|
24
|
+
<Shape.Line
|
|
25
|
+
fill="dotted"
|
|
26
|
+
from={{ x: positionX, y: 0 }}
|
|
27
|
+
pointerEvents="none"
|
|
28
|
+
stroke={grey[400]}
|
|
29
|
+
strokeDasharray="5,2"
|
|
30
|
+
strokeWidth={1}
|
|
31
|
+
to={{ x: positionX, y: graphHeight }}
|
|
32
|
+
/>
|
|
33
|
+
<Shape.Line
|
|
34
|
+
from={{ x: 0, y: positionY }}
|
|
35
|
+
pointerEvents="none"
|
|
36
|
+
stroke={grey[400]}
|
|
37
|
+
strokeDasharray="5,2"
|
|
38
|
+
strokeWidth={1}
|
|
39
|
+
to={{ x: graphWidth, y: positionY }}
|
|
40
|
+
/>
|
|
41
|
+
</>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default GuidingLines;
|
|
@@ -5,19 +5,15 @@ import { bisectDate, getDates } from '../../timeSeries';
|
|
|
5
5
|
import { TimeValue } from '../../timeSeries/models';
|
|
6
6
|
|
|
7
7
|
import useTickGraph from './useTickGraph';
|
|
8
|
+
import { GetYAnchorPoint } from './models';
|
|
8
9
|
|
|
9
10
|
import AnchorPoint from '.';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
areaColor: string;
|
|
13
|
-
graphHeight: number;
|
|
14
|
-
graphWidth: number;
|
|
15
14
|
lineColor: string;
|
|
16
15
|
metric: string;
|
|
17
|
-
positionX?: number;
|
|
18
|
-
positionY?: number;
|
|
19
16
|
timeSeries: Array<TimeValue>;
|
|
20
|
-
timeTick?: Date;
|
|
21
17
|
transparency: number;
|
|
22
18
|
xScale: ScaleTime<number, number>;
|
|
23
19
|
yScale: ScaleLinear<number, number>;
|
|
@@ -28,7 +24,7 @@ const getYAnchorPoint = ({
|
|
|
28
24
|
timeSeries,
|
|
29
25
|
yScale,
|
|
30
26
|
metric
|
|
31
|
-
}:
|
|
27
|
+
}: GetYAnchorPoint): number => {
|
|
32
28
|
const index = bisectDate(getDates(timeSeries), timeTick);
|
|
33
29
|
const timeValue = timeSeries[index];
|
|
34
30
|
|
|
@@ -42,10 +38,9 @@ const RegularAnchorPoint = ({
|
|
|
42
38
|
timeSeries,
|
|
43
39
|
areaColor,
|
|
44
40
|
transparency,
|
|
45
|
-
lineColor
|
|
46
|
-
...rest
|
|
41
|
+
lineColor
|
|
47
42
|
}: Props): JSX.Element | null => {
|
|
48
|
-
const { timeTick
|
|
43
|
+
const { tickAxisBottom: timeTick } = useTickGraph({
|
|
49
44
|
timeSeries,
|
|
50
45
|
xScale
|
|
51
46
|
});
|
|
@@ -71,12 +66,9 @@ const RegularAnchorPoint = ({
|
|
|
71
66
|
<AnchorPoint
|
|
72
67
|
areaColor={areaColor}
|
|
73
68
|
lineColor={lineColor}
|
|
74
|
-
positionX={positionX}
|
|
75
|
-
positionY={positionY}
|
|
76
69
|
transparency={transparency}
|
|
77
70
|
x={xAnchorPoint}
|
|
78
71
|
y={yAnchorPoint}
|
|
79
|
-
{...rest}
|
|
80
72
|
/>
|
|
81
73
|
);
|
|
82
74
|
};
|
|
@@ -2,24 +2,27 @@ import { ScaleLinear, ScaleTime } from 'd3-scale';
|
|
|
2
2
|
import { isNil, map, pipe } from 'ramda';
|
|
3
3
|
|
|
4
4
|
import { bisectDate } from '../../timeSeries';
|
|
5
|
+
import { TimeValue } from '../../timeSeries/models';
|
|
5
6
|
|
|
6
7
|
import { StackValue } from './models';
|
|
8
|
+
import useTickGraph from './useTickGraph';
|
|
7
9
|
|
|
8
10
|
import AnchorPoint from '.';
|
|
9
11
|
|
|
10
12
|
interface Props {
|
|
11
13
|
areaColor: string;
|
|
12
|
-
graphHeight: number;
|
|
13
|
-
graphWidth: number;
|
|
14
14
|
lineColor: string;
|
|
15
|
-
positionX?: number;
|
|
16
|
-
positionY?: number;
|
|
17
15
|
stackValues: Array<StackValue>;
|
|
18
|
-
|
|
16
|
+
timeSeries: Array<TimeValue>;
|
|
19
17
|
transparency: number;
|
|
20
18
|
xScale: ScaleTime<number, number>;
|
|
21
19
|
yScale: ScaleLinear<number, number>;
|
|
22
20
|
}
|
|
21
|
+
interface GetYAnchorPoint {
|
|
22
|
+
stackValues: Array<StackValue>;
|
|
23
|
+
timeTick: Date | null;
|
|
24
|
+
yScale: ScaleTime<number, number>;
|
|
25
|
+
}
|
|
23
26
|
|
|
24
27
|
const getStackedDates = (stackValues: Array<StackValue>): Array<Date> => {
|
|
25
28
|
const toTimeTick = (stackValue: StackValue): string =>
|
|
@@ -34,7 +37,7 @@ const getYAnchorPoint = ({
|
|
|
34
37
|
timeTick,
|
|
35
38
|
stackValues,
|
|
36
39
|
yScale
|
|
37
|
-
}:
|
|
40
|
+
}: GetYAnchorPoint): number => {
|
|
38
41
|
const index = bisectDate(getStackedDates(stackValues), timeTick);
|
|
39
42
|
const timeValue = stackValues[index];
|
|
40
43
|
|
|
@@ -45,12 +48,16 @@ const StackedAnchorPoint = ({
|
|
|
45
48
|
xScale,
|
|
46
49
|
yScale,
|
|
47
50
|
stackValues,
|
|
48
|
-
|
|
51
|
+
timeSeries,
|
|
49
52
|
areaColor,
|
|
50
53
|
transparency,
|
|
51
|
-
lineColor
|
|
52
|
-
...rest
|
|
54
|
+
lineColor
|
|
53
55
|
}: Props): JSX.Element | null => {
|
|
56
|
+
const { tickAxisBottom: timeTick } = useTickGraph({
|
|
57
|
+
timeSeries,
|
|
58
|
+
xScale
|
|
59
|
+
});
|
|
60
|
+
|
|
54
61
|
if (isNil(timeTick)) {
|
|
55
62
|
return null;
|
|
56
63
|
}
|
|
@@ -73,7 +80,6 @@ const StackedAnchorPoint = ({
|
|
|
73
80
|
transparency={transparency}
|
|
74
81
|
x={xAnchorPoint}
|
|
75
82
|
y={yAnchorPoint}
|
|
76
|
-
{...rest}
|
|
77
83
|
/>
|
|
78
84
|
);
|
|
79
85
|
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import Paper from '@mui/material/Paper';
|
|
2
|
+
import { Typography } from '@mui/material';
|
|
3
|
+
|
|
4
|
+
import useTooltipAnchorPoint from './useTooltipAnchorPoint';
|
|
5
|
+
import { useStyles } from './AnchorPoint.styles';
|
|
6
|
+
import { TooltipAnchorModel } from './models';
|
|
7
|
+
|
|
8
|
+
const TooltipAnchorPoint = ({
|
|
9
|
+
timeSeries,
|
|
10
|
+
xScale,
|
|
11
|
+
graphHeight,
|
|
12
|
+
leftScale,
|
|
13
|
+
rightScale,
|
|
14
|
+
graphWidth,
|
|
15
|
+
lines,
|
|
16
|
+
baseAxis
|
|
17
|
+
}: TooltipAnchorModel): JSX.Element => {
|
|
18
|
+
const {
|
|
19
|
+
tooltipDataAxisX,
|
|
20
|
+
tooltipDataAxisYLeft,
|
|
21
|
+
tooltipLeftAxisX,
|
|
22
|
+
tooltipLeftAxisYLeft,
|
|
23
|
+
tooltipTopAxisX,
|
|
24
|
+
tooltipTopAxisYLeft,
|
|
25
|
+
tooltipDataAxisYRight,
|
|
26
|
+
tooltipTopAxisYRight,
|
|
27
|
+
tooltipLeftAxisYRight
|
|
28
|
+
} = useTooltipAnchorPoint({
|
|
29
|
+
baseAxis,
|
|
30
|
+
graphHeight,
|
|
31
|
+
graphWidth,
|
|
32
|
+
leftScale,
|
|
33
|
+
lines,
|
|
34
|
+
rightScale,
|
|
35
|
+
timeSeries,
|
|
36
|
+
xScale
|
|
37
|
+
});
|
|
38
|
+
const { classes } = useStyles({
|
|
39
|
+
tooltipLeftAxisX,
|
|
40
|
+
tooltipLeftAxisYLeft,
|
|
41
|
+
tooltipLeftAxisYRight,
|
|
42
|
+
tooltipTopAxisX,
|
|
43
|
+
tooltipTopAxisYLeft,
|
|
44
|
+
tooltipTopAxisYRight
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
{tooltipDataAxisYLeft && (
|
|
50
|
+
<Paper className={classes.tooltipAxisLeftY}>
|
|
51
|
+
<Typography variant="caption">{tooltipDataAxisYLeft}</Typography>
|
|
52
|
+
</Paper>
|
|
53
|
+
)}
|
|
54
|
+
{tooltipDataAxisX && (
|
|
55
|
+
<Paper className={classes.tooltipAxisBottom}>
|
|
56
|
+
<Typography variant="caption">{tooltipDataAxisX}</Typography>
|
|
57
|
+
</Paper>
|
|
58
|
+
)}
|
|
59
|
+
{tooltipDataAxisYRight && (
|
|
60
|
+
<Paper className={classes.tooltipLeftAxisRightY}>
|
|
61
|
+
<Typography variant="caption">{tooltipDataAxisYRight}</Typography>
|
|
62
|
+
</Paper>
|
|
63
|
+
)}
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default TooltipAnchorPoint;
|
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
import { Shape } from '@visx/visx';
|
|
2
|
-
|
|
3
|
-
import { grey } from '@mui/material/colors';
|
|
4
|
-
|
|
5
1
|
interface Props {
|
|
6
2
|
areaColor: string;
|
|
7
|
-
graphHeight: number;
|
|
8
|
-
graphWidth: number;
|
|
9
3
|
lineColor: string;
|
|
10
|
-
positionX?: number;
|
|
11
|
-
positionY?: number;
|
|
12
4
|
transparency: number;
|
|
13
5
|
x: number;
|
|
14
6
|
y: number;
|
|
@@ -19,37 +11,17 @@ const Point = ({
|
|
|
19
11
|
lineColor,
|
|
20
12
|
transparency,
|
|
21
13
|
x,
|
|
22
|
-
y
|
|
23
|
-
...rest
|
|
14
|
+
y
|
|
24
15
|
}: Props): JSX.Element => {
|
|
25
|
-
const { positionX, positionY, graphHeight, graphWidth } = rest;
|
|
26
|
-
|
|
27
16
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/>
|
|
37
|
-
|
|
38
|
-
<Shape.Line
|
|
39
|
-
from={{ x: positionX, y: 0 }}
|
|
40
|
-
pointerEvents="none"
|
|
41
|
-
stroke={grey[400]}
|
|
42
|
-
strokeWidth={1}
|
|
43
|
-
to={{ x: positionX, y: graphHeight }}
|
|
44
|
-
/>
|
|
45
|
-
<Shape.Line
|
|
46
|
-
from={{ x: 0, y: positionY }}
|
|
47
|
-
pointerEvents="none"
|
|
48
|
-
stroke={grey[400]}
|
|
49
|
-
strokeWidth={1}
|
|
50
|
-
to={{ x: graphWidth, y: positionY }}
|
|
51
|
-
/>
|
|
52
|
-
</g>
|
|
17
|
+
<circle
|
|
18
|
+
cx={x}
|
|
19
|
+
cy={y}
|
|
20
|
+
fill={areaColor}
|
|
21
|
+
fillOpacity={(1 - transparency * 0.01).toString()}
|
|
22
|
+
r={3}
|
|
23
|
+
stroke={lineColor}
|
|
24
|
+
/>
|
|
53
25
|
);
|
|
54
26
|
};
|
|
55
27
|
|