@centreon/ui 23.10.18-MON-fix-chromatic-parameters.0 → 23.10.18-MON-17793-create-graph-component-centreon-ui.2

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.
Files changed (118) hide show
  1. package/package.json +2 -1
  2. package/src/Button/Icon/index.tsx +1 -1
  3. package/src/Button/Save/index.tsx +1 -1
  4. package/src/FileDropZone/index.tsx +1 -1
  5. package/src/Form/FormButtons.tsx +1 -2
  6. package/src/Form/Inputs/Autocomplete.tsx +1 -1
  7. package/src/Form/Inputs/Radio.tsx +1 -1
  8. package/src/Form/Inputs/Switch.tsx +1 -1
  9. package/src/Graph/BasicComponents/Axes/UnitLabel.tsx +20 -0
  10. package/src/Graph/BasicComponents/Axes/index.tsx +84 -0
  11. package/src/Graph/BasicComponents/Axes/models.ts +26 -0
  12. package/src/Graph/BasicComponents/Axes/useAxisY.ts +100 -0
  13. package/src/Graph/BasicComponents/Grids/index.tsx +20 -0
  14. package/src/Graph/BasicComponents/Lines/RegularLines/index.tsx +99 -0
  15. package/src/Graph/BasicComponents/Lines/RegularLines/useRegularLines.ts +15 -0
  16. package/src/Graph/BasicComponents/Lines/StackedLines/index.tsx +74 -0
  17. package/src/Graph/BasicComponents/Lines/StackedLines/useStackedLines.ts +39 -0
  18. package/src/Graph/BasicComponents/Lines/index.tsx +153 -0
  19. package/src/Graph/BasicComponents/Lines/models.ts +32 -0
  20. package/src/Graph/BasicComponents/LoadingProgress.tsx +46 -0
  21. package/src/Graph/Graph.styles.ts +37 -0
  22. package/src/Graph/Graph.tsx +256 -0
  23. package/src/Graph/Header/index.tsx +34 -0
  24. package/src/Graph/IntercatifsComponents/AnchorPoint/RegularAnchorPoint.tsx +88 -0
  25. package/src/Graph/IntercatifsComponents/AnchorPoint/StackedAnchorPoint.tsx +97 -0
  26. package/src/Graph/IntercatifsComponents/AnchorPoint/index.tsx +56 -0
  27. package/src/Graph/IntercatifsComponents/AnchorPoint/models.ts +25 -0
  28. package/src/Graph/IntercatifsComponents/AnchorPoint/useAnchorPoint.ts +107 -0
  29. package/src/Graph/IntercatifsComponents/Annotations/Annotation/Area.tsx +114 -0
  30. package/src/Graph/IntercatifsComponents/Annotations/Annotation/Line.tsx +103 -0
  31. package/src/Graph/IntercatifsComponents/Annotations/Annotation/index.tsx +81 -0
  32. package/src/Graph/IntercatifsComponents/Annotations/Area/Downtime.tsx +27 -0
  33. package/src/Graph/IntercatifsComponents/Annotations/EventAnnotations.tsx +61 -0
  34. package/src/Graph/IntercatifsComponents/Annotations/Line/Acknowledgement.tsx +27 -0
  35. package/src/Graph/IntercatifsComponents/Annotations/Line/Comments.tsx +25 -0
  36. package/src/Graph/IntercatifsComponents/Annotations/annotationsAtoms.ts +183 -0
  37. package/src/Graph/IntercatifsComponents/Annotations/index.tsx +49 -0
  38. package/src/Graph/IntercatifsComponents/Annotations/models.ts +25 -0
  39. package/src/Graph/IntercatifsComponents/Annotations/useAnnotation.ts +62 -0
  40. package/src/Graph/IntercatifsComponents/Bar.tsx +21 -0
  41. package/src/Graph/IntercatifsComponents/TimeShiftZones/TimeShiftIcon.tsx +58 -0
  42. package/src/Graph/IntercatifsComponents/TimeShiftZones/TimeShiftZone.tsx +74 -0
  43. package/src/Graph/IntercatifsComponents/TimeShiftZones/index.tsx +84 -0
  44. package/src/Graph/IntercatifsComponents/TimeShiftZones/models.ts +12 -0
  45. package/src/Graph/IntercatifsComponents/TimeShiftZones/useTimeShiftZones.ts +72 -0
  46. package/src/Graph/IntercatifsComponents/Tooltip/index.tsx +64 -0
  47. package/src/Graph/IntercatifsComponents/Tooltip/models.ts +9 -0
  48. package/src/Graph/IntercatifsComponents/Tooltip/useGraphTooltip.ts +77 -0
  49. package/src/Graph/IntercatifsComponents/ZoomPreview/index.tsx +40 -0
  50. package/src/Graph/IntercatifsComponents/ZoomPreview/models.ts +12 -0
  51. package/src/Graph/IntercatifsComponents/ZoomPreview/useZoomPreview.ts +113 -0
  52. package/src/Graph/IntercatifsComponents/ZoomPreview/zoomPreviewAtoms.ts +3 -0
  53. package/src/Graph/IntercatifsComponents/index.tsx +134 -0
  54. package/src/Graph/IntercatifsComponents/interactionWithGraphAtoms.ts +52 -0
  55. package/src/Graph/common/index.ts +33 -0
  56. package/src/Graph/helpers/doc.ts +334 -0
  57. package/src/Graph/helpers/index.ts +47 -0
  58. package/src/Graph/icons/Downtime.tsx +9 -0
  59. package/src/Graph/icons/downtime.icon.svg +1 -0
  60. package/src/Graph/index.stories.tsx +161 -0
  61. package/src/Graph/index.tsx +75 -0
  62. package/src/Graph/map.md +51 -0
  63. package/src/Graph/mockedData/annotationData.json +189 -0
  64. package/src/Graph/mockedData/lastDay.json +1338 -0
  65. package/src/Graph/mockedData/lastDayForward.json +1338 -0
  66. package/src/Graph/mockedData/lastMonth.json +1674 -0
  67. package/src/Graph/mockedData/lastWeek.json +2202 -0
  68. package/src/Graph/mockedData/zoomPreview.json +350 -0
  69. package/src/Graph/models.ts +104 -0
  70. package/src/Graph/timeSeries/index.test.ts +484 -0
  71. package/src/Graph/timeSeries/index.ts +512 -0
  72. package/src/Graph/timeSeries/models.ts +119 -0
  73. package/src/Graph/translatedLabels.ts +6 -0
  74. package/src/Graph/useGraphData.ts +63 -0
  75. package/src/InputField/Select/Autocomplete/Connected/index.tsx +5 -3
  76. package/src/InputField/Select/Autocomplete/index.tsx +1 -1
  77. package/src/InputField/Select/index.tsx +1 -1
  78. package/src/InputField/Text/index.tsx +1 -1
  79. package/src/Listing/ActionBar/index.tsx +1 -1
  80. package/src/Listing/index.tsx +1 -2
  81. package/src/ListingPage/index.tsx +1 -1
  82. package/src/Panel/Memoized.tsx +1 -1
  83. package/src/Panel/Section/index.tsx +1 -1
  84. package/src/SortableItems/SortableItem.tsx +1 -1
  85. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +57 -0
  86. package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.tsx +78 -0
  87. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/ErrorText.tsx +14 -0
  88. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +163 -0
  89. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/index.tsx +76 -0
  90. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +61 -0
  91. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/usePickersStartEndDate.ts +82 -0
  92. package/src/TimePeriods/CustomTimePeriod/index.tsx +68 -0
  93. package/src/TimePeriods/DateTimePickerInput.tsx +49 -0
  94. package/src/TimePeriods/SelectedTimePeriod.tsx +99 -0
  95. package/src/TimePeriods/TimePeriods.cypress.spec.tsx +510 -0
  96. package/src/TimePeriods/helpers/index.ts +25 -0
  97. package/src/TimePeriods/index.stories.tsx +74 -0
  98. package/src/TimePeriods/index.tsx +67 -0
  99. package/src/TimePeriods/map.md +34 -0
  100. package/src/TimePeriods/models.ts +99 -0
  101. package/src/TimePeriods/timePeriods.styles.ts +20 -0
  102. package/src/TimePeriods/timePeriodsAtoms.ts +122 -0
  103. package/src/TimePeriods/useAwesomeTimePeriod.ts +48 -0
  104. package/src/TimePeriods/useSortTimePeriods.ts +24 -0
  105. package/src/index.ts +2 -18
  106. package/src/utils/getNormalizedId.ts +1 -3
  107. package/src/utils/index.ts +15 -0
  108. package/src/utils/useCopyToClipboard.ts +2 -3
  109. package/src/utils/useDateTimePickerAdapter.ts +309 -0
  110. package/src/utils/useDebounce.ts +1 -3
  111. package/src/utils/useDeepCallback.ts +1 -3
  112. package/src/utils/useDeepMemo.ts +1 -3
  113. package/src/utils/useIntersectionObserver.ts +1 -3
  114. package/src/utils/useKeyObserver.tsx +1 -3
  115. package/src/utils/useLocaleDateTimeFormat/index.test.tsx +1 -1
  116. package/src/utils/useLocaleDateTimeFormat/index.ts +1 -2
  117. package/src/utils/useLocaleDateTimeFormat/localeFallback.test.tsx +1 -1
  118. package/src/utils/useMemoComponent.ts +1 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "23.10.18-MON-fix-chromatic-parameters.0",
