@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.
- package/package.json +25 -11
- package/public/mockServiceWorker.js +8 -31
- package/src/Button/Save/index.stories.tsx +1 -0
- package/src/Checkbox/Checkbox.tsx +3 -1
- package/src/Checkbox/CheckboxGroup/index.tsx +6 -1
- package/src/Colors/index.tsx +1 -1
- package/src/Dashboard/Dashboard.styles.ts +1 -1
- package/src/Dashboard/Layout.tsx +1 -1
- package/src/Dialog/UnsavedChanges/index.stories.tsx +1 -0
- package/src/Form/CollapsibleGroup.tsx +13 -13
- package/src/Form/Form.cypress.spec.tsx +137 -2
- package/src/Form/Form.stories.tsx +11 -31
- package/src/Form/Form.tsx +2 -0
- package/src/Form/Inputs/Checkbox.tsx +3 -2
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +6 -1
- package/src/Form/Inputs/Grid.tsx +18 -29
- package/src/Form/Inputs/SubGroupDivider.tsx +7 -0
- package/src/Form/Inputs/Text.tsx +1 -0
- package/src/Form/Inputs/index.tsx +31 -24
- package/src/Form/Inputs/models.ts +8 -1
- package/src/Form/Section/FormSection.tsx +34 -0
- package/src/Form/Section/PanelTabs.tsx +13 -0
- package/src/Form/Section/navigateToSection.ts +9 -0
- package/src/Form/storiesData.tsx +14 -4
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +46 -6
- package/src/Graph/BarChart/BarChart.stories.tsx +60 -0
- package/src/Graph/BarChart/BarChart.tsx +56 -32
- package/src/Graph/BarChart/BarGroup.tsx +22 -32
- package/src/Graph/BarChart/MemoizedGroup.tsx +8 -11
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +145 -32
- package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +7 -1
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +18 -45
- package/src/Graph/Chart/BasicComponents/Lines/index.tsx +42 -28
- package/src/Graph/Chart/Chart.cypress.spec.tsx +85 -15
- package/src/Graph/Chart/Chart.stories.tsx +84 -1
- package/src/Graph/Chart/Chart.tsx +17 -4
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/RegularAnchorPoint.tsx +8 -2
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/StackedAnchorPoint.tsx +10 -3
- package/src/Graph/Chart/InteractiveComponents/AnchorPoint/useTickGraph.ts +19 -2
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +2 -4
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/index.tsx +14 -3
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/models.ts +3 -0
- package/src/Graph/Chart/InteractiveComponents/ZoomPreview/useZoomPreview.ts +12 -10
- package/src/Graph/Chart/InteractiveComponents/index.tsx +63 -5
- package/src/Graph/Chart/Legend/index.tsx +26 -2
- package/src/Graph/Chart/index.tsx +45 -45
- package/src/Graph/Chart/models.ts +8 -0
- package/src/Graph/Chart/useChartData.ts +14 -2
- package/src/Graph/Gauge/Gauge.tsx +18 -14
- package/src/Graph/Gauge/ResponsiveGauge.tsx +10 -6
- package/src/Graph/Gauge/useResizeObserver.ts +68 -0
- package/src/Graph/SingleBar/ResponsiveSingleBar.tsx +18 -16
- package/src/Graph/SingleBar/ThresholdLine.tsx +4 -4
- package/src/Graph/SingleBar/models.ts +1 -0
- package/src/Graph/Text/Text.styles.ts +2 -2
- package/src/Graph/Text/Text.tsx +23 -10
- package/src/Graph/Timeline/ResponsiveTimeline.tsx +4 -0
- package/src/Graph/Timeline/Timeline.tsx +21 -4
- package/src/Graph/Tree/Links.tsx +2 -2
- package/src/Graph/Tree/Tree.tsx +2 -2
- package/src/Graph/Tree/constants.ts +1 -1
- package/src/Graph/common/BaseChart/BaseChart.tsx +6 -1
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +5 -4
- package/src/Graph/common/BaseChart/Header/index.tsx +3 -1
- package/src/Graph/common/BaseChart/useComputeBaseChartDimensions.ts +13 -9
- package/src/Graph/common/timeSeries/index.test.ts +20 -0
- package/src/Graph/common/timeSeries/index.ts +225 -44
- package/src/Graph/common/timeSeries/models.ts +6 -2
- package/src/Graph/common/utils.ts +45 -12
- package/src/Graph/index.ts +3 -1
- package/src/Graph/mockedData/dataWithMissingPoint.json +74 -0
- package/src/Graph/mockedData/pingServiceWithStackedKeys.json +205 -0
- package/src/Icon/RegexIcon.tsx +20 -0
- package/src/Icon/index.ts +1 -0
- package/src/InputField/Select/Autocomplete/Connected/Multi/MultiConnectedAutocompleteField.cypress.spec.tsx +68 -14
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +49 -14
- package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +78 -0
- package/src/InputField/Select/Autocomplete/Multi/Multi.styles.ts +26 -0
- package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +124 -0
- package/src/InputField/Select/Autocomplete/Multi/index.tsx +1 -117
- package/src/InputField/Select/Autocomplete/index.tsx +28 -17
- package/src/InputField/Select/Option.tsx +3 -3
- package/src/InputField/Select/index.tsx +4 -0
- package/src/InputField/Text/index.tsx +4 -2
- package/src/InputField/translatedLabels.ts +4 -0
- package/src/Listing/ActionBar/Pagination.tsx +10 -23
- package/src/Listing/ActionBar/PaginationActions.tsx +1 -10
- package/src/Listing/ActionBar/index.tsx +1 -1
- package/src/Listing/Cell/DataCell.tsx +6 -6
- package/src/Listing/Cell/EllipsisTypography.tsx +10 -32
- package/src/Listing/Cell/index.tsx +37 -76
- package/src/Listing/Checkbox.tsx +8 -20
- package/src/Listing/Header/Cell/ListingHeaderCell.tsx +17 -14
- package/src/Listing/Header/Cell/SelectActionListingHeaderCell.tsx +5 -9
- package/src/Listing/Header/ListingHeader.tsx +2 -5
- package/src/Listing/Header/_internals/Label.tsx +1 -17
- package/src/Listing/Row/EmptyRow.tsx +2 -6
- package/src/Listing/Row/Row.tsx +7 -36
- package/src/Listing/index.stories.tsx +1 -0
- package/src/Listing/index.tsx +26 -26
- package/src/Listing/useStyleTable.ts +58 -32
- package/src/ListingPage/index.stories.tsx +1 -0
- package/src/Module/index.tsx +8 -2
- package/src/MultiSelectEntries/index.stories.tsx +1 -0
- package/src/MultiSelectEntries/index.tsx +1 -1
- package/src/Pagination/Pagination.cypress.spec.tsx +137 -0
- package/src/Pagination/Pagination.stories.tsx +46 -0
- package/src/Pagination/Pagination.styles.ts +56 -0
- package/src/Pagination/Pagination.tsx +146 -0
- package/src/Pagination/index.ts +3 -0
- package/src/Pagination/utils.ts +7 -0
- package/src/SortableItems/index.stories.tsx +2 -2
- package/src/StoryBookThemeProvider/index.tsx +3 -1
- package/src/ThemeProvider/base.css +49 -0
- package/src/ThemeProvider/index.tsx +21 -47
- package/src/ThemeProvider/palettes.ts +3 -1
- package/src/ThemeProvider/tailwindcss.css +230 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +9 -11
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +1 -0
- package/src/TimePeriods/DateTimePickerInput.tsx +3 -1
- package/src/api/models.ts +9 -0
- package/src/api/useGraphQuery/index.ts +108 -12
- package/src/components/Avatar/Avatar.stories.tsx +1 -0
- package/src/components/Button/Button.module.css +38 -0
- package/src/components/Button/Button.stories.tsx +25 -0
- package/src/components/Button/Button.tsx +2 -5
- package/src/components/CrudPage/CrudPage.stories.tsx +1 -0
- package/src/components/CrudPage/CrudPageRoot.tsx +1 -1
- package/src/components/DataTable/DataTable.stories.tsx +1 -0
- package/src/components/DataTable/EmptyState/DataTableEmptyState.stories.tsx +1 -0
- package/src/components/DataTable/EmptyState/DataTableEmptyState.styles.ts +3 -1
- package/src/components/DataTable/EmptyState/DataTableEmptyState.tsx +4 -1
- package/src/components/DataTable/Item/DataTableItem.stories.tsx +1 -0
- package/src/components/Form/AccessRights/AccessRights.stories.tsx +1 -0
- package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +4 -3
- package/src/components/Form/AccessRights/ShareInput/useShareInput.tsx +15 -10
- package/src/components/Form/FormActions.tsx +21 -12
- package/src/components/Layout/AreaIndicator.tsx +4 -6
- package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
- package/src/components/Layout/PageLayout/PageLayout.tsx +9 -3
- package/src/components/Layout/PageLayout/PageLayoutActions.tsx +5 -3
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +5 -3
- package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +5 -3
- package/src/components/Layout/PageLayout/PageQuickAccess.tsx +17 -17
- package/src/components/Menu/Button/MenuButton.tsx +6 -6
- package/src/components/Menu/MenuDivider.tsx +1 -5
- package/src/components/Menu/MenuItem.tsx +1 -5
- package/src/components/Menu/MenuItems.tsx +5 -4
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.stories.tsx +1 -0
- package/src/components/Modal/ConfirmationModal/ConfirmationModal.tsx +4 -1
- package/src/components/Modal/Modal.stories.tsx +21 -0
- package/src/components/Modal/Modal.styles.ts +1 -19
- package/src/components/Modal/Modal.tsx +1 -1
- package/src/components/Modal/ModalBody.tsx +6 -4
- package/src/components/Modal/ModalHeader.tsx +9 -5
- package/src/components/Modal/modal.module.css +16 -0
- package/src/components/Tabs/Tab.styles.ts +0 -6
- package/src/components/Tabs/Tabs.tsx +37 -15
- package/src/index.ts +3 -0
- package/src/queryParameters/url/index.ts +7 -2
- package/src/utils/index.ts +1 -0
- package/src/utils/useLocale/index.ts +9 -0
- package/src/utils/useLocale/useLocale.cypress.spec.tsx +38 -0
- package/src/utils/useLocaleDateTimeFormat/index.ts +4 -2
- package/src/utils/usePluralizedTranslation.ts +2 -3
- package/src/Listing/Cell/DataCell.styles.ts +0 -27
- package/src/Listing/Header/Cell/ListingHeaderCell.styles.ts +0 -71
- package/src/Listing/Header/Cell/SelectActionListingHeaderCell.styles.ts +0 -26
- package/src/Listing/Header/ListingHeader.styles.ts +0 -16
- package/src/Listing/Listing.styles.ts +0 -78
- package/src/Listing/Row/EmptyRow.styles.ts +0 -14
- package/src/components/Button/Button.styles.ts +0 -44
- package/src/components/Layout/AreaIndicator.styles.ts +0 -33
- package/src/components/Menu/Button/MenuButton.styles.ts +0 -27
- 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
|
-
|
|
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
|
|
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.
|
|
169
|
-
cy.contains('
|
|
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
|
-
'
|
|
205
|
+
'true'
|
|
192
206
|
);
|
|
193
207
|
cy.get('[data-metric="hitratio"]').should(
|
|
194
208
|
'have.attr',
|
|
195
209
|
'data-highlight',
|
|
196
|
-
'
|
|
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,
|
|
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.
|
|
455
|
-
cy.contains('-0.
|
|
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="
|
|
522
|
-
cy.get('circle[cy="
|
|
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.
|
|
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,
|
|
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,
|
|
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={
|
|
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[
|
|
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({
|
|
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)
|
|
@@ -27,15 +27,13 @@ export const useGraphValueTooltip = ({
|
|
|
27
27
|
isSingleMode,
|
|
28
28
|
sortOrder
|
|
29
29
|
}: UseGraphValueTooltipProps): UseGraphValueTooltipState | null => {
|
|
30
|
-
const {
|
|
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:
|
|
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 {
|
|
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 =
|
|
45
|
-
|
|
46
|
-
|
|
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 -
|
|
51
|
+
? mousePointDown.x - graphMarginLeft
|
|
50
52
|
: null;
|
|
51
53
|
|
|
52
54
|
const movingMousePositionX = mousePosition
|
|
53
|
-
? mousePosition[0] -
|
|
55
|
+
? mousePosition[0] - graphMarginLeft
|
|
54
56
|
: null;
|
|
55
57
|
|
|
56
58
|
const applyZoom = (): void => {
|