@centreon/ui 24.5.13 → 24.6.1

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 (29) hide show
  1. package/package.json +1 -1
  2. package/src/Dashboard/Item.tsx +7 -5
  3. package/src/Graph/LineChart/BasicComponents/Axes/index.tsx +12 -3
  4. package/src/Graph/LineChart/BasicComponents/Axes/models.ts +3 -1
  5. package/src/Graph/LineChart/BasicComponents/Grids/index.tsx +28 -4
  6. package/src/Graph/LineChart/BasicComponents/Lines/Point.tsx +36 -0
  7. package/src/Graph/LineChart/BasicComponents/Lines/RegularLines/index.tsx +37 -8
  8. package/src/Graph/LineChart/BasicComponents/Lines/StackedLines/index.tsx +65 -6
  9. package/src/Graph/LineChart/BasicComponents/Lines/index.tsx +59 -6
  10. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +1 -1
  11. package/src/Graph/LineChart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +1 -1
  12. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/GraphValueTooltip.tsx +9 -3
  13. package/src/Graph/LineChart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +36 -4
  14. package/src/Graph/LineChart/InteractiveComponents/TimeShiftZones/TimeShiftZone.tsx +2 -2
  15. package/src/Graph/LineChart/InteractiveComponents/TimeShiftZones/index.tsx +10 -11
  16. package/src/Graph/LineChart/Legend/Legend.styles.ts +27 -4
  17. package/src/Graph/LineChart/Legend/LegendHeader.tsx +14 -4
  18. package/src/Graph/LineChart/Legend/index.tsx +41 -12
  19. package/src/Graph/LineChart/LineChart.cypress.spec.tsx +273 -10
  20. package/src/Graph/LineChart/LineChart.tsx +195 -98
  21. package/src/Graph/LineChart/common/index.ts +7 -4
  22. package/src/Graph/LineChart/index.stories.tsx +11 -1
  23. package/src/Graph/LineChart/index.tsx +12 -7
  24. package/src/Graph/LineChart/models.ts +27 -2
  25. package/src/Graph/common/timeSeries/index.ts +39 -6
  26. package/src/Graph/common/timeSeries/models.ts +7 -1
  27. package/src/Graph/common/utils.ts +32 -0
  28. package/src/InputField/Number/Number.tsx +4 -3
  29. package/src/InputField/Text/index.tsx +14 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centreon/ui",
3
- "version": "24.5.13",
3
+ "version": "24.6.1",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -88,11 +88,13 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
88
88
  >
89
89
  {header && (
90
90
  <div className={classes.widgetHeader} data-canMove={canMove}>
91
- <div
92
- {...listeners}
93
- className={classes.widgetHeaderDraggable}
94
- data-testid={`${id}_move_panel`}
95
- />
91
+ {canMove && (
92
+ <div
93
+ {...listeners}
94
+ className={classes.widgetHeaderDraggable}
95
+ data-testid={`${id}_move_panel`}
96
+ />
97
+ )}
96
98
  {header}
97
99
  </div>
98
100
  )}
@@ -32,7 +32,7 @@ const Axes = ({
32
32
  graphInterval
33
33
  }: Props): JSX.Element => {
34
34
  const { format } = useLocaleDateTimeFormat();
35
- const { lines } = data;
35
+ const { lines, showBorder, yAxisTickLabelRotation } = data;
36
36
 
37
37
  const { axisLeft, axisRight } = useAxisY({ data, graphHeight: height });
38
38
 
@@ -54,6 +54,7 @@ const Axes = ({
54
54
  <Axis.AxisBottom
55
55
  numTicks={xTickCount}
56
56
  scale={xScale}
57
+ strokeWidth={!isNil(showBorder) && !showBorder ? 0 : 1}
57
58
  tickFormat={formatAxisTick}
58
59
  top={height - 5}
59
60
  />
@@ -64,8 +65,12 @@ const Axes = ({
64
65
  numTicks={axisLeft?.numTicks}
65
66
  orientation="left"
66
67
  scale={leftScale}
68
+ strokeWidth={!isNil(showBorder) && !showBorder ? 0 : 1}
67
69
  tickFormat={axisLeft.tickFormat}
68
- tickLabelProps={axisLeft.tickLabelProps}
70
+ tickLabelProps={() => ({
71
+ ...axisLeft.tickLabelProps(),
72
+ angle: yAxisTickLabelRotation
73
+ })}
69
74
  tickLength={2}
70
75
  />
71
76
 
@@ -75,8 +80,12 @@ const Axes = ({
75
80
  numTicks={axisRight?.numTicks}
76
81
  orientation="right"
77
82
  scale={rightScale}
83
+ strokeWidth={!isNil(showBorder) && !showBorder ? 0 : 1}
78
84
  tickFormat={axisRight.tickFormat}
79
- tickLabelProps={axisRight.tickLabelProps}
85
+ tickLabelProps={() => ({
86
+ ...axisRight.tickLabelProps(),
87
+ angle: yAxisTickLabelRotation
88
+ })}
80
89
  tickLength={2}
81
90
  />
82
91
  )}
@@ -1,4 +1,5 @@
1
1
  import { Line, TimeValue } from '../../../common/timeSeries/models';
2
+ import { LineChartAxis } from '../../models';
2
3
 
3
4
  export interface LabelProps {
4
5
  [x: string]: unknown;
@@ -16,7 +17,8 @@ export interface AxisYRight extends Axis {
16
17
  export interface AxisX {
17
18
  xAxisTickFormat?: string;
18
19
  }
19
- export interface Data {
20
+ export interface Data
21
+ extends Omit<LineChartAxis, 'axisX' | 'axisYLeft' | 'axisYRight'> {
20
22
  axisX?: AxisX;
21
23
  axisYLeft?: Axis;
22
24
  axisYRight?: AxisYRight;
@@ -1,18 +1,42 @@
1
+ import { useMemo } from 'react';
2
+
1
3
  import { Grid } from '@visx/visx';
2
4
  import { ScaleLinear } from 'd3-scale';
5
+ import { includes } from 'ramda';
6
+
7
+ import { LineChartAxis } from '../../models';
3
8
 
4
- interface Props {
9
+ interface Props extends Pick<LineChartAxis, 'gridLinesType'> {
5
10
  height: number;
6
11
  leftScale: ScaleLinear<number, number>;
7
12
  width: number;
8
13
  xScale: ScaleLinear<number, number>;
9
14
  }
10
15
 
11
- const Grids = ({ height, width, leftScale, xScale }: Props): JSX.Element => {
16
+ const Grids = ({
17
+ height,
18
+ width,
19
+ leftScale,
20
+ xScale,
21
+ gridLinesType
22
+ }: Props): JSX.Element => {
23
+ const displayRows = useMemo(
24
+ () => includes(gridLinesType, ['all', 'horizontal', undefined]),
25
+ [gridLinesType]
26
+ );
27
+ const displayColumns = useMemo(
28
+ () => includes(gridLinesType, ['all', 'vertical', undefined]),
29
+ [gridLinesType]
30
+ );
31
+
12
32
  return (
13
33
  <g>
14
- <Grid.GridRows height={height} scale={leftScale} width={width} />
15
- <Grid.GridColumns height={height} scale={xScale} width={width} />
34
+ {displayRows && (
35
+ <Grid.GridRows height={height} scale={leftScale} width={width} />
36
+ )}
37
+ {displayColumns && (
38
+ <Grid.GridColumns height={height} scale={xScale} width={width} />
39
+ )}
16
40
  </g>
17
41
  );
18
42
  };
@@ -0,0 +1,36 @@
1
+ import { isNil } from 'ramda';
2
+
3
+ interface Props {
4
+ lineColor: string;
5
+ radius: number;
6
+ timeTick: Date;
7
+ xScale;
8
+ yPoint: number;
9
+ }
10
+
11
+ const Point = ({
12
+ timeTick,
13
+ yPoint,
14
+ lineColor,
15
+ xScale,
16
+ radius
17
+ }: Props): JSX.Element | null => {
18
+ const x = xScale(timeTick);
19
+
20
+ if (isNil(x) || isNil(yPoint)) {
21
+ return null;
22
+ }
23
+
24
+ return (
25
+ <circle
26
+ cx={x}
27
+ cy={yPoint}
28
+ fill={lineColor}
29
+ r={radius}
30
+ stroke={lineColor}
31
+ strokeWidth={2}
32
+ />
33
+ );
34
+ };
35
+
36
+ export default Point;
@@ -2,19 +2,24 @@ import { memo } from 'react';
2
2
 
3
3
  import { Shape } from '@visx/visx';
4
4
  import { ScaleLinear, ScaleTime } from 'd3-scale';
5
- import { equals, isNil, prop } from 'ramda';
5
+ import { equals, isNil, pick, prop } from 'ramda';
6
6
 
7
7
  import { getTime } from '../../../../common/timeSeries';
8
8
  import { TimeValue } from '../../../../common/timeSeries/models';
9
9
  import { getCurveFactory, getFillColor } from '../../../common';
10
+ import { getStrokeDashArray } from '../../../../common/utils';
10
11
 
11
12
  interface Props {
12
13
  areaColor: string;
13
14
  curve: 'linear' | 'step' | 'natural';
15
+ dashLength?: number;
16
+ dashOffset?: number;
17
+ dotOffset?: number;
14
18
  filled: boolean;
15
19
  graphHeight: number;
16
20
  highlight?: boolean;
17
21
  lineColor: string;
22
+ lineWidth?: number;
18
23
  metric_id: number;
19
24
  shapeAreaClosed?: Record<string, unknown>;
20
25
  shapeLinePath?: Record<string, unknown>;
@@ -37,16 +42,30 @@ const RegularLine = ({
37
42
  areaColor,
38
43
  transparency,
39
44
  graphHeight,
40
- curve
45
+ curve,
46
+ lineWidth,
47
+ dotOffset,
48
+ dashLength,
49
+ dashOffset
41
50
  }: Props): JSX.Element => {
42
51
  const curveType = getCurveFactory(curve);
52
+ const formattedLineWidth = lineWidth ?? 2;
53
+
43
54
  const props = {
44
55
  curve: curveType,
45
56
  data: timeSeries,
46
57
  defined: (value): boolean => !isNil(value[metric_id]),
47
58
  opacity: 1,
48
59
  stroke: lineColor,
49
- strokeWidth: !highlight ? 2 : 3,
60
+ strokeDasharray: getStrokeDashArray({
61
+ dashLength,
62
+ dashOffset,
63
+ dotOffset,
64
+ lineWidth: formattedLineWidth
65
+ }),
66
+ strokeWidth: highlight
67
+ ? Math.ceil((formattedLineWidth || 1) * 1.3)
68
+ : formattedLineWidth,
50
69
  unit,
51
70
  x: (timeValue): number => xScale(getTime(timeValue)) as number,
52
71
  y: (timeValue): number => yScale(prop(metric_id, timeValue)) ?? null
@@ -69,22 +88,32 @@ const RegularLine = ({
69
88
  return <Shape.LinePath<TimeValue> data-metric={metric_id} {...props} />;
70
89
  };
71
90
 
91
+ const memoizedProps = [
92
+ 'curve',
93
+ 'lineColor',
94
+ 'areaColor',
95
+ 'filled',
96
+ 'transparency',
97
+ 'lineWidth',
98
+ 'dotOffset',
99
+ 'dashLength',
100
+ 'dashOffset'
101
+ ];
102
+
72
103
  export default memo(RegularLine, (prevProps, nextProps) => {
73
104
  const {
74
105
  timeSeries: prevTimeSeries,
75
106
  graphHeight: prevGraphHeight,
76
107
  highlight: prevHighlight,
77
108
  xScale: prevXScale,
78
- yScale: prevYScale,
79
- curve: prevCurve
109
+ yScale: prevYScale
80
110
  } = prevProps;
81
111
  const {
82
112
  timeSeries: nextTimeSeries,
83
113
  graphHeight: nextGraphHeight,
84
114
  highlight: nextHighlight,
85
115
  xScale: nextXScale,
86
- yScale: nextYScale,
87
- curve: nextCurve
116
+ yScale: nextYScale
88
117
  } = nextProps;
89
118
 
90
119
  const prevXScaleRange = prevXScale.range();
@@ -98,6 +127,6 @@ export default memo(RegularLine, (prevProps, nextProps) => {
98
127
  equals(prevHighlight, nextHighlight) &&
99
128
  equals(prevXScaleRange, nextXScaleRange) &&
100
129
  equals(prevYScaleDomain, nextYScaleDomain) &&
101
- equals(prevCurve, nextCurve)
130
+ equals(pick(memoizedProps, prevProps), pick(memoizedProps, nextProps))
102
131
  );
103
132
  });
@@ -1,17 +1,28 @@
1
1
  import { Shape } from '@visx/visx';
2
2
  import { ScaleLinear, ScaleTime } from 'd3-scale';
3
- import { all, isNil, map, not, nth, path, pipe, prop } from 'ramda';
3
+ import { all, equals, isNil, map, not, nth, path, pipe, prop } from 'ramda';
4
4
 
5
- import StackedAnchorPoint from '../../../InteractiveComponents/AnchorPoint/StackedAnchorPoint';
5
+ import StackedAnchorPoint, {
6
+ getYAnchorPoint
7
+ } from '../../../InteractiveComponents/AnchorPoint/StackedAnchorPoint';
6
8
  import { StackValue } from '../../../InteractiveComponents/AnchorPoint/models';
7
9
  import { getCurveFactory, getFillColor } from '../../../common';
8
- import { getTime } from '../../../../common/timeSeries';
10
+ import { getDates, getTime } from '../../../../common/timeSeries';
9
11
  import { Line, TimeValue } from '../../../../common/timeSeries/models';
12
+ import Point from '../Point';
13
+ import { getPointRadius, getStrokeDashArray } from '../../../../common/utils';
10
14
 
11
15
  interface Props {
16
+ areaTransparency?: number;
12
17
  curve: 'linear' | 'step' | 'natural';
18
+ dashLength?: number;
19
+ dashOffset?: number;
13
20
  displayAnchor: boolean;
21
+ dotOffset?: number;
22
+ lineWidth?: number;
14
23
  lines: Array<Line>;
24
+ showArea?: boolean;
25
+ showPoints?: boolean;
15
26
  timeSeries: Array<TimeValue>;
16
27
  xScale: ScaleTime<number, number>;
17
28
  yScale: ScaleLinear<number, number>;
@@ -23,10 +34,19 @@ const StackLines = ({
23
34
  yScale,
24
35
  xScale,
25
36
  displayAnchor,
26
- curve
37
+ curve,
38
+ showPoints,
39
+ showArea,
40
+ areaTransparency,
41
+ lineWidth,
42
+ dashLength,
43
+ dashOffset,
44
+ dotOffset
27
45
  }: Props): JSX.Element => {
28
46
  const curveType = getCurveFactory(curve);
29
47
 
48
+ const formattedLineWidth = lineWidth ?? 2;
49
+
30
50
  return (
31
51
  <Shape.AreaStack
32
52
  curve={curveType}
@@ -49,6 +69,10 @@ const StackLines = ({
49
69
  const { areaColor, transparency, lineColor, highlight, metric_id } =
50
70
  nth(index, lines) as Line;
51
71
 
72
+ const formattedTransparency = isNil(areaTransparency)
73
+ ? transparency || 80
74
+ : areaTransparency;
75
+
52
76
  return (
53
77
  <g key={`stack-${prop('key', stack)}`}>
54
78
  {displayAnchor && (
@@ -62,13 +86,48 @@ const StackLines = ({
62
86
  yScale={yScale}
63
87
  />
64
88
  )}
89
+ {showPoints &&
90
+ getDates(timeSeries).map((timeTick) => (
91
+ <Point
92
+ key={timeTick.toString()}
93
+ lineColor={lineColor}
94
+ metric_id={metric_id}
95
+ radius={getPointRadius(lineWidth)}
96
+ timeSeries={timeSeries}
97
+ timeTick={timeTick}
98
+ xScale={xScale}
99
+ yPoint={getYAnchorPoint({
100
+ stackValues: stack as unknown as Array<StackValue>,
101
+ timeTick,
102
+ yScale
103
+ })}
104
+ yScale={yScale}
105
+ />
106
+ ))}
65
107
  <path
66
108
  d={linePath(stack) || ''}
67
109
  data-metric={metric_id}
68
- fill={getFillColor({ areaColor, transparency })}
110
+ fill={
111
+ equals(showArea, false)
112
+ ? 'transparent'
113
+ : getFillColor({
114
+ areaColor: areaColor || lineColor,
115
+ transparency: formattedTransparency
116
+ })
117
+ }
69
118
  opacity={highlight === false ? 0.3 : 1}
70
119
  stroke={lineColor}
71
- strokeWidth={highlight ? 2 : 1}
120
+ strokeDasharray={getStrokeDashArray({
121
+ dashLength,
122
+ dashOffset,
123
+ dotOffset,
124
+ lineWidth: formattedLineWidth
125
+ })}
126
+ strokeWidth={
127
+ highlight
128
+ ? Math.ceil(formattedLineWidth * 1.3)
129
+ : formattedLineWidth
130
+ }
72
131
  />
73
132
  </g>
74
133
  );
@@ -3,11 +3,15 @@ import { MutableRefObject } from 'react';
3
3
  import { ScaleLinear } from 'd3-scale';
4
4
  import { isNil } from 'ramda';
5
5
 
6
+ import { getPointRadius } from '../../../common/utils';
6
7
  import GuidingLines from '../../InteractiveComponents/AnchorPoint/GuidingLines';
7
- import RegularAnchorPoint from '../../InteractiveComponents/AnchorPoint/RegularAnchorPoint';
8
+ import RegularAnchorPoint, {
9
+ getYAnchorPoint
10
+ } from '../../InteractiveComponents/AnchorPoint/RegularAnchorPoint';
8
11
  import { displayArea } from '../../helpers/index';
9
12
  import { DisplayAnchor, GlobalAreaLines } from '../../models';
10
13
  import {
14
+ getDates,
11
15
  getStackedYScale,
12
16
  getUnits,
13
17
  getYScale
@@ -23,34 +27,49 @@ import {
23
27
  canDisplayThreshold,
24
28
  requiredNumberLinesThreshold
25
29
  } from './Threshold/models';
30
+ import Point from './Point';
26
31
 
27
32
  interface Props extends GlobalAreaLines {
33
+ areaTransparency?: number;
28
34
  curve: 'linear' | 'step' | 'natural';
35
+ dashLength?: number;
36
+ dashOffset?: number;
29
37
  displayAnchor?: DisplayAnchor;
30
38
  displayedLines: Array<Line>;
39
+ dotOffset?: number;
31
40
  graphSvgRef: MutableRefObject<SVGSVGElement | null>;
32
41
  height: number;
33
42
  leftScale: ScaleLinear<number, number>;
43
+ lineWidth?: number;
34
44
  rightScale: ScaleLinear<number, number>;
45
+ showArea?: boolean;
46
+ showPoints?: boolean;
35
47
  timeSeries: Array<TimeValue>;
36
48
  width: number;
37
49
  xScale: ScaleLinear<number, number>;
38
50
  }
39
51
 
40
52
  const Lines = ({
53
+ areaTransparency,
41
54
  height,
42
55
  graphSvgRef,
43
56
  width,
44
57
  displayAnchor,
45
58
  leftScale,
46
59
  rightScale,
60
+ curve,
47
61
  xScale,
48
62
  timeSeries,
49
63
  displayedLines,
50
64
  areaThresholdLines,
51
65
  areaStackedLines,
52
66
  areaRegularLines,
53
- curve
67
+ showArea,
68
+ showPoints,
69
+ lineWidth,
70
+ dotOffset,
71
+ dashLength,
72
+ dashOffset
54
73
  }: Props): JSX.Element => {
55
74
  const { stackedLinesData, invertedStackedLinesData } = useStackedLines({
56
75
  lines: displayedLines,
@@ -73,11 +92,18 @@ const Lines = ({
73
92
 
74
93
  const displayGuidingLines = displayAnchor?.displayGuidingLines ?? true;
75
94
  const commonStackedLinesProps = {
95
+ areaTransparency,
76
96
  curve,
97
+ dashLength,
98
+ dashOffset,
77
99
  displayAnchor: displayGuidingLines,
100
+ dotOffset,
78
101
  graphHeight: height,
79
102
  graphSvgRef,
80
103
  graphWidth: width,
104
+ lineWidth,
105
+ showArea,
106
+ showPoints,
81
107
  xScale,
82
108
  yScale: stackedYScale
83
109
  };
@@ -153,7 +179,7 @@ const Lines = ({
153
179
  <g key={metric_id}>
154
180
  {displayGuidingLines && (
155
181
  <RegularAnchorPoint
156
- areaColor={areaColor}
182
+ areaColor={areaColor || lineColor}
157
183
  lineColor={lineColor}
158
184
  metric_id={metric_id}
159
185
  timeSeries={timeSeries}
@@ -162,16 +188,43 @@ const Lines = ({
162
188
  yScale={yScale}
163
189
  />
164
190
  )}
191
+ {showPoints &&
192
+ getDates(timeSeries).map((timeTick) => (
193
+ <Point
194
+ key={timeTick.toString()}
195
+ lineColor={lineColor}
196
+ metric_id={metric_id}
197
+ radius={getPointRadius(lineWidth)}
198
+ timeSeries={timeSeries}
199
+ timeTick={timeTick}
200
+ xScale={xScale}
201
+ yPoint={getYAnchorPoint({
202
+ metric_id,
203
+ timeSeries,
204
+ timeTick,
205
+ yScale
206
+ })}
207
+ yScale={yScale}
208
+ />
209
+ ))}
165
210
  <RegularLine
166
- areaColor={areaColor}
211
+ areaColor={areaColor || lineColor}
167
212
  curve={curve}
168
- filled={filled}
213
+ dashLength={dashLength}
214
+ dashOffset={dashOffset}
215
+ dotOffset={dotOffset}
216
+ filled={isNil(showArea) ? filled : showArea}
169
217
  graphHeight={height}
170
218
  highlight={highlight}
171
219
  lineColor={lineColor}
220
+ lineWidth={lineWidth}
172
221
  metric_id={metric_id}
173
222
  timeSeries={timeSeries}
174
- transparency={transparency}
223
+ transparency={
224
+ isNil(areaTransparency)
225
+ ? transparency || 80
226
+ : areaTransparency
227
+ }
175
228
  unit={unit}
176
229
  xScale={xScale}
177
230
  yScale={yScale}
@@ -17,7 +17,7 @@ interface Props {
17
17
  yScale: ScaleLinear<number, number>;
18
18
  }
19
19
 
20
- const getYAnchorPoint = ({
20
+ export const getYAnchorPoint = ({
21
21
  timeTick,
22
22
  timeSeries,
23
23
  yScale,
@@ -30,7 +30,7 @@ const getStackedDates = (stackValues: Array<StackValue>): Array<Date> => {
30
30
  return pipe(map(toTimeTick), map(toDate))(stackValues);
31
31
  };
32
32
 
33
- const getYAnchorPoint = ({
33
+ export const getYAnchorPoint = ({
34
34
  timeTick,
35
35
  stackValues,
36
36
  yScale
@@ -5,19 +5,25 @@ import { Box, Typography } from '@mui/material';
5
5
 
6
6
  import { mousePositionAtom } from '../interactionWithGraphAtoms';
7
7
  import { formatMetricValueWithUnit } from '../../../common/timeSeries';
8
+ import { Tooltip } from '../../models';
8
9
 
9
10
  import { useGraphValueTooltip } from './useGraphValueTooltip';
10
11
  import { useGraphValueTooltipStyles } from './useGraphValueTooltipStyles';
11
12
 
12
- interface Props {
13
+ interface Props extends Pick<Tooltip, 'sortOrder'> {
13
14
  base: number;
15
+ isSingleMode: boolean;
14
16
  }
15
17
 
16
- const GraphValueTooltip = ({ base }: Props): JSX.Element | null => {
18
+ const GraphValueTooltip = ({
19
+ base,
20
+ isSingleMode,
21
+ sortOrder
22
+ }: Props): JSX.Element | null => {
17
23
  const { classes } = useGraphValueTooltipStyles();
18
24
  const mousePosition = useAtomValue(mousePositionAtom);
19
25
 
20
- const graphValue = useGraphValueTooltip();
26
+ const graphValue = useGraphValueTooltip({ isSingleMode, sortOrder });
21
27
 
22
28
  if (isNil(graphValue) || isNil(mousePosition)) {
23
29
  return null;
@@ -1,15 +1,31 @@
1
1
  import { useAtomValue } from 'jotai';
2
- import { isNil } from 'ramda';
2
+ import {
3
+ always,
4
+ cond,
5
+ equals,
6
+ filter,
7
+ isNil,
8
+ prop,
9
+ reverse,
10
+ sortBy
11
+ } from 'ramda';
3
12
 
4
13
  import { graphTooltipDataAtom } from '../interactionWithGraphAtoms';
5
14
  import { useLocaleDateTimeFormat } from '../../../../utils';
6
- import { GraphTooltipData } from '../../models';
15
+ import { GraphTooltipData, Tooltip } from '../../models';
7
16
 
8
17
  interface UseGraphValueTooltipState extends Omit<GraphTooltipData, 'date'> {
9
18
  dateTime: string;
10
19
  }
11
20
 
12
- export const useGraphValueTooltip = (): UseGraphValueTooltipState | null => {
21
+ interface UseGraphValueTooltipProps extends Pick<Tooltip, 'sortOrder'> {
22
+ isSingleMode: boolean;
23
+ }
24
+
25
+ export const useGraphValueTooltip = ({
26
+ isSingleMode,
27
+ sortOrder
28
+ }: UseGraphValueTooltipProps): UseGraphValueTooltipState | null => {
13
29
  const { toDate, toTime } = useLocaleDateTimeFormat();
14
30
  const graphTooltipData = useAtomValue(graphTooltipDataAtom);
15
31
 
@@ -19,9 +35,25 @@ export const useGraphValueTooltip = (): UseGraphValueTooltipState | null => {
19
35
 
20
36
  const formattedDateTime = `${toDate(graphTooltipData.date)} / ${toTime(graphTooltipData.date)}`;
21
37
 
38
+ const filteredMetrics = isSingleMode
39
+ ? filter(
40
+ ({ id }) => equals(id, graphTooltipData.highlightedMetricId),
41
+ graphTooltipData.metrics
42
+ )
43
+ : graphTooltipData.metrics;
44
+
45
+ const sortedMetrics = cond([
46
+ [equals('name'), always(sortBy(prop('name'), filteredMetrics))],
47
+ [equals('ascending'), always(sortBy(prop('value'), filteredMetrics))],
48
+ [
49
+ equals('descending'),
50
+ always(reverse(sortBy(prop('value'), filteredMetrics)))
51
+ ]
52
+ ])(sortOrder);
53
+
22
54
  return {
23
55
  dateTime: formattedDateTime,
24
56
  highlightedMetricId: graphTooltipData.highlightedMetricId,
25
- metrics: graphTooltipData.metrics
57
+ metrics: sortedMetrics
26
58
  };
27
59
  };
@@ -11,7 +11,7 @@ import { GraphInterval, Interval } from '../../models';
11
11
  import { TimeShiftDirection } from './models';
12
12
  import { useTimeShiftZones } from './useTimeShiftZones';
13
13
 
14
- export const timeShiftZoneWidth = 50;
14
+ export const timeShiftZoneWidth = 30;
15
15
 
16
16
  const useStyles = makeStyles()({
17
17
  translationZone: {
@@ -53,7 +53,7 @@ const TimeShiftZone = ({
53
53
  className={classes.translationZone}
54
54
  fill={
55
55
  equals(directionHovered, direction)
56
- ? alpha(theme.palette.background.paper, 0.2)
56
+ ? alpha(theme.palette.background.paper, 0.5)
57
57
  : 'transparent'
58
58
  }
59
59
  height={graphHeight}