3
+ "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.2",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -85,6 +85,7 @@
85
85
  "@lexical/selection": "0.8.0",
86
86
  "@lexical/utils": "0.8.0",
87
87
  "anylogger": "^1.0.11",
88
+ "d3-array": "3.2.0",
88
89
  "humanize-duration": "^3.27.3",
89
90
  "lexical": "0.8.0",
90
91
  "notistack": "^2.0.8",
@@ -6,7 +6,7 @@ import {
6
6
  Tooltip
7
7
  } from '@mui/material';
8
8
 
9
- import getNormalizedId from '../../utils/getNormalizedId';
9
+ import { getNormalizedId } from '../../utils';
10
10
 
11
11
  const useStyles = makeStyles()((theme) => ({
12
12
  button: {
@@ -4,7 +4,7 @@ import { makeStyles } from 'tss-react/mui';
4
4
  import { Theme, Tooltip } from '@mui/material';
5
5
  import { LoadingButton } from '@mui/lab';
6
6
 
7
- import getNormalizedId from '../../utils/getNormalizedId';
7
+ import { getNormalizedId } from '../../utils';
8
8
 
9
9
  import StartIcon from './StartIcon';
10
10
  import Content from './Content';
@@ -17,7 +17,7 @@ import { alpha, Box, FormHelperText, Typography } from '@mui/material';
17
17
 
18
18
  import { userAtom } from '@centreon/ui-context';
19
19
 
20
- import useMemoComponent from '../utils/useMemoComponent';
20
+ import { useMemoComponent } from '../utils';
21
21
 
22
22
  import { labelDropOr, labelSelectAFile } from './translatedLabels';
23
23
  import useDropzone, { UseDropzoneState } from './useDropzone';
@@ -8,8 +8,7 @@ import { makeStyles } from 'tss-react/mui';
8
8
  import { Button } from '@mui/material';
9
9
 
10
10
  import SaveButton from '../Button/Save';
11
- import useMemoComponent from '../utils/useMemoComponent';
12
- import getNormalizedId from '../utils/getNormalizedId';
11
+ import { useMemoComponent, getNormalizedId } from '../utils';
13
12
 
14
13
  import {
15
14
  labelReset,
@@ -9,7 +9,7 @@ import { FormHelperText, Stack } from '@mui/material';
9
9
  import SingleAutocompleteField from '../../InputField/Select/Autocomplete';
10
10
  import { labelPressEnterToAccept } from '../translatedLabels';
11
11
  import MultiAutocompleteField from '../../InputField/Select/Autocomplete/Multi';
12
- import useMemoComponent from '../../utils/useMemoComponent';
12
+ import { useMemoComponent } from '../../utils';
13
13
  import { SelectEntry } from '../../InputField/Select';
14
14
 
15
15
  import { InputPropsWithoutGroup, InputType } from './models';
@@ -11,7 +11,7 @@ import {
11
11
  } from '@mui/material';
12
12
 
13
13
  import { useMemoComponent } from '../..';
14
- import getNormalizedId from '../../utils/getNormalizedId';
14
+ import { getNormalizedId } from '../../utils';
15
15
 
16
16
  import { InputPropsWithoutGroup } from './models';
17
17
 
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { FormControlLabel, Switch as MUISwitch } from '@mui/material';
8
8
 
9
- import getNormalizedId from '../../utils/getNormalizedId';
9
+ import { getNormalizedId } from '../../utils/getNormalizedId';
10
10
  import { useMemoComponent } from '../..';
11
11
 
12
12
  import { InputPropsWithoutGroup } from './models';
@@ -0,0 +1,20 @@
1
+ import { commonTickLabelProps } from '../../common';
2
+
3
+ interface UnitLabelProps {
4
+ unit: string;
5
+ x: number;
6
+ y?: number;
7
+ }
8
+
9
+ const UnitLabel = ({ x, y = 16, unit }: UnitLabelProps): JSX.Element => (
10
+ <text
11
+ fontFamily={commonTickLabelProps.fontFamily}
12
+ fontSize={commonTickLabelProps.fontSize}
13
+ x={x}
14
+ y={-y}
15
+ >
16
+ {unit}
17
+ </text>
18
+ );
19
+
20
+ export default UnitLabel;
@@ -0,0 +1,84 @@
1
+ import { Axis } from '@visx/visx';
2
+ import { ScaleLinear } from 'd3-scale';
3
+
4
+ import { useLocaleDateTimeFormat } from '@centreon/ui';
5
+
6
+ import { getUnits } from '../../timeSeries';
7
+ import { getXAxisTickFormat } from '../../helpers';
8
+ import { GraphInterval } from '../../models';
9
+
10
+ import UnitLabel from './UnitLabel';
11
+ import { Data } from './models';
12
+ import useAxisY from './useAxisY';
13
+
14
+ interface Props {
15
+ data: Data;
16
+ graphInterval: GraphInterval;
17
+ height: number;
18
+ leftScale: ScaleLinear<number, number>;
19
+ rightScale: ScaleLinear<number, number>;
20
+ width: number;
21
+ xScale: ScaleLinear<number, number>;
22
+ }
23
+
24
+ const Axes = ({
25
+ height,
26
+ width,
27
+ data,
28
+ rightScale,
29
+ leftScale,
30
+ xScale,
31
+ graphInterval
32
+ }: Props): JSX.Element => {
33
+ const { format } = useLocaleDateTimeFormat();
34
+ const { lines } = data;
35
+
36
+ const { axisLeft, axisRight } = useAxisY({ data, graphHeight: height });
37
+
38
+ const [firstUnit, secondUnit] = getUnits(lines);
39
+
40
+ const xTickCount = Math.ceil(width / 82);
41
+
42
+ const tickFormat =
43
+ data?.axisX?.xAxisTickFormat ?? getXAxisTickFormat(graphInterval);
44
+
45
+ const formatAxisTick = (tick): string =>
46
+ format({ date: new Date(tick), formatString: tickFormat });
47
+
48
+ return (
49
+ <g>
50
+ <Axis.AxisBottom
51
+ numTicks={xTickCount}
52
+ scale={xScale}
53
+ tickFormat={formatAxisTick}
54
+ top={height}
55
+ />
56
+
57
+ {axisLeft.displayUnit && <UnitLabel unit={firstUnit} x={-4} />}
58
+
59
+ <Axis.AxisLeft
60
+ numTicks={axisLeft.numTicks}
61
+ orientation="left"
62
+ scale={leftScale}
63
+ tickFormat={axisLeft.tickFormat}
64
+ tickLabelProps={axisLeft.tickLabelProps}
65
+ tickLength={2}
66
+ />
67
+
68
+ {axisRight.display && (
69
+ <Axis.AxisRight
70
+ left={width}
71
+ numTicks={axisRight.numTicks}
72
+ orientation="right"
73
+ scale={rightScale}
74
+ tickFormat={axisRight.tickFormat}
75
+ tickLabelProps={axisRight.tickLabelProps}
76
+ tickLength={2}
77
+ />
78
+ )}
79
+ {axisRight.displayUnit && <UnitLabel unit={secondUnit} x={width} />}
80
+ </g>
81
+ );
82
+ };
83
+
84
+ export default Axes;
@@ -0,0 +1,26 @@
1
+ import { Line, TimeValue } from '../../timeSeries/models';
2
+
3
+ export interface LabelProps {
4
+ [x: string]: unknown;
5
+ textAnchor?: string;
6
+ }
7
+
8
+ export interface Axis {
9
+ displayUnit?: boolean;
10
+ }
11
+
12
+ export interface AxisYRight extends Axis {
13
+ display?: boolean;
14
+ }
15
+
16
+ export interface AxisX {
17
+ xAxisTickFormat?: string;
18
+ }
19
+ export interface Data {
20
+ axisX?: AxisX;
21
+ axisYLeft?: Axis;
22
+ axisYRight?: AxisYRight;
23
+ baseAxis: number;
24
+ lines: Array<Line>;
25
+ timeSeries: Array<TimeValue>;
26
+ }
@@ -0,0 +1,100 @@
1
+ import { isNil } from 'ramda';
2
+ import { Axis } from '@visx/visx';
3
+
4
+ import { useTheme } from '@mui/material';
5
+
6
+ import { formatMetricValue, getUnits } from '../../timeSeries';
7
+ import { commonTickLabelProps } from '../../common';
8
+
9
+ import { Data, LabelProps } from './models';
10
+
11
+ interface AxisYData {
12
+ displayUnit: boolean;
13
+ numTicks: number;
14
+ tickFormat: Axis.TickFormatter<unknown>;
15
+ tickLabelProps: Axis.TickLabelProps<unknown>;
16
+ }
17
+
18
+ interface AxisRightData extends AxisYData {
19
+ display: boolean;
20
+ }
21
+
22
+ interface AxisY {
23
+ axisLeft: AxisYData;
24
+ axisRight: AxisRightData;
25
+ }
26
+
27
+ interface Props {
28
+ data: Data;
29
+ graphHeight: number;
30
+ }
31
+
32
+ const useAxisY = ({ data, graphHeight }: Props): AxisY => {
33
+ const theme = useTheme();
34
+
35
+ const { lines } = data;
36
+ const [firstUnit, secondUnit, thirdUnit] = getUnits(lines);
37
+
38
+ const numTicks = Math.ceil(graphHeight / 30);
39
+
40
+ const hasMoreThanTwoUnits = !isNil(thirdUnit);
41
+ const hasTwoUnits = !isNil(secondUnit) && !hasMoreThanTwoUnits;
42
+
43
+ const displayAxisRight = data?.axisYRight?.display ?? hasTwoUnits;
44
+ const displayUnitAxisRight = data?.axisYRight?.displayUnit ?? hasTwoUnits;
45
+ const displayUnitAxisLeft =
46
+ data?.axisYLeft?.displayUnit ?? !hasMoreThanTwoUnits;
47
+
48
+ const formatTick =
49
+ ({ unit }) =>
50
+ (value): string => {
51
+ if (isNil(value)) {
52
+ return '';
53
+ }
54
+
55
+ return formatMetricValue({ base: data.baseAxis, unit, value }) as string;
56
+ };
57
+
58
+ const labelProps = ({
59
+ textAnchor,
60
+ ...rest
61
+ }: LabelProps): Record<string, unknown> => ({
62
+ ...commonTickLabelProps,
63
+ textAnchor,
64
+ ...rest
65
+ });
66
+
67
+ const tickLabelPropsAxisLeft = (): Record<string, unknown> =>
68
+ labelProps({
69
+ dx: theme.spacing(-1),
70
+ dy: theme.spacing(0.5),
71
+ textAnchor: 'end'
72
+ });
73
+
74
+ const tickLabelPropsAxisRight = (): Record<string, unknown> =>
75
+ labelProps({
76
+ dx: theme.spacing(0.5),
77
+ dy: theme.spacing(0.5),
78
+ textAnchor: 'start'
79
+ });
80
+
81
+ return {
82
+ axisLeft: {
83
+ displayUnit: displayUnitAxisLeft,
84
+ numTicks,
85
+ tickFormat: formatTick({
86
+ unit: hasMoreThanTwoUnits ? '' : firstUnit
87
+ }),
88
+ tickLabelProps: tickLabelPropsAxisLeft
89
+ },
90
+ axisRight: {
91
+ display: displayAxisRight,
92
+ displayUnit: displayUnitAxisRight,
93
+ numTicks,
94
+ tickFormat: formatTick({ unit: secondUnit }),
95
+ tickLabelProps: tickLabelPropsAxisRight
96
+ }
97
+ };
98
+ };
99
+
100
+ export default useAxisY;
@@ -0,0 +1,20 @@
1
+ import { Grid } from '@visx/visx';
2
+ import { ScaleLinear } from 'd3-scale';
3
+
4
+ interface Props {
5
+ height: number;
6
+ leftScale: ScaleLinear<number, number>;
7
+ width: number;
8
+ xScale: ScaleLinear<number, number>;
9
+ }
10
+
11
+ const Grids = ({ height, width, leftScale, xScale }: Props): JSX.Element => {
12
+ return (
13
+ <g>
14
+ <Grid.GridRows height={height} scale={leftScale} width={width} />
15
+ <Grid.GridColumns height={height} scale={xScale} width={width} />
16
+ </g>
17
+ );
18
+ };
19
+
20
+ export default Grids;
@@ -0,0 +1,99 @@
1
+ import { memo } from 'react';
2
+
3
+ import { Curve, Shape } from '@visx/visx';
4
+ import { ScaleLinear, ScaleTime } from 'd3-scale';
5
+ import { equals, isNil, prop } from 'ramda';
6
+
7
+ import { getTime } from '../../../timeSeries';
8
+ import { TimeValue } from '../../../timeSeries/models';
9
+ import { getFillColor } from '../../../common';
10
+
11
+ interface Props {
12
+ areaColor: string;
13
+ filled: boolean;
14
+ graphHeight: number;
15
+ highlight?: boolean;
16
+ lineColor: string;
17
+ metric: string;
18
+ shapeAreaClosed?: Record<string, unknown>;
19
+ shapeLinePath?: Record<string, unknown>;
20
+ timeSeries: Array<TimeValue>;
21
+ transparency: number;
22
+ unit: string;
23
+ xScale: ScaleTime<number, number>;
24
+ yScale: ScaleLinear<number, number>;
25
+ }
26
+
27
+ const RegularLine = ({
28
+ filled,
29
+ timeSeries,
30
+ highlight,
31
+ metric,
32
+ lineColor,
33
+ unit,
34
+ yScale,
35
+ xScale,
36
+ areaColor,
37
+ transparency,
38
+ graphHeight
39
+ }: Props): JSX.Element => {
40
+ const isHighlighted = highlight ? 2 : 0.8;
41
+
42
+ const props = {
43
+ curve: Curve.curveLinear,
44
+ data: timeSeries,
45
+ defined: (value): boolean => !isNil(value[metric]),
46
+ opacity: highlight === false ? 0.3 : 1,
47
+ stroke: lineColor,
48
+ strokeWidth: isHighlighted,
49
+ unit,
50
+ x: (timeValue): number => xScale(getTime(timeValue)) as number,
51
+ y: (timeValue): number => yScale(prop(metric, timeValue)) ?? null
52
+ };
53
+
54
+ if (filled) {
55
+ return (
56
+ <Shape.AreaClosed<TimeValue>
57
+ fill={getFillColor({ areaColor, transparency })}
58
+ fillRule="nonzero"
59
+ key={metric}
60
+ y0={Math.min(yScale(0), graphHeight)}
61
+ yScale={yScale}
62
+ {...props}
63
+ />
64
+ );
65
+ }
66
+
67
+ return <Shape.LinePath<TimeValue> {...props} />;
68
+ };
69
+
70
+ export default memo(RegularLine, (prevProps, nextProps) => {
71
+ const {
72
+ timeSeries: prevTimeSeries,
73
+ graphHeight: prevGraphHeight,
74
+ highlight: prevHighlight,
75
+ xScale: prevXScale,
76
+ shapeLinePath: prevShapeLinePath,
77
+ shapeAreaClosed: prevShapeAreaClosed
78
+ } = prevProps;
79
+ const {
80
+ timeSeries: nextTimeSeries,
81
+ graphHeight: nextGraphHeight,
82
+ highlight: nextHighlight,
83
+ xScale: nextXScale,
84
+ shapeLinePath: nextShapeLinePath,
85
+ shapeAreaClosed: nextShapeAreaClosed
86
+ } = nextProps;
87
+
88
+ const prevXScaleRange = prevXScale.range();
89
+ const nextXScaleRange = nextXScale.range();
90
+
91
+ return (
92
+ equals(prevTimeSeries, nextTimeSeries) &&
93
+ equals(prevGraphHeight, nextGraphHeight) &&
94
+ equals(prevHighlight, nextHighlight) &&
95
+ equals(prevXScaleRange, nextXScaleRange) &&
96
+ equals(prevShapeAreaClosed, nextShapeAreaClosed) &&
97
+ equals(prevShapeLinePath, nextShapeLinePath)
98
+ );
99
+ });
@@ -0,0 +1,15 @@
1
+ import { difference } from 'ramda';
2
+
3
+ import { Line } from '../../../timeSeries/models';
4
+ import { getSortedStackedLines } from '../../../timeSeries';
5
+
6
+ interface RegularLines {
7
+ regularLines: Array<Line>;
8
+ }
9
+ const useRegularLines = ({ lines }): RegularLines => {
10
+ const stackedLines = getSortedStackedLines(lines);
11
+
12
+ return { regularLines: difference(lines, stackedLines) };
13
+ };
14
+
15
+ export default useRegularLines;
@@ -0,0 +1,74 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ import { map, nth, pipe, path, all, not, isNil, prop } from 'ramda';
4
+ import { Shape, Curve } from '@visx/visx';
5
+ import { ScaleLinear, ScaleTime } from 'd3-scale';
6
+
7
+ import { Line, TimeValue } from '../../../timeSeries/models';
8
+ import { getTime } from '../../../timeSeries';
9
+ import { getFillColor } from '../../../common';
10
+ import { StackedAnchorPoint } from '../../../IntercatifsComponents/AnchorPoint/models';
11
+
12
+ interface Props {
13
+ lines: Array<Line>;
14
+ renderStackedAnchorPoint: (args: StackedAnchorPoint) => ReactNode;
15
+ timeSeries: Array<TimeValue>;
16
+ xScale: ScaleTime<number, number>;
17
+ yScale: ScaleLinear<number, number>;
18
+ }
19
+
20
+ const StackLines = ({
21
+ timeSeries,
22
+ lines,
23
+ yScale,
24
+ xScale,
25
+ renderStackedAnchorPoint
26
+ }: Props): JSX.Element => {
27
+ return (
28
+ <Shape.AreaStack
29
+ curve={Curve.curveLinear}
30
+ data={timeSeries}
31
+ defined={(d): boolean => {
32
+ return pipe(
33
+ map(prop('metric')) as (lines) => Array<string>,
34
+ all((metric) => pipe(path(['data', metric]), isNil, not)(d))
35
+ )(lines);
36
+ }}
37
+ keys={map(prop('metric'), lines)}
38
+ x={(d): number => xScale(getTime(d.data)) ?? 0}
39
+ y0={(d): number => yScale(d[0]) ?? 0}
40
+ y1={(d): number => yScale(d[1]) ?? 0}
41
+ >
42
+ {({ stacks, path: linePath }): Array<JSX.Element> => {
43
+ return stacks.map((stack, index) => {
44
+ const { areaColor, transparency, lineColor, highlight } = nth(
45
+ index,
46
+ lines
47
+ ) as Line;
48
+
49
+ return (
50
+ <g key={`stack-${prop('key', stack)}`}>
51
+ {renderStackedAnchorPoint?.({
52
+ areaColor,
53
+ lineColor,
54
+ stack,
55
+ transparency,
56
+ xScale,
57
+ yScale
58
+ })}
59
+ <path
60
+ d={linePath(stack) || ''}
61
+ fill={getFillColor({ areaColor, transparency })}
62
+ opacity={highlight === false ? 0.3 : 1}
63
+ stroke={lineColor}
64
+ strokeWidth={highlight ? 2 : 1}
65
+ />
66
+ </g>
67
+ );
68
+ });
69
+ }}
70
+ </Shape.AreaStack>
71
+ );
72
+ };
73
+
74
+ export default StackLines;
@@ -0,0 +1,39 @@
1
+ import {
2
+ getInvertedStackedLines,
3
+ getNotInvertedStackedLines,
4
+ getTimeSeriesForLines
5
+ } from '../../../timeSeries';
6
+ import { LinesData } from '../models';
7
+
8
+ interface StackedLines {
9
+ invertedStackedLinesData: LinesData;
10
+ stackedLinesData: LinesData;
11
+ }
12
+
13
+ const useStackedLines = ({ lines, timeSeries }): StackedLines => {
14
+ const regularStackedLines = getNotInvertedStackedLines(lines);
15
+
16
+ const regularStackedTimeSeries = getTimeSeriesForLines({
17
+ lines: regularStackedLines,
18
+ timeSeries
19
+ });
20
+
21
+ const invertedStackedLines = getInvertedStackedLines(lines);
22
+ const invertedStackedTimeSeries = getTimeSeriesForLines({
23
+ lines: invertedStackedLines,
24
+ timeSeries
25
+ });
26
+
27
+ return {
28
+ invertedStackedLinesData: {
29
+ lines: invertedStackedLines,
30
+ timeSeries: invertedStackedTimeSeries
31
+ },
32
+ stackedLinesData: {
33
+ lines: regularStackedLines,
34
+ timeSeries: regularStackedTimeSeries
35
+ }
36
+ };
37
+ };
38
+
39
+ export default useStackedLines;