@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.
- package/package.json +25 -11
- package/public/mockServiceWorker.js +8 -31
- package/src/ActionsList/index.tsx +1 -0
- package/src/Button/Icon/index.tsx +3 -1
- 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/Annotations/Annotation/index.tsx +1 -1
- 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/helpers/index.ts +4 -3
- 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 +57 -89
- 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 +5 -3
- 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/customFetch.ts +0 -9
- package/src/api/models.ts +9 -0
- package/src/api/useBulkResponse.ts +58 -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/Actions/Actions.styles.ts +15 -1
- package/src/components/CrudPage/Actions/Actions.tsx +7 -4
- package/src/components/CrudPage/Actions/Search.tsx +15 -14
- 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/Header/PageHeader/PageHeader.styles.ts +5 -5
- package/src/components/Layout/AreaIndicator.tsx +4 -6
- package/src/components/Layout/PageLayout/PageLayout.stories.tsx +1 -0
- package/src/components/Layout/PageLayout/PageLayout.styles.ts +1 -1
- 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 +4 -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
|
@@ -20,13 +20,13 @@ import {
|
|
|
20
20
|
includes,
|
|
21
21
|
isEmpty,
|
|
22
22
|
isNil,
|
|
23
|
-
isNotNil,
|
|
24
23
|
keys,
|
|
25
24
|
last,
|
|
26
25
|
lt,
|
|
27
26
|
map,
|
|
28
27
|
negate,
|
|
29
28
|
pipe,
|
|
29
|
+
pluck,
|
|
30
30
|
prop,
|
|
31
31
|
propEq,
|
|
32
32
|
reduce,
|
|
@@ -73,7 +73,7 @@ const toTimeTickValue = (
|
|
|
73
73
|
const getMetricsForIndex = (): Omit<TimeValue, 'timeTick'> => {
|
|
74
74
|
const addMetricForTimeIndex = (acc, { metric_id, data }): TimeValue => ({
|
|
75
75
|
...acc,
|
|
76
|
-
[metric_id]: data[timeIndex]
|
|
76
|
+
[metric_id]: data[timeIndex] === undefined ? null : data[timeIndex]
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
return reduce(addMetricForTimeIndex, {} as TimeValue, metrics);
|
|
@@ -140,6 +140,7 @@ const toLine = ({
|
|
|
140
140
|
equals(ds_data.ds_stack, '1') || equals(ds_data.ds_stack, true)
|
|
141
141
|
? Number.parseInt(ds_data.ds_order || '0', 10)
|
|
142
142
|
: null,
|
|
143
|
+
stackKey: ds_data.ds_stack_key || null,
|
|
143
144
|
transparency: ds_data.ds_transparency,
|
|
144
145
|
unit
|
|
145
146
|
});
|
|
@@ -241,7 +242,10 @@ const getStackedMetricValues = ({
|
|
|
241
242
|
timeSeries
|
|
242
243
|
}: LinesTimeSeries): Array<number> => {
|
|
243
244
|
const getTimeSeriesValuesForMetric = (metric_id): Array<number> =>
|
|
244
|
-
map(
|
|
245
|
+
map(
|
|
246
|
+
(timeValue) => getValueForMetric(timeValue)(metric_id) || 0,
|
|
247
|
+
timeSeries
|
|
248
|
+
);
|
|
245
249
|
|
|
246
250
|
const metricsValues = pipe(
|
|
247
251
|
map(prop('metric_id')) as (metric) => Array<number>,
|
|
@@ -353,6 +357,19 @@ const getScaleType = (
|
|
|
353
357
|
const hasOnlyZeroesHasValue = (graphValues: Array<number>): boolean =>
|
|
354
358
|
graphValues.every((value) => equals(value, 0) || equals(value, null));
|
|
355
359
|
|
|
360
|
+
const getSanitizedValues = reject(
|
|
361
|
+
(
|
|
362
|
+
value:
|
|
363
|
+
| number
|
|
364
|
+
| boolean
|
|
365
|
+
| typeof Number.POSITIVE_INFINITY
|
|
366
|
+
| typeof Number.NEGATIVE_INFINITY
|
|
367
|
+
) =>
|
|
368
|
+
equals(value, false) ||
|
|
369
|
+
equals(value, Number.POSITIVE_INFINITY) ||
|
|
370
|
+
equals(value, Number.NEGATIVE_INFINITY)
|
|
371
|
+
);
|
|
372
|
+
|
|
356
373
|
const getScale = ({
|
|
357
374
|
graphValues,
|
|
358
375
|
height,
|
|
@@ -363,23 +380,39 @@ const getScale = ({
|
|
|
363
380
|
scaleLogarithmicBase,
|
|
364
381
|
isHorizontal,
|
|
365
382
|
invert,
|
|
366
|
-
hasDisplayAsBar
|
|
383
|
+
hasDisplayAsBar,
|
|
384
|
+
hasLineFilled,
|
|
385
|
+
min,
|
|
386
|
+
max
|
|
367
387
|
}): ScaleLinear<number, number> => {
|
|
368
388
|
const isLogScale = equals(scale, 'logarithmic');
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
389
|
+
const sanitizedValuesForMinimum = min
|
|
390
|
+
? [min]
|
|
391
|
+
: getSanitizedValues([
|
|
392
|
+
invert && graphValues.every(lt(0))
|
|
393
|
+
? negate(getMax(graphValues))
|
|
394
|
+
: getMin(graphValues),
|
|
395
|
+
!isEmpty(stackedValues) &&
|
|
396
|
+
!equals(stackedValues, [0]) &&
|
|
397
|
+
getMin(stackedValues),
|
|
398
|
+
Math.min(...thresholds)
|
|
399
|
+
]);
|
|
400
|
+
const minValue = Math.min(...sanitizedValuesForMinimum);
|
|
401
|
+
const minValueWithMargin =
|
|
402
|
+
(hasDisplayAsBar || hasLineFilled) && minValue > 0 && !min
|
|
403
|
+
? 0
|
|
404
|
+
: minValue - Math.abs(minValue) * 0.05;
|
|
405
|
+
|
|
406
|
+
const sanitizedValuesForMaximum = max
|
|
407
|
+
? [max]
|
|
408
|
+
: getSanitizedValues([
|
|
409
|
+
getMax(graphValues),
|
|
410
|
+
getMax(stackedValues),
|
|
411
|
+
hasOnlyZeroesHasValue(graphValues) ? 1 : 0,
|
|
412
|
+
Math.max(...thresholds)
|
|
413
|
+
]);
|
|
414
|
+
const maxValue = Math.max(...sanitizedValuesForMaximum);
|
|
415
|
+
const maxValueWithMargin = maxValue + Math.abs(maxValue) * 0.05;
|
|
383
416
|
|
|
384
417
|
const scaleType = getScaleType(scale);
|
|
385
418
|
|
|
@@ -387,21 +420,26 @@ const getScale = ({
|
|
|
387
420
|
const range = [height, upperRangeValue];
|
|
388
421
|
|
|
389
422
|
if (isCenteredZero) {
|
|
390
|
-
const greatestValue = Math.max(
|
|
423
|
+
const greatestValue = Math.max(
|
|
424
|
+
Math.abs(maxValueWithMargin),
|
|
425
|
+
Math.abs(minValueWithMargin)
|
|
426
|
+
);
|
|
391
427
|
|
|
392
428
|
return scaleType<number>({
|
|
393
429
|
base: scaleLogarithmicBase || 2,
|
|
394
430
|
domain: [-greatestValue, greatestValue],
|
|
395
|
-
range: isHorizontal ? range : range.reverse()
|
|
431
|
+
range: isHorizontal ? range : range.reverse(),
|
|
432
|
+
clamp: min || max
|
|
396
433
|
});
|
|
397
434
|
}
|
|
398
435
|
|
|
399
|
-
const domain = [isLogScale ? 0.001 :
|
|
436
|
+
const domain = [isLogScale ? 0.001 : minValueWithMargin, maxValueWithMargin];
|
|
400
437
|
|
|
401
438
|
return scaleType<number>({
|
|
402
439
|
base: scaleLogarithmicBase || 2,
|
|
403
440
|
domain,
|
|
404
|
-
range: isHorizontal ? range : range.reverse()
|
|
441
|
+
range: isHorizontal ? range : range.reverse(),
|
|
442
|
+
clamp: min || max
|
|
405
443
|
});
|
|
406
444
|
};
|
|
407
445
|
|
|
@@ -437,11 +475,19 @@ const getYScaleUnit = ({
|
|
|
437
475
|
scaleLogarithmicBase,
|
|
438
476
|
isHorizontal = true,
|
|
439
477
|
unit,
|
|
440
|
-
invert
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
478
|
+
invert,
|
|
479
|
+
min,
|
|
480
|
+
max,
|
|
481
|
+
isBarChart,
|
|
482
|
+
boundariesUnit
|
|
483
|
+
}: AxeScale & {
|
|
484
|
+
invert?: boolean | string | null;
|
|
485
|
+
unit: string;
|
|
486
|
+
max?: number;
|
|
487
|
+
min?: number;
|
|
488
|
+
boundariesUnit?: string;
|
|
489
|
+
isBarChart?: boolean;
|
|
490
|
+
}): ScaleLinear<number, number> => {
|
|
445
491
|
const [firstUnit] = getUnits(dataLines);
|
|
446
492
|
const shouldApplyThresholds =
|
|
447
493
|
equals(unit, thresholdUnit) || (!thresholdUnit && equals(firstUnit, unit));
|
|
@@ -468,11 +514,14 @@ const getYScaleUnit = ({
|
|
|
468
514
|
|
|
469
515
|
return getScale({
|
|
470
516
|
graphValues,
|
|
471
|
-
hasDisplayAsBar:
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
517
|
+
hasDisplayAsBar:
|
|
518
|
+
isBarChart ||
|
|
519
|
+
dataLines.some(
|
|
520
|
+
({ displayAs, unit: lineUnit }) =>
|
|
521
|
+
equals(unit, lineUnit) && equals(displayAs, 'bar')
|
|
522
|
+
),
|
|
523
|
+
hasLineFilled: dataLines.some(
|
|
524
|
+
({ unit: lineUnit, filled }) => equals(unit, lineUnit) && filled
|
|
476
525
|
),
|
|
477
526
|
height: valueGraphHeight,
|
|
478
527
|
invert,
|
|
@@ -481,10 +530,24 @@ const getYScaleUnit = ({
|
|
|
481
530
|
scale,
|
|
482
531
|
scaleLogarithmicBase,
|
|
483
532
|
stackedValues,
|
|
484
|
-
thresholds: shouldApplyThresholds ? thresholds : []
|
|
533
|
+
thresholds: shouldApplyThresholds ? thresholds : [],
|
|
534
|
+
min: boundaryToApplyToUnit({ unit, boundariesUnit, boundary: min }),
|
|
535
|
+
max: boundaryToApplyToUnit({ unit, boundariesUnit, boundary: max })
|
|
485
536
|
});
|
|
486
537
|
};
|
|
487
538
|
|
|
539
|
+
const boundaryToApplyToUnit = ({
|
|
540
|
+
boundary,
|
|
541
|
+
boundariesUnit,
|
|
542
|
+
unit
|
|
543
|
+
}): number | undefined => {
|
|
544
|
+
if (!boundariesUnit) {
|
|
545
|
+
return boundary;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return equals(boundariesUnit, unit) ? boundary : undefined;
|
|
549
|
+
};
|
|
550
|
+
|
|
488
551
|
const getYScalePerUnit = ({
|
|
489
552
|
dataLines,
|
|
490
553
|
dataTimeSeries,
|
|
@@ -494,8 +557,17 @@ const getYScalePerUnit = ({
|
|
|
494
557
|
isCenteredZero,
|
|
495
558
|
scale,
|
|
496
559
|
scaleLogarithmicBase,
|
|
497
|
-
isHorizontal = true
|
|
498
|
-
|
|
560
|
+
isHorizontal = true,
|
|
561
|
+
isBarChart,
|
|
562
|
+
min,
|
|
563
|
+
max,
|
|
564
|
+
boundariesUnit
|
|
565
|
+
}: AxeScale & {
|
|
566
|
+
min?: number;
|
|
567
|
+
max?: number;
|
|
568
|
+
isBarChart?: boolean;
|
|
569
|
+
boundariesUnit?: string;
|
|
570
|
+
}): Record<string, ScaleLinear<number, number>> => {
|
|
499
571
|
const units = getUnits(dataLines);
|
|
500
572
|
|
|
501
573
|
const scalePerUnit = units.reduce((acc, unit) => {
|
|
@@ -514,7 +586,11 @@ const getYScalePerUnit = ({
|
|
|
514
586
|
thresholdUnit,
|
|
515
587
|
thresholds,
|
|
516
588
|
unit,
|
|
517
|
-
valueGraphHeight
|
|
589
|
+
valueGraphHeight,
|
|
590
|
+
min,
|
|
591
|
+
max,
|
|
592
|
+
isBarChart,
|
|
593
|
+
boundariesUnit
|
|
518
594
|
})
|
|
519
595
|
};
|
|
520
596
|
}, {});
|
|
@@ -522,15 +598,15 @@ const getYScalePerUnit = ({
|
|
|
522
598
|
return scalePerUnit;
|
|
523
599
|
};
|
|
524
600
|
|
|
525
|
-
const formatTime = (value
|
|
526
|
-
return `${numeral(value).format('0.[00]a')}
|
|
601
|
+
const formatTime = ({ value, unit }): string => {
|
|
602
|
+
return `${numeral(value).format('0.[00]a')} ${unit}`;
|
|
527
603
|
};
|
|
528
604
|
|
|
529
605
|
const registerMsUnitToNumeral = (): null => {
|
|
530
606
|
try {
|
|
531
607
|
numeral.register('format', 'milliseconds', {
|
|
532
608
|
format: (value) => {
|
|
533
|
-
return formatTime(value);
|
|
609
|
+
return formatTime({ value, unit: 'ms' });
|
|
534
610
|
},
|
|
535
611
|
regexps: {
|
|
536
612
|
format: /(ms)/,
|
|
@@ -547,6 +623,27 @@ const registerMsUnitToNumeral = (): null => {
|
|
|
547
623
|
|
|
548
624
|
registerMsUnitToNumeral();
|
|
549
625
|
|
|
626
|
+
const registerSecondsUnitToNumeral = (): null => {
|
|
627
|
+
try {
|
|
628
|
+
numeral.register('format', 'seconds', {
|
|
629
|
+
format: (value) => {
|
|
630
|
+
return formatTime({ value, unit: 's' });
|
|
631
|
+
},
|
|
632
|
+
regexps: {
|
|
633
|
+
format: /(s)/,
|
|
634
|
+
unformat: /(s)/
|
|
635
|
+
},
|
|
636
|
+
unformat: () => ''
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
return null;
|
|
640
|
+
} catch (_) {
|
|
641
|
+
return null;
|
|
642
|
+
}
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
registerSecondsUnitToNumeral();
|
|
646
|
+
|
|
550
647
|
const getBase1024 = ({ unit, base }): boolean => {
|
|
551
648
|
const base2Units = [
|
|
552
649
|
'B',
|
|
@@ -576,6 +673,7 @@ const formatMetricValue = ({
|
|
|
576
673
|
|
|
577
674
|
const formatSuffix = cond([
|
|
578
675
|
[equals('ms'), always(' ms')],
|
|
676
|
+
[equals('s'), always(' s')],
|
|
579
677
|
[T, always(base1024 ? ' ib' : 'a')]
|
|
580
678
|
])(unit);
|
|
581
679
|
|
|
@@ -600,8 +698,6 @@ const formatMetricValueWithUnit = ({
|
|
|
600
698
|
return null;
|
|
601
699
|
}
|
|
602
700
|
|
|
603
|
-
const base1024 = getBase1024({ base, unit });
|
|
604
|
-
|
|
605
701
|
if (isRaw) {
|
|
606
702
|
const unitText = equals('%', unit) ? unit : ` ${unit}`;
|
|
607
703
|
|
|
@@ -614,9 +710,7 @@ const formatMetricValueWithUnit = ({
|
|
|
614
710
|
|
|
615
711
|
const formattedMetricValue = formatMetricValue({ base, unit, value });
|
|
616
712
|
|
|
617
|
-
return
|
|
618
|
-
? formattedMetricValue
|
|
619
|
-
: `${formattedMetricValue} ${unit}`;
|
|
713
|
+
return formattedMetricValue;
|
|
620
714
|
};
|
|
621
715
|
|
|
622
716
|
const bisectDate = bisector(identity).center;
|
|
@@ -666,6 +760,93 @@ export const formatMetricName = ({
|
|
|
666
760
|
return metricName;
|
|
667
761
|
};
|
|
668
762
|
|
|
763
|
+
export const getStackedLinesTimeSeriesPerStackAndUnit = ({
|
|
764
|
+
stackedLines,
|
|
765
|
+
timeSeries,
|
|
766
|
+
invert
|
|
767
|
+
}: {
|
|
768
|
+
stackedLines: Array<Line>;
|
|
769
|
+
timeSeries: Array<TimeValue>;
|
|
770
|
+
invert?: boolean;
|
|
771
|
+
}): {
|
|
772
|
+
stackedLinesTimeSeriesPerStackKeyAndUnit: Record<
|
|
773
|
+
string,
|
|
774
|
+
{ lines: Array<Line>; timeSeries: Array<TimeValue> }
|
|
775
|
+
>;
|
|
776
|
+
stackedKeys: Record<string, null>;
|
|
777
|
+
} => {
|
|
778
|
+
const stackedKeys = stackedLines.reduce(
|
|
779
|
+
(acc, { unit, stackKey }) => ({
|
|
780
|
+
...acc,
|
|
781
|
+
[`stacked-${unit || ''}-${stackKey ? stackKey : ''}`]: null
|
|
782
|
+
}),
|
|
783
|
+
{}
|
|
784
|
+
);
|
|
785
|
+
const stackedKeysWithOnlyStackKey = Object.keys(stackedKeys).filter(
|
|
786
|
+
(stackKey: string) => stackKey.split('-')[2]
|
|
787
|
+
);
|
|
788
|
+
const stackedKeysWithOnlyUnit = Object.keys(stackedKeys).filter(
|
|
789
|
+
(stackKey: string) => !stackKey.split('-')[2]
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
const stackedLinesTimeSeriesPerStackKey = stackedKeysWithOnlyStackKey.reduce(
|
|
793
|
+
(acc, stackedKey: string) => {
|
|
794
|
+
const [, stackUnit, stackKey] = stackedKey.split('-');
|
|
795
|
+
const relatedLines = stackedLines.filter(({ unit, stackKey: key }) => {
|
|
796
|
+
return stackUnit === (unit || '') && stackKey === key;
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
return {
|
|
800
|
+
...acc,
|
|
801
|
+
[stackedKey]: {
|
|
802
|
+
lines: relatedLines,
|
|
803
|
+
timeSeries: getTimeSeriesForLines({
|
|
804
|
+
invert,
|
|
805
|
+
lines: relatedLines,
|
|
806
|
+
timeSeries
|
|
807
|
+
})
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
},
|
|
811
|
+
{}
|
|
812
|
+
);
|
|
813
|
+
const affectedLinesPerStackKey = flatten(
|
|
814
|
+
pluck('lines', Object.values(stackedLinesTimeSeriesPerStackKey))
|
|
815
|
+
);
|
|
816
|
+
const stackedLinesTimeSeriesPerUnit = stackedKeysWithOnlyUnit.reduce(
|
|
817
|
+
(acc, stackedKey: string) => {
|
|
818
|
+
const [, stackUnit] = stackedKey.split('-');
|
|
819
|
+
const relatedLines = stackedLines.filter(
|
|
820
|
+
(line) =>
|
|
821
|
+
!affectedLinesPerStackKey.some(
|
|
822
|
+
(affectedLine) => line.metric_id === affectedLine.metric_id
|
|
823
|
+
) && stackUnit === (line.unit || '')
|
|
824
|
+
);
|
|
825
|
+
|
|
826
|
+
return {
|
|
827
|
+
...acc,
|
|
828
|
+
[stackedKey]: {
|
|
829
|
+
lines: relatedLines,
|
|
830
|
+
timeSeries: getTimeSeriesForLines({
|
|
831
|
+
lines: relatedLines,
|
|
832
|
+
timeSeries,
|
|
833
|
+
invert
|
|
834
|
+
})
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
},
|
|
838
|
+
{}
|
|
839
|
+
);
|
|
840
|
+
|
|
841
|
+
return {
|
|
842
|
+
stackedLinesTimeSeriesPerStackKeyAndUnit: {
|
|
843
|
+
...stackedLinesTimeSeriesPerStackKey,
|
|
844
|
+
...stackedLinesTimeSeriesPerUnit
|
|
845
|
+
},
|
|
846
|
+
stackedKeys
|
|
847
|
+
};
|
|
848
|
+
};
|
|
849
|
+
|
|
669
850
|
export {
|
|
670
851
|
getTimeSeries,
|
|
671
852
|
getLineData,
|
|
@@ -9,7 +9,8 @@ interface DsData {
|
|
|
9
9
|
ds_invert: string | null;
|
|
10
10
|
ds_legend: string | null;
|
|
11
11
|
ds_order: string | null;
|
|
12
|
-
ds_stack: string | null;
|
|
12
|
+
ds_stack: string | boolean | null;
|
|
13
|
+
ds_stack_key?: string | null;
|
|
13
14
|
ds_transparency: number;
|
|
14
15
|
}
|
|
15
16
|
|
|
@@ -20,7 +21,7 @@ export interface Metric {
|
|
|
20
21
|
critical_low_threshold: number | null;
|
|
21
22
|
data: Array<number | null>;
|
|
22
23
|
displayAs?: 'line' | 'bar';
|
|
23
|
-
ds_data
|
|
24
|
+
ds_data: DsData;
|
|
24
25
|
legend: string;
|
|
25
26
|
maximum_value: number | null;
|
|
26
27
|
metric: string;
|
|
@@ -29,6 +30,8 @@ export interface Metric {
|
|
|
29
30
|
unit: string;
|
|
30
31
|
warning_high_threshold: number | null;
|
|
31
32
|
warning_low_threshold: number | null;
|
|
33
|
+
service_name: string | null;
|
|
34
|
+
host_name: string | null;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
type TimeSeries = { timeTick: string };
|
|
@@ -54,6 +57,7 @@ export interface Line {
|
|
|
54
57
|
minimum_value: number | null;
|
|
55
58
|
name: string;
|
|
56
59
|
stackOrder: number | null;
|
|
60
|
+
stackKey: string | null;
|
|
57
61
|
transparency: number;
|
|
58
62
|
unit: string;
|
|
59
63
|
}
|
|
@@ -4,9 +4,11 @@ import {
|
|
|
4
4
|
always,
|
|
5
5
|
cond,
|
|
6
6
|
equals,
|
|
7
|
+
flatten,
|
|
7
8
|
gt,
|
|
8
9
|
gte,
|
|
9
10
|
head,
|
|
11
|
+
isEmpty,
|
|
10
12
|
isNil,
|
|
11
13
|
last,
|
|
12
14
|
length,
|
|
@@ -18,10 +20,12 @@ import {
|
|
|
18
20
|
|
|
19
21
|
import { Theme, darken, getLuminance, lighten } from '@mui/material';
|
|
20
22
|
|
|
23
|
+
import dayjs from 'dayjs';
|
|
21
24
|
import { BarStyle } from '../BarChart/models';
|
|
25
|
+
import { margin } from '../Chart/common';
|
|
22
26
|
import { LineStyle } from '../Chart/models';
|
|
23
27
|
import { Threshold, Thresholds } from './models';
|
|
24
|
-
import {
|
|
28
|
+
import { formatMetricValueWithUnit } from './timeSeries';
|
|
25
29
|
import { Line, TimeValue } from './timeSeries/models';
|
|
26
30
|
|
|
27
31
|
interface GetColorFromDataAndThresholdsProps {
|
|
@@ -220,23 +224,29 @@ export const getFormattedAxisValues = ({
|
|
|
220
224
|
lines,
|
|
221
225
|
threshold
|
|
222
226
|
}: GetFormattedAxisValuesProps): Array<string> => {
|
|
223
|
-
const
|
|
224
|
-
?.metric_id;
|
|
227
|
+
const filteredMetrics = lines.filter(({ unit }) => equals(unit, axisUnit));
|
|
225
228
|
|
|
226
|
-
if (
|
|
229
|
+
if (isEmpty(filteredMetrics)) {
|
|
227
230
|
return [];
|
|
228
231
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
|
|
233
|
+
const metricIds = pluck('metric_id', filteredMetrics);
|
|
234
|
+
|
|
235
|
+
const formattedData = metricIds.map((metricId) =>
|
|
236
|
+
timeSeries.map((data) =>
|
|
237
|
+
formatMetricValueWithUnit({
|
|
238
|
+
value: data[metricId],
|
|
239
|
+
unit: axisUnit,
|
|
240
|
+
base
|
|
241
|
+
})
|
|
242
|
+
)
|
|
235
243
|
);
|
|
236
244
|
|
|
245
|
+
const flattenedFormattedData = flatten(formattedData);
|
|
246
|
+
|
|
237
247
|
const formattedThresholdValues = equals(thresholdUnit, axisUnit)
|
|
238
248
|
? threshold.map(({ value }) =>
|
|
239
|
-
|
|
249
|
+
formatMetricValueWithUnit({
|
|
240
250
|
value,
|
|
241
251
|
unit: axisUnit,
|
|
242
252
|
base
|
|
@@ -244,7 +254,30 @@ export const getFormattedAxisValues = ({
|
|
|
244
254
|
) || []
|
|
245
255
|
: [];
|
|
246
256
|
|
|
247
|
-
return
|
|
257
|
+
return flattenedFormattedData
|
|
248
258
|
.concat(formattedThresholdValues)
|
|
249
259
|
.filter((v) => v) as Array<string>;
|
|
250
260
|
};
|
|
261
|
+
|
|
262
|
+
interface ComputeGElementMarginLeftProps {
|
|
263
|
+
maxCharacters: number;
|
|
264
|
+
hasSecondUnit?: boolean;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export const computeGElementMarginLeft = ({
|
|
268
|
+
maxCharacters,
|
|
269
|
+
hasSecondUnit
|
|
270
|
+
}: ComputeGElementMarginLeftProps): number =>
|
|
271
|
+
maxCharacters * 5 + (hasSecondUnit ? margin.top * 0.8 : margin.top * 0.6);
|
|
272
|
+
|
|
273
|
+
export const computPixelsToShiftMouse = (xScale): number => {
|
|
274
|
+
const domain = xScale.domain();
|
|
275
|
+
|
|
276
|
+
const hoursDiffInGraph = dayjs(domain[1]).diff(domain[0], 'h');
|
|
277
|
+
|
|
278
|
+
if (!hoursDiffInGraph) {
|
|
279
|
+
return 0;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return Math.round(8 / hoursDiffInGraph);
|
|
283
|
+
};
|
package/src/Graph/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type { ParentSizeProps } from '@visx/responsive/lib/components/ParentSize';
|
|
1
2
|
export { default as LineChart } from './Chart';
|
|
2
3
|
export { default as ThresholdLines } from './Chart/BasicComponents/Lines/Threshold';
|
|
3
4
|
export { default as useLineChartData } from './Chart/useChartData';
|
|
@@ -5,13 +6,14 @@ export { default as BarChart } from './BarChart/BarChart';
|
|
|
5
6
|
export { Gauge } from './Gauge';
|
|
6
7
|
export { SingleBar } from './SingleBar';
|
|
7
8
|
export { Text as GraphText } from './Text';
|
|
9
|
+
export { default as Header } from './common/BaseChart/Header';
|
|
8
10
|
|
|
9
11
|
export { HeatMap } from './HeatMap';
|
|
10
12
|
export { BarStack } from './BarStack';
|
|
11
13
|
export { PieChart } from './PieChart';
|
|
12
14
|
export { Timeline } from './Timeline';
|
|
13
15
|
export * from './Tree';
|
|
14
|
-
export type { LineChartData } from './common/models';
|
|
16
|
+
export type { LineChartData, Threshold, Thresholds } from './common/models';
|
|
15
17
|
export * from './common/timeSeries';
|
|
16
18
|
export type { Metric } from './common/timeSeries/models';
|
|
17
19
|
export * from './Chart/models';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"global": {},
|
|
3
|
+
"metrics": [
|
|
4
|
+
{
|
|
5
|
+
"metric": "count",
|
|
6
|
+
"metric_id": 1,
|
|
7
|
+
"legend": "count",
|
|
8
|
+
"displayAs": "bar",
|
|
9
|
+
"ds_data": {
|
|
10
|
+
"ds_stack": true,
|
|
11
|
+
"ds_transparency": 0,
|
|
12
|
+
"ds_filled": false,
|
|
13
|
+
"ds_color_area": "#4269d0",
|
|
14
|
+
"ds_color_line": "#4269d0"
|
|
15
|
+
},
|
|
16
|
+
"datasourceOptions": {
|
|
17
|
+
"field": null,
|
|
18
|
+
"group_by": null,
|
|
19
|
+
"op": "count-doc",
|
|
20
|
+
"query": "severity_text:\"Fatal\" OR severity_text:\"Error\"",
|
|
21
|
+
"period": 3600
|
|
22
|
+
},
|
|
23
|
+
"data": [
|
|
24
|
+
217, 270, 293, 300, 303, 295, 298, 283, 299, 299, 297, 285, 270, 248,
|
|
25
|
+
274, 292, 284, 47
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"metric": "count",
|
|
30
|
+
"metric_id": 2,
|
|
31
|
+
"legend": "count",
|
|
32
|
+
"displayAs": "bar",
|
|
33
|
+
"ds_data": {
|
|
34
|
+
"ds_stack": true,
|
|
35
|
+
"ds_transparency": 0,
|
|
36
|
+
"ds_filled": false,
|
|
37
|
+
"ds_color_area": "#efb118",
|
|
38
|
+
"ds_color_line": "#efb118"
|
|
39
|
+
},
|
|
40
|
+
"datasourceOptions": {
|
|
41
|
+
"field": null,
|
|
42
|
+
"group_by": null,
|
|
43
|
+
"op": "count-doc",
|
|
44
|
+
"query": "",
|
|
45
|
+
"period": 3600
|
|
46
|
+
},
|
|
47
|
+
"data": [
|
|
48
|
+
32, 825, 939, 922, 918, 939, 943, 947, 946, 909, 931, 939, 883, 907,
|
|
49
|
+
928, 904, 923, 893, 139
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"times": [
|
|
54
|
+
"2025-10-04T16:19:30.000Z",
|
|
55
|
+
"2025-10-04T16:20:00.000Z",
|
|
56
|
+
"2025-10-04T16:20:30.000Z",
|
|
57
|
+
"2025-10-04T16:21:00.000Z",
|
|
58
|
+
"2025-10-04T16:21:30.000Z",
|
|
59
|
+
"2025-10-04T16:22:00.000Z",
|
|
60
|
+
"2025-10-04T16:22:30.000Z",
|
|
61
|
+
"2025-10-04T16:23:00.000Z",
|
|
62
|
+
"2025-10-04T16:23:30.000Z",
|
|
63
|
+
"2025-10-04T16:24:00.000Z",
|
|
64
|
+
"2025-10-04T16:24:30.000Z",
|
|
65
|
+
"2025-10-04T16:25:00.000Z",
|
|
66
|
+
"2025-10-04T16:25:30.000Z",
|
|
67
|
+
"2025-10-04T16:26:00.000Z",
|
|
68
|
+
"2025-10-04T16:26:30.000Z",
|
|
69
|
+
"2025-10-04T16:27:00.000Z",
|
|
70
|
+
"2025-10-04T16:27:30.000Z",
|
|
71
|
+
"2025-10-04T16:28:00.000Z",
|
|
72
|
+
"2025-10-04T16:28:30.000Z"
|
|
73
|
+
]
|
|
74
|
+
}
|