@centreon/ui 24.6.3 → 24.6.5

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 (54) hide show
  1. package/package.json +1 -1
  2. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +233 -0
  3. package/src/Graph/BarChart/BarChart.stories.tsx +213 -0
  4. package/src/Graph/BarChart/BarChart.tsx +101 -0
  5. package/src/Graph/BarChart/BarGroup.tsx +246 -0
  6. package/src/Graph/BarChart/BarStack.tsx +126 -0
  7. package/src/Graph/BarChart/ResponsiveBarChart.tsx +263 -0
  8. package/src/Graph/BarChart/SingleBar.tsx +62 -0
  9. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +122 -0
  10. package/src/Graph/BarChart/Tooltip/useBarChartTooltipStyles.ts +28 -0
  11. package/src/Graph/BarChart/atoms.ts +5 -0
  12. package/src/Graph/BarChart/models.ts +21 -0
  13. package/src/Graph/BarChart/useBarChartStyles.tsx +5 -0
  14. package/src/Graph/BarChart/useBarStack.ts +114 -0
  15. package/src/Graph/BarChart/useSingleBar.ts +199 -0
  16. package/src/Graph/Gauge/Gauge.cypress.spec.tsx +1 -1
  17. package/src/Graph/Gauge/Gauge.stories.tsx +1 -1
  18. package/src/Graph/LineChart/LineChart.cypress.spec.tsx +4 -4
  19. package/src/Graph/LineChart/LineChart.styles.ts +0 -5
  20. package/src/Graph/LineChart/LineChart.tsx +164 -137
  21. package/src/Graph/LineChart/index.stories.tsx +12 -12
  22. package/src/Graph/SingleBar/SingleBar.cypress.spec.tsx +1 -1
  23. package/src/Graph/SingleBar/SingleBar.stories.tsx +1 -1
  24. package/src/Graph/Text/Text.cypress.spec.tsx +1 -1
  25. package/src/Graph/Text/Text.stories.tsx +1 -1
  26. package/src/Graph/common/Axes/index.tsx +40 -13
  27. package/src/Graph/common/BaseChart/BaseChart.tsx +25 -6
  28. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +15 -4
  29. package/src/Graph/{LineChart → common/BaseChart}/Header/index.tsx +3 -3
  30. package/src/Graph/common/BaseChart/Header/models.ts +4 -0
  31. package/src/Graph/common/BaseChart/Header/useHeaderStyles.ts +9 -0
  32. package/src/Graph/common/BaseChart/useBaseChartStyles.ts +6 -0
  33. package/src/Graph/{LineChart/BasicComponents → common/Thresholds}/ThresholdLine.tsx +20 -10
  34. package/src/Graph/{LineChart/BasicComponents → common/Thresholds}/Thresholds.tsx +8 -4
  35. package/src/Graph/common/timeSeries/index.ts +33 -11
  36. package/src/Graph/common/timeSeries/models.ts +1 -0
  37. package/src/Graph/common/useTooltipStyles.ts +1 -0
  38. package/src/Graph/mockedData/pingService.json +203 -0
  39. package/src/Graph/mockedData/pingServiceMixedStacked.json +203 -0
  40. package/src/Graph/mockedData/pingServiceStacked.json +203 -0
  41. /package/src/Graph/{LineChart/mockedData → mockedData}/annotationData.json +0 -0
  42. /package/src/Graph/{LineChart/mockedData → mockedData}/curvesWithSameColor.json +0 -0
  43. /package/src/Graph/{LineChart/mockedData → mockedData}/exclusionPeriodFirstPeriod.json +0 -0
  44. /package/src/Graph/{LineChart/mockedData → mockedData}/exclusionPeriodSecondPeriod.json +0 -0
  45. /package/src/Graph/{LineChart/mockedData → mockedData}/exclusionPeriodThirdPeriod.json +0 -0
  46. /package/src/Graph/{LineChart/mockedData → mockedData}/lastDay.json +0 -0
  47. /package/src/Graph/{LineChart/mockedData → mockedData}/lastDayAreaStack.json +0 -0
  48. /package/src/Graph/{LineChart/mockedData → mockedData}/lastDayForward.json +0 -0
  49. /package/src/Graph/{LineChart/mockedData → mockedData}/lastDayThreshold.json +0 -0
  50. /package/src/Graph/{LineChart/mockedData → mockedData}/lastDayWithIncompleteValues.json +0 -0
  51. /package/src/Graph/{LineChart/mockedData → mockedData}/lastDayWithNullValues.json +0 -0
  52. /package/src/Graph/{LineChart/mockedData → mockedData}/lastMonth.json +0 -0
  53. /package/src/Graph/{LineChart/mockedData → mockedData}/lastWeek.json +0 -0
  54. /package/src/Graph/{LineChart/mockedData → mockedData}/zoomPreview.json +0 -0
@@ -1,7 +1,7 @@
1
- import { MutableRefObject, useMemo, useRef, useState } from 'react';
1
+ import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Tooltip } from '@visx/visx';
4
- import { equals, flatten, isNil, pluck } from 'ramda';
4
+ import { equals, flatten, isNil, pluck, reject } from 'ramda';
5
5
 
6
6
  import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
7
7
 
@@ -18,18 +18,22 @@ import { useTooltipStyles } from '../common/useTooltipStyles';
18
18
  import BaseChart from '../common/BaseChart/BaseChart';
19
19
  import { useComputeBaseChartDimensions } from '../common/BaseChart/useComputeBaseChartDimensions';
20
20
  import ChartSvgWrapper from '../common/BaseChart/ChartSvgWrapper';
21
+ import Thresholds from '../common/Thresholds/Thresholds';
22
+ import { useDeepCompare } from '../../utils';
21
23
 
22
24
  import Lines from './BasicComponents/Lines';
23
- import { canDisplayThreshold } from './BasicComponents/Lines/Threshold/models';
24
- import useFilterLines from './BasicComponents/useFilterLines';
25
- import Header from './Header';
25
+ import {
26
+ canDisplayThreshold,
27
+ findLineOfOriginMetricThreshold,
28
+ lowerLineName,
29
+ upperLineName
30
+ } from './BasicComponents/Lines/Threshold/models';
26
31
  import InteractionWithGraph from './InteractiveComponents';
27
32
  import GraphTooltip from './InteractiveComponents/Tooltip';
28
33
  import useGraphTooltip from './InteractiveComponents/Tooltip/useGraphTooltip';
29
34
  import { margin } from './common';
30
35
  import { Data, GlobalAreaLines, GraphInterval, LineChartProps } from './models';
31
36
  import { useIntersection } from './useLineChartIntersection';
32
- import Thresholds from './BasicComponents/Thresholds';
33
37
  import GraphValueTooltip from './InteractiveComponents/GraphValueTooltip/GraphValueTooltip';
34
38
  import { useLineChartStyles } from './LineChart.styles';
35
39
 
@@ -48,6 +52,23 @@ const baseStyles = {
48
52
  textAlign: 'center'
49
53
  };
50
54
 
55
+ const filterLines = (lines: Array<Line>, displayThreshold): Array<Line> => {
56
+ if (!displayThreshold) {
57
+ return lines;
58
+ }
59
+ const lineOriginMetric = findLineOfOriginMetricThreshold(lines);
60
+
61
+ const findLinesUpperLower = lines.map((line) =>
62
+ equals(line.name, lowerLineName) || equals(line.name, upperLineName)
63
+ ? line
64
+ : null
65
+ );
66
+
67
+ const linesUpperLower = reject((element) => !element, findLinesUpperLower);
68
+
69
+ return [...lineOriginMetric, ...linesUpperLower] as Array<Line>;
70
+ };
71
+
51
72
  const LineChart = ({
52
73
  graphData,
53
74
  height = 500,
@@ -73,7 +94,11 @@ const LineChart = ({
73
94
 
74
95
  const theme = useTheme();
75
96
 
76
- const [linesGraph, setLinesGraph] = useState<Array<Line> | null>(null);
97
+ const { title, timeSeries, baseAxis, lines } = graphData;
98
+
99
+ const [linesGraph, setLinesGraph] = useState<Array<Line>>(
100
+ filterLines(lines, canDisplayThreshold(shapeLines?.areaThresholdLines))
101
+ );
77
102
  const graphSvgRef = useRef<SVGSVGElement | null>(null);
78
103
 
79
104
  const { isInViewport } = useIntersection({ element: graphRef?.current });
@@ -87,21 +112,12 @@ const LineChart = ({
87
112
  showTooltip: showThresholdTooltip
88
113
  } = Tooltip.useTooltip();
89
114
 
90
- const { title, timeSeries, baseAxis, lines } = graphData;
91
-
92
115
  const thresholdValues = flatten([
93
116
  pluck('value', thresholds?.warning || []),
94
117
  pluck('value', thresholds?.critical || [])
95
118
  ]);
96
119
 
97
- const { displayedLines } = useFilterLines({
98
- displayThreshold: canDisplayThreshold(shapeLines?.areaThresholdLines),
99
- lines,
100
- linesGraph,
101
- setLinesGraph
102
- });
103
-
104
- const [, secondUnit] = getUnits(displayedLines);
120
+ const [, secondUnit] = getUnits(linesGraph);
105
121
 
106
122
  const { legendRef, graphWidth, graphHeight } = useComputeBaseChartDimensions({
107
123
  hasSecondUnit: Boolean(secondUnit),
@@ -120,6 +136,11 @@ const LineChart = ({
120
136
  [timeSeries, graphWidth]
121
137
  );
122
138
 
139
+ const displayedLines = useMemo(
140
+ () => linesGraph.filter(({ display }) => display),
141
+ [linesGraph]
142
+ );
143
+
123
144
  const leftScale = useMemo(
124
145
  () =>
125
146
  getLeftScale({
@@ -165,6 +186,15 @@ const LineChart = ({
165
186
  ]
166
187
  );
167
188
 
189
+ useEffect(
190
+ () => {
191
+ setLinesGraph(
192
+ filterLines(lines, canDisplayThreshold(shapeLines?.areaThresholdLines))
193
+ );
194
+ },
195
+ useDeepCompare([lines])
196
+ );
197
+
168
198
  const graphTooltipData = useGraphTooltip({
169
199
  graphWidth,
170
200
  timeSeries,
@@ -190,134 +220,131 @@ const LineChart = ({
190
220
  }
191
221
 
192
222
  return (
193
- <>
194
- <Header header={header} title={title} />
195
- <ClickAwayListener onClickAway={graphTooltipData?.hideTooltip}>
196
- <>
197
- <BaseChart
198
- base={baseAxis}
199
- graphWidth={graphWidth}
200
- height={height}
201
- legend={{
202
- displayLegend,
203
- mode: legend?.mode,
204
- placement: legend?.placement,
205
- renderExtraComponent: legend?.renderExtraComponent
223
+ <ClickAwayListener onClickAway={graphTooltipData?.hideTooltip}>
224
+ <>
225
+ <BaseChart
226
+ base={baseAxis}
227
+ graphWidth={graphWidth}
228
+ header={header}
229
+ height={height}
230
+ legend={{
231
+ displayLegend,
232
+ mode: legend?.mode,
233
+ placement: legend?.placement,
234
+ renderExtraComponent: legend?.renderExtraComponent
235
+ }}
236
+ legendRef={legendRef}
237
+ limitLegend={limitLegend}
238
+ lines={linesGraph}
239
+ setLines={setLinesGraph}
240
+ title={title}
241
+ >
242
+ <MuiTooltip
243
+ classes={{
244
+ tooltip: cx(
245
+ tooltipClasses.tooltip,
246
+ tooltipClasses.tooltipDisablePadding
247
+ )
206
248
  }}
207
- legendRef={legendRef}
208
- limitLegend={limitLegend}
209
- lines={displayedLines}
210
- setLines={setLinesGraph}
249
+ placement="top-start"
250
+ title={
251
+ equals('hidden', tooltip?.mode) ? null : (
252
+ <GraphValueTooltip
253
+ base={baseAxis}
254
+ isSingleMode={equals('single', tooltip?.mode)}
255
+ sortOrder={tooltip?.sortOrder}
256
+ />
257
+ )
258
+ }
211
259
  >
212
- <MuiTooltip
213
- classes={{
214
- tooltip: cx(
215
- tooltipClasses.tooltip,
216
- tooltipClasses.tooltipDisablePadding
217
- )
218
- }}
219
- placement="top-start"
220
- title={
221
- equals('hidden', tooltip?.mode) ? null : (
222
- <GraphValueTooltip
223
- base={baseAxis}
224
- isSingleMode={equals('single', tooltip?.mode)}
225
- sortOrder={tooltip?.sortOrder}
260
+ <div className={classes.tooltipChildren}>
261
+ <ChartSvgWrapper
262
+ axis={axis}
263
+ base={baseAxis}
264
+ displayedLines={displayedLines}
265
+ graphHeight={graphHeight}
266
+ graphWidth={graphWidth}
267
+ gridLinesType={axis?.gridLinesType}
268
+ leftScale={leftScale}
269
+ rightScale={rightScale}
270
+ showGridLines={showGridLines}
271
+ svgRef={graphSvgRef}
272
+ timeSeries={timeSeries}
273
+ xScale={xScale}
274
+ >
275
+ <>
276
+ <Lines
277
+ areaTransparency={lineStyle?.areaTransparency}
278
+ curve={lineStyle?.curve || 'linear'}
279
+ dashLength={lineStyle?.dashLength}
280
+ dashOffset={lineStyle?.dashOffset}
281
+ displayAnchor={displayAnchor}
282
+ displayedLines={displayedLines}
283
+ dotOffset={lineStyle?.dotOffset}
284
+ graphSvgRef={graphSvgRef}
285
+ height={graphHeight - margin.top}
286
+ leftScale={leftScale}
287
+ lineWidth={lineStyle?.lineWidth}
288
+ rightScale={rightScale}
289
+ showArea={lineStyle?.showArea}
290
+ showPoints={lineStyle?.showPoints}
291
+ timeSeries={timeSeries}
292
+ width={graphWidth}
293
+ xScale={xScale}
294
+ {...shapeLines}
226
295
  />
227
- )
228
- }
229
- >
230
- <div className={classes.tooltipChildren}>
231
- <ChartSvgWrapper
232
- axis={axis}
233
- base={baseAxis}
234
- displayedLines={displayedLines}
235
- graphHeight={graphHeight}
236
- graphWidth={graphWidth}
237
- gridLinesType={axis?.gridLinesType}
238
- leftScale={leftScale}
239
- rightScale={rightScale}
240
- showGridLines={showGridLines}
241
- svgRef={graphSvgRef}
242
- timeSeries={timeSeries}
243
- xScale={xScale}
244
- >
245
- <>
246
- <Lines
247
- areaTransparency={lineStyle?.areaTransparency}
248
- curve={lineStyle?.curve || 'linear'}
249
- dashLength={lineStyle?.dashLength}
250
- dashOffset={lineStyle?.dashOffset}
251
- displayAnchor={displayAnchor}
296
+ <InteractionWithGraph
297
+ annotationData={{ ...annotationEvent }}
298
+ commonData={{
299
+ graphHeight,
300
+ graphSvgRef,
301
+ graphWidth,
302
+ leftScale,
303
+ lines: linesGraph,
304
+ rightScale,
305
+ timeSeries,
306
+ xScale
307
+ }}
308
+ timeShiftZonesData={{
309
+ ...timeShiftZones,
310
+ graphInterval
311
+ }}
312
+ zoomData={{ ...zoomPreview }}
313
+ />
314
+ {thresholds?.enabled && (
315
+ <Thresholds
252
316
  displayedLines={displayedLines}
253
- dotOffset={lineStyle?.dotOffset}
254
- graphSvgRef={graphSvgRef}
255
- height={graphHeight - margin.top}
317
+ hideTooltip={hideThresholdTooltip}
256
318
  leftScale={leftScale}
257
- lineWidth={lineStyle?.lineWidth}
258
319
  rightScale={rightScale}
259
- showArea={lineStyle?.showArea}
260
- showPoints={lineStyle?.showPoints}
261
- timeSeries={timeSeries}
320
+ showTooltip={showThresholdTooltip}
321
+ thresholdUnit={thresholdUnit}
322
+ thresholds={thresholds as ThresholdsModel}
262
323
  width={graphWidth}
263
- xScale={xScale}
264
- {...shapeLines}
265
324
  />
266
- <InteractionWithGraph
267
- annotationData={{ ...annotationEvent }}
268
- commonData={{
269
- graphHeight,
270
- graphSvgRef,
271
- graphWidth,
272
- leftScale,
273
- lines: displayedLines,
274
- rightScale,
275
- timeSeries,
276
- xScale
277
- }}
278
- timeShiftZonesData={{
279
- ...timeShiftZones,
280
- graphInterval
281
- }}
282
- zoomData={{ ...zoomPreview }}
283
- />
284
- {thresholds?.enabled && (
285
- <Thresholds
286
- displayedLines={displayedLines}
287
- hideTooltip={hideThresholdTooltip}
288
- leftScale={leftScale}
289
- rightScale={rightScale}
290
- showTooltip={showThresholdTooltip}
291
- thresholdUnit={thresholdUnit}
292
- thresholds={thresholds as ThresholdsModel}
293
- width={graphWidth}
294
- />
295
- )}
296
- </>
297
- </ChartSvgWrapper>
298
- </div>
299
- </MuiTooltip>
300
- </BaseChart>
301
- {displayTooltip && (
302
- <GraphTooltip {...tooltip} {...graphTooltipData} />
303
- )}
304
- <Fade in={thresholdTooltipOpen}>
305
- <Tooltip.Tooltip
306
- left={thresholdTooltipLeft}
307
- style={{
308
- ...baseStyles,
309
- backgroundColor: theme.palette.background.paper,
310
- color: theme.palette.text.primary,
311
- transform: `translate(${graphWidth / 2}px, -10px)`
312
- }}
313
- top={thresholdTooltipTop}
314
- >
315
- {thresholdTooltipData}
316
- </Tooltip.Tooltip>
317
- </Fade>
318
- </>
319
- </ClickAwayListener>
320
- </>
325
+ )}
326
+ </>
327
+ </ChartSvgWrapper>
328
+ </div>
329
+ </MuiTooltip>
330
+ </BaseChart>
331
+ {displayTooltip && <GraphTooltip {...tooltip} {...graphTooltipData} />}
332
+ <Fade in={thresholdTooltipOpen}>
333
+ <Tooltip.Tooltip
334
+ left={thresholdTooltipLeft}
335
+ style={{
336
+ ...baseStyles,
337
+ backgroundColor: theme.palette.background.paper,
338
+ color: theme.palette.text.primary,
339
+ transform: `translate(${graphWidth / 2}px, -10px)`
340
+ }}
341
+ top={thresholdTooltipTop}
342
+ >
343
+ {thresholdTooltipData}
344
+ </Tooltip.Tooltip>
345
+ </Fade>
346
+ </>
347
+ </ClickAwayListener>
321
348
  );
322
349
  };
323
350
 
@@ -11,8 +11,18 @@ import { useLocaleDateTimeFormat } from '@centreon/ui';
11
11
 
12
12
  import TimePeriod from '../../TimePeriods';
13
13
  import { LineChartData } from '../common/models';
14
+ import annotationData from '../mockedData/annotationData.json';
15
+ import exclusionPeriodFirstPeriod from '../mockedData/exclusionPeriodFirstPeriod.json';
16
+ import exclusionPeriodSecondPeriod from '../mockedData/exclusionPeriodSecondPeriod.json';
17
+ import exclusionPeriodThirdPeriod from '../mockedData/exclusionPeriodThirdPeriod.json';
18
+ import dataLastDayForword from '../mockedData/lastDayForward.json';
19
+ import dataLastDayThreshold from '../mockedData/lastDayThreshold.json';
20
+ import dataLastMonth from '../mockedData/lastMonth.json';
21
+ import dataLastWeek from '../mockedData/lastWeek.json';
22
+ import dataZoomPreview from '../mockedData/zoomPreview.json';
23
+ import dataLastDay from '../mockedData/lastDay.json';
24
+ import dataCurvesSameColor from '../mockedData/curvesWithSameColor.json';
14
25
 
15
- import { dateTimeFormat } from './common';
16
26
  import {
17
27
  argTypes,
18
28
  args as argumentsData,
@@ -23,17 +33,7 @@ import {
23
33
  lastDayForwardDate,
24
34
  zoomPreviewDate
25
35
  } from './helpers/doc';
26
- import annotationData from './mockedData/annotationData.json';
27
- import exclusionPeriodFirstPeriod from './mockedData/exclusionPeriodFirstPeriod.json';
28
- import exclusionPeriodSecondPeriod from './mockedData/exclusionPeriodSecondPeriod.json';
29
- import exclusionPeriodThirdPeriod from './mockedData/exclusionPeriodThirdPeriod.json';
30
- import dataLastDayForword from './mockedData/lastDayForward.json';
31
- import dataLastDayThreshold from './mockedData/lastDayThreshold.json';
32
- import dataLastMonth from './mockedData/lastMonth.json';
33
- import dataLastWeek from './mockedData/lastWeek.json';
34
- import dataZoomPreview from './mockedData/zoomPreview.json';
35
- import dataLastDay from './mockedData/lastDay.json';
36
- import dataCurvesSameColor from './mockedData/curvesWithSameColor.json';
36
+ import { dateTimeFormat } from './common';
37
37
  import { Interval, ThresholdType, TooltipData } from './models';
38
38
 
39
39
  import WrapperLineChart from './index';
@@ -1,4 +1,4 @@
1
- import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
1
+ import dataLastWeek from '../mockedData/lastWeek.json';
2
2
  import {
3
3
  criticalThresholds,
4
4
  rangedThresholds,
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
 
3
- import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
3
+ import dataLastWeek from '../mockedData/lastWeek.json';
4
4
 
5
5
  import { SingleBar } from '.';
6
6
 
@@ -1,4 +1,4 @@
1
- import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
1
+ import dataLastWeek from '../mockedData/lastWeek.json';
2
2
  import {
3
3
  criticalThresholds,
4
4
  rangedThresholds,
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
 
3
- import dataLastWeek from '../LineChart/mockedData/lastWeek.json';
3
+ import dataLastWeek from '../mockedData/lastWeek.json';
4
4
 
5
5
  import { Text } from '.';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { Axis } from '@visx/visx';
2
2
  import { ScaleLinear } from 'd3-scale';
3
- import { isNil } from 'ramda';
3
+ import { equals, isNil } from 'ramda';
4
4
 
5
5
  import { useLocaleDateTimeFormat } from '@centreon/ui';
6
6
 
@@ -15,6 +15,7 @@ interface Props {
15
15
  data: Data;
16
16
  height: number;
17
17
  leftScale: ScaleLinear<number, number>;
18
+ orientation: 'horizontal' | 'vertical';
18
19
  rightScale: ScaleLinear<number, number>;
19
20
  width: number;
20
21
  xScale: ScaleLinear<number, number>;
@@ -26,7 +27,8 @@ const Axes = ({
26
27
  data,
27
28
  rightScale,
28
29
  leftScale,
29
- xScale
30
+ xScale,
31
+ orientation
30
32
  }: Props): JSX.Element => {
31
33
  const { format } = useLocaleDateTimeFormat();
32
34
  const { lines, showBorder, yAxisTickLabelRotation } = data;
@@ -50,47 +52,72 @@ const Axes = ({
50
52
  const hasMoreThanTwoUnits = !isNil(thirdUnit);
51
53
  const displayAxisRight = !isNil(secondUnit) && !hasMoreThanTwoUnits;
52
54
 
55
+ const isHorizontal = equals(orientation, 'horizontal');
56
+
57
+ const AxisBottom = isHorizontal ? Axis.AxisBottom : Axis.AxisLeft;
58
+ const AxisLeft = isHorizontal ? Axis.AxisLeft : Axis.AxisTop;
59
+ const AxisRight = isHorizontal ? Axis.AxisRight : Axis.AxisBottom;
60
+
53
61
  return (
54
62
  <g>
55
- <Axis.AxisBottom
63
+ <AxisBottom
56
64
  numTicks={xTickCount}
57
65
  scale={xScale}
58
66
  strokeWidth={!isNil(showBorder) && !showBorder ? 0 : 1}
59
67
  tickFormat={formatAxisTick}
60
- top={height - 5}
68
+ tickLabelProps={() => ({
69
+ ...axisLeft.tickLabelProps(),
70
+ dx: isHorizontal ? 16 : -4
71
+ })}
72
+ top={isHorizontal ? height - 5 : 0}
61
73
  />
62
74
 
63
- {axisLeft.displayUnit && <UnitLabel unit={firstUnit} x={-4} />}
75
+ {axisLeft.displayUnit && (
76
+ <UnitLabel
77
+ unit={firstUnit}
78
+ x={isHorizontal ? -8 : width + 8}
79
+ y={isHorizontal ? 16 : 0}
80
+ />
81
+ )}
64
82
 
65
- <Axis.AxisLeft
83
+ <AxisLeft
66
84
  numTicks={axisLeft?.numTicks}
67
- orientation="left"
68
85
  scale={leftScale}
69
86
  strokeWidth={!isNil(showBorder) && !showBorder ? 0 : 1}
70
87
  tickFormat={axisLeft.tickFormat}
71
88
  tickLabelProps={() => ({
72
89
  ...axisLeft.tickLabelProps(),
73
- angle: yAxisTickLabelRotation
90
+ angle: yAxisTickLabelRotation,
91
+ dx: isHorizontal ? -8 : 2,
92
+ dy: isHorizontal ? 4 : -4
74
93
  })}
75
94
  tickLength={2}
76
95
  />
77
96
 
78
97
  {displayAxisRight && (
79
- <Axis.AxisRight
80
- left={width}
98
+ <AxisRight
99
+ left={isHorizontal ? width : 0}
81
100
  numTicks={axisRight?.numTicks}
82
- orientation="right"
83
101
  scale={rightScale}
84
102
  strokeWidth={!isNil(showBorder) && !showBorder ? 0 : 1}
85
103
  tickFormat={axisRight.tickFormat}
86
104
  tickLabelProps={() => ({
87
105
  ...axisRight.tickLabelProps(),
88
- angle: yAxisTickLabelRotation
106
+ angle: yAxisTickLabelRotation,
107
+ dx: isHorizontal ? 4 : -8,
108
+ dy: 4
89
109
  })}
90
110
  tickLength={2}
111
+ top={isHorizontal ? 0 : height}
112
+ />
113
+ )}
114
+ {axisRight.displayUnit && (
115
+ <UnitLabel
116
+ unit={secondUnit}
117
+ x={width + 8}
118
+ y={isHorizontal ? 16 : -(height + 8)}
91
119
  />
92
120
  )}
93
- {axisRight.displayUnit && <UnitLabel unit={secondUnit} x={width} />}
94
121
  </g>
95
122
  );
96
123
  };
@@ -15,22 +15,29 @@ import { legendWidth } from '../../LineChart/Legend/Legend.styles';
15
15
  import { Line } from '../timeSeries/models';
16
16
 
17
17
  import { useBaseChartStyles } from './useBaseChartStyles';
18
+ import Header from './Header';
19
+ import { LineChartHeader } from './Header/models';
18
20
 
19
21
  interface Props {
20
22
  base?: number;
21
23
  children: JSX.Element;
22
24
  graphWidth: number;
25
+ header?: LineChartHeader;
23
26
  height: number | null;
27
+ isHorizontal?: boolean;
24
28
  legend: {
25
29
  displayLegend: boolean;
26
- mode: 'grid' | 'list';
27
- placement: string;
30
+ mode?: 'grid' | 'list';
31
+ placement?: 'left' | 'right' | 'bottom';
28
32
  renderExtraComponent?: ReactNode;
29
33
  };
30
34
  legendRef: MutableRefObject<HTMLDivElement | null>;
31
35
  limitLegend?: number | false;
32
36
  lines: Array<Line>;
33
- setLines: Dispatch<SetStateAction<Array<Line> | null>>;
37
+ setLines:
38
+ | Dispatch<SetStateAction<Array<Line> | null>>
39
+ | Dispatch<SetStateAction<Array<Line>>>;
40
+ title: string;
34
41
  }
35
42
 
36
43
  const BaseChart = ({
@@ -42,9 +49,12 @@ const BaseChart = ({
42
49
  limitLegend = false,
43
50
  setLines,
44
51
  children,
45
- legendRef
52
+ legendRef,
53
+ title,
54
+ header,
55
+ isHorizontal = true
46
56
  }: Props): JSX.Element => {
47
- const { classes } = useBaseChartStyles();
57
+ const { classes, cx } = useBaseChartStyles();
48
58
 
49
59
  const legendItemsWidth = useMemo(
50
60
  () => reduce((acc) => acc + legendWidth * 8 + 24, 0, lines),
@@ -66,6 +76,7 @@ const BaseChart = ({
66
76
 
67
77
  return (
68
78
  <>
79
+ <Header header={header} title={title} />
69
80
  <div className={classes.container}>
70
81
  <Stack
71
82
  direction={equals(legend?.placement, 'left') ? 'row' : 'row-reverse'}
@@ -73,7 +84,15 @@ const BaseChart = ({
73
84
  {legend.displayLegend &&
74
85
  (equals(legend?.placement, 'left') ||
75
86
  equals(legend?.placement, 'right')) && (
76
- <div ref={legendRef} style={{ maxWidth: '60%' }}>
87
+ <div
88
+ className={cx(
89
+ classes.legendContainer,
90
+ equals(legend?.placement, 'right') &&
91
+ !isHorizontal &&
92
+ classes.legendContainerVerticalSide
93
+ )}
94
+ ref={legendRef}
95
+ >
77
96
  <Legend
78
97
  base={base}
79
98
  height={height}