@centreon/ui 23.10.18-MON-17793-create-graph-component-centreon-ui.6 → 23.10.18-MON-17793-create-graph-component-centreon-ui.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.6",
3
+ "version": "23.10.18-MON-17793-create-graph-component-centreon-ui.7",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "eslint": "eslint ./src --ext .js,.jsx,.ts,.tsx --max-warnings 0",
@@ -1,9 +1,8 @@
1
1
  import { ScaleLinear } from 'd3-scale';
2
2
 
3
- import { Line, TimeValue } from '../../timeSeries/models';
4
- import { displayArea } from '../../helpers/index';
5
-
6
- import { AreaRegularLines } from './models';
3
+ import { Line, TimeValue } from '../../../timeSeries/models';
4
+ import { displayArea } from '../../../helpers/index';
5
+ import { AreaRegularLines } from '../models';
7
6
 
8
7
  interface RegularLinesData {
9
8
  display: boolean;
@@ -1,10 +1,9 @@
1
1
  import { ScaleLinear } from 'd3-scale';
2
2
 
3
- import { getStackedYScale } from '../../timeSeries';
4
- import { displayArea } from '../../helpers/index';
5
- import { Line, TimeValue } from '../../timeSeries/models';
6
-
7
- import { AreaStackedLines } from './models';
3
+ import { getStackedYScale } from '../../../timeSeries';
4
+ import { displayArea } from '../../../helpers/index';
5
+ import { Line, TimeValue } from '../../../timeSeries/models';
6
+ import { AreaStackedLines } from '../models';
8
7
 
9
8
  interface StackedLinesData {
10
9
  displayAreaInvertedStackedLines: boolean;
@@ -0,0 +1,48 @@
1
+ import { curveBasis } from '@visx/curve';
2
+ import { ScaleLinear } from 'd3-scale';
3
+ import { Threshold } from '@visx/threshold';
4
+
5
+ import { TimeValue } from '../../../timeSeries/models';
6
+
7
+ interface Props {
8
+ getX: ScaleLinear<number, number>;
9
+ getY0: ScaleLinear<number, number>;
10
+ getY1: ScaleLinear<number, number>;
11
+ graphHeight: number;
12
+ lineColorY0: string;
13
+ lineColorY1: string;
14
+ timeSeries: Array<TimeValue>;
15
+ }
16
+
17
+ const BasicThreshold = ({
18
+ getX,
19
+ getY0,
20
+ getY1,
21
+ lineColorY0,
22
+ lineColorY1,
23
+ graphHeight,
24
+ timeSeries
25
+ }: Props): JSX.Element => {
26
+ return (
27
+ <Threshold
28
+ aboveAreaProps={{
29
+ fill: lineColorY1,
30
+ fillOpacity: 0.1
31
+ }}
32
+ belowAreaProps={{
33
+ fill: lineColorY0,
34
+ fillOpacity: 0.1
35
+ }}
36
+ clipAboveTo={0}
37
+ clipBelowTo={graphHeight}
38
+ curve={curveBasis}
39
+ data={timeSeries}
40
+ id="threshold"
41
+ x={getX}
42
+ y0={getY0}
43
+ y1={getY1}
44
+ />
45
+ );
46
+ };
47
+
48
+ export default BasicThreshold;
@@ -0,0 +1,51 @@
1
+ import { Shape } from '@visx/visx';
2
+ import { isEmpty, isNil, prop } from 'ramda';
3
+ import { ScaleLinear } from 'd3-scale';
4
+
5
+ import { getTime } from '../../../timeSeries/index';
6
+ import { TimeValue } from '../../../timeSeries/models';
7
+
8
+ import usePointsOnline from './usePointsOnline';
9
+ import { Data } from './models';
10
+
11
+ interface Circle {
12
+ dataY0: Data;
13
+ dataY1: Data;
14
+ dataYOrigin: Data;
15
+ timeValue: TimeValue;
16
+ variation: number;
17
+ xScale: ScaleLinear<number, number>;
18
+ }
19
+
20
+ const Circle = ({
21
+ timeValue,
22
+ dataY0,
23
+ dataY1,
24
+ dataYOrigin,
25
+ xScale,
26
+ variation
27
+ }: Circle): JSX.Element | null => {
28
+ const { metric: metricY0, yScale: y0Scale } = dataY0;
29
+ const { metric: metricY1, yScale: y1Scale } = dataY1;
30
+ const { metric: metricYOrigin, yScale } = dataYOrigin;
31
+
32
+ const x = xScale(getTime(timeValue));
33
+ const y = yScale(prop(metricYOrigin, timeValue));
34
+
35
+ const y0 = y0Scale(prop(metricY0, timeValue) + variation);
36
+
37
+ const y1 = y1Scale(prop(metricY1, timeValue) - variation);
38
+ const coordinate = usePointsOnline({
39
+ pointLower: { x, y: y0 },
40
+ pointOrigin: { x, y },
41
+ pointUpper: { x, y: y1 }
42
+ });
43
+
44
+ if (isEmpty(coordinate) || isNil(coordinate)) {
45
+ return null;
46
+ }
47
+
48
+ return <Shape.Circle cx={coordinate.x} cy={coordinate.y} fill="red" r={2} />;
49
+ };
50
+
51
+ export default Circle;
@@ -1,11 +1,14 @@
1
1
  import { curveBasis } from '@visx/curve';
2
- import { Threshold } from '@visx/threshold';
2
+ import { LinePath } from '@visx/shape';
3
3
  import { ScaleLinear } from 'd3-scale';
4
4
  import { prop } from 'ramda';
5
5
 
6
+ import { useTheme } from '@mui/material/styles';
7
+
6
8
  import { getTime } from '../../../timeSeries/index';
7
9
  import { TimeValue } from '../../../timeSeries/models';
8
10
 
11
+ import BasicThreshold from './BasicThreshold';
9
12
  import { Data } from './models';
10
13
 
11
14
  interface Props {
@@ -13,6 +16,7 @@ interface Props {
13
16
  dataY1: Data;
14
17
  graphHeight: number;
15
18
  timeSeries: Array<TimeValue>;
19
+ variation?: number;
16
20
  xScale: ScaleLinear<number, number>;
17
21
  }
18
22
 
@@ -21,30 +25,66 @@ const ThresholdLines = ({
21
25
  dataY1,
22
26
  timeSeries,
23
27
  xScale,
24
- graphHeight
28
+ graphHeight,
29
+ variation
25
30
  }: Props): JSX.Element => {
31
+ const theme = useTheme();
32
+
26
33
  const { lineColor: lineColorY0, metric: metricY0, yScale: y0Scale } = dataY0;
27
34
  const { lineColor: lineColorY1, metric: metricY1, yScale: y1Scale } = dataY1;
28
35
 
36
+ const getX = (timeValue: TimeValue): number =>
37
+ xScale(getTime(timeValue)) as number;
38
+
39
+ if (!variation) {
40
+ const getY0 = (timeValue: TimeValue): number =>
41
+ y0Scale(prop(metricY0, timeValue)) ?? null;
42
+ const getY1 = (timeValue: TimeValue): number =>
43
+ y1Scale(prop(metricY1, timeValue)) ?? null;
44
+
45
+ return (
46
+ <BasicThreshold
47
+ getX={getX}
48
+ getY0={getY0}
49
+ getY1={getY1}
50
+ graphHeight={graphHeight}
51
+ lineColorY0={lineColorY0}
52
+ lineColorY1={lineColorY1}
53
+ timeSeries={timeSeries}
54
+ />
55
+ );
56
+ }
57
+
58
+ const getY0 = (timeValue: TimeValue): number =>
59
+ y0Scale(prop(metricY0, timeValue) + variation) ?? null;
60
+
61
+ const getY1 = (timeValue: TimeValue): number =>
62
+ y1Scale(prop(metricY1, timeValue) - variation) ?? null;
63
+
64
+ const props = {
65
+ curve: curveBasis,
66
+ data: timeSeries,
67
+ stroke: theme.palette.secondary.main,
68
+ strokeDasharray: 5,
69
+ strokeOpacity: 0.8,
70
+ x: getX
71
+ };
72
+
29
73
  return (
30
- <Threshold
31
- aboveAreaProps={{
32
- fill: lineColorY1,
33
- fillOpacity: 0.1
34
- }}
35
- belowAreaProps={{
36
- fill: lineColorY0,
37
- fillOpacity: 0.1
38
- }}
39
- clipAboveTo={0}
40
- clipBelowTo={graphHeight}
41
- curve={curveBasis}
42
- data={timeSeries}
43
- id="threshold"
44
- x={(timeValue: TimeValue): number => xScale(getTime(timeValue)) as number}
45
- y0={(timeValue): number => y0Scale(prop(metricY0, timeValue)) ?? null}
46
- y1={(timeValue): number => y1Scale(prop(metricY1, timeValue)) ?? null}
47
- />
74
+ <>
75
+ <BasicThreshold
76
+ getX={getX}
77
+ getY0={getY0}
78
+ getY1={getY1}
79
+ graphHeight={graphHeight}
80
+ lineColorY0={lineColorY0}
81
+ lineColorY1={lineColorY1}
82
+ timeSeries={timeSeries}
83
+ />
84
+
85
+ <LinePath {...props} y={getY0} />
86
+ <LinePath {...props} y={getY1} />
87
+ </>
48
88
  );
49
89
  };
50
90
 
@@ -5,3 +5,17 @@ export interface Data {
5
5
  metric: string;
6
6
  yScale: ScaleLinear<number, number>;
7
7
  }
8
+
9
+ export interface Point {
10
+ x: number;
11
+ y: number;
12
+ }
13
+
14
+ export interface Props {
15
+ pointLower: Point;
16
+ pointOrigin: Point;
17
+ pointUpper: Point;
18
+ }
19
+ export interface Online extends Props {
20
+ maxDistance?: number;
21
+ }
@@ -1,26 +1,32 @@
1
1
  import { equals, isNil } from 'ramda';
2
2
  import { ScaleLinear } from 'd3-scale';
3
3
 
4
- import { lowerLineName, upperLineName } from '../../helpers/index';
5
- import { getUnits, getYScale } from '../../timeSeries/index';
6
- import { Line } from '../../timeSeries/models';
4
+ import {
5
+ findLineOfOriginMetricThreshold,
6
+ lowerLineName,
7
+ upperLineName
8
+ } from '../../../helpers/index';
9
+ import { getUnits, getYScale } from '../../../timeSeries/index';
10
+ import { Line } from '../../../timeSeries/models';
7
11
 
8
- import { Data } from './Threshold/models';
12
+ import { Data } from './models';
9
13
 
10
14
  interface DataThreshold {
11
15
  dataY0?: Data;
12
16
  dataY1?: Data;
17
+ dataYOrigin?: Data;
13
18
  displayThreshold: boolean;
14
19
  }
15
20
 
16
21
  interface Props {
22
+ display: boolean;
17
23
  leftScale: ScaleLinear<number, number>;
18
24
  lines: Array<Line>;
19
25
  rightScale: ScaleLinear<number, number>;
20
26
  }
21
27
 
22
28
  const useDataThreshold = (areaThreshold: Props): DataThreshold => {
23
- const { lines, leftScale, rightScale } = areaThreshold;
29
+ const { lines, leftScale, rightScale, display } = areaThreshold;
24
30
 
25
31
  const dataMetricUpper = lines.find((line) =>
26
32
  equals(line.name, upperLineName)
@@ -30,10 +36,21 @@ const useDataThreshold = (areaThreshold: Props): DataThreshold => {
30
36
  equals(line.name, lowerLineName)
31
37
  );
32
38
 
33
- const displayThreshold = !isNil(dataMetricLower) && !isNil(dataMetricUpper);
39
+ const dataMetricOrigin = findLineOfOriginMetricThreshold(lines);
40
+
41
+ const displayThreshold =
42
+ !isNil(dataMetricLower) &&
43
+ !isNil(dataMetricUpper) &&
44
+ display &&
45
+ !isNil(dataMetricOrigin[0]);
34
46
 
35
47
  if (!displayThreshold) {
36
- return { dataY0: undefined, dataY1: undefined, displayThreshold };
48
+ return {
49
+ dataY0: undefined,
50
+ dataY1: undefined,
51
+ dataYOrigin: undefined,
52
+ displayThreshold
53
+ };
37
54
  }
38
55
 
39
56
  const [, secondUnit, thirdUnit] = getUnits(lines);
@@ -52,6 +69,13 @@ const useDataThreshold = (areaThreshold: Props): DataThreshold => {
52
69
  lineColor: lineColorY0
53
70
  } = dataMetricLower;
54
71
 
72
+ const {
73
+ metric: metricOrigin,
74
+ unit: unitYOrigin,
75
+ invert: invertYOrigin,
76
+ lineColor: lineColorYOrigin
77
+ } = dataMetricOrigin[0];
78
+
55
79
  const y1Scale = getYScale({
56
80
  hasMoreThanTwoUnits: !isNil(thirdUnit),
57
81
  invert: invertY1,
@@ -70,9 +94,19 @@ const useDataThreshold = (areaThreshold: Props): DataThreshold => {
70
94
  unit: unitY0
71
95
  });
72
96
 
97
+ const yScale = getYScale({
98
+ hasMoreThanTwoUnits: !isNil(thirdUnit),
99
+ invert: invertYOrigin,
100
+ leftScale,
101
+ rightScale,
102
+ secondUnit,
103
+ unit: unitYOrigin
104
+ });
105
+
73
106
  return {
74
107
  dataY0: { lineColor: lineColorY0, metric: metricY0, yScale: y0Scale },
75
108
  dataY1: { lineColor: lineColorY1, metric: metricY1, yScale: y1Scale },
109
+ dataYOrigin: { lineColor: lineColorYOrigin, metric: metricOrigin, yScale },
76
110
  displayThreshold
77
111
  };
78
112
  };
@@ -0,0 +1,50 @@
1
+ import { isNil } from 'ramda';
2
+
3
+ import { Online, Point, Props } from './models';
4
+
5
+ const usePointsOnline = ({
6
+ pointOrigin,
7
+ pointUpper,
8
+ pointLower
9
+ }: Props): Point | null => {
10
+ const isPointDefined = ({ x, y }: Point): boolean => !isNil(x) && !isNil(y);
11
+
12
+ const arePointsDefined =
13
+ isPointDefined(pointOrigin) &&
14
+ isPointDefined(pointUpper) &&
15
+ isPointDefined(pointLower);
16
+
17
+ const isOnLine = ({
18
+ pointOrigin: origin,
19
+ pointLower: firstPoint,
20
+ pointUpper: secondPoint,
21
+ maxDistance = 0
22
+ }: Online): boolean => {
23
+ const { x, y } = origin;
24
+ const { x: x1, y: y1 } = firstPoint;
25
+ const { x: x2, y: y2 } = secondPoint;
26
+
27
+ const dxL = x2 - x1;
28
+ const dyL = y2 - y1;
29
+ const dxP = x - x1;
30
+ const dyP = y - y1;
31
+
32
+ const squareLen = dxL * dxL + dyL * dyL;
33
+ const dotProd = dxP * dxL + dyP * dyL;
34
+ const crossProd = dyP * dxL - dxP * dyL;
35
+
36
+ const distance = Math.abs(crossProd) / Math.sqrt(squareLen);
37
+
38
+ return distance <= maxDistance && dotProd >= 0 && dotProd <= squareLen;
39
+ };
40
+
41
+ const arePointsOnline = isOnLine({
42
+ pointLower,
43
+ pointOrigin,
44
+ pointUpper
45
+ });
46
+
47
+ return !arePointsOnline && arePointsDefined ? pointOrigin : null;
48
+ };
49
+
50
+ export default usePointsOnline;
@@ -10,13 +10,14 @@ import { getUnits, getYScale } from '../../timeSeries';
10
10
  import { Line } from '../../timeSeries/models';
11
11
 
12
12
  import RegularLine from './RegularLines';
13
+ import useDataRegularLines from './RegularLines/useDataRegularLines';
13
14
  import StackedLines from './StackedLines';
15
+ import useDataStackedLines from './StackedLines/useDataStackLines';
14
16
  import ThresholdLines from './Threshold';
15
- import { Shape } from './models';
16
- import useDataRegularLines from './useDataRegularLines';
17
- import useDataStackedLines from './useDataStackLines';
18
- import useDataThreshold from './useDataThreshold';
17
+ import AwesomeCircles from './Threshold/Circle';
19
18
  import { Data } from './Threshold/models';
19
+ import useDataThreshold from './Threshold/useDataThreshold';
20
+ import { Shape } from './models';
20
21
 
21
22
  interface AnchorPoint {
22
23
  renderRegularLinesAnchorPoint: (args: RegularLinesAnchorPoint) => ReactNode;
@@ -33,7 +34,8 @@ const Lines = ({ height, shape, anchorPoint }: Props): JSX.Element => {
33
34
  const { areaRegularLines, areaStackedLines, areaThreshold } = shape;
34
35
  const { renderRegularLinesAnchorPoint, renderStackedAnchorPoint } =
35
36
  anchorPoint;
36
- const { lines, leftScale, rightScale, timeSeries, xScale } = areaThreshold;
37
+ const { lines, leftScale, rightScale, timeSeries, xScale, display } =
38
+ areaThreshold;
37
39
 
38
40
  const {
39
41
  displayAreaInvertedStackedLines,
@@ -55,7 +57,8 @@ const Lines = ({ height, shape, anchorPoint }: Props): JSX.Element => {
55
57
  lines: regularLines
56
58
  } = useDataRegularLines(areaRegularLines);
57
59
 
58
- const { dataY0, dataY1, displayThreshold } = useDataThreshold({
60
+ const { dataY0, dataY1, dataYOrigin, displayThreshold } = useDataThreshold({
61
+ display,
59
62
  leftScale,
60
63
  lines,
61
64
  rightScale
@@ -83,13 +86,35 @@ const Lines = ({ height, shape, anchorPoint }: Props): JSX.Element => {
83
86
  )}
84
87
 
85
88
  {displayThreshold && (
86
- <ThresholdLines
87
- dataY0={dataY0 as Data}
88
- dataY1={dataY1 as Data}
89
- graphHeight={height}
90
- timeSeries={timeSeries}
91
- xScale={xScale}
92
- />
89
+ <>
90
+ <ThresholdLines
91
+ dataY0={dataY0 as Data}
92
+ dataY1={dataY1 as Data}
93
+ graphHeight={height}
94
+ timeSeries={timeSeries}
95
+ xScale={xScale}
96
+ />
97
+ <ThresholdLines
98
+ dataY0={dataY0 as Data}
99
+ dataY1={dataY1 as Data}
100
+ graphHeight={height}
101
+ timeSeries={timeSeries}
102
+ variation={areaThreshold?.variation}
103
+ xScale={xScale}
104
+ />
105
+ {areaThreshold?.variation &&
106
+ timeSeries.map((timeValue) => (
107
+ <AwesomeCircles
108
+ dataY0={dataY0 as Data}
109
+ dataY1={dataY1 as Data}
110
+ dataYOrigin={dataYOrigin as Data}
111
+ key={timeValue.timeTick}
112
+ timeValue={timeValue}
113
+ variation={areaThreshold?.variation as number}
114
+ xScale={xScale}
115
+ />
116
+ ))}
117
+ </>
93
118
  )}
94
119
 
95
120
  {displayAreaRegularLines
@@ -26,8 +26,12 @@ export interface AreaRegularLines extends ShapeGraphData {
26
26
  timeSeries: Array<TimeValue>;
27
27
  }
28
28
 
29
+ export interface AreaThreshold extends AreaRegularLines {
30
+ variation?: number;
31
+ }
32
+
29
33
  export interface Shape {
30
34
  areaRegularLines: AreaRegularLines;
31
35
  areaStackedLines: AreaStackedLines;
32
- areaThreshold: AreaRegularLines;
36
+ areaThreshold: AreaThreshold;
33
37
  }
@@ -4,7 +4,11 @@ import { useAtom } from 'jotai';
4
4
  import { equals, propEq, reject } from 'ramda';
5
5
 
6
6
  import { linesGraphAtom } from '../graphAtoms';
7
- import { lowerLineName, upperLineName } from '../helpers';
7
+ import {
8
+ findLineOfOriginMetricThreshold,
9
+ lowerLineName,
10
+ upperLineName
11
+ } from '../helpers';
8
12
  import { Line } from '../timeSeries/models';
9
13
 
10
14
  interface UseFilterLines {
@@ -25,20 +29,7 @@ const useFilterLines = ({
25
29
 
26
30
  const displayedLines = reject(propEq('display', false), linesGraph ?? lines);
27
31
  const filterLines = (): Array<Line> => {
28
- const metrics = lines.map((line) => {
29
- const { metric } = line;
30
-
31
- return metric.includes('_upper_thresholds')
32
- ? metric.replace('_upper_thresholds', '')
33
- : null;
34
- });
35
-
36
- const originMetric = metrics.find((element) => element);
37
-
38
- const lineOriginMetric = reject(
39
- (line: Line) => !equals(line.name, originMetric),
40
- lines
41
- );
32
+ const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
42
33
 
43
34
  const findLinesUpperLower = lines.map((line) =>
44
35
  equals(line.name, lowerLineName) || equals(line.name, upperLineName)
@@ -113,7 +113,6 @@ const Graph = ({
113
113
  });
114
114
 
115
115
  const commonLinesProps = {
116
- display: true,
117
116
  leftScale,
118
117
  rightScale,
119
118
  xScale
@@ -122,21 +121,23 @@ const Graph = ({
122
121
  const areaThreshold = {
123
122
  lines: displayedLines,
124
123
  timeSeries,
125
- ...commonLinesProps
124
+ ...commonLinesProps,
125
+ ...shapeLines?.areaThresholdLines,
126
+ display: shapeLines?.areaThresholdLines?.display ?? true
126
127
  };
127
128
 
128
129
  const areaRegularLines = {
130
+ display: shapeLines?.areaRegularLines?.display ?? true,
129
131
  lines: regularLines,
130
132
  timeSeries,
131
- ...commonLinesProps,
132
- ...shapeLines?.areaRegularLines
133
+ ...commonLinesProps
133
134
  };
134
135
 
135
136
  const areaStackedLines = {
137
+ display: shapeLines?.areaStackedLines?.display ?? true,
136
138
  invertedStackedLinesData,
137
139
  stackedLinesData,
138
- ...commonLinesProps,
139
- ...shapeLines?.areaStackedLines
140
+ ...commonLinesProps
140
141
  };
141
142
 
142
143
  const displayRegularLinesAnchorPoint =
@@ -1,10 +1,21 @@
1
- import { gte, isNil, prop, propEq, reject, sortBy, gt, isEmpty } from 'ramda';
1
+ import {
2
+ gte,
3
+ isNil,
4
+ prop,
5
+ propEq,
6
+ reject,
7
+ sortBy,
8
+ gt,
9
+ isEmpty,
10
+ equals
11
+ } from 'ramda';
2
12
  import dayjs from 'dayjs';
3
13
 
4
14
  import { getLineData, getTimeSeries } from '../timeSeries';
5
15
  import { LinesData } from '../BasicComponents/Lines/models';
6
16
  import { GraphData, GraphInterval } from '../models';
7
17
  import { dateFormat, timeFormat } from '../common';
18
+ import { Line } from '../timeSeries/models';
8
19
 
9
20
  export const adjustGraphData = (graphData: GraphData): LinesData => {
10
21
  const lines = getLineData(graphData);
@@ -49,3 +60,19 @@ export const displayArea = (data: unknown): boolean =>
49
60
 
50
61
  export const lowerLineName = 'Lower Threshold';
51
62
  export const upperLineName = 'Upper Threshold';
63
+
64
+ export const findLineOfOriginMetricThreshold = (
65
+ lines: Array<Line>
66
+ ): Array<Line> => {
67
+ const metrics = lines.map((line) => {
68
+ const { metric } = line;
69
+
70
+ return metric.includes('_upper_thresholds')
71
+ ? metric.replace('_upper_thresholds', '')
72
+ : null;
73
+ });
74
+
75
+ const originMetric = metrics.find((element) => element);
76
+
77
+ return reject((line: Line) => !equals(line.name, originMetric), lines);
78
+ };
@@ -165,7 +165,7 @@ const GraphAndTimePeriod = (args): JSX.Element => {
165
165
  annotationEvent={annotationEventData}
166
166
  end={end}
167
167
  loading={false}
168
- shapeLines={{ areaThresholdLines: { display: true } }}
168
+ shapeLines={{ areaThresholdLines: { display: true, variation: 1.5 } }}
169
169
  start={start}
170
170
  timeShiftZones={{ enable: true, getInterval }}
171
171
  tooltip={{
@@ -98,8 +98,12 @@ export interface Area {
98
98
  display: boolean;
99
99
  }
100
100
 
101
+ export interface ThresholdArea extends Area {
102
+ variation?: number;
103
+ }
104
+
101
105
  export interface GlobalAreaLines {
102
106
  areaRegularLines: Area;
103
107
  areaStackedLines: Area;
104
- areaThresholdLines: Area;
108
+ areaThresholdLines: ThresholdArea;
105
109
  }
@@ -22,10 +22,11 @@ export interface Metric {
22
22
  unit: string;
23
23
  }
24
24
 
25
- export interface TimeValue {
26
- [field: string]: string | number;
27
- timeTick: string;
28
- }
25
+ type TimeSeries = { timeTick: string };
26
+
27
+ export type TimeValue = TimeSeries & {
28
+ [field: string]: number;
29
+ };
29
30
 
30
31
  export interface Line {
31
32
  areaColor: string;