@centreon/ui 24.10.21 → 24.10.23

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": "24.10.21",
3
+ "version": "24.10.23",
4
4
  "description": "Centreon UI Components",
5
5
  "scripts": {
6
6
  "update:deps": "pnpx npm-check-updates -i --format group",
@@ -24,8 +24,8 @@
24
24
  "url": "git+https://github.com/centreon/centreon.git"
25
25
  },
26
26
  "keywords": [
27
- "centreon",
28
- "react"
27
+ "react",
28
+ "centreon"
29
29
  ],
30
30
  "author": {
31
31
  "name": "centreon@centreon.com"
@@ -61,7 +61,7 @@ const ResponsiveBarChart = ({
61
61
 
62
62
  const { classes, cx } = useTooltipStyles();
63
63
 
64
- const [linesGraph, setLinesGraph] = useState<Array<Line>>(lines);
64
+ const [linesGraph, setLinesGraph] = useState<Array<Line>>(lines || []);
65
65
  const graphSvgRef = useRef<SVGSVGElement | null>(null);
66
66
 
67
67
  const [tooltipData, setTooltipData] = useAtom(tooltipDataAtom);
@@ -74,7 +74,7 @@ const ResponsiveBarChart = ({
74
74
  );
75
75
 
76
76
  const [firstUnit, secondUnit] = getUnits(displayedLines);
77
- const allUnits = getUnits(lines);
77
+ const allUnits = getUnits(lines || []);
78
78
 
79
79
  const { maxLeftAxisCharacters, maxRightAxisCharacters } =
80
80
  useComputeYAxisMaxCharacters({
@@ -147,12 +147,12 @@ const ResponsiveBarChart = ({
147
147
  ]
148
148
  );
149
149
 
150
- const leftScale = yScalesPerUnit[firstUnit];
151
- const rightScale = yScalesPerUnit[secondUnit];
150
+ const leftScale = yScalesPerUnit[firstUnit ?? allUnits[0]];
151
+ const rightScale = yScalesPerUnit[secondUnit ?? allUnits[1]];
152
152
 
153
153
  useEffect(
154
154
  () => {
155
- setLinesGraph(lines);
155
+ setLinesGraph(lines || []);
156
156
  },
157
157
  useDeepCompare([lines])
158
158
  );
@@ -194,8 +194,11 @@ const Chart = ({
194
194
  ]
195
195
  );
196
196
 
197
- const leftScale = yScalesPerUnit[axis?.axisYLeft?.unit ?? firstUnit];
198
- const rightScale = yScalesPerUnit[axis?.axisYRight?.unit ?? secondUnit];
197
+ const fallbackLeftUnit = axis?.axisYLeft?.unit ?? firstUnit ?? allUnits[0];
198
+ const fallbackRightUnit = axis?.axisYRight?.unit ?? secondUnit ?? allUnits[1];
199
+
200
+ const leftScale = yScalesPerUnit[fallbackLeftUnit];
201
+ const rightScale = yScalesPerUnit[fallbackRightUnit];
199
202
 
200
203
  const linesDisplayedAsLine = useMemo(
201
204
  () =>
@@ -1,9 +1,12 @@
1
1
  import dayjs from "dayjs";
2
- import { memo, useRef } from "react";
3
2
  import "dayjs/locale/en";
4
3
  import "dayjs/locale/es";
5
4
  import "dayjs/locale/fr";
6
5
  import "dayjs/locale/pt";
6
+ import { memo, useRef } from "react";
7
+
8
+ import { NoData } from "@centreon/ui";
9
+
7
10
  import localizedFormat from "dayjs/plugin/localizedFormat";
8
11
  import timezonePlugin from "dayjs/plugin/timezone";
9
12
  import utcPlugin from "dayjs/plugin/utc";
@@ -31,6 +34,10 @@ interface Props extends Partial<LineChartProps> {
31
34
  thresholds?: Thresholds;
32
35
  getRef?: (ref: React.RefObject<HTMLDivElement | null>) => void;
33
36
  containerStyle?: string;
37
+ transformMatrix?: {
38
+ fx?: (pointX: number) => number;
39
+ fy?: (pointY: number) => number;
40
+ };
34
41
  }
35
42
 
36
43
  const WrapperChart = ({
@@ -52,8 +59,8 @@ const WrapperChart = ({
52
59
  annotationEvent,
53
60
  legend = {
54
61
  display: true,
55
- mode: 'grid',
56
- placement: 'bottom'
62
+ mode: "grid",
63
+ placement: "bottom",
57
64
  },
58
65
  header,
59
66
  lineStyle,
@@ -62,11 +69,14 @@ const WrapperChart = ({
62
69
  thresholdUnit,
63
70
  limitLegend,
64
71
  getRef,
72
+ transformMatrix,
73
+ additionalLines,
74
+ min,
75
+ max,
76
+ boundariesUnit,
65
77
  ...rest
66
78
  }: Props): JSX.Element | null => {
67
79
  const { classes, cx } = useChartStyles();
68
- const ref = useRef<HTMLDivElement | null>(null);
69
-
70
80
  const { adjustedData } = useChartData({ data, end, start });
71
81
 
72
82
  const containerRef = useRef<HTMLDivElement | null>(null);
@@ -97,13 +107,17 @@ const WrapperChart = ({
97
107
  );
98
108
  }
99
109
 
110
+ if (!adjustedData) {
111
+ return <NoData />;
112
+ }
113
+
100
114
  return (
101
115
  <div
102
116
  ref={combinedRef}
103
117
  className={cx(classes.wrapperContainer, rest?.containerStyle)}
104
118
  >
105
119
  {!responsiveHeight || !data ? (
106
- <Loading height={height || '100%'} width={width} />
120
+ <Loading height={height || "100%"} width={width} />
107
121
  ) : (
108
122
  <Chart
109
123
  annotationEvent={annotationEvent}
@@ -125,6 +139,12 @@ const WrapperChart = ({
125
139
  tooltip={tooltip}
126
140
  width={width || responsiveWidth || 0}
127
141
  zoomPreview={zoomPreview}
142
+ skipIntersectionObserver={rest.skipIntersectionObserver}
143
+ additionalLines={additionalLines}
144
+ transformMatrix={transformMatrix}
145
+ min={min}
146
+ max={max}
147
+ boundariesUnit={boundariesUnit}
128
148
  />
129
149
  )}
130
150
  </div>
@@ -7,3 +7,4 @@ export const labelDowntime = 'Downtime';
7
7
  export const labelMin = 'Min';
8
8
  export const labelMax = 'Max';
9
9
  export const labelAvg = 'Avg';
10
+ export const labelNoDataForThisPeriod = 'No data available for this period';
@@ -31,6 +31,15 @@ interface Props {
31
31
  }
32
32
 
33
33
  const getBoolean = (value) => Boolean(Number(value));
34
+ const defaultDsData = {
35
+ ds_color_line: '#000000',
36
+ ds_filled: false,
37
+ ds_invert: false,
38
+ ds_legend: '',
39
+ ds_order: '0',
40
+ ds_stack: '0',
41
+ ds_transparency: 80
42
+ };
34
43
 
35
44
  const useGraphData = ({ data, end, start }: Props): GraphDataResult => {
36
45
  const adjustedDataRef = useRef<Data>();
@@ -44,9 +53,21 @@ const useGraphData = ({ data, end, start }: Props): GraphDataResult => {
44
53
  return undefined;
45
54
  }
46
55
 
56
+ const metricsWithValidDsData = (data?.metrics || []).map((metric) => ({
57
+ ...metric,
58
+ ds_data: {
59
+ ...defaultDsData,
60
+ ...(metric?.ds_data || {}),
61
+ ds_color_area:
62
+ metric?.ds_data?.ds_color_area ??
63
+ metric?.ds_data?.ds_color_line ??
64
+ defaultDsData.ds_color_line
65
+ }
66
+ }));
67
+
47
68
  const metricsGroupedByColor = groupBy(
48
- (metric) => metric.ds_data.ds_color_line
49
- )(data?.metrics || []);
69
+ (metric) => metric.ds_data?.ds_color_line || '#000000'
70
+ )(metricsWithValidDsData);
50
71
 
51
72
  const newMetrics = Object.entries(metricsGroupedByColor).map(
52
73
  ([color, value]) => {
@@ -59,7 +59,7 @@ const Axes = ({
59
59
  const formatAxisTick = (tick): string =>
60
60
  format({ date: new Date(tick), formatString: tickFormat });
61
61
 
62
- const displayAxisRight = !isNil(secondUnit);
62
+ const displayAxisRight = !isNil(secondUnit) && !isNil(rightScale);
63
63
 
64
64
  const AxisBottom = isHorizontal ? Axis.AxisBottom : Axis.AxisLeft;
65
65
  const AxisLeft = isHorizontal ? Axis.AxisLeft : Axis.AxisTop;
@@ -49,6 +49,11 @@ const ChartSvgWrapper = ({
49
49
  hasSecondUnit
50
50
  }: Props): JSX.Element => {
51
51
  const isHorizontal = equals(orientation, 'horizontal');
52
+ const hasValidLeftScale = Boolean(leftScale);
53
+ const hasValidXScale = Boolean(xScale);
54
+ const canRenderAxes = hasValidLeftScale && hasValidXScale;
55
+ const canRenderGridRows = Boolean(isHorizontal ? leftScale : xScale);
56
+ const canRenderGridColumns = Boolean(isHorizontal ? xScale : leftScale);
52
57
 
53
58
  return (
54
59
  <svg
@@ -64,7 +69,7 @@ const ChartSvgWrapper = ({
64
69
  }
65
70
  top={margin.top}
66
71
  >
67
- {showGridLines && (
72
+ {showGridLines && (canRenderGridRows || canRenderGridColumns) && (
68
73
  <Grids
69
74
  gridLinesType={gridLinesType}
70
75
  height={graphHeight - margin.top}
@@ -73,21 +78,23 @@ const ChartSvgWrapper = ({
73
78
  xScale={isHorizontal ? xScale : leftScale}
74
79
  />
75
80
  )}
76
- <Axes
77
- allUnits={allUnits}
78
- data={{
79
- baseAxis: base,
80
- lines: displayedLines,
81
- timeSeries,
82
- ...axis
83
- }}
84
- height={graphHeight}
85
- leftScale={leftScale}
86
- orientation={orientation}
87
- rightScale={rightScale}
88
- width={graphWidth}
89
- xScale={xScale}
90
- />
81
+ {canRenderAxes && (
82
+ <Axes
83
+ allUnits={allUnits}
84
+ data={{
85
+ baseAxis: base,
86
+ lines: displayedLines,
87
+ timeSeries,
88
+ ...axis
89
+ }}
90
+ height={graphHeight}
91
+ leftScale={leftScale}
92
+ orientation={orientation}
93
+ rightScale={rightScale}
94
+ width={graphWidth}
95
+ xScale={xScale}
96
+ />
97
+ )}
91
98
  {children}
92
99
  </Group.Group>
93
100
  </svg>
@@ -0,0 +1,18 @@
1
+ import { Typography } from '@mui/material';
2
+
3
+ import { useTranslation } from 'react-i18next';
4
+
5
+ import { labelNoDataForThisPeriod } from '../../Chart/translatedLabels';
6
+
7
+ const NoData = () => {
8
+ const { t } = useTranslation();
9
+ return (
10
+ <div className={'flex items-center justify-center h-full'}>
11
+ <Typography align="center" variant="body1">
12
+ {t(labelNoDataForThisPeriod)}
13
+ </Typography>
14
+ </div>
15
+ );
16
+ };
17
+
18
+ export default NoData;
@@ -8,9 +8,9 @@ import { ChartAxis } from '../../Chart/models';
8
8
 
9
9
  interface Props extends Pick<ChartAxis, 'gridLinesType'> {
10
10
  height: number;
11
- leftScale: ScaleLinear<number, number>;
11
+ leftScale?: ScaleLinear<number, number>;
12
12
  width: number;
13
- xScale: ScaleLinear<number, number>;
13
+ xScale?: ScaleLinear<number, number>;
14
14
  }
15
15
 
16
16
  const Grids = ({
@@ -31,10 +31,10 @@ const Grids = ({
31
31
 
32
32
  return (
33
33
  <g>
34
- {displayRows && (
34
+ {displayRows && leftScale && (
35
35
  <Grid.GridRows height={height} scale={leftScale} width={width} />
36
36
  )}
37
- {displayColumns && (
37
+ {displayColumns && xScale && (
38
38
  <Grid.GridColumns height={height} scale={xScale} width={width} />
39
39
  )}
40
40
  </g>
@@ -53,6 +53,17 @@ interface TimeTickWithMetrics {
53
53
  timeTick: string;
54
54
  }
55
55
 
56
+ const defaultDsData = {
57
+ ds_color_line: '#000000',
58
+ ds_filled: false,
59
+ ds_invert: false,
60
+ ds_legend: '',
61
+ ds_order: '0',
62
+ ds_stack: '0',
63
+ ds_stack_key: null,
64
+ ds_transparency: 80
65
+ };
66
+
56
67
  const toTimeTickWithMetrics = ({
57
68
  metrics,
58
69
  times
@@ -119,29 +130,39 @@ const toLine = ({
119
130
  maximum_value,
120
131
  metric_id,
121
132
  displayAs
122
- }: Metric): Line => ({
123
- areaColor: ds_data.ds_color_area,
124
- average_value,
125
- color: ds_data.ds_color_line,
126
- display: true,
127
- displayAs,
128
- filled: ds_data.ds_filled,
129
- highlight: undefined,
130
- invert: ds_data.ds_invert,
131
- legend: ds_data.ds_legend,
132
- lineColor: ds_data.ds_color_line,
133
- maximum_value,
134
- metric,
135
- metric_id,
136
- minimum_value,
137
- name: legend,
138
- stackOrder:
139
- equals(ds_data.ds_stack, '1') || equals(ds_data.ds_stack, true)
140
- ? Number.parseInt(ds_data.ds_order || '0', 10)
141
- : null,
142
- transparency: ds_data.ds_transparency,
143
- unit
144
- });
133
+ }: Metric): Line => {
134
+ const safeDsData = {
135
+ ...defaultDsData,
136
+ ...(ds_data || {}),
137
+ ds_color_area:
138
+ ds_data?.ds_color_area ?? ds_data?.ds_color_line ?? defaultDsData.ds_color_line
139
+ };
140
+
141
+ return {
142
+ areaColor: safeDsData.ds_color_area,
143
+ average_value,
144
+ color: safeDsData.ds_color_line,
145
+ display: true,
146
+ displayAs,
147
+ filled: safeDsData.ds_filled,
148
+ highlight: undefined,
149
+ invert: safeDsData.ds_invert,
150
+ legend: safeDsData.ds_legend,
151
+ lineColor: safeDsData.ds_color_line,
152
+ maximum_value,
153
+ metric,
154
+ metric_id,
155
+ minimum_value,
156
+ name: legend,
157
+ stackKey: safeDsData.ds_stack_key || null,
158
+ stackOrder:
159
+ equals(safeDsData.ds_stack, '1') || equals(safeDsData.ds_stack, true)
160
+ ? Number.parseInt(safeDsData.ds_order || '0', 10)
161
+ : null,
162
+ transparency: safeDsData.ds_transparency,
163
+ unit
164
+ };
165
+ };
145
166
 
146
167
  const getLineData = (graphData: LineChartData): Array<Line> =>
147
168
  map(toLine, graphData.metrics);
@@ -9,7 +9,8 @@ interface DsData {
9
9
  ds_invert: string | null;
10
10
  ds_legend: string | null;
11
11
  ds_order: string | null;
12
- ds_stack: string | null;
12
+ ds_stack: string | boolean | null;
13
+ ds_stack_key?: string | null;
13
14
  ds_transparency: number;
14
15
  }
15
16
 
@@ -56,6 +57,7 @@ export interface Line {
56
57
  minimum_value: number | null;
57
58
  name: string;
58
59
  stackOrder: number | null;
60
+ stackKey: string | null;
59
61
  transparency: number;
60
62
  unit: string;
61
63
  }
@@ -1,20 +1,20 @@
1
- export type { ParentSizeProps } from '@visx/responsive/lib/components/ParentSize';
2
- export { default as LineChart } from './Chart';
3
- export { default as ThresholdLines } from './Chart/BasicComponents/Lines/Threshold';
4
- export { default as useLineChartData } from './Chart/useChartData';
5
- export { default as BarChart } from './BarChart/BarChart';
6
- export { Gauge } from './Gauge';
7
- export { SingleBar } from './SingleBar';
8
- export { Text as GraphText } from './Text';
9
- export { default as Header } from './common/BaseChart/Header';
10
-
11
- export { HeatMap } from './HeatMap';
12
- export { BarStack } from './BarStack';
13
- export { PieChart } from './PieChart';
14
- export { Timeline } from './Timeline';
15
- export * from './Tree';
16
- export type { LineChartData, Threshold, Thresholds } from './common/models';
17
- export * from './common/timeSeries';
18
- export type { Metric } from './common/timeSeries/models';
19
- export * from './Chart/models';
20
- export * from './PieChart/models';
1
+ export type { ParentSizeProps } from "@visx/responsive/lib/components/ParentSize";
2
+ export { default as BarChart } from "./BarChart/BarChart";
3
+ export { BarStack } from "./BarStack";
4
+ export { default as LineChart } from "./Chart";
5
+ export { default as ThresholdLines } from "./Chart/BasicComponents/Lines/Threshold";
6
+ export * from "./Chart/models";
7
+ export { default as useLineChartData } from "./Chart/useChartData";
8
+ export { default as Header } from "./common/BaseChart/Header";
9
+ export { default as NoData } from "./common/Error/NoData";
10
+ export type { LineChartData, Threshold, Thresholds } from "./common/models";
11
+ export * from "./common/timeSeries";
12
+ export type { Metric } from "./common/timeSeries/models";
13
+ export { Gauge } from "./Gauge";
14
+ export { HeatMap } from "./HeatMap";
15
+ export { PieChart } from "./PieChart";
16
+ export * from "./PieChart/models";
17
+ export { SingleBar } from "./SingleBar";
18
+ export { Text as GraphText } from "./Text";
19
+ export { Timeline } from "./Timeline";
20
+ export * from "./Tree";