@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
@@ -1,11 +1,22 @@
1
1
  import { MutableRefObject, useMemo, useRef, useState } from 'react';
2
2
 
3
3
  import { Group, Tooltip } from '@visx/visx';
4
- import { flatten, gt, isNil, lte, pluck, reduce } from 'ramda';
4
+ import { equals, flatten, gt, isNil, lte, pluck, reduce } from 'ramda';
5
5
 
6
- import { ClickAwayListener, Fade, Skeleton, useTheme } from '@mui/material';
6
+ import {
7
+ ClickAwayListener,
8
+ Fade,
9
+ Skeleton,
10
+ Stack,
11
+ useTheme
12
+ } from '@mui/material';
7
13
 
8
- import { getLeftScale, getRightScale, getXScale } from '../common/timeSeries';
14
+ import {
15
+ getLeftScale,
16
+ getRightScale,
17
+ getUnits,
18
+ getXScale
19
+ } from '../common/timeSeries';
9
20
  import { Line } from '../common/timeSeries/models';
10
21
  import { Thresholds as ThresholdsModel } from '../common/models';
11
22
  import { Tooltip as MuiTooltip } from '../../components/Tooltip';
@@ -22,13 +33,7 @@ import GraphTooltip from './InteractiveComponents/Tooltip';
22
33
  import useGraphTooltip from './InteractiveComponents/Tooltip/useGraphTooltip';
23
34
  import Legend from './Legend';
24
35
  import { margin } from './common';
25
- import {
26
- Data,
27
- GlobalAreaLines,
28
- GraphInterval,
29
- LineChartProps,
30
- LegendModel
31
- } from './models';
36
+ import { Data, GlobalAreaLines, GraphInterval, LineChartProps } from './models';
32
37
  import { useIntersection } from './useLineChartIntersection';
33
38
  import Thresholds from './BasicComponents/Thresholds';
34
39
  import { legendWidth } from './Legend/Legend.styles';
@@ -37,11 +42,9 @@ import GraphValueTooltip from './InteractiveComponents/GraphValueTooltip/GraphVa
37
42
  const extraMargin = 10;
38
43
 
39
44
  interface Props extends LineChartProps {
40
- curve: 'linear' | 'step' | 'natural';
41
45
  graphData: Data;
42
46
  graphInterval: GraphInterval;
43
47
  graphRef: MutableRefObject<HTMLDivElement | null>;
44
- legend?: LegendModel;
45
48
  limitLegend?: false | number;
46
49
  shapeLines?: GlobalAreaLines;
47
50
  thresholdUnit?: string;
@@ -68,7 +71,7 @@ const LineChart = ({
68
71
  legend,
69
72
  graphRef,
70
73
  header,
71
- curve,
74
+ lineStyle,
72
75
  thresholds,
73
76
  thresholdUnit,
74
77
  limitLegend
@@ -93,16 +96,6 @@ const LineChart = ({
93
96
  showTooltip: showThresholdTooltip
94
97
  } = Tooltip.useTooltip();
95
98
 
96
- const graphWidth =
97
- width > 0 ? width - margin.left - margin.right - extraMargin : 0;
98
- const graphHeight =
99
- (height || 0) > 0
100
- ? (height || 0) -
101
- margin.top -
102
- 5 -
103
- (legendRef.current?.getBoundingClientRect().height || 0)
104
- : 0;
105
-
106
99
  const { title, timeSeries, baseAxis, lines } = graphData;
107
100
 
108
101
  const thresholdValues = flatten([
@@ -117,6 +110,32 @@ const LineChart = ({
117
110
  setLinesGraph
118
111
  });
119
112
 
113
+ const legendBoundingHeight =
114
+ !equals(legend?.display, false) &&
115
+ (isNil(legend?.placement) || equals(legend?.placement, 'bottom'))
116
+ ? legendRef.current?.getBoundingClientRect().height || 0
117
+ : 0;
118
+ const legendBoundingWidth =
119
+ !equals(legend?.display, false) &&
120
+ (equals(legend?.placement, 'left') || equals(legend?.placement, 'right'))
121
+ ? legendRef.current?.getBoundingClientRect().width || 0
122
+ : 0;
123
+
124
+ const [, secondUnit] = getUnits(displayedLines);
125
+
126
+ const graphWidth =
127
+ width > 0
128
+ ? width -
129
+ margin.left -
130
+ (secondUnit ? margin.right : 8) -
131
+ extraMargin -
132
+ legendBoundingWidth
133
+ : 0;
134
+ const graphHeight =
135
+ (height || 0) > 0
136
+ ? (height || 0) - margin.top - 5 - legendBoundingHeight
137
+ : 0;
138
+
120
139
  const xScale = useMemo(
121
140
  () =>
122
141
  getXScale({
@@ -131,11 +150,22 @@ const LineChart = ({
131
150
  getLeftScale({
132
151
  dataLines: displayedLines,
133
152
  dataTimeSeries: timeSeries,
153
+ isCenteredZero: axis?.isCenteredZero,
154
+ scale: axis?.scale,
155
+ scaleLogarithmicBase: axis?.scaleLogarithmicBase,
134
156
  thresholdUnit,
135
157
  thresholds: (thresholds?.enabled && thresholdValues) || [],
136
158
  valueGraphHeight: graphHeight - 35
137
159
  }),
138
- [displayedLines, timeSeries, graphHeight, thresholdValues]
160
+ [
161
+ displayedLines,
162
+ timeSeries,
163
+ graphHeight,
164
+ thresholdValues,
165
+ axis?.isCenteredZero,
166
+ axis?.scale,
167
+ axis?.scaleLogarithmicBase
168
+ ]
139
169
  );
140
170
 
141
171
  const rightScale = useMemo(
@@ -143,11 +173,21 @@ const LineChart = ({
143
173
  getRightScale({
144
174
  dataLines: displayedLines,
145
175
  dataTimeSeries: timeSeries,
176
+ isCenteredZero: axis?.isCenteredZero,
177
+ scale: axis?.scale,
178
+ scaleLogarithmicBase: axis?.scaleLogarithmicBase,
146
179
  thresholdUnit,
147
180
  thresholds: (thresholds?.enabled && thresholdValues) || [],
148
181
  valueGraphHeight: graphHeight - 35
149
182
  }),
150
- [timeSeries, displayedLines, graphHeight]
183
+ [
184
+ timeSeries,
185
+ displayedLines,
186
+ graphHeight,
187
+ axis?.isCenteredZero,
188
+ axis?.scale,
189
+ axis?.scaleLogarithmicBase
190
+ ]
151
191
  );
152
192
 
153
193
  const graphTooltipData = useGraphTooltip({
@@ -165,8 +205,18 @@ const LineChart = ({
165
205
  displayedLines
166
206
  );
167
207
 
208
+ const displayLegendInBottom =
209
+ isNil(legend?.placement) || equals(legend?.placement, 'bottom');
210
+
168
211
  const shouldDisplayLegendInCompactMode =
169
- lte(graphWidth, 808) && gt(legendItemsWidth, graphWidth);
212
+ lte(graphWidth, 808) &&
213
+ gt(legendItemsWidth, graphWidth) &&
214
+ displayLegendInBottom;
215
+
216
+ const showGridLines = useMemo(
217
+ () => isNil(axis?.showGridLines) || axis?.showGridLines,
218
+ [axis?.showGridLines]
219
+ );
170
220
 
171
221
  if (!isInViewport) {
172
222
  return (
@@ -187,86 +237,130 @@ const LineChart = ({
187
237
  tooltip: classes.graphValueTooltip
188
238
  }}
189
239
  placement="top-start"
190
- title={<GraphValueTooltip base={baseAxis} />}
240
+ title={
241
+ equals('hidden', tooltip?.mode) ? null : (
242
+ <GraphValueTooltip
243
+ base={baseAxis}
244
+ isSingleMode={equals('single', tooltip?.mode)}
245
+ sortOrder={tooltip?.sortOrder}
246
+ />
247
+ )
248
+ }
191
249
  >
192
250
  <div className={classes.container}>
193
- <svg
194
- height={graphHeight + margin.top}
195
- ref={graphSvgRef}
196
- width="100%"
251
+ <Stack
252
+ direction={
253
+ equals(legend?.placement, 'left') ? 'row' : 'row-reverse'
254
+ }
197
255
  >
198
- <Group.Group
199
- left={margin.left + extraMargin / 2}
200
- top={margin.top}
256
+ {displayLegend &&
257
+ (equals(legend?.placement, 'left') ||
258
+ equals(legend?.placement, 'right')) && (
259
+ <div ref={legendRef} style={{ maxWidth: '40%' }}>
260
+ <Legend
261
+ base={baseAxis}
262
+ height={height}
263
+ limitLegend={limitLegend}
264
+ lines={newLines}
265
+ mode={legend?.mode}
266
+ placement="left"
267
+ renderExtraComponent={legend?.renderExtraComponent}
268
+ setLinesGraph={setLinesGraph}
269
+ shouldDisplayLegendInCompactMode={
270
+ shouldDisplayLegendInCompactMode
271
+ }
272
+ width={width}
273
+ />
274
+ </div>
275
+ )}
276
+ <svg
277
+ height={graphHeight + margin.top}
278
+ ref={graphSvgRef}
279
+ width="100%"
201
280
  >
202
- <Grids
203
- height={graphHeight - margin.top}
204
- leftScale={leftScale}
205
- width={graphWidth}
206
- xScale={xScale}
207
- />
208
- <Axes
209
- data={{
210
- baseAxis,
211
- lines: displayedLines,
212
- timeSeries,
213
- ...axis
214
- }}
215
- graphInterval={graphInterval}
216
- height={graphHeight - margin.top}
217
- leftScale={leftScale}
218
- rightScale={rightScale}
219
- width={graphWidth}
220
- xScale={xScale}
221
- />
222
-
223
- <Lines
224
- curve={curve}
225
- displayAnchor={displayAnchor}
226
- displayedLines={displayedLines}
227
- graphSvgRef={graphSvgRef}
228
- height={graphHeight - margin.top}
229
- leftScale={leftScale}
230
- rightScale={rightScale}
231
- timeSeries={timeSeries}
232
- width={graphWidth}
233
- xScale={xScale}
234
- {...shapeLines}
235
- />
236
-
237
- <InteractionWithGraph
238
- annotationData={{ ...annotationEvent }}
239
- commonData={{
240
- graphHeight,
241
- graphSvgRef,
242
- graphWidth,
243
- leftScale,
244
- lines: displayedLines,
245
- rightScale,
246
- timeSeries,
247
- xScale
248
- }}
249
- timeShiftZonesData={{
250
- ...timeShiftZones,
251
- graphInterval
252
- }}
253
- zoomData={{ ...zoomPreview }}
254
- />
255
-
256
- {thresholds?.enabled && (
257
- <Thresholds
281
+ <Group.Group
282
+ left={margin.left + extraMargin / 2}
283
+ top={margin.top}
284
+ >
285
+ {showGridLines && (
286
+ <Grids
287
+ gridLinesType={axis?.gridLinesType}
288
+ height={graphHeight - margin.top}
289
+ leftScale={leftScale}
290
+ width={graphWidth}
291
+ xScale={xScale}
292
+ />
293
+ )}
294
+ <Axes
295
+ data={{
296
+ baseAxis,
297
+ lines: displayedLines,
298
+ timeSeries,
299
+ ...axis
300
+ }}
301
+ graphInterval={graphInterval}
302
+ height={graphHeight - margin.top}
303
+ leftScale={leftScale}
304
+ rightScale={rightScale}
305
+ width={graphWidth}
306
+ xScale={xScale}
307
+ />
308
+
309
+ <Lines
310
+ areaTransparency={lineStyle?.areaTransparency}
311
+ curve={lineStyle?.curve || 'linear'}
312
+ dashLength={lineStyle?.dashLength}
313
+ dashOffset={lineStyle?.dashOffset}
314
+ displayAnchor={displayAnchor}
258
315
  displayedLines={displayedLines}
259
- hideTooltip={hideThresholdTooltip}
316
+ dotOffset={lineStyle?.dotOffset}
317
+ graphSvgRef={graphSvgRef}
318
+ height={graphHeight - margin.top}
260
319
  leftScale={leftScale}
320
+ lineWidth={lineStyle?.lineWidth}
261
321
  rightScale={rightScale}
262
- showTooltip={showThresholdTooltip}
263
- thresholdUnit={thresholdUnit}
264
- thresholds={thresholds as ThresholdsModel}
322
+ showArea={lineStyle?.showArea}
323
+ showPoints={lineStyle?.showPoints}
324
+ timeSeries={timeSeries}
265
325
  width={graphWidth}
326
+ xScale={xScale}
327
+ {...shapeLines}
266
328
  />
267
- )}
268
- </Group.Group>
269
- </svg>
329
+
330
+ <InteractionWithGraph
331
+ annotationData={{ ...annotationEvent }}
332
+ commonData={{
333
+ graphHeight,
334
+ graphSvgRef,
335
+ graphWidth,
336
+ leftScale,
337
+ lines: displayedLines,
338
+ rightScale,
339
+ timeSeries,
340
+ xScale
341
+ }}
342
+ timeShiftZonesData={{
343
+ ...timeShiftZones,
344
+ graphInterval
345
+ }}
346
+ zoomData={{ ...zoomPreview }}
347
+ />
348
+
349
+ {thresholds?.enabled && (
350
+ <Thresholds
351
+ displayedLines={displayedLines}
352
+ hideTooltip={hideThresholdTooltip}
353
+ leftScale={leftScale}
354
+ rightScale={rightScale}
355
+ showTooltip={showThresholdTooltip}
356
+ thresholdUnit={thresholdUnit}
357
+ thresholds={thresholds as ThresholdsModel}
358
+ width={graphWidth}
359
+ />
360
+ )}
361
+ </Group.Group>
362
+ </svg>
363
+ </Stack>
270
364
  {displayTooltip && (
271
365
  <GraphTooltip {...tooltip} {...graphTooltipData} />
272
366
  )}
@@ -287,12 +381,15 @@ const LineChart = ({
287
381
  </div>
288
382
  </MuiTooltip>
289
383
  </ClickAwayListener>
290
- {displayLegend && (
384
+ {displayLegend && displayLegendInBottom && (
291
385
  <div ref={legendRef}>
292
386
  <Legend
293
387
  base={baseAxis}
388
+ height={height}
294
389
  limitLegend={limitLegend}
295
390
  lines={newLines}
391
+ mode={legend?.mode}
392
+ placement="bottom"
296
393
  renderExtraComponent={legend?.renderExtraComponent}
297
394
  setLinesGraph={setLinesGraph}
298
395
  shouldDisplayLegendInCompactMode={shouldDisplayLegendInCompactMode}
@@ -1,5 +1,5 @@
1
1
  import * as Curve from '@visx/curve';
2
- import { always, cond, equals } from 'ramda';
2
+ import { always, cond, equals, isNil } from 'ramda';
3
3
 
4
4
  import { alpha } from '@mui/material';
5
5
 
@@ -9,7 +9,7 @@ const commonTickLabelProps = {
9
9
  textAnchor: 'middle'
10
10
  };
11
11
 
12
- const margin = { bottom: 30, left: 55, right: 55, top: 30 };
12
+ const margin = { bottom: 30, left: 50, right: 50, top: 30 };
13
13
 
14
14
  interface FillColor {
15
15
  areaColor: string;
@@ -19,8 +19,11 @@ interface FillColor {
19
19
  const getFillColor = ({
20
20
  transparency,
21
21
  areaColor
22
- }: FillColor): string | undefined =>
23
- transparency ? alpha(areaColor, 1 - transparency * 0.01) : undefined;
22
+ }: FillColor): string | undefined => {
23
+ return !isNil(transparency)
24
+ ? alpha(areaColor, 1 - transparency * 0.01)
25
+ : undefined;
26
+ };
24
27
 
25
28
  const dateFormat = 'L';
26
29
  const timeFormat = 'LT';
@@ -482,7 +482,17 @@ export const thresholdsRange: Story = {
482
482
  export const LineChartWithSameColorCurves: Story = {
483
483
  ...Template,
484
484
  argTypes,
485
- args: argumentsData,
485
+ args: {
486
+ ...argumentsData,
487
+ lineStyle: {
488
+ areaTransparency: 10,
489
+ dashLength: 10,
490
+ dashOffset: 10,
491
+ lineWidth: 9,
492
+ showArea: true,
493
+ showPoints: true
494
+ }
495
+ },
486
496
  render: (args) => (
487
497
  <WrapperLineChart
488
498
  {...args}
@@ -14,7 +14,7 @@ import { LineChartData, Thresholds } from '../common/models';
14
14
 
15
15
  import LineChart from './LineChart';
16
16
  import LoadingSkeleton from './LoadingSkeleton';
17
- import { GlobalAreaLines, LineChartProps, LegendModel } from './models';
17
+ import { GlobalAreaLines, LineChartProps } from './models';
18
18
  import useLineChartData from './useLineChartData';
19
19
 
20
20
  dayjs.extend(localizedFormat);
@@ -22,10 +22,8 @@ dayjs.extend(utcPlugin);
22
22
  dayjs.extend(timezonePlugin);
23
23
 
24
24
  interface Props extends Partial<LineChartProps> {
25
- curve?: 'linear' | 'step' | 'natural';
26
25
  data?: LineChartData;
27
26
  end: string;
28
- legend: LegendModel;
29
27
  limitLegend?: false | number;
30
28
  loading: boolean;
31
29
  shapeLines?: GlobalAreaLines;
@@ -46,11 +44,18 @@ const WrapperLineChart = ({
46
44
  data,
47
45
  loading,
48
46
  timeShiftZones,
49
- tooltip,
47
+ tooltip = {
48
+ mode: 'all',
49
+ sortOrder: 'name'
50
+ },
50
51
  annotationEvent,
51
- legend,
52
+ legend = {
53
+ display: true,
54
+ mode: 'grid',
55
+ placement: 'bottom'
56
+ },
52
57
  header,
53
- curve = 'linear',
58
+ lineStyle,
54
59
  thresholds,
55
60
  thresholdUnit,
56
61
  limitLegend
@@ -85,7 +90,6 @@ const WrapperLineChart = ({
85
90
  <LineChart
86
91
  annotationEvent={annotationEvent}
87
92
  axis={axis}
88
- curve={curve}
89
93
  displayAnchor={displayAnchor}
90
94
  graphData={adjustedData}
91
95
  graphInterval={{ end, start }}
@@ -94,6 +98,7 @@ const WrapperLineChart = ({
94
98
  height={height || responsiveHeight}
95
99
  legend={legend}
96
100
  limitLegend={limitLegend}
101
+ lineStyle={lineStyle}
97
102
  shapeLines={shapeLines}
98
103
  thresholdUnit={thresholdUnit}
99
104
  thresholds={thresholds}
@@ -48,10 +48,17 @@ export interface ShapeLines {
48
48
  areaStackedLines?: AreaStackedLines;
49
49
  }
50
50
 
51
- export interface Axis {
51
+ export interface LineChartAxis {
52
52
  axisX?: AxisX;
53
53
  axisYLeft?: AxisYLeft;
54
54
  axisYRight?: AxisYRight;
55
+ gridLinesType?: 'horizontal' | 'vertical' | 'all';
56
+ isCenteredZero?: boolean;
57
+ scale?: 'linear' | 'logarithimc';
58
+ scaleLogarithmicBase?: number;
59
+ showBorder?: boolean;
60
+ showGridLines?: boolean;
61
+ yAxisTickLabelRotation?: number;
55
62
  }
56
63
 
57
64
  export interface InteractedZone {
@@ -65,7 +72,9 @@ export interface TooltipData {
65
72
  tooltipOpen: boolean;
66
73
  }
67
74
  export interface Tooltip {
75
+ mode: 'all' | 'single' | 'hidden';
68
76
  renderComponent?: (args: TooltipData) => ReactNode;
77
+ sortOrder: 'name' | 'ascending' | 'descending';
69
78
  }
70
79
 
71
80
  export interface AnnotationEvent {
@@ -82,12 +91,26 @@ export interface DisplayAnchor {
82
91
  displayTooltipsGuidingLines?: boolean;
83
92
  }
84
93
 
94
+ export interface LineStyle {
95
+ areaTransparency?: number;
96
+ curve?: 'linear' | 'step' | 'natural';
97
+ dashLength?: number;
98
+ dashOffset?: number;
99
+ dotOffset?: number;
100
+ lineWidth?: number;
101
+ pathStyle?: 'solid' | 'dash' | 'dotted';
102
+ showArea?: boolean;
103
+ showPoints?: boolean;
104
+ }
105
+
85
106
  export interface LineChartProps {
86
107
  annotationEvent?: AnnotationEvent;
87
- axis?: Axis;
108
+ axis?: LineChartAxis;
88
109
  displayAnchor?: DisplayAnchor;
89
110
  header?: LineChartHeader;
90
111
  height?: number | null;
112
+ legend?: LegendModel;
113
+ lineStyle?: LineStyle;
91
114
  timeShiftZones?: InteractedZone;
92
115
  tooltip?: Tooltip;
93
116
  width: number;
@@ -135,6 +158,8 @@ export interface GlobalAreaLines {
135
158
  }
136
159
  export interface LegendModel {
137
160
  display?: boolean;
161
+ mode: 'grid' | 'list';
162
+ placement: 'bottom' | 'left' | 'right';
138
163
  renderExtraComponent?: ReactNode;
139
164
  }
140
165
 
@@ -341,12 +341,21 @@ const getYScale = ({
341
341
  : scale;
342
342
  };
343
343
 
344
+ const getScaleType = (
345
+ scale: 'linear' | 'logarithimc'
346
+ ): typeof Scale.scaleLinear | typeof Scale.scaleLog =>
347
+ equals(scale, 'logarithmic') ? Scale.scaleLog : Scale.scaleLinear;
348
+
344
349
  const getScale = ({
345
350
  graphValues,
346
351
  height,
347
352
  stackedValues,
348
- thresholds
353
+ thresholds,
354
+ isCenteredZero,
355
+ scale,
356
+ scaleLogarithmicBase
349
357
  }): ScaleLinear<number, number> => {
358
+ const isLogScale = equals(scale, 'logarithmic');
350
359
  const minValue = Math.min(
351
360
  getMin(graphValues),
352
361
  getMin(stackedValues),
@@ -358,11 +367,23 @@ const getScale = ({
358
367
  Math.max(...thresholds)
359
368
  );
360
369
 
370
+ const scaleType = getScaleType(scale);
371
+
361
372
  const upperRangeValue = minValue === maxValue && maxValue === 0 ? height : 0;
362
373
 
363
- return Scale.scaleLinear<number>({
364
- domain: [minValue, maxValue],
365
- nice: true,
374
+ if (isCenteredZero) {
375
+ const greatestValue = Math.max(Math.abs(maxValue), Math.abs(minValue));
376
+
377
+ return scaleType<number>({
378
+ base: scaleLogarithmicBase || 2,
379
+ domain: [-greatestValue, greatestValue],
380
+ range: [height, upperRangeValue]
381
+ });
382
+ }
383
+
384
+ return scaleType<number>({
385
+ base: scaleLogarithmicBase || 2,
386
+ domain: [isLogScale ? 0.001 : minValue, maxValue],
366
387
  range: [height, upperRangeValue]
367
388
  });
368
389
  };
@@ -372,7 +393,10 @@ const getLeftScale = ({
372
393
  dataTimeSeries,
373
394
  valueGraphHeight,
374
395
  thresholds,
375
- thresholdUnit
396
+ thresholdUnit,
397
+ isCenteredZero,
398
+ scale,
399
+ scaleLogarithmicBase
376
400
  }: AxeScale): ScaleLinear<number, number> => {
377
401
  const [firstUnit, , thirdUnit] = getUnits(dataLines);
378
402
 
@@ -407,6 +431,9 @@ const getLeftScale = ({
407
431
  return getScale({
408
432
  graphValues,
409
433
  height: valueGraphHeight,
434
+ isCenteredZero,
435
+ scale,
436
+ scaleLogarithmicBase,
410
437
  stackedValues,
411
438
  thresholds: shouldApplyThresholds ? thresholds : []
412
439
  });
@@ -427,7 +454,10 @@ const getRightScale = ({
427
454
  dataTimeSeries,
428
455
  valueGraphHeight,
429
456
  thresholds,
430
- thresholdUnit
457
+ thresholdUnit,
458
+ isCenteredZero,
459
+ scale,
460
+ scaleLogarithmicBase
431
461
  }: AxeScale): ScaleLinear<number, number> => {
432
462
  const [, secondUnit] = getUnits(dataLines);
433
463
 
@@ -453,6 +483,9 @@ const getRightScale = ({
453
483
  return getScale({
454
484
  graphValues,
455
485
  height: valueGraphHeight,
486
+ isCenteredZero,
487
+ scale,
488
+ scaleLogarithmicBase,
456
489
  stackedValues,
457
490
  thresholds: shouldApplyThresholds ? thresholds : []
458
491
  });
@@ -1,5 +1,7 @@
1
1
  import { ScaleLinear, ScaleTime } from 'd3-scale';
2
2
 
3
+ import { LineChartAxis } from '../../LineChart/models';
4
+
3
5
  interface DsData {
4
6
  ds_color_area: string;
5
7
  ds_color_line: string;
@@ -67,7 +69,11 @@ export interface Xscale {
67
69
  dataTime: Array<TimeValue>;
68
70
  valueWidth: number;
69
71
  }
70
- export interface AxeScale {
72
+ export interface AxeScale
73
+ extends Pick<
74
+ LineChartAxis,
75
+ 'isCenteredZero' | 'scale' | 'scaleLogarithmicBase'
76
+ > {
71
77
  dataLines: Array<Line>;
72
78
  dataTimeSeries: Array<TimeValue>;
73
79
  thresholdUnit?: string;