@centreon/ui 25.3.3 → 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 (187) hide show
  1. package/package.json +25 -11
  2. package/public/mockServiceWorker.js +8 -31
  3. package/src/ActionsList/index.tsx +1 -0
  4. package/src/Button/Icon/index.tsx +3 -1
  5. package/src/Button/Save/index.stories.tsx +1 -0
  6. package/src/Checkbox/Checkbox.tsx +3 -1
  7. package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
  8. package/src/Colors/index.tsx +1 -1
  9. package/src/Dashboard/Dashboard.styles.ts +1 -1
  10. package/src/Dashboard/Layout.tsx +1 -1
  11. package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
  12. package/src/Form/CollapsibleGroup.tsx +13 -13
  13. package/src/Form/Form.cypress.spec.tsx +137 -2
  14. package/src/Form/Form.stories.tsx +11 -31
  15. package/src/Form/Form.tsx +2 -0
  16. package/src/Form/Inputs/Checkbox.tsx +3 -2
  17. package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
  18. package/src/Form/Inputs/Grid.tsx +18 -29
  19. package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
  20. package/src/Form/Inputs/Text.tsx +1 -0
  21. package/src/Form/Inputs/index.tsx +31 -24
  22. package/src/Form/Inputs/models.ts +8 -1
  23. package/src/Form/Section/FormSection.tsx +34 -0
  24. package/src/Form/Section/PanelTabs.tsx +13 -0
  25. package/src/Form/Section/navigateToSection.ts +9 -0
  26. package/src/Form/storiesData.tsx +14 -4
  27. package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
  28. package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
  29. package/src/Graph/BarChart/BarChart.tsx +56 -32
  30. package/src/Graph/BarChart/BarGroup.tsx +22 -32
  31. package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
  32. package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
  33. package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
  34. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
  35. package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
  36. package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
  37. package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
  38. package/src/Graph/Chart/Chart.stories.tsx +84 -1
  39. package/src/Graph/Chart/Chart.tsx +17 -4
  40. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
  41. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
  42. package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
  43. package/src/Graph/Chart/InteractiveComponents/Annotations/Annotation/index.tsx +1 -1
  44. package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
  45. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
  46. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
  47. package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
  48. package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
  49. package/src/Graph/Chart/Legend/index.tsx +26 -2
  50. package/src/Graph/Chart/helpers/index.ts +4 -3
  51. package/src/Graph/Chart/index.tsx +45 -45
  52. package/src/Graph/Chart/models.ts +8 -0
  53. package/src/Graph/Chart/useChartData.ts +14 -2
  54. package/src/Graph/Gauge/Gauge.tsx +18 -14
  55. package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
  56. package/src/Graph/Gauge/useResizeObserver.ts +68 -0
  57. package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
  58. package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
  59. package/src/Graph/SingleBar/models.ts +1 -0
  60. package/src/Graph/Text/Text.styles.ts +2 -2
  61. package/src/Graph/Text/Text.tsx +23 -10
  62. package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
  63. package/src/Graph/Timeline/Timeline.tsx +21 -4
  64. package/src/Graph/Tree/Links.tsx +2 -2
  65. package/src/Graph/Tree/Tree.tsx +2 -2
  66. package/src/Graph/Tree/constants.ts +1 -1
  67. package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
  68. package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
  69. package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
  70. package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
  71. package/src/Graph/common/timeSeries/index.test.ts +20 -0
  72. package/src/Graph/common/timeSeries/index.ts +225 -44
  73. package/src/Graph/common/timeSeries/models.ts +6 -2
  74. package/src/Graph/common/utils.ts +45 -12
  75. package/src/Graph/index.ts +3 -1
  76. package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
  77. package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
  78. package/src/Icon/RegexIcon.tsx +20 -0
  79. package/src/Icon/index.ts +1 -0
  80. package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
  81. package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
  82. package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
  83. package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
  84. package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
  85. package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
  86. package/src/InputField/Select/Autocomplete/index.tsx +28 -17
  87. package/src/InputField/Select/Option.tsx +3 -3
  88. package/src/InputField/Select/index.tsx +4 -0
  89. package/src/InputField/Text/index.tsx +4 -2
  90. package/src/InputField/translatedLabels.ts +4 -0
  91. package/src/Listing/ActionBar/Pagination.tsx +10 -23
  92. package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
  93. package/src/Listing/ActionBar/index.tsx +1 -1
  94. package/src/Listing/Cell/DataCell.tsx +6 -6
  95. package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
  96. package/src/Listing/Cell/index.tsx +57 -89
  97. package/src/Listing/Checkbox.tsx +8 -20
  98. package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
  99. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
  100. package/src/Listing/Header/ListingHeader.tsx +2 -5
  101. package/src/Listing/Header/_internals/Label.tsx +1 -17
  102. package/src/Listing/Row/EmptyRow.tsx +2 -6
  103. package/src/Listing/Row/Row.tsx +7 -36
  104. package/src/Listing/index.stories.tsx +1 -0
  105. package/src/Listing/index.tsx +26 -26
  106. package/src/Listing/useStyleTable.ts +58 -32
  107. package/src/ListingPage/index.stories.tsx +1 -0
  108. package/src/Module/index.tsx +8 -2
  109. package/src/MultiSelectEntries/index.stories.tsx +1 -0
  110. package/src/MultiSelectEntries/index.tsx +1 -1
  111. package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
  112. package/src/Pagination/Pagination.stories.tsx +46 -0
  113. package/src/Pagination/Pagination.styles.ts +56 -0
  114. package/src/Pagination/Pagination.tsx +146 -0
  115. package/src/Pagination/index.ts +3 -0
  116. package/src/Pagination/utils.ts +7 -0
  117. package/src/SortableItems/index.stories.tsx +2 -2
  118. package/src/StoryBookThemeProvider/index.tsx +3 -1
  119. package/src/ThemeProvider/base.css +49 -0
  120. package/src/ThemeProvider/index.tsx +21 -47
  121. package/src/ThemeProvider/palettes.ts +5 -3
  122. package/src/ThemeProvider/tailwindcss.css +230 -0
  123. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
  124. package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
  125. package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
  126. package/src/api/customFetch.ts +0 -9
  127. package/src/api/models.ts +9 -0
  128. package/src/api/useBulkResponse.ts +58 -0
  129. package/src/api/useGraphQuery/index.ts +108 -12
  130. package/src/components/Avatar/Avatar.stories.tsx +1 -0
  131. package/src/components/Button/Button.module.css +38 -0
  132. package/src/components/Button/Button.stories.tsx +25 -0
  133. package/src/components/Button/Button.tsx +2 -5
  134. package/src/components/CrudPage/Actions/Actions.styles.ts +15 -1
  135. package/src/components/CrudPage/Actions/Actions.tsx +7 -4
  136. package/src/components/CrudPage/Actions/Search.tsx +15 -14
  137. package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
  138. package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
  139. package/src/components/DataTable/DataTable.stories.tsx +1 -0
  140. package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
  141. package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
  142. package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
  143. package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
  144. package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
  145. package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
  146. package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
  147. package/src/components/Form/FormActions.tsx +21 -12
  148. package/src/components/Header/PageHeader/PageHeader.styles.ts +5 -5
  149. package/src/components/Layout/AreaIndicator.tsx +4 -6
  150. package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
  151. package/src/components/Layout/PageLayout/PageLayout.styles.ts +1 -1
  152. package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
  153. package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
  154. package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
  155. package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
  156. package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
  157. package/src/components/Menu/Button/MenuButton.tsx +6 -6
  158. package/src/components/Menu/MenuDivider.tsx +1 -5
  159. package/src/components/Menu/MenuItem.tsx +1 -5
  160. package/src/components/Menu/MenuItems.tsx +5 -4
  161. package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
  162. package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
  163. package/src/components/Modal/Modal.stories.tsx +21 -0
  164. package/src/components/Modal/Modal.styles.ts +1 -19
  165. package/src/components/Modal/Modal.tsx +1 -1
  166. package/src/components/Modal/ModalBody.tsx +6 -4
  167. package/src/components/Modal/ModalHeader.tsx +9 -5
  168. package/src/components/Modal/modal.module.css +16 -0
  169. package/src/components/Tabs/Tab.styles.ts +0 -6
  170. package/src/components/Tabs/Tabs.tsx +37 -15
  171. package/src/index.ts +4 -0
  172. package/src/queryParameters/url/index.ts +7 -2
  173. package/src/utils/index.ts +1 -0
  174. package/src/utils/useLocale/index.ts +9 -0
  175. package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
  176. package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
  177. package/src/utils/usePluralizedTranslation.ts +2 -3
  178. package/src/Listing/Cell/DataCell.styles.ts +0 -27
  179. package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
  180. package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
  181. package/src/Listing/Header/ListingHeader.styles.ts +0 -16
  182. package/src/Listing/Listing.styles.ts +0 -78
  183. package/src/Listing/Row/EmptyRow.styles.ts +0 -14
  184. package/src/components/Button/Button.styles.ts +0 -44
  185. package/src/components/Layout/AreaIndicator.styles.ts +0 -33
  186. package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
  187. package/src/components/Menu/Menu.styles.ts +0 -68
@@ -22,7 +22,15 @@ import WrapperChart from '.';
22
22
  interface Props
23
23
  extends Pick<
24
24
  LineChartProps,
25
- 'legend' | 'tooltip' | 'axis' | 'lineStyle' | 'barStyle' | 'additionalLines'
25
+ | 'legend'
26
+ | 'tooltip'
27
+ | 'axis'
28
+ | 'lineStyle'
29
+ | 'barStyle'
30
+ | 'additionalLines'
31
+ | 'min'
32
+ | 'max'
33
+ | 'boundariesUnit'
26
34
  > {
27
35
  data?: LineChartData;
28
36
  }
@@ -69,7 +77,10 @@ const initialize = ({
69
77
  axis,
70
78
  lineStyle,
71
79
  barStyle,
72
- additionalLines
80
+ additionalLines,
81
+ min,
82
+ max,
83
+ boundariesUnit
73
84
  }: Props): void => {
74
85
  cy.adjustViewport();
75
86
 
@@ -93,6 +104,9 @@ const initialize = ({
93
104
  barStyle={barStyle}
94
105
  tooltip={tooltip}
95
106
  additionalLines={additionalLines}
107
+ min={min}
108
+ max={max}
109
+ boundariesUnit={boundariesUnit}
96
110
  />
97
111
  </Provider>
98
112
  )
@@ -139,7 +153,7 @@ const initializeCustomUnits = ({
139
153
  const checkGraphWidth = (): void => {
140
154
  cy.findByTestId('graph-interaction-zone')
141
155
  .should('have.attr', 'height')
142
- .and('equal', '376.203125');
156
+ .and('equal', '376');
143
157
 
144
158
  cy.findByTestId('graph-interaction-zone').then((graph) => {
145
159
  expect(Number(graph[0].attributes.width.value)).to.be.greaterThan(1170);
@@ -165,8 +179,8 @@ describe('Line chart', () => {
165
179
 
166
180
  cy.contains('06/18/2023').should('be.visible');
167
181
 
168
- cy.contains('0.45 s').should('be.visible');
169
- cy.contains('73.65%').should('be.visible');
182
+ cy.contains('0.4 s').should('be.visible');
183
+ cy.contains('75.64%').should('be.visible');
170
184
 
171
185
  cy.makeSnapshot();
172
186
  });
@@ -188,12 +202,12 @@ describe('Line chart', () => {
188
202
  cy.get('[data-metric="connTime"]').should(
189
203
  'have.attr',
190
204
  'data-highlight',
191
- 'false'
205
+ 'true'
192
206
  );
193
207
  cy.get('[data-metric="hitratio"]').should(
194
208
  'have.attr',
195
209
  'data-highlight',
196
- 'true'
210
+ 'false'
197
211
  );
198
212
 
199
213
  cy.makeSnapshot();
@@ -437,7 +451,7 @@ describe('Line chart', () => {
437
451
 
438
452
  cy.contains(':00 AM').should('be.visible');
439
453
 
440
- cy.get('text[transform="rotate(-35, -2, 145.04834208635688)"]').should(
454
+ cy.get('text[transform="rotate(-35, -2, 274.47726401277305)"]').should(
441
455
  'be.visible'
442
456
  );
443
457
 
@@ -451,8 +465,8 @@ describe('Line chart', () => {
451
465
 
452
466
  cy.contains(':00 AM').should('be.visible');
453
467
 
454
- cy.contains('0.9').should('be.visible');
455
- cy.contains('-0.9').should('be.visible');
468
+ cy.contains('0.8').should('be.visible');
469
+ cy.contains('-0.8').should('be.visible');
456
470
 
457
471
  cy.makeSnapshot();
458
472
  });
@@ -518,8 +532,8 @@ describe('Line chart', () => {
518
532
 
519
533
  checkGraphWidth();
520
534
  cy.contains(':00 AM').should('be.visible');
521
- cy.get('circle[cx="250.83333333333334"]').should('be.visible');
522
- cy.get('circle[cy="52.93597418085514"]').should('be.visible');
535
+ cy.get('circle[cx="248.33333333333334"]').should('be.visible');
536
+ cy.get('circle[cy="251.79089393069725"]').should('be.visible');
523
537
 
524
538
  cy.makeSnapshot();
525
539
  });
@@ -577,7 +591,7 @@ describe('Line chart', () => {
577
591
  cy.get('path.visx-area-closed')
578
592
  .should('have.attr', 'stroke-dasharray')
579
593
  .and('equals', '5 4');
580
- cy.get('circle[cx="33.44444444444444"]').should('be.visible');
594
+ cy.get('circle[cx="33.11111111111111"]').should('be.visible');
581
595
 
582
596
  cy.makeSnapshot();
583
597
  });
@@ -733,10 +747,10 @@ describe('Lines and bars', () => {
733
747
  checkGraphWidth();
734
748
 
735
749
  cy.get(
736
- 'path[d="M7.501377410468319,273.3424587717121 h56.51239669421488 h1v1 v100.86066622828793 a1,1 0 0 1 -1,1 h-56.51239669421488 a1,1 0 0 1 -1,-1 v-100.86066622828793 v-1h1z"]'
750
+ 'path[d="M7.501377410468319,350.5553648585503 h56.51239669421488 h1v1 v23.44463514144968 a1,1 0 0 1 -1,1 h-56.51239669421488 a1,1 0 0 1 -1,-1 v-23.44463514144968 v-1h1z"]'
737
751
  ).should('be.visible');
738
752
  cy.get(
739
- 'path[d="M24.05509641873278,218.3663782225586 h23.404958677685954 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,17.553719008264462 v19.86864253262454 v17.553719008264462h-17.553719008264462 h-23.404958677685954 h-17.553719008264462v-17.553719008264462 v-19.86864253262454 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,-17.553719008264462z"]'
753
+ 'path[d="M24.05509641873278,201.58170928199803 h23.404958677685954 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,17.553719008264462 v113.86621756002336 v17.553719008264462h-17.553719008264462 h-23.404958677685954 h-17.553719008264462v-17.553719008264462 v-113.86621756002336 a17.553719008264462,17.553719008264462 0 0 1 17.553719008264462,-17.553719008264462z"]'
740
754
  ).should('be.visible');
741
755
 
742
756
  cy.makeSnapshot();
@@ -763,4 +777,60 @@ describe('Lines and bars', () => {
763
777
 
764
778
  cy.makeSnapshot();
765
779
  });
780
+
781
+ it('displays graph according to min and max boundaries', () => {
782
+ initialize({
783
+ data: dataPingServiceLines,
784
+ min: 0.01,
785
+ max: 0.1
786
+ });
787
+
788
+ checkGraphWidth();
789
+
790
+ cy.get('path[data-metric="1"]').should('be.visible');
791
+ cy.get('path[data-metric="3"]').should('be.visible');
792
+ cy.get('path[data-metric="3"]').should('be.visible');
793
+
794
+ cy.contains('0.1 ms').should('be.visible');
795
+ cy.contains('0.1%').should('be.visible');
796
+
797
+ cy.makeSnapshot();
798
+ });
799
+
800
+ it('displays graph according to min and max boundaries for a unit', () => {
801
+ initialize({
802
+ data: dataPingServiceLines,
803
+ min: 0.01,
804
+ max: 0.1,
805
+ boundariesUnit: 'ms'
806
+ });
807
+
808
+ checkGraphWidth();
809
+
810
+ cy.get('path[data-metric="1"]').should('be.visible');
811
+ cy.get('path[data-metric="3"]').should('be.visible');
812
+ cy.get('path[data-metric="3"]').should('be.visible');
813
+
814
+ cy.contains('0.1 ms').should('be.visible');
815
+ cy.contains('2%').should('be.visible');
816
+
817
+ cy.makeSnapshot();
818
+ });
819
+
820
+ it('calls the secondary function when a metric is clicked in the legend', () => {
821
+ const secondaryClick = cy.stub().as('secondaryClick');
822
+ initialize({
823
+ data: dataPingServiceLines,
824
+ legend: {
825
+ mode: 'grid',
826
+ placement: 'bottom',
827
+ secondaryClick
828
+ }
829
+ });
830
+
831
+ checkGraphWidth();
832
+
833
+ cy.contains('Packet Loss').rightclick();
834
+ cy.get('@secondaryClick').should('have.been.called');
835
+ });
766
836
  });
@@ -2,7 +2,7 @@ import { useEffect, useState } from 'react';
2
2
 
3
3
  import { Meta, StoryObj } from '@storybook/react';
4
4
 
5
- import { Button } from '@mui/material';
5
+ import { Button, Menu } from '@mui/material';
6
6
  import ButtonGroup from '@mui/material/ButtonGroup';
7
7
  import Switch from '@mui/material/Switch';
8
8
  import Tooltip from '@mui/material/Tooltip';
@@ -26,6 +26,7 @@ import dataPingService from '../mockedData/pingService.json';
26
26
  import dataPingServiceLinesBars from '../mockedData/pingServiceLinesBars.json';
27
27
  import dataPingServiceLinesBarsMixed from '../mockedData/pingServiceLinesBarsMixed.json';
28
28
  import dataPingServiceLinesBarsStacked from '../mockedData/pingServiceLinesBarsStacked.json';
29
+ import dataPingServiceLinesStackKeys from '../mockedData/pingServiceWithStackedKeys.json';
29
30
  import dataZoomPreview from '../mockedData/zoomPreview.json';
30
31
 
31
32
  import { dateTimeFormat } from './common';
@@ -717,3 +718,85 @@ export const WithAdditionalLines: Story = {
717
718
  />
718
719
  )
719
720
  };
721
+
722
+ export const linesAndBarsMinMax: Story = {
723
+ argTypes,
724
+ args: {
725
+ ...argumentsData,
726
+ min: 10,
727
+ max: 30,
728
+ lineStyle: {
729
+ curve: 'natural',
730
+ lineWidth: 2,
731
+ showPoints: true
732
+ }
733
+ },
734
+ render: (args) => (
735
+ <WrapperChart
736
+ {...args}
737
+ data={dataPingServiceLinesBarsMixed as unknown as LineChartData}
738
+ />
739
+ )
740
+ };
741
+
742
+ export const linesAndBarsMinMaxForUnit: Story = {
743
+ argTypes,
744
+ args: {
745
+ ...argumentsData,
746
+ min: 10,
747
+ max: 30,
748
+ boundariesUnit: '%',
749
+ lineStyle: {
750
+ curve: 'natural',
751
+ lineWidth: 2,
752
+ showPoints: true
753
+ }
754
+ },
755
+ render: (args) => (
756
+ <WrapperChart
757
+ {...args}
758
+ data={dataPingServiceLinesBarsMixed as unknown as LineChartData}
759
+ />
760
+ )
761
+ };
762
+
763
+ const LegendSecondaryClick = (args) => {
764
+ const [anchor, setAnchor] = useState<EventTarget | null>(null);
765
+
766
+ return (
767
+ <>
768
+ <WrapperChart
769
+ {...args}
770
+ legend={{
771
+ secondaryClick: ({ element }) => setAnchor(element)
772
+ }}
773
+ />
774
+ <Menu
775
+ anchorEl={anchor}
776
+ open={Boolean(anchor)}
777
+ onClose={() => setAnchor(null)}
778
+ >
779
+ menu
780
+ </Menu>
781
+ </>
782
+ );
783
+ };
784
+
785
+ export const withLegendSecondaryClick: Story = {
786
+ argTypes,
787
+ args: argumentsData,
788
+ render: (args) => (
789
+ <LegendSecondaryClick
790
+ {...args}
791
+ data={dataPingService as unknown as LineChartData}
792
+ />
793
+ )
794
+ };
795
+
796
+ export const stackedKey: Story = {
797
+ argTypes,
798
+ args: {
799
+ ...argumentsData,
800
+ data: dataPingServiceLinesStackKeys
801
+ }
802
+ };
@@ -112,7 +112,10 @@ const Chart = ({
112
112
  limitLegend,
113
113
  skipIntersectionObserver,
114
114
  transformMatrix,
115
- additionalLines
115
+ additionalLines,
116
+ min,
117
+ max,
118
+ boundariesUnit
116
119
  }: Props): JSX.Element => {
117
120
  const { classes } = useChartStyles();
118
121
 
@@ -191,7 +194,10 @@ const Chart = ({
191
194
  scaleLogarithmicBase: axis?.scaleLogarithmicBase,
192
195
  thresholdUnit,
193
196
  thresholds: (thresholds?.enabled && thresholdValues) || [],
194
- valueGraphHeight: graphHeight - margin.bottom
197
+ valueGraphHeight: graphHeight - margin.bottom,
198
+ min,
199
+ max,
200
+ boundariesUnit
195
201
  }),
196
202
  [
197
203
  linesGraph,
@@ -246,6 +252,8 @@ const Chart = ({
246
252
  [axis?.showGridLines]
247
253
  );
248
254
 
255
+ const hasSecondUnit = useMemo(() => Boolean(secondUnit), [secondUnit]);
256
+
249
257
  if ((!isInViewport && !skipIntersectionObserver) || !height) {
250
258
  return (
251
259
  <Skeleton
@@ -269,7 +277,8 @@ const Chart = ({
269
277
  legendHeight: legend?.height,
270
278
  mode: legend?.mode,
271
279
  placement: legend?.placement,
272
- renderExtraComponent: legend?.renderExtraComponent
280
+ renderExtraComponent: legend?.renderExtraComponent,
281
+ secondaryClick: legend?.secondaryClick
273
282
  }}
274
283
  legendRef={legendRef}
275
284
  limitLegend={limitLegend}
@@ -299,7 +308,7 @@ const Chart = ({
299
308
  timeSeries={timeSeries}
300
309
  xScale={xScale}
301
310
  maxAxisCharacters={maxLeftAxisCharacters}
302
- hasSecondUnit={Boolean(secondUnit)}
311
+ hasSecondUnit={hasSecondUnit}
303
312
  >
304
313
  <>
305
314
  {!isEmpty(linesDisplayedAsBar) && (
@@ -327,6 +336,8 @@ const Chart = ({
327
336
  width={graphWidth}
328
337
  xScale={xScale}
329
338
  yScalesPerUnit={yScalesPerUnit}
339
+ hasSecondUnit={hasSecondUnit}
340
+ maxLeftAxisCharacters={maxLeftAxisCharacters}
330
341
  {...shapeLines}
331
342
  />
332
343
  )}
@@ -355,6 +366,8 @@ const Chart = ({
355
366
  }}
356
367
  zoomData={{ ...zoomPreview }}
357
368
  transformMatrix={transformMatrix}
369
+ hasSecondUnit={hasSecondUnit}
370
+ maxLeftAxisCharacters={maxLeftAxisCharacters}
358
371
  />
359
372
  {thresholds?.enabled && (
360
373
  <Thresholds
@@ -15,6 +15,8 @@ interface Props {
15
15
  timeSeries: Array<TimeValue>;
16
16
  xScale: ScaleTime<number, number>;
17
17
  yScale: ScaleLinear<number, number>;
18
+ hasSecondUnit?: boolean;
19
+ maxLeftAxisCharacters: number;
18
20
  }
19
21
 
20
22
  export const getYAnchorPoint = ({
@@ -38,11 +40,15 @@ const RegularAnchorPoint = ({
38
40
  yScale,
39
41
  metric_id,
40
42
  timeSeries,
41
- lineColor
43
+ lineColor,
44
+ maxLeftAxisCharacters,
45
+ hasSecondUnit
42
46
  }: Props): JSX.Element | null => {
43
47
  const { tickAxisBottom: timeTick } = useTickGraph({
44
48
  timeSeries,
45
- xScale
49
+ xScale,
50
+ maxLeftAxisCharacters,
51
+ hasSecondUnit
46
52
  });
47
53
 
48
54
  if (isNil(timeTick)) {
@@ -15,7 +15,10 @@ interface Props {
15
15
  timeSeries: Array<TimeValue>;
16
16
  xScale: ScaleTime<number, number>;
17
17
  yScale: ScaleLinear<number, number>;
18
+ hasSecondUnit?: boolean;
19
+ maxLeftAxisCharacters: number;
18
20
  }
21
+
19
22
  interface GetYAnchorPoint {
20
23
  stackValues: Array<StackValue>;
21
24
  timeTick: Date | null;
@@ -43,7 +46,7 @@ export const getYAnchorPoint = ({
43
46
  return null;
44
47
  }
45
48
 
46
- return yScale(timeValue[1] as number);
49
+ return yScale(timeValue[0] as number);
47
50
  };
48
51
 
49
52
  const StackedAnchorPoint = ({
@@ -51,11 +54,15 @@ const StackedAnchorPoint = ({
51
54
  yScale,
52
55
  stackValues,
53
56
  timeSeries,
54
- lineColor
57
+ lineColor,
58
+ hasSecondUnit,
59
+ maxLeftAxisCharacters
55
60
  }: Props): JSX.Element | null => {
56
61
  const { tickAxisBottom: timeTick } = useTickGraph({
57
62
  timeSeries,
58
- xScale
63
+ xScale,
64
+ hasSecondUnit,
65
+ maxLeftAxisCharacters
59
66
  });
60
67
 
61
68
  if (isNil(timeTick)) {
@@ -6,6 +6,10 @@ import { useAtomValue } from 'jotai';
6
6
  import useAxisY from '../../../common/Axes/useAxisY';
7
7
  import { getTimeValue } from '../../../common/timeSeries';
8
8
  import { Line, TimeValue } from '../../../common/timeSeries/models';
9
+ import {
10
+ computPixelsToShiftMouse,
11
+ computeGElementMarginLeft
12
+ } from '../../../common/utils';
9
13
  import { margin } from '../../common';
10
14
  import { mousePositionAtom } from '../interactionWithGraphAtoms';
11
15
 
@@ -25,6 +29,8 @@ interface Props {
25
29
  rightScale?: ScaleLinear<number, number>;
26
30
  timeSeries: Array<TimeValue>;
27
31
  xScale: ScaleLinear<number, number>;
32
+ hasSecondUnit?: boolean;
33
+ maxLeftAxisCharacters: number;
28
34
  }
29
35
 
30
36
  const useTickGraph = ({
@@ -33,7 +39,9 @@ const useTickGraph = ({
33
39
  leftScale,
34
40
  rightScale,
35
41
  lines = [],
36
- baseAxis = 1000
42
+ baseAxis = 1000,
43
+ hasSecondUnit,
44
+ maxLeftAxisCharacters
37
45
  }: Props): AnchorPointResult => {
38
46
  const guidingLinesRef = useRef<SVGGElement | null>(null);
39
47
  const [tickAxisBottom, setTickAxisBottom] = useState<Date | null>(null);
@@ -69,8 +77,17 @@ const useTickGraph = ({
69
77
 
70
78
  return;
71
79
  }
80
+ const pixelToShift = computPixelsToShiftMouse(xScale);
72
81
  const mousePositionTimeTick = mousePosition
73
- ? getTimeValue({ timeSeries, x: mousePosition[0], xScale })?.timeTick
82
+ ? getTimeValue({
83
+ timeSeries,
84
+ x: mousePosition[0] - pixelToShift,
85
+ xScale,
86
+ marginLeft: computeGElementMarginLeft({
87
+ maxCharacters: maxLeftAxisCharacters,
88
+ hasSecondUnit
89
+ })
90
+ })?.timeTick
74
91
  : 0;
75
92
  const timeTickValue = mousePosition
76
93
  ? new Date(mousePositionTimeTick || 0)
@@ -43,7 +43,7 @@ const Annotation = ({
43
43
 
44
44
  const setAnnotationHovered = useSetAtom(annotationHoveredAtom);
45
45
 
46
- const content = `${truncate(event.content)} (${t(labelBy)} ${
46
+ const content = `${truncate({ content: event.content })} (${t(labelBy)} ${
47
47
  event.contact?.name
48
48
  })`;
49
49
 
@@ -27,15 +27,13 @@ export const useGraphValueTooltip = ({
27
27
  isSingleMode,
28
28
  sortOrder
29
29
  }: UseGraphValueTooltipProps): UseGraphValueTooltipState | null => {
30
- const { toDate, toTime } = useLocaleDateTimeFormat();
30
+ const { format } = useLocaleDateTimeFormat();
31
31
  const graphTooltipData = useAtomValue(graphTooltipDataAtom);
32
32
 
33
33
  if (isNil(graphTooltipData) || isNil(graphTooltipData.metrics)) {
34
34
  return null;
35
35
  }
36
36
 
37
- const formattedDateTime = `${toDate(graphTooltipData.date)} / ${toTime(graphTooltipData.date)}`;
38
-
39
37
  const filteredMetrics = isSingleMode
40
38
  ? filter(
41
39
  ({ id }) => equals(id, graphTooltipData.highlightedMetricId),
@@ -54,7 +52,7 @@ export const useGraphValueTooltip = ({
54
52
  ])(sortOrder);
55
53
 
56
54
  return {
57
- dateTime: formattedDateTime,
55
+ dateTime: format({ date: graphTooltipData.date, formatString: 'L LTS' }),
58
56
  highlightedMetricId: graphTooltipData.highlightedMetricId,
59
57
  metrics: sortedMetrics
60
58
  };
@@ -4,18 +4,29 @@ import { alpha, useTheme } from '@mui/system';
4
4
 
5
5
  import Bar from '../Bar';
6
6
 
7
+ import { margin } from '../../common';
7
8
  import { ZoomPreviewData } from './models';
8
9
  import useZoomPreview from './useZoomPreview';
9
10
 
10
11
  const ZoomPreview = (data: ZoomPreviewData): JSX.Element => {
11
12
  const theme = useTheme();
12
13
 
13
- const { graphHeight, xScale, graphWidth, getInterval, ...rest } = data;
14
+ const {
15
+ graphHeight,
16
+ xScale,
17
+ graphWidth,
18
+ getInterval,
19
+ graphSvgRef,
20
+ graphMarginLeft,
21
+ ...rest
22
+ } = data;
14
23
 
15
24
  const { zoomBarWidth, zoomBoundaries } = useZoomPreview({
16
25
  getInterval,
17
26
  graphWidth,
18
- xScale
27
+ xScale,
28
+ graphSvgRef,
29
+ graphMarginLeft
19
30
  });
20
31
 
21
32
  const restData = omit(['enable'], { ...rest });
@@ -24,7 +35,7 @@ const ZoomPreview = (data: ZoomPreviewData): JSX.Element => {
24
35
  <g>
25
36
  <Bar
26
37
  fill={alpha(theme.palette.primary.main, 0.2)}
27
- height={graphHeight}
38
+ height={graphHeight - margin.bottom}
28
39
  stroke={alpha(theme.palette.primary.main, 0.5)}
29
40
  width={zoomBarWidth}
30
41
  x={zoomBoundaries?.start || 0}
@@ -1,9 +1,12 @@
1
1
  import { ScaleTime } from 'd3-scale';
2
2
 
3
+ import { RefObject } from 'react';
3
4
  import { InteractedZone } from '../../models';
4
5
 
5
6
  export interface ZoomPreviewData extends InteractedZone {
6
7
  graphHeight: number;
7
8
  graphWidth: number;
8
9
  xScale: ScaleTime<number, number>;
10
+ graphSvgRef: RefObject<SVGSVGElement | null>;
11
+ graphMarginLeft: number;
9
12
  }
@@ -1,18 +1,15 @@
1
- import { useEffect, useState } from 'react';
1
+ import { RefObject, useEffect, useState } from 'react';
2
2
 
3
3
  import { Event } from '@visx/visx';
4
4
  import { ScaleTime } from 'd3-scale';
5
5
  import { useAtomValue, useSetAtom } from 'jotai';
6
6
  import { equals, gte, isNil, lt } from 'ramda';
7
-
8
- import { margin } from '../../common';
9
7
  import { Interval } from '../../models';
10
8
  import {
11
9
  eventMouseDownAtom,
12
10
  eventMouseUpAtom,
13
11
  mousePositionAtom
14
12
  } from '../interactionWithGraphAtoms';
15
-
16
13
  import { applyingZoomAtomAtom } from './zoomPreviewAtoms';
17
14
 
18
15
  interface Boundaries {
@@ -28,12 +25,16 @@ interface Props {
28
25
  getInterval?: (args: Interval) => void;
29
26
  graphWidth: number;
30
27
  xScale: ScaleTime<number, number>;
28
+ graphSvgRef: RefObject<SVGSVGElement | null>;
29
+ graphMarginLeft: number;
31
30
  }
32
31
 
33
32
  const useZoomPreview = ({
34
33
  xScale,
35
34
  graphWidth,
36
- getInterval
35
+ getInterval,
36
+ graphSvgRef,
37
+ graphMarginLeft
37
38
  }: Props): ZoomPreview => {
38
39
  const [zoomBoundaries, setZoomBoundaries] = useState<Boundaries | null>(null);
39
40
  const eventMouseDown = useAtomValue(eventMouseDownAtom);
@@ -41,16 +42,17 @@ const useZoomPreview = ({
41
42
  const mousePosition = useAtomValue(mousePositionAtom);
42
43
  const setApplyingZoom = useSetAtom(applyingZoomAtomAtom);
43
44
 
44
- const mousePointDown = eventMouseDown
45
- ? Event.localPoint(eventMouseDown)
46
- : null;
45
+ const mousePointDown =
46
+ eventMouseDown && graphSvgRef.current
47
+ ? Event.localPoint(graphSvgRef.current, eventMouseDown)
48
+ : null;
47
49
 
48
50
  const mouseDownPositionX = mousePointDown
49
- ? mousePointDown.x - margin.left
51
+ ? mousePointDown.x - graphMarginLeft
50
52
  : null;
51
53
 
52
54
  const movingMousePositionX = mousePosition
53
- ? mousePosition[0] - margin.left
55
+ ? mousePosition[0] - graphMarginLeft
54
56
  : null;
55
57
 
56
58
  const applyZoom = (): void => {