@centreon/ui 25.3.4 → 25.4.0-MON-191119-npm-develop.0

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 (176) hide show
  1. package/package.json +25 -11
  2. package/public/mockServiceWorker.js +8 -31
  3. package/src/Button/Save/index.stories.tsx +1 -0
  4. package/src/Checkbox/Checkbox.tsx +3 -1
  5. package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
  6. package/src/Colors/index.tsx +1 -1
  7. package/src/Dashboard/Dashboard.styles.ts +1 -1
  8. package/src/Dashboard/Layout.tsx +1 -1
  9. package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
  10. package/src/Form/CollapsibleGroup.tsx +13 -13
  11. package/src/Form/Form.cypress.spec.tsx +137 -2
  12. package/src/Form/Form.stories.tsx +11 -31
  13. package/src/Form/Form.tsx +2 -0
  14. package/src/Form/Inputs/Checkbox.tsx +3 -2
  15. package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
  16. package/src/Form/Inputs/Grid.tsx +18 -29
  17. package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
  18. package/src/Form/Inputs/Text.tsx +1 -0
  19. package/src/Form/Inputs/index.tsx +31 -24
  20. package/src/Form/Inputs/models.ts +8 -1
  21. package/src/Form/Section/FormSection.tsx +34 -0
  22. package/src/Form/Section/PanelTabs.tsx +13 -0
  23. package/src/Form/Section/navigateToSection.ts +9 -0
  24. package/src/Form/storiesData.tsx +14 -4
  25. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
  26. package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
  27. package/src/Graph/BarChart/BarChart.tsx +56 -32
  28. package/src/Graph/BarChart/BarGroup.tsx +22 -32
  29. package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
  30. package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
  31. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
  32. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
  33. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
  34. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
  35. package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
  36. package/src/Graph/Chart/Chart.stories.tsx +84 -1
  37. package/src/Graph/Chart/Chart.tsx +17 -4
  38. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
  39. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
  40. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
  41. package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
  42. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
  43. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
  44. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
  45. package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
  46. package/src/Graph/Chart/Legend/index.tsx +26 -2
  47. package/src/Graph/Chart/index.tsx +45 -45
  48. package/src/Graph/Chart/models.ts +8 -0
  49. package/src/Graph/Chart/useChartData.ts +14 -2
  50. package/src/Graph/Gauge/Gauge.tsx +18 -14
  51. package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
  52. package/src/Graph/Gauge/useResizeObserver.ts +68 -0
  53. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
  54. package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
  55. package/src/Graph/SingleBar/models.ts +1 -0
  56. package/src/Graph/Text/Text.styles.ts +2 -2
  57. package/src/Graph/Text/Text.tsx +23 -10
  58. package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
  59. package/src/Graph/Timeline/Timeline.tsx +21 -4
  60. package/src/Graph/Tree/Links.tsx +2 -2
  61. package/src/Graph/Tree/Tree.tsx +2 -2
  62. package/src/Graph/Tree/constants.ts +1 -1
  63. package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
  64. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
  65. package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
  66. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
  67. package/src/Graph/common/timeSeries/index.test.ts +20 -0
  68. package/src/Graph/common/timeSeries/index.ts +225 -44
  69. package/src/Graph/common/timeSeries/models.ts +6 -2
  70. package/src/Graph/common/utils.ts +45 -12
  71. package/src/Graph/index.ts +3 -1
  72. package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
  73. package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
  74. package/src/Icon/RegexIcon.tsx +20 -0
  75. package/src/Icon/index.ts +1 -0
  76. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
  77. package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
  78. package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
  79. package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
  80. package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
  81. package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
  82. package/src/InputField/Select/Autocomplete/index.tsx +28 -17
  83. package/src/InputField/Select/Option.tsx +3 -3
  84. package/src/InputField/Select/index.tsx +4 -0
  85. package/src/InputField/Text/index.tsx +4 -2
  86. package/src/InputField/translatedLabels.ts +4 -0
  87. package/src/Listing/ActionBar/Pagination.tsx +10 -23
  88. package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
  89. package/src/Listing/ActionBar/index.tsx +1 -1
  90. package/src/Listing/Cell/DataCell.tsx +6 -6
  91. package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
  92. package/src/Listing/Cell/index.tsx +37 -76
  93. package/src/Listing/Checkbox.tsx +8 -20
  94. package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
  95. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
  96. package/src/Listing/Header/ListingHeader.tsx +2 -5
  97. package/src/Listing/Header/_internals/Label.tsx +1 -17
  98. package/src/Listing/Row/EmptyRow.tsx +2 -6
  99. package/src/Listing/Row/Row.tsx +7 -36
  100. package/src/Listing/index.stories.tsx +1 -0
  101. package/src/Listing/index.tsx +26 -26
  102. package/src/Listing/useStyleTable.ts +58 -32
  103. package/src/ListingPage/index.stories.tsx +1 -0
  104. package/src/Module/index.tsx +8 -2
  105. package/src/MultiSelectEntries/index.stories.tsx +1 -0
  106. package/src/MultiSelectEntries/index.tsx +1 -1
  107. package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
  108. package/src/Pagination/Pagination.stories.tsx +46 -0
  109. package/src/Pagination/Pagination.styles.ts +56 -0
  110. package/src/Pagination/Pagination.tsx +146 -0
  111. package/src/Pagination/index.ts +3 -0
  112. package/src/Pagination/utils.ts +7 -0
  113. package/src/SortableItems/index.stories.tsx +2 -2
  114. package/src/StoryBookThemeProvider/index.tsx +3 -1
  115. package/src/ThemeProvider/base.css +49 -0
  116. package/src/ThemeProvider/index.tsx +21 -47
  117. package/src/ThemeProvider/palettes.ts +3 -1
  118. package/src/ThemeProvider/tailwindcss.css +230 -0
  119. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
  120. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
  121. package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
  122. package/src/api/models.ts +9 -0
  123. package/src/api/useGraphQuery/index.ts +108 -12
  124. package/src/components/Avatar/Avatar.stories.tsx +1 -0
  125. package/src/components/Button/Button.module.css +38 -0
  126. package/src/components/Button/Button.stories.tsx +25 -0
  127. package/src/components/Button/Button.tsx +2 -5
  128. package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
  129. package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
  130. package/src/components/DataTable/DataTable.stories.tsx +1 -0
  131. package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
  132. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
  133. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
  134. package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
  135. package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
  136. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
  137. package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
  138. package/src/components/Form/FormActions.tsx +21 -12
  139. package/src/components/Layout/AreaIndicator.tsx +4 -6
  140. package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
  141. package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
  142. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
  143. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
  144. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
  145. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
  146. package/src/components/Menu/Button/MenuButton.tsx +6 -6
  147. package/src/components/Menu/MenuDivider.tsx +1 -5
  148. package/src/components/Menu/MenuItem.tsx +1 -5
  149. package/src/components/Menu/MenuItems.tsx +5 -4
  150. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
  151. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
  152. package/src/components/Modal/Modal.stories.tsx +21 -0
  153. package/src/components/Modal/Modal.styles.ts +1 -19
  154. package/src/components/Modal/Modal.tsx +1 -1
  155. package/src/components/Modal/ModalBody.tsx +6 -4
  156. package/src/components/Modal/ModalHeader.tsx +9 -5
  157. package/src/components/Modal/modal.module.css +16 -0
  158. package/src/components/Tabs/Tab.styles.ts +0 -6
  159. package/src/components/Tabs/Tabs.tsx +37 -15
  160. package/src/index.ts +3 -0
  161. package/src/queryParameters/url/index.ts +7 -2
  162. package/src/utils/index.ts +1 -0
  163. package/src/utils/useLocale/index.ts +9 -0
  164. package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
  165. package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
  166. package/src/utils/usePluralizedTranslation.ts +2 -3
  167. package/src/Listing/Cell/DataCell.styles.ts +0 -27
  168. package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
  169. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
  170. package/src/Listing/Header/ListingHeader.styles.ts +0 -16
  171. package/src/Listing/Listing.styles.ts +0 -78
  172. package/src/Listing/Row/EmptyRow.styles.ts +0 -14
  173. package/src/components/Button/Button.styles.ts +0 -44
  174. package/src/components/Layout/AreaIndicator.styles.ts +0 -33
  175. package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
  176. package/src/components/Menu/Menu.styles.ts +0 -68
@@ -1,12 +1,13 @@
1
1
  import { scaleBand, scaleOrdinal } from '@visx/scale';
2
2
  import { BarGroupHorizontal, BarGroup as VisxBarGroup } from '@visx/shape';
3
3
  import { ScaleLinear } from 'd3-scale';
4
- import { difference, equals, keys, omit, pick, pluck, uniq } from 'ramda';
4
+ import { difference, equals, keys, omit, pick } from 'ramda';
5
5
  import { memo, useMemo } from 'react';
6
6
 
7
7
  import { useDeepMemo } from '../../utils';
8
8
  import {
9
9
  getSortedStackedLines,
10
+ getStackedLinesTimeSeriesPerStackAndUnit,
10
11
  getTime,
11
12
  getTimeSeriesForLines,
12
13
  getUnits
@@ -54,41 +55,18 @@ const BarGroup = ({
54
55
  );
55
56
 
56
57
  const stackedLines = getSortedStackedLines(lines);
57
- const stackedUnits = uniq(pluck('unit', stackedLines));
58
58
  const notStackedLines = difference(lines, stackedLines);
59
-
60
- const stackedKeys = stackedUnits.reduce(
61
- (acc, unit) => ({
62
- ...acc,
63
- [`stacked-${unit}`]: null
64
- }),
65
- {}
66
- );
67
- const stackedLinesTimeSeriesPerUnit = stackedUnits.reduce(
68
- (acc, stackedUnit) => {
69
- const relatedLines = stackedLines.filter(({ unit }) =>
70
- equals(unit, stackedUnit)
71
- );
72
-
73
- return {
74
- ...acc,
75
- [stackedUnit]: {
76
- lines: relatedLines,
77
- timeSeries: getTimeSeriesForLines({
78
- lines: relatedLines,
79
- timeSeries
80
- })
81
- }
82
- };
83
- },
84
- {}
85
- );
86
-
87
59
  const notStackedTimeSeries = getTimeSeriesForLines({
88
60
  lines: notStackedLines,
89
61
  timeSeries
90
62
  });
91
63
 
64
+ const { stackedLinesTimeSeriesPerStackKeyAndUnit, stackedKeys } = useMemo(
65
+ () =>
66
+ getStackedLinesTimeSeriesPerStackAndUnit({ stackedLines, timeSeries }),
67
+ [stackedLines, timeSeries]
68
+ );
69
+
92
70
  const normalizedTimeSeries = notStackedTimeSeries.map((timeSerie) => ({
93
71
  ...timeSerie,
94
72
  ...stackedKeys
@@ -98,6 +76,16 @@ const BarGroup = ({
98
76
  deps: [normalizedTimeSeries],
99
77
  variable: keys(omit(['timeTick'], normalizedTimeSeries[0]))
100
78
  });
79
+ const sortedLineKeys = lineKeys.sort((lineKeyA: string, lineKeyB: string) => {
80
+ if (lineKeyA.startsWith('stacked-') && !lineKeyB.startsWith('stacked-')) {
81
+ return true;
82
+ }
83
+
84
+ const lineKeysA = lineKeyA.split('-');
85
+ const lineKeysB = lineKeyB.split('-');
86
+
87
+ return lineKeysA[2] === '' && lineKeysB[2] !== '';
88
+ });
101
89
  const colors = useDeepMemo({
102
90
  deps: [lineKeys, lines],
103
91
  variable: lineKeys.map((key) => {
@@ -154,7 +142,7 @@ const BarGroup = ({
154
142
  color={colorScale}
155
143
  data={normalizedTimeSeries}
156
144
  height={size}
157
- keys={lineKeys}
145
+ keys={sortedLineKeys}
158
146
  {...barComponentBaseProps}
159
147
  >
160
148
  {(barGroups) =>
@@ -164,7 +152,9 @@ const BarGroup = ({
164
152
  key={`bar-group-${barGroup.index}-${barGroup.x0}`}
165
153
  barGroup={barGroup}
166
154
  barStyle={barStyle}
167
- stackedLinesTimeSeriesPerUnit={stackedLinesTimeSeriesPerUnit}
155
+ stackedLinesTimeSeriesPerStackKeyAndUnit={
156
+ stackedLinesTimeSeriesPerStackKeyAndUnit
157
+ }
168
158
  notStackedTimeSeries={notStackedTimeSeries}
169
159
  notStackedLines={notStackedLines}
170
160
  isTooltipHidden={isTooltipHidden}
@@ -12,7 +12,7 @@ interface Props {
12
12
  isTooltipHidden: boolean;
13
13
  barStyle: BarStyle;
14
14
  yScalesPerUnit: Record<string, ScaleLinear<number, number>>;
15
- stackedLinesTimeSeriesPerUnit: Record<
15
+ stackedLinesTimeSeriesPerStackKeyAndUnit: Record<
16
16
  string,
17
17
  { lines: Array<Line>; timeSeries: Array<TimeValue> }
18
18
  >;
@@ -25,7 +25,7 @@ interface Props {
25
25
 
26
26
  const MemoizedGroup = ({
27
27
  barGroup,
28
- stackedLinesTimeSeriesPerUnit,
28
+ stackedLinesTimeSeriesPerStackKeyAndUnit,
29
29
  notStackedLines,
30
30
  notStackedTimeSeries,
31
31
  isHorizontal,
@@ -38,9 +38,7 @@ const MemoizedGroup = ({
38
38
  const hasEmptyValues = barGroup.bars.every(({ key, value }) => {
39
39
  if (key.startsWith('stacked-')) {
40
40
  const timeValueBar =
41
- stackedLinesTimeSeriesPerUnit[key.replace('stacked-', '')].timeSeries[
42
- barIndex
43
- ];
41
+ stackedLinesTimeSeriesPerStackKeyAndUnit[key].timeSeries[barIndex];
44
42
 
45
43
  return Object.values(omit(['timeTick'], timeValueBar)).every(
46
44
  (value) => !value
@@ -59,13 +57,12 @@ const MemoizedGroup = ({
59
57
  {barGroup.bars.map((bar) => {
60
58
  const isStackedBar = bar.key.startsWith('stacked-');
61
59
  const linesBar = isStackedBar
62
- ? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')].lines
60
+ ? stackedLinesTimeSeriesPerStackKeyAndUnit[bar.key].lines
63
61
  : (notStackedLines.find(({ metric_id }) =>
64
62
  equals(metric_id, Number(bar.key))
65
63
  ) as Line);
66
64
  const timeSeriesBar = isStackedBar
67
- ? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')]
68
- .timeSeries
65
+ ? stackedLinesTimeSeriesPerStackKeyAndUnit[bar.key].timeSeries
69
66
  : notStackedTimeSeries.map((timeSerie) => ({
70
67
  timeTick: timeSerie.timeTick,
71
68
  [bar.key]: timeSerie[Number(bar.key)]
@@ -82,7 +79,7 @@ const MemoizedGroup = ({
82
79
  isTooltipHidden={isTooltipHidden}
83
80
  lines={linesBar as Array<Line>}
84
81
  timeSeries={timeSeriesBar}
85
- yScale={yScalesPerUnit[bar.key.replace('stacked-', '')]}
82
+ yScale={yScalesPerUnit[bar.key.split('-')[1] || undefined]}
86
83
  neutralValue={neutralValue}
87
84
  />
88
85
  ) : (
@@ -110,8 +107,8 @@ export default memo(
110
107
  (prevProps, nextProps) =>
111
108
  equals(prevProps.barGroup, nextProps.barGroup) &&
112
109
  equals(
113
- prevProps.stackedLinesTimeSeriesPerUnit,
114
- nextProps.stackedLinesTimeSeriesPerUnit
110
+ prevProps.stackedLinesTimeSeriesPerStackKeyAndUnit,
111
+ nextProps.stackedLinesTimeSeriesPerStackKeyAndUnit
115
112
  ) &&
116
113
  equals(prevProps.notStackedLines, nextProps.notStackedLines) &&
117
114
  equals(prevProps.notStackedTimeSeries, nextProps.notStackedTimeSeries) &&
@@ -1,12 +1,21 @@
1
- import { MutableRefObject, useEffect, useMemo, useRef, useState } from 'react';
1
+ import {
2
+ MutableRefObject,
3
+ ReactElement,
4
+ useEffect,
5
+ useMemo,
6
+ useRef,
7
+ useState
8
+ } from 'react';
2
9
 
3
- import { useAtom } from 'jotai';
10
+ import { useAtom, useAtomValue } from 'jotai';
4
11
  import { equals, flatten, gte, has, isNil, pluck } from 'ramda';
5
12
 
6
13
  import { Skeleton } from '@mui/material';
7
14
 
8
15
  import { Tooltip } from '../../components';
9
16
  import { useDeepCompare } from '../../utils';
17
+ import InteractionWithGraph from '../Chart/InteractiveComponents';
18
+ import { applyingZoomAtomAtom } from '../Chart/InteractiveComponents/ZoomPreview/zoomPreviewAtoms';
10
19
  import { margin } from '../Chart/common';
11
20
  import { Data, LineChartProps } from '../Chart/models';
12
21
  import { useIntersection } from '../Chart/useChartIntersection';
@@ -18,18 +27,29 @@ import Thresholds from '../common/Thresholds/Thresholds';
18
27
  import { Thresholds as ThresholdsModel } from '../common/models';
19
28
  import {
20
29
  getUnits,
30
+ getXScale,
21
31
  getXScaleBand,
22
32
  getYScalePerUnit
23
33
  } from '../common/timeSeries';
24
34
  import { Line } from '../common/timeSeries/models';
25
35
  import { useTooltipStyles } from '../common/useTooltipStyles';
36
+ import { computPixelsToShiftMouse } from '../common/utils';
26
37
  import BarGroup from './BarGroup';
27
38
  import BarChartTooltip from './Tooltip/BarChartTooltip';
28
39
  import { tooltipDataAtom } from './atoms';
29
40
  import { BarStyle } from './models';
30
41
 
31
42
  interface Props
32
- extends Pick<LineChartProps, 'tooltip' | 'legend' | 'axis' | 'header'> {
43
+ extends Pick<
44
+ LineChartProps,
45
+ | 'tooltip'
46
+ | 'legend'
47
+ | 'axis'
48
+ | 'header'
49
+ | 'zoomPreview'
50
+ | 'timeShiftZones'
51
+ | 'annotationEvent'
52
+ > {
33
53
  barStyle: BarStyle;
34
54
  graphData: Data;
35
55
  graphRef: MutableRefObject<HTMLDivElement | null>;
@@ -40,6 +60,11 @@ interface Props
40
60
  thresholds?: ThresholdsModel;
41
61
  width: number;
42
62
  skipIntersectionObserver?: boolean;
63
+ min?: number;
64
+ max?: number;
65
+ boundariesUnit?: string;
66
+ start: string;
67
+ end: string;
43
68
  }
44
69
 
45
70
  const ResponsiveBarChart = ({
@@ -56,8 +81,16 @@ const ResponsiveBarChart = ({
56
81
  orientation,
57
82
  tooltip,
58
83
  barStyle,
59
- skipIntersectionObserver
60
- }: Props): JSX.Element => {
84
+ skipIntersectionObserver,
85
+ min,
86
+ max,
87
+ boundariesUnit,
88
+ start,
89
+ end,
90
+ timeShiftZones,
91
+ zoomPreview,
92
+ annotationEvent
93
+ }: Props): ReactElement => {
61
94
  const { title, timeSeries, baseAxis, lines } = graphData || {};
62
95
 
63
96
  const { classes, cx } = useTooltipStyles();
@@ -66,6 +99,7 @@ const ResponsiveBarChart = ({
66
99
  const graphSvgRef = useRef<SVGSVGElement | null>(null);
67
100
 
68
101
  const [tooltipData, setTooltipData] = useAtom(tooltipDataAtom);
102
+ const isApplyingZoom = useAtomValue(applyingZoomAtomAtom);
69
103
 
70
104
  const { isInViewport } = useIntersection({ element: graphRef?.current });
71
105
 
@@ -119,6 +153,15 @@ const ResponsiveBarChart = ({
119
153
  [timeSeries, graphWidth, isHorizontal, graphHeight]
120
154
  );
121
155
 
156
+ const xScaleLinear = useMemo(
157
+ () =>
158
+ getXScale({
159
+ dataTime: timeSeries,
160
+ valueWidth: isHorizontal ? graphWidth : graphHeight - 30
161
+ }),
162
+ [timeSeries, graphWidth, isHorizontal, graphHeight]
163
+ );
164
+
122
165
  const yScalesPerUnit = useMemo(
123
166
  () =>
124
167
  getYScalePerUnit({
@@ -131,7 +174,11 @@ const ResponsiveBarChart = ({
131
174
  thresholdUnit,
132
175
  thresholds: (thresholds?.enabled && thresholdValues) || [],
133
176
  valueGraphHeight:
134
- (isHorizontal ? graphHeight : graphWidth) - margin.bottom
177
+ (isHorizontal ? graphHeight : graphWidth) - margin.bottom,
178
+ min,
179
+ max,
180
+ isBarChart: true,
181
+ boundariesUnit
135
182
  }),
136
183
  [
137
184
  displayedLines,
@@ -148,6 +195,7 @@ const ResponsiveBarChart = ({
148
195
 
149
196
  const leftScale = yScalesPerUnit[firstUnit];
150
197
  const rightScale = yScalesPerUnit[secondUnit];
198
+ const pixelsToShift = computPixelsToShiftMouse(xScaleLinear);
151
199
 
152
200
  useEffect(
153
201
  () => {
@@ -186,7 +234,8 @@ const ResponsiveBarChart = ({
186
234
  displayLegend,
187
235
  mode: legend?.mode,
188
236
  placement: legend?.placement,
189
- renderExtraComponent: legend?.renderExtraComponent
237
+ renderExtraComponent: legend?.renderExtraComponent,
238
+ secondaryClick: legend?.secondaryClick
190
239
  }}
191
240
  legendRef={legendRef}
192
241
  limitLegend={limitLegend}
@@ -233,33 +282,97 @@ const ResponsiveBarChart = ({
233
282
  hasSecondUnit={Boolean(secondUnit)}
234
283
  >
235
284
  <>
236
- <BarGroup
237
- barStyle={barStyle}
238
- isTooltipHidden={isTooltipHidden}
239
- lines={displayedLines}
240
- orientation={isHorizontal ? 'horizontal' : 'vertical'}
241
- size={isHorizontal ? graphHeight - margin.top - 5 : graphWidth}
242
- timeSeries={timeSeries}
243
- xScale={xScale}
244
- yScalesPerUnit={yScalesPerUnit}
245
- scaleType={axis?.scale}
246
- />
247
- {thresholds?.enabled && (
248
- <Thresholds
249
- displayedLines={displayedLines}
250
- hideTooltip={() => setTooltipData(null)}
251
- isHorizontal={isHorizontal}
252
- showTooltip={({ tooltipData: thresholdLabel }) =>
253
- setTooltipData({
254
- thresholdLabel
255
- })
256
- }
257
- thresholdUnit={thresholdUnit}
258
- thresholds={thresholds as ThresholdsModel}
259
- width={isHorizontal ? graphWidth : graphHeight - margin.top}
260
- yScalesPerUnit={yScalesPerUnit}
285
+ {isApplyingZoom && (
286
+ <>
287
+ <BarGroup
288
+ barStyle={barStyle}
289
+ isTooltipHidden={isTooltipHidden}
290
+ lines={displayedLines}
291
+ orientation={isHorizontal ? 'horizontal' : 'vertical'}
292
+ size={
293
+ isHorizontal ? graphHeight - margin.top - 5 : graphWidth
294
+ }
295
+ timeSeries={timeSeries}
296
+ xScale={xScale}
297
+ yScalesPerUnit={yScalesPerUnit}
298
+ scaleType={axis?.scale}
299
+ />
300
+ {thresholds?.enabled && (
301
+ <Thresholds
302
+ displayedLines={displayedLines}
303
+ hideTooltip={() => setTooltipData(null)}
304
+ isHorizontal={isHorizontal}
305
+ showTooltip={({ tooltipData: thresholdLabel }) =>
306
+ setTooltipData({
307
+ thresholdLabel
308
+ })
309
+ }
310
+ thresholdUnit={thresholdUnit}
311
+ thresholds={thresholds as ThresholdsModel}
312
+ width={
313
+ isHorizontal ? graphWidth : graphHeight - margin.top
314
+ }
315
+ yScalesPerUnit={yScalesPerUnit}
316
+ />
317
+ )}
318
+ </>
319
+ )}
320
+ {isHorizontal && (
321
+ <InteractionWithGraph
322
+ additionalZoomMargin={pixelsToShift}
323
+ maxLeftAxisCharacters={maxLeftAxisCharacters}
324
+ commonData={{
325
+ graphHeight,
326
+ graphSvgRef,
327
+ graphWidth,
328
+ lines,
329
+ xScale: xScaleLinear,
330
+ timeSeries,
331
+ yScalesPerUnit
332
+ }}
333
+ annotationData={{ ...annotationEvent }}
334
+ zoomData={{ ...zoomPreview }}
335
+ timeShiftZonesData={{
336
+ ...timeShiftZones,
337
+ graphInterval: { start, end }
338
+ }}
261
339
  />
262
340
  )}
341
+ {!isApplyingZoom && (
342
+ <>
343
+ <BarGroup
344
+ barStyle={barStyle}
345
+ isTooltipHidden={isTooltipHidden}
346
+ lines={displayedLines}
347
+ orientation={isHorizontal ? 'horizontal' : 'vertical'}
348
+ size={
349
+ isHorizontal ? graphHeight - margin.top - 5 : graphWidth
350
+ }
351
+ timeSeries={timeSeries}
352
+ xScale={xScale}
353
+ yScalesPerUnit={yScalesPerUnit}
354
+ scaleType={axis?.scale}
355
+ />
356
+ {thresholds?.enabled && (
357
+ <Thresholds
358
+ displayedLines={displayedLines}
359
+ hideTooltip={() => setTooltipData(null)}
360
+ isHorizontal={isHorizontal}
361
+ showTooltip={({ tooltipData: thresholdLabel }) =>
362
+ setTooltipData({
363
+ thresholdLabel
364
+ })
365
+ }
366
+ thresholdUnit={thresholdUnit}
367
+ thresholds={thresholds as ThresholdsModel}
368
+ width={
369
+ isHorizontal ? graphWidth : graphHeight - margin.top
370
+ }
371
+ yScalesPerUnit={yScalesPerUnit}
372
+ />
373
+ )}
374
+ </>
375
+ )}
263
376
  </>
264
377
  </ChartSvgWrapper>
265
378
  </div>
@@ -36,7 +36,7 @@ const BarChartTooltip = ({
36
36
  sortOrder
37
37
  }: Props): JSX.Element | null => {
38
38
  const { classes } = useBarChartTooltipStyles();
39
- const { toDate, toTime } = useLocaleDateTimeFormat();
39
+ const { format } = useLocaleDateTimeFormat();
40
40
  const tooltipData = useAtomValue(tooltipDataAtom);
41
41
 
42
42
  if (isNil(tooltipData)) {
@@ -48,7 +48,7 @@ const BarChartTooltip = ({
48
48
  }
49
49
 
50
50
  const date = timeSeries[tooltipData.index].timeTick;
51
- const formattedDateTime = `${toDate(date)} / ${toTime(date)}`;
51
+ const formattedDateTime = format({ date, formatString: 'L LTS' });
52
52
 
53
53
  const isSingleMode = equals(mode, 'single');
54
54
 
@@ -43,6 +43,8 @@ interface Props {
43
43
  xScale: ScaleTime<number, number>;
44
44
  yScale: ScaleLinear<number, number>;
45
45
  lineStyle: LineStyle | Array<LineStyle>;
46
+ hasSecondUnit?: boolean;
47
+ maxLeftAxisCharacters: number;
46
48
  }
47
49
 
48
50
  const StackLines = ({
@@ -51,7 +53,9 @@ const StackLines = ({
51
53
  yScale,
52
54
  xScale,
53
55
  displayAnchor,
54
- lineStyle
56
+ lineStyle,
57
+ hasSecondUnit,
58
+ maxLeftAxisCharacters
55
59
  }: Props): JSX.Element => {
56
60
  const curveType = getCurveFactory(
57
61
  (equals(type(lineStyle), 'Array')
@@ -101,6 +105,8 @@ const StackLines = ({
101
105
  transparency={transparency}
102
106
  xScale={xScale}
103
107
  yScale={yScale}
108
+ hasSecondUnit={hasSecondUnit}
109
+ maxLeftAxisCharacters={maxLeftAxisCharacters}
104
110
  />
105
111
  )}
106
112
  {style?.showPoints &&
@@ -1,9 +1,7 @@
1
- import { equals, pluck, uniq } from 'ramda';
2
-
3
1
  import {
4
2
  getInvertedStackedLines,
5
3
  getNotInvertedStackedLines,
6
- getTimeSeriesForLines
4
+ getStackedLinesTimeSeriesPerStackAndUnit
7
5
  } from '../../../../common/timeSeries';
8
6
  import { LinesData } from '../models';
9
7
 
@@ -14,53 +12,28 @@ interface StackedLinesState {
14
12
 
15
13
  const useStackedLines = ({ lines, timeSeries }): StackedLinesState => {
16
14
  const regularStackedLines = getNotInvertedStackedLines(lines);
17
- const regularStackedUnits = uniq(pluck('unit', regularStackedLines));
18
- const regularStackedLinesTimeSeriesPerUnit = regularStackedUnits.reduce(
19
- (acc, stackedUnit) => {
20
- const relatedLines = regularStackedLines.filter(({ unit }) =>
21
- equals(unit, stackedUnit)
22
- );
23
-
24
- return {
25
- ...acc,
26
- [stackedUnit]: {
27
- lines: relatedLines,
28
- timeSeries: getTimeSeriesForLines({
29
- lines: relatedLines,
30
- timeSeries
31
- })
32
- }
33
- };
34
- },
35
- {}
36
- );
15
+ const {
16
+ stackedLinesTimeSeriesPerStackKeyAndUnit:
17
+ regularStackedLinesTimeSeriesPerStackKeyAndUnit
18
+ } = getStackedLinesTimeSeriesPerStackAndUnit({
19
+ stackedLines: regularStackedLines,
20
+ timeSeries
21
+ });
37
22
 
38
23
  const invertedStackedLines = getInvertedStackedLines(lines);
39
- const invertedStackedUnits = uniq(pluck('unit', invertedStackedLines));
40
- const invertedStackedLinesTimeSeriesPerUnit = invertedStackedUnits.reduce(
41
- (acc, stackedUnit) => {
42
- const relatedLines = invertedStackedLines.filter(({ unit }) =>
43
- equals(unit, stackedUnit)
44
- );
45
24
 
46
- return {
47
- ...acc,
48
- [stackedUnit]: {
49
- lines: relatedLines,
50
- timeSeries: getTimeSeriesForLines({
51
- invert: true,
52
- lines: relatedLines,
53
- timeSeries
54
- })
55
- }
56
- };
57
- },
58
- {}
59
- );
25
+ const {
26
+ stackedLinesTimeSeriesPerStackKeyAndUnit:
27
+ invertedStackedLinesTimeSeriesPerStackKeyAndUnit
28
+ } = getStackedLinesTimeSeriesPerStackAndUnit({
29
+ stackedLines: invertedStackedLines,
30
+ timeSeries,
31
+ invert: true
32
+ });
60
33
 
61
34
  return {
62
- invertedStackedLinesData: invertedStackedLinesTimeSeriesPerUnit,
63
- stackedLinesData: regularStackedLinesTimeSeriesPerUnit
35
+ invertedStackedLinesData: invertedStackedLinesTimeSeriesPerStackKeyAndUnit,
36
+ stackedLinesData: regularStackedLinesTimeSeriesPerStackKeyAndUnit
64
37
  };
65
38
  };
66
39
 
@@ -40,6 +40,8 @@ interface Props extends GlobalAreaLines {
40
40
  xScale: ScaleLinear<number, number>;
41
41
  yScalesPerUnit: Record<string, ScaleLinear<number, number>>;
42
42
  lineStyle: LineStyle | Array<LineStyle>;
43
+ hasSecondUnit?: boolean;
44
+ maxLeftAxisCharacters: number;
43
45
  }
44
46
 
45
47
  const Lines = ({
@@ -56,7 +58,9 @@ const Lines = ({
56
58
  areaRegularLines,
57
59
  scale,
58
60
  scaleLogarithmicBase,
59
- lineStyle
61
+ lineStyle,
62
+ hasSecondUnit,
63
+ maxLeftAxisCharacters
60
64
  }: Props): JSX.Element => {
61
65
  const { stackedLinesData, invertedStackedLinesData } = useStackedLines({
62
66
  lines: displayedLines,
@@ -78,7 +82,9 @@ const Lines = ({
78
82
  graphHeight: height,
79
83
  graphSvgRef,
80
84
  graphWidth: width,
81
- xScale
85
+ xScale,
86
+ hasSecondUnit,
87
+ maxLeftAxisCharacters
82
88
  };
83
89
 
84
90
  return (
@@ -95,34 +101,40 @@ const Lines = ({
95
101
  {(areaStackedLines?.display ?? true) && (
96
102
  <>
97
103
  {Object.entries(stackedLinesData).map(
98
- ([unit, { lines, timeSeries: stackedTimeSeries }]) => (
99
- <StackedLines
100
- lineStyle={lineStyle}
101
- key={`stacked-${unit}`}
102
- lines={lines}
103
- timeSeries={stackedTimeSeries}
104
- yScale={yScalesPerUnit[unit]}
105
- {...commonStackedLinesProps}
106
- />
107
- )
104
+ ([stackedKey, { lines, timeSeries: stackedTimeSeries }]) => {
105
+ const [, unit] = stackedKey.split('-');
106
+ return (
107
+ <StackedLines
108
+ lineStyle={lineStyle}
109
+ key={`stacked-${unit}`}
110
+ lines={lines}
111
+ timeSeries={stackedTimeSeries}
112
+ yScale={yScalesPerUnit[unit || undefined]}
113
+ {...commonStackedLinesProps}
114
+ />
115
+ );
116
+ }
108
117
  )}
109
118
  {Object.entries(invertedStackedLinesData).map(
110
- ([unit, { lines, timeSeries: stackedTimeSeries }]) => (
111
- <StackedLines
112
- lineStyle={lineStyle}
113
- key={`invert-stacked-${unit}`}
114
- lines={lines}
115
- timeSeries={stackedTimeSeries}
116
- yScale={getYScale({
117
- invert: '1',
118
- scale,
119
- scaleLogarithmicBase,
120
- unit,
121
- yScalesPerUnit
122
- })}
123
- {...commonStackedLinesProps}
124
- />
125
- )
119
+ ([stackedKey, { lines, timeSeries: stackedTimeSeries }]) => {
120
+ const [, unit] = stackedKey.split('-');
121
+ return (
122
+ <StackedLines
123
+ lineStyle={lineStyle}
124
+ key={`invert-stacked-${unit}`}
125
+ lines={lines}
126
+ timeSeries={stackedTimeSeries}
127
+ yScale={getYScale({
128
+ invert: '1',
129
+ scale,
130
+ scaleLogarithmicBase,
131
+ unit: unit || undefined,
132
+ yScalesPerUnit
133
+ })}
134
+ {...commonStackedLinesProps}
135
+ />
136
+ );
137
+ }
126
138
  )}
127
139
  </>
128
140
  )}
@@ -192,6 +204,8 @@ const Lines = ({
192
204
  transparency={transparency}
193
205
  xScale={xScale}
194
206
  yScale={yScale}
207
+ maxLeftAxisCharacters={maxLeftAxisCharacters}
208
+ hasSecondUnit={hasSecondUnit}
195
209
  />
196
210
  )}
197
211
  {style?.showPoints &&