@scality/core-ui 0.193.0 → 0.195.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/dist/components/UnsuccessfulResult.component.d.ts.map +1 -1
- package/dist/components/accordion/Accordion.component.d.ts.map +1 -1
- package/dist/components/banner/Banner.component.d.ts +6 -1
- package/dist/components/banner/Banner.component.d.ts.map +1 -1
- package/dist/components/banner/Banner.component.js +30 -9
- package/dist/components/breadcrumb/Breadcrumb.component.d.ts.map +1 -1
- package/dist/components/buttonv2/CopyButton.component.d.ts.map +1 -1
- package/dist/components/charts/MetricsTimeSpanProvider.d.ts.map +1 -1
- package/dist/components/charts/barchart/Barchart.d.ts.map +1 -1
- package/dist/components/charts/barchart/Barchart.js +29 -19
- package/dist/components/charts/barchart/Barchart.utils.d.ts.map +1 -1
- package/dist/components/charts/barchart/BarchartTooltip.d.ts.map +1 -1
- package/dist/components/charts/common/ChartTooltip.d.ts.map +1 -1
- package/dist/components/charts/common/SharedComponents.d.ts +6 -6
- package/dist/components/charts/common/SharedComponents.d.ts.map +1 -1
- package/dist/components/charts/common/SharedComponents.js +7 -3
- package/dist/components/charts/common/chartUtils.d.ts +7 -2
- package/dist/components/charts/common/chartUtils.d.ts.map +1 -1
- package/dist/components/charts/common/chartUtils.js +55 -20
- package/dist/components/charts/globalhealthbar/GlobalHealthBar.hooks.d.ts.map +1 -1
- package/dist/components/charts/globalhealthbar/GlobalHealthBar.utils.d.ts +3 -1
- package/dist/components/charts/globalhealthbar/GlobalHealthBar.utils.d.ts.map +1 -1
- package/dist/components/charts/globalhealthbar/GlobalHealthBarTooltip.d.ts.map +1 -1
- package/dist/components/charts/globalhealthbar/HealthBarXAxis.d.ts.map +1 -1
- package/dist/components/charts/index.d.ts +1 -1
- package/dist/components/charts/index.d.ts.map +1 -1
- package/dist/components/charts/legend/ChartLegend.d.ts.map +1 -1
- package/dist/components/charts/legend/ChartLegendWrapper.d.ts.map +1 -1
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.d.ts +12 -47
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.d.ts.map +1 -1
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.js +46 -220
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.types.d.ts +77 -0
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.types.d.ts.map +1 -0
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.types.js +6 -0
- package/dist/components/charts/linetimeseries/LineTimeSerieChart.utils.d.ts.map +1 -1
- package/dist/components/charts/linetimeseries/LineTimeSerieChartTooltip.d.ts +18 -0
- package/dist/components/charts/linetimeseries/LineTimeSerieChartTooltip.d.ts.map +1 -0
- package/dist/components/charts/linetimeseries/LineTimeSerieChartTooltip.js +65 -0
- package/dist/components/charts/linetimeseries/useChartData.d.ts +44 -0
- package/dist/components/charts/linetimeseries/useChartData.d.ts.map +1 -0
- package/dist/components/charts/linetimeseries/useChartData.js +207 -0
- package/dist/components/charts/linetimeseries/useChartHover.d.ts +15 -0
- package/dist/components/charts/linetimeseries/useChartHover.d.ts.map +1 -0
- package/dist/components/charts/linetimeseries/useChartHover.js +29 -0
- package/dist/components/checkbox/Checkbox.component.d.ts.map +1 -1
- package/dist/components/checkbox/Checkbox.component.js +15 -7
- package/dist/components/constrainedtext/Constrainedtext.component.d.ts.map +1 -1
- package/dist/components/constrainedtext/Constrainedtext.component.js +3 -2
- package/dist/components/coreuithemeprovider/CoreUiThemeProvider.d.ts.map +1 -1
- package/dist/components/date/FormattedDateTime.d.ts.map +1 -1
- package/dist/components/dropdown/Dropdown.component.d.ts.map +1 -1
- package/dist/components/dropdown/Dropdown.component.js +3 -0
- package/dist/components/error-pages/ErrorPage401.component.js +1 -1
- package/dist/components/error-pages/ErrorPage404.component.js +1 -1
- package/dist/components/error-pages/ErrorPage500.component.js +1 -1
- package/dist/components/form/Form.component.d.ts.map +1 -1
- package/dist/components/form/Form.component.js +3 -3
- package/dist/components/icon/CustomsIcons.d.ts +10 -0
- package/dist/components/icon/CustomsIcons.d.ts.map +1 -1
- package/dist/components/icon/CustomsIcons.js +8 -0
- package/dist/components/icon/Icon.component.d.ts +2 -131
- package/dist/components/icon/Icon.component.d.ts.map +1 -1
- package/dist/components/icon/Icon.component.js +10 -133
- package/dist/components/icon/iconTable.d.ts +138 -0
- package/dist/components/icon/iconTable.d.ts.map +1 -0
- package/dist/components/icon/iconTable.js +137 -0
- package/dist/components/iconhelper/IconHelper.d.ts.map +1 -1
- package/dist/components/infomessage/InfoMessage.component.d.ts.map +1 -1
- package/dist/components/infomessage/InfoMessage.component.js +1 -1
- package/dist/components/infomessage/InfoMessageUtils.d.ts.map +1 -1
- package/dist/components/inlineinput/InlineInput.d.ts.map +1 -1
- package/dist/components/inputlist/InputButtons.d.ts.map +1 -1
- package/dist/components/inputlist/InputList.component.d.ts +2 -0
- package/dist/components/inputlist/InputList.component.d.ts.map +1 -1
- package/dist/components/inputlist/InputList.component.js +2 -2
- package/dist/components/inputv2/inputv2.d.ts +2 -0
- package/dist/components/inputv2/inputv2.d.ts.map +1 -1
- package/dist/components/inputv2/inputv2.js +6 -2
- package/dist/components/layout/v2/panels.d.ts.map +1 -1
- package/dist/components/modal/Modal.component.d.ts.map +1 -1
- package/dist/components/searchinput/SearchInput.component.d.ts.map +1 -1
- package/dist/components/searchinput/SearchInput.component.js +1 -1
- package/dist/components/statusicon/StatusIcon.component.d.ts.map +1 -1
- package/dist/components/tablev2/MultiSelectableContent.d.ts.map +1 -1
- package/dist/components/tablev2/Search.d.ts.map +1 -1
- package/dist/components/tablev2/TableCommon.d.ts.map +1 -1
- package/dist/components/tablev2/TableUtils.d.ts.map +1 -1
- package/dist/components/tablev2/Tablestyle.d.ts.map +1 -1
- package/dist/components/tablev2/Tablestyle.js +2 -3
- package/dist/components/tablev2/Tablev2.component.d.ts.map +1 -1
- package/dist/components/tabsv2/useScrollingTabs.d.ts.map +1 -1
- package/dist/components/text/Text.component.d.ts +9 -6
- package/dist/components/text/Text.component.d.ts.map +1 -1
- package/dist/components/text/Text.component.js +5 -0
- package/dist/components/toast/Toast.component.d.ts.map +1 -1
- package/dist/components/toast/useMutationsHandler.d.ts.map +1 -1
- package/dist/components/tooltip/Tooltip.component.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/next.d.ts +3 -3
- package/dist/next.d.ts.map +1 -1
- package/dist/organisms/attachments/AttachmentTable.d.ts.map +1 -1
- package/dist/spacing.d.ts.map +1 -1
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +27 -0
- package/jest.config.js +6 -1
- package/package.json +7 -7
- package/src/lib/components/banner/Banner.component.test.tsx +58 -0
- package/src/lib/components/banner/Banner.component.tsx +57 -10
- package/src/lib/components/charts/barchart/Barchart.test.tsx +3 -1
- package/src/lib/components/charts/barchart/Barchart.tsx +123 -106
- package/src/lib/components/charts/common/SharedComponents.tsx +15 -11
- package/src/lib/components/charts/common/chartUtils.test.ts +27 -12
- package/src/lib/components/charts/common/chartUtils.ts +67 -23
- package/src/lib/components/charts/index.ts +1 -1
- package/src/lib/components/charts/linetimeseries/LineTimeSerieChart.tsx +136 -516
- package/src/lib/components/charts/linetimeseries/LineTimeSerieChart.types.ts +93 -0
- package/src/lib/components/charts/linetimeseries/LineTimeSerieChartTooltip.tsx +137 -0
- package/src/lib/components/charts/linetimeseries/useChartData.ts +322 -0
- package/src/lib/components/charts/linetimeseries/useChartHover.ts +35 -0
- package/src/lib/components/checkbox/Checkbox.component.tsx +19 -20
- package/src/lib/components/constrainedtext/Constrainedtext.component.tsx +3 -2
- package/src/lib/components/dropdown/Dropdown.component.tsx +3 -0
- package/src/lib/components/error-pages/ErrorPage401.component.tsx +1 -1
- package/src/lib/components/error-pages/ErrorPage404.component.tsx +1 -1
- package/src/lib/components/error-pages/ErrorPage500.component.tsx +1 -1
- package/src/lib/components/form/Form.component.tsx +5 -19
- package/src/lib/components/icon/CustomsIcons.tsx +36 -0
- package/src/lib/components/icon/Icon.component.tsx +17 -137
- package/src/lib/components/icon/iconTable.ts +137 -0
- package/src/lib/components/iconhelper/IconHelper.test.tsx +2 -2
- package/src/lib/components/infomessage/InfoMessage.component.tsx +1 -1
- package/src/lib/components/inputlist/InputList.component.tsx +4 -2
- package/src/lib/components/inputv2/inputv2.tsx +11 -5
- package/src/lib/components/searchinput/SearchInput.component.tsx +1 -0
- package/src/lib/components/searchinput/SearchInput.test.tsx +6 -6
- package/src/lib/components/tablev2/Tablestyle.tsx +2 -4
- package/src/lib/components/text/Text.component.tsx +18 -10
- package/src/lib/components/tooltip/Tooltip.component.tsx +1 -1
- package/src/lib/index.ts +3 -2
- package/src/lib/next.ts +3 -3
- package/src/lib/utils.ts +42 -0
- package/stories/GlobalHealthBar/globalhealthbar.stories.tsx +1 -1
- package/stories/banner.stories.tsx +37 -5
- package/stories/inputlist.stories.tsx +18 -6
- package/stories/linetimeseriechart.stories.tsx +325 -6
- package/tsconfig.json +1 -1
- package/dist/components/date/FormattedDateTime.spec.d.ts +0 -2
- package/dist/components/date/FormattedDateTime.spec.d.ts.map +0 -1
- package/dist/components/date/FormattedDateTime.spec.js +0 -161
- package/dist/components/date/dateDiffer.spec.d.ts +0 -2
- package/dist/components/date/dateDiffer.spec.d.ts.map +0 -1
- package/dist/components/date/dateDiffer.spec.js +0 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineTimeSerieChart.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/LineTimeSerieChart.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LineTimeSerieChart.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/LineTimeSerieChart.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAW5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAiB,EACjB,SAAqB,EACrB,UAAU,EACV,QAAQ,EACR,MAAM,EACN,aAAa,GACd,EAAE,cAAc,2CAgJhB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useRef } from 'react';
|
|
3
3
|
import { CartesianGrid, Line, LineChart, ReferenceLine, Tooltip, XAxis, YAxis, } from 'recharts';
|
|
4
4
|
import styled, { useTheme } from 'styled-components';
|
|
5
5
|
import { Stack } from '../../../spacing';
|
|
@@ -7,241 +7,67 @@ import { fontSize } from '../../../style/theme';
|
|
|
7
7
|
import { IconHelp } from '../../iconhelper/IconHelper';
|
|
8
8
|
import { Loader } from '../../loader/Loader.component';
|
|
9
9
|
import { ChartTitleText } from '../../text/Text.component';
|
|
10
|
-
import { LegendShape } from '../legend/ChartLegend';
|
|
11
|
-
import { useChartLegend } from '../legend/ChartLegendWrapper';
|
|
12
10
|
import { StyledResponsiveContainer } from '../common/SharedComponents';
|
|
13
|
-
import {
|
|
14
|
-
import { addMissingDataPoint, formatToISONumber, getTicks, maxWidthTooltip, normalizeChartDataWithUnits, } from '../common/chartUtils';
|
|
11
|
+
import { formatTickValue, getTicks, maxWidthTooltip } from '../common/chartUtils';
|
|
15
12
|
import { formatXAxisLabel } from './LineTimeSerieChart.utils';
|
|
13
|
+
import { LineTimeSerieChartTooltip } from './LineTimeSerieChartTooltip';
|
|
14
|
+
import { useChartHover } from './useChartHover';
|
|
15
|
+
import { useChartData } from './useChartData';
|
|
16
16
|
const LineTemporalChartWrapper = styled.div `
|
|
17
17
|
display: flex;
|
|
18
18
|
flex-direction: column;
|
|
19
19
|
justify-content: flex-start;
|
|
20
20
|
`;
|
|
21
|
-
const LineTimeSerieChartTooltip = ({ unitLabel, duration, isChartActive, tooltipProps, renderTooltip, hoveredValue, isSymmetrical, chartContainerRef, }) => {
|
|
22
|
-
const { active, payload, label, coordinate } = tooltipProps;
|
|
23
|
-
if (!active || !payload || !payload.length || !label || !isChartActive)
|
|
24
|
-
return null;
|
|
25
|
-
const tooltipContent = renderTooltip ? (renderTooltip(tooltipProps, unitLabel, duration)) : (_jsxs(_Fragment, { children: [_jsx(ChartTooltipHeader, { children: _jsx(TooltipHeader, { duration: duration, value: label }) }), _jsx(ChartTooltipItemsContainer, { children: (() => {
|
|
26
|
-
// We can't use the default itemSorter method because it's a custom tooltip.
|
|
27
|
-
// Sort the payload here instead
|
|
28
|
-
const sortedPayload = [...payload].sort((a, b) => {
|
|
29
|
-
const aValue = a.value;
|
|
30
|
-
const bValue = b.value;
|
|
31
|
-
if (aValue >= 0 && bValue >= 0) {
|
|
32
|
-
return bValue - aValue; // Higher positive values first
|
|
33
|
-
}
|
|
34
|
-
if (aValue < 0 && bValue < 0) {
|
|
35
|
-
return bValue - aValue; // Lower negative values first
|
|
36
|
-
}
|
|
37
|
-
return bValue - aValue; // Positives before negatives
|
|
38
|
-
});
|
|
39
|
-
// Find the transition point between positive and negative values
|
|
40
|
-
const separatorIndex = sortedPayload.findIndex((entry) => entry.value < 0);
|
|
41
|
-
const hasBothPositiveAndNegative = separatorIndex > 0 && separatorIndex < sortedPayload.length;
|
|
42
|
-
return sortedPayload.map((entry, index) => {
|
|
43
|
-
const legendIcon = (_jsx(LegendShape, { color: entry.color, shape: "line", chartColors: { [entry.color]: entry.color } }));
|
|
44
|
-
const isHovered = entry.name === hoveredValue;
|
|
45
|
-
const formattedValue = !Number.isFinite(entry.value)
|
|
46
|
-
? '-'
|
|
47
|
-
: `${entry.value.toFixed(2)}${unitLabel ? ` ${unitLabel}` : ''}`;
|
|
48
|
-
return (_jsxs(React.Fragment, { children: [isSymmetrical &&
|
|
49
|
-
hasBothPositiveAndNegative &&
|
|
50
|
-
index === separatorIndex && _jsx(ChartTooltipSeparator, {}), _jsx(ChartTooltipItem, { label: entry.name, value: formattedValue, legendIcon: legendIcon, isHovered: isHovered })] }, index));
|
|
51
|
-
});
|
|
52
|
-
})() })] }));
|
|
53
|
-
return (_jsx(ChartTooltipPortal, { coordinate: coordinate, chartContainerRef: chartContainerRef, isVisible: active && isChartActive, children: tooltipContent }));
|
|
54
|
-
};
|
|
55
|
-
const isSymmetricalSeries = (series) => {
|
|
56
|
-
return 'above' in series && 'below' in series;
|
|
57
|
-
};
|
|
58
21
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
22
|
+
* LineTimeSerieChart - A time series line chart component
|
|
23
|
+
*
|
|
24
|
+
* @param series - The data series to display (can be symmetrical with above/below)
|
|
61
25
|
* @param title - The title of the chart
|
|
62
26
|
* @param height - The height of the chart in pixels
|
|
63
27
|
* @param startingTimeStamp - Starting timestamp in seconds
|
|
64
28
|
* @param interval - Interval between data points in seconds
|
|
65
29
|
* @param duration - Total duration of the chart in seconds
|
|
66
|
-
*
|
|
30
|
+
* @param unitRange - Configuration for automatic unit scaling
|
|
31
|
+
* @param syncId - ID to synchronize multiple charts
|
|
32
|
+
* @param isLoading - Whether to show loading state
|
|
33
|
+
* @param yAxisType - Type of Y-axis: 'default', 'percentage', or 'symmetrical'
|
|
34
|
+
* @param yAxisTitle - Label for the Y-axis
|
|
35
|
+
* @param helpText - Help text shown as tooltip
|
|
36
|
+
* @param renderTooltip - Custom tooltip renderer
|
|
67
37
|
*/
|
|
68
|
-
export function LineTimeSerieChart({ series, title, height, startingTimeStamp, interval, duration, unitRange, isLoading = false,
|
|
38
|
+
export function LineTimeSerieChart({ series, title, height, startingTimeStamp, interval, duration, unitRange, isLoading = false, yAxisType = 'default', yAxisTitle, helpText, syncId, renderTooltip, }) {
|
|
69
39
|
const theme = useTheme();
|
|
70
|
-
const { getColor, selectedResources } = useChartLegend();
|
|
71
40
|
const chartRef = useRef(null);
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// 1. Add missing data points
|
|
87
|
-
const normalizedSeries = yAxisType === 'symmetrical' && isSymmetricalSeries(series)
|
|
88
|
-
? {
|
|
89
|
-
above: series.above
|
|
90
|
-
? series.above.map((line) => ({
|
|
91
|
-
...line,
|
|
92
|
-
data: addMissingDataPoint(line.data, startingTimeStamp, duration, interval),
|
|
93
|
-
}))
|
|
94
|
-
: [],
|
|
95
|
-
// Convert positive values to negative values
|
|
96
|
-
below: series.below
|
|
97
|
-
? series.below.map((line) => ({
|
|
98
|
-
...line,
|
|
99
|
-
data: addMissingDataPoint(line.data, startingTimeStamp, duration, interval).map(([timestamp, value]) => [
|
|
100
|
-
timestamp,
|
|
101
|
-
value === null ? null : `-${Number(value)}`,
|
|
102
|
-
]),
|
|
103
|
-
}))
|
|
104
|
-
: [],
|
|
105
|
-
}
|
|
106
|
-
: series.map((line) => ({
|
|
107
|
-
...line,
|
|
108
|
-
data: addMissingDataPoint(line.data, startingTimeStamp, duration, interval),
|
|
109
|
-
}));
|
|
110
|
-
// 2. Convert directly to Recharts format
|
|
111
|
-
// Initialize an object to hold data points by timestamp
|
|
112
|
-
const dataPointsByTime = {};
|
|
113
|
-
const seriesToProcess = yAxisType === 'symmetrical' && isSymmetricalSeries(normalizedSeries)
|
|
114
|
-
? [...normalizedSeries.above, ...normalizedSeries.below]
|
|
115
|
-
: normalizedSeries;
|
|
116
|
-
seriesToProcess.forEach((serie) => {
|
|
117
|
-
const label = serie.getTooltipLabel(serie.metricPrefix, serie.resource);
|
|
118
|
-
serie.data.forEach((point) => {
|
|
119
|
-
const timestamp = typeof point[0] === 'number' ? point[0] * 1000 : Number(point[0]);
|
|
120
|
-
const value = point[1];
|
|
121
|
-
// Initialize this timestamp if it doesn't exist
|
|
122
|
-
if (!dataPointsByTime[timestamp]) {
|
|
123
|
-
dataPointsByTime[timestamp] = { timestamp };
|
|
124
|
-
}
|
|
125
|
-
// Add this metric's value to the data point, and convert the value to a number if it's a string
|
|
126
|
-
dataPointsByTime[timestamp][label] =
|
|
127
|
-
typeof value === 'string' ? Number(value) : value;
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
// Convert object to array for Recharts
|
|
131
|
-
return Object.values(dataPointsByTime).sort((a, b) => a.timestamp - b.timestamp);
|
|
132
|
-
}, [series, startingTimeStamp, duration, interval, yAxisType]);
|
|
133
|
-
// Calculate evenly spaced ticks that avoid the very beginning and end
|
|
134
|
-
const xAxisTicks = useMemo(() => {
|
|
135
|
-
if (!chartData || chartData.length === 0)
|
|
136
|
-
return [];
|
|
137
|
-
const timestamps = chartData.map((d) => d.timestamp);
|
|
138
|
-
const minTimestamp = Math.min(...timestamps);
|
|
139
|
-
const maxTimestamp = Math.max(...timestamps);
|
|
140
|
-
const timeRange = maxTimestamp - minTimestamp;
|
|
141
|
-
// Add padding to avoid labels at the very edges (10% padding on each side)
|
|
142
|
-
const padding = timeRange * 0.1;
|
|
143
|
-
const paddedStart = minTimestamp + padding;
|
|
144
|
-
const paddedEnd = maxTimestamp - padding;
|
|
145
|
-
const paddedRange = paddedEnd - paddedStart;
|
|
146
|
-
// Create 5 evenly spaced ticks within the padded range
|
|
147
|
-
const numTicks = 5;
|
|
148
|
-
const tickInterval = paddedRange / (numTicks - 1);
|
|
149
|
-
const evenlySpacedTicks = Array.from({ length: numTicks }, (_, index) => paddedStart + index * tickInterval);
|
|
150
|
-
return evenlySpacedTicks;
|
|
151
|
-
}, [chartData]);
|
|
152
|
-
// 3. Transform the data base on the valuebase
|
|
153
|
-
const { topValue, unitLabel, rechartsData, topDomain } = useMemo(() => {
|
|
154
|
-
var _a;
|
|
155
|
-
const values = chartData.flatMap((dataPoint) => Object.entries(dataPoint)
|
|
156
|
-
.filter(([key]) => key !== 'timestamp')
|
|
157
|
-
.map(([_, value]) => {
|
|
158
|
-
if (value === null || value === undefined)
|
|
159
|
-
return null;
|
|
160
|
-
const num = typeof value === 'string' ? Number(value) : value;
|
|
161
|
-
return !isNaN(num) ? num : null;
|
|
162
|
-
})
|
|
163
|
-
.filter((value) => value !== null));
|
|
164
|
-
// Guard against empty values array
|
|
165
|
-
if (values.length === 0) {
|
|
166
|
-
return {
|
|
167
|
-
topValue: 100, // Default value for empty charts
|
|
168
|
-
unitLabel: yAxisType === 'percentage' ? '%' : undefined,
|
|
169
|
-
rechartsData: [],
|
|
170
|
-
topDomain: 100,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
const top = Math.abs(Math.max(...values));
|
|
174
|
-
const bottom = Math.abs(Math.min(...values));
|
|
175
|
-
const maxValue = Math.max(top, bottom);
|
|
176
|
-
// Use shared normalization function
|
|
177
|
-
const result = normalizeChartDataWithUnits(chartData, maxValue, unitRange, 'timestamp');
|
|
178
|
-
// For percentage charts, ensure Y-axis goes to at least 100%
|
|
179
|
-
const topDomain = yAxisType === 'percentage'
|
|
180
|
-
? Math.max(result.topDomain, 100)
|
|
181
|
-
: result.topDomain;
|
|
182
|
-
return {
|
|
183
|
-
topValue: yAxisType === 'percentage' ? Math.max(result.topValue, 100) : result.topValue,
|
|
184
|
-
unitLabel: (_a = result.unitLabel) !== null && _a !== void 0 ? _a : (yAxisType === 'percentage' ? '%' : undefined),
|
|
185
|
-
rechartsData: result.rechartsData,
|
|
186
|
-
topDomain,
|
|
187
|
-
};
|
|
188
|
-
}, [chartData, yAxisType, unitRange]);
|
|
189
|
-
// Group series by resource and create color mapping
|
|
190
|
-
const { colorMapping, groupedSeries } = useMemo(() => {
|
|
191
|
-
const mapping = {};
|
|
192
|
-
// Guard against empty/undefined series
|
|
193
|
-
if (!series) {
|
|
194
|
-
return { colorMapping: mapping, groupedSeries: {} };
|
|
195
|
-
}
|
|
196
|
-
const allSeries = isSymmetricalSeries(series)
|
|
197
|
-
? [...(series.above || []), ...(series.below || [])]
|
|
198
|
-
: series;
|
|
199
|
-
// Group series by resource
|
|
200
|
-
const groups = allSeries
|
|
201
|
-
.filter((serie) => selectedResources.includes(serie.resource))
|
|
202
|
-
.reduce((acc, serie) => {
|
|
203
|
-
const key = serie.resource;
|
|
204
|
-
if (!acc[key]) {
|
|
205
|
-
acc[key] = [];
|
|
206
|
-
}
|
|
207
|
-
acc[key].push(serie);
|
|
208
|
-
return acc;
|
|
209
|
-
}, {});
|
|
210
|
-
// Get colors from the ChartLegend context
|
|
211
|
-
Object.keys(groups).forEach((resource) => {
|
|
212
|
-
const color = getColor(resource);
|
|
213
|
-
if (color) {
|
|
214
|
-
mapping[resource] = color;
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
console.warn(`Color not defined for resource: ${resource}`);
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
return {
|
|
221
|
-
colorMapping: mapping,
|
|
222
|
-
groupedSeries: groups,
|
|
223
|
-
};
|
|
224
|
-
}, [series, getColor, selectedResources]);
|
|
225
|
-
// Format time for display the tick in the x axis
|
|
41
|
+
// Hover state management for tooltip display
|
|
42
|
+
const { handleMouseEnter, handleMouseLeave, chartId } = useChartHover();
|
|
43
|
+
// Process chart data
|
|
44
|
+
const { rechartsData, topDomain, topValue, unitLabel, xAxisTicks, linesToRender, belowSeriesLabels, } = useChartData({
|
|
45
|
+
series,
|
|
46
|
+
startingTimeStamp,
|
|
47
|
+
duration,
|
|
48
|
+
interval,
|
|
49
|
+
yAxisType,
|
|
50
|
+
unitRange,
|
|
51
|
+
});
|
|
52
|
+
// Format X-axis labels based on duration
|
|
226
53
|
const formatXAxisLabelCallback = useCallback((timestamp) => formatXAxisLabel(timestamp, duration), [duration]);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
},
|
|
238
|
-
}, domain: yAxisType === 'symmetrical'
|
|
239
|
-
? [-topDomain, topDomain]
|
|
240
|
-
: [0, topDomain], axisLine: { stroke: theme.border }, tick: {
|
|
54
|
+
// Format Y-axis tick values
|
|
55
|
+
const tickFormatter = useCallback((value) => formatTickValue(value, topValue), [topValue]);
|
|
56
|
+
return (_jsxs(LineTemporalChartWrapper, { children: [_jsxs(Stack, { gap: "r4", children: [_jsxs(ChartTitleText, { children: [title, " ", unitLabel && `(${unitLabel})`] }), helpText && (_jsx(IconHelp, { tooltipMessage: helpText, overlayStyle: maxWidthTooltip })), isLoading && _jsx(Loader, {})] }), _jsx(StyledResponsiveContainer, { width: "100%", height: height, children: _jsxs(LineChart, { ref: chartRef, data: rechartsData, margin: { top: 0, right: 0, bottom: 0, left: 0 }, "aria-label": `Time series chart for ${title}`, syncId: syncId, accessibilityLayer: true, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [_jsx(CartesianGrid, { vertical: true, horizontal: true, verticalPoints: [0], horizontalPoints: [0], stroke: theme.border, fill: theme.backgroundLevel4, strokeWidth: 1 }), _jsx(XAxis, { dataKey: "timestamp", type: "number", domain: ['dataMin', 'dataMax'], ticks: xAxisTicks, tickFormatter: formatXAxisLabelCallback, tickCount: 5, tick: {
|
|
57
|
+
fill: theme.textSecondary,
|
|
58
|
+
fontSize: fontSize.smaller,
|
|
59
|
+
}, axisLine: { stroke: theme.border } }), _jsx(YAxis, { orientation: "right", label: {
|
|
60
|
+
value: yAxisTitle,
|
|
61
|
+
angle: 90,
|
|
62
|
+
dx: 20,
|
|
63
|
+
style: {
|
|
241
64
|
fill: theme.textSecondary,
|
|
242
65
|
fontSize: fontSize.smaller,
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
66
|
+
},
|
|
67
|
+
}, domain: yAxisType === 'symmetrical'
|
|
68
|
+
? [-topDomain, topDomain]
|
|
69
|
+
: [0, topDomain], allowDataOverflow: true, axisLine: { stroke: theme.border }, tick: {
|
|
70
|
+
fill: theme.textSecondary,
|
|
71
|
+
fontSize: fontSize.smaller,
|
|
72
|
+
}, tickFormatter: tickFormatter, ticks: getTicks(topValue, yAxisType === 'symmetrical'), interval: 0 }), _jsx(Tooltip, { content: (props) => (_jsx(LineTimeSerieChartTooltip, { unitLabel: unitLabel, duration: duration, renderTooltip: renderTooltip, isSymmetrical: yAxisType === 'symmetrical', belowSeriesLabels: belowSeriesLabels, tooltipProps: props, chartContainerRef: chartRef, chartId: chartId })) }), yAxisType === 'symmetrical' && (_jsx(ReferenceLine, { y: 0, stroke: theme.border })), linesToRender.map((line) => (_jsx(Line, { type: "monotone", dataKey: line.dataKey, stroke: line.stroke, dot: false, isAnimationActive: false, strokeDasharray: line.strokeDasharray }, `${title}-${line.key}`)))] }) })] }));
|
|
247
73
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { TooltipContentProps } from 'recharts';
|
|
2
|
+
export type Serie = {
|
|
3
|
+
/** The name of the resource */
|
|
4
|
+
resource: string;
|
|
5
|
+
/** The original data format from prometheus, extend the value to include number type */
|
|
6
|
+
data: [number, number | string | null][];
|
|
7
|
+
/** Function to generate the tooltip label - mandatory for tooltip display */
|
|
8
|
+
getTooltipLabel: (metricPrefix?: string, resource?: string) => string;
|
|
9
|
+
/** The name of the metric prefix (e.g., read, write, in, out) */
|
|
10
|
+
metricPrefix?: string;
|
|
11
|
+
/** Whether the line should be dashed */
|
|
12
|
+
isLineDashed?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export type NonSymmetricalChartSerie = {
|
|
15
|
+
yAxisType?: 'default' | 'percentage';
|
|
16
|
+
series: Serie[] | undefined;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The symmetrical chart props are used to display two series on the same chart,
|
|
20
|
+
* such as in/out, write/read
|
|
21
|
+
*/
|
|
22
|
+
export type SymmetricalChartSerie = {
|
|
23
|
+
yAxisType: 'symmetrical';
|
|
24
|
+
series: {
|
|
25
|
+
above: Serie[] | undefined;
|
|
26
|
+
below: Serie[] | undefined;
|
|
27
|
+
} | undefined;
|
|
28
|
+
};
|
|
29
|
+
export type LineChartProps = (NonSymmetricalChartSerie | SymmetricalChartSerie) & {
|
|
30
|
+
/** The title of the chart */
|
|
31
|
+
title: string;
|
|
32
|
+
/** The height of the chart in pixels */
|
|
33
|
+
height: number;
|
|
34
|
+
/** Starting timestamp in seconds */
|
|
35
|
+
startingTimeStamp: number;
|
|
36
|
+
/** Interval between data points in seconds */
|
|
37
|
+
interval: number;
|
|
38
|
+
/** Total duration of the chart in seconds */
|
|
39
|
+
duration: number;
|
|
40
|
+
/** Unit range configuration for automatic unit scaling */
|
|
41
|
+
unitRange?: {
|
|
42
|
+
threshold: number;
|
|
43
|
+
label: string;
|
|
44
|
+
}[];
|
|
45
|
+
/** Sync ID for synchronizing multiple charts */
|
|
46
|
+
syncId?: string;
|
|
47
|
+
/** Whether the chart is in loading state */
|
|
48
|
+
isLoading?: boolean;
|
|
49
|
+
/** Y-axis title label */
|
|
50
|
+
yAxisTitle?: string;
|
|
51
|
+
/** Help text displayed as a tooltip icon */
|
|
52
|
+
helpText?: string;
|
|
53
|
+
/** Custom tooltip renderer */
|
|
54
|
+
renderTooltip?: (tooltipProps: TooltipContentProps<number, string>, unitLabel?: string, duration?: number) => React.ReactNode;
|
|
55
|
+
};
|
|
56
|
+
export type LineTimeSerieChartTooltipProps = {
|
|
57
|
+
tooltipProps: TooltipContentProps<number, string>;
|
|
58
|
+
unitLabel?: string;
|
|
59
|
+
duration: number;
|
|
60
|
+
renderTooltip?: (tooltipProps: TooltipContentProps<number, string>, unitLabel?: string, duration?: number) => React.ReactNode;
|
|
61
|
+
isSymmetrical?: boolean;
|
|
62
|
+
belowSeriesLabels?: Set<string>;
|
|
63
|
+
chartContainerRef: React.RefObject<HTMLDivElement>;
|
|
64
|
+
/** The unique ID of this chart instance */
|
|
65
|
+
chartId: string;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Type guard to check if series is symmetrical (has above/below structure)
|
|
69
|
+
*/
|
|
70
|
+
export declare const isSymmetricalSeries: (series: Serie[] | {
|
|
71
|
+
above: Serie[] | undefined;
|
|
72
|
+
below: Serie[] | undefined;
|
|
73
|
+
}) => series is {
|
|
74
|
+
above: Serie[];
|
|
75
|
+
below: Serie[];
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=LineTimeSerieChart.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LineTimeSerieChart.types.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/LineTimeSerieChart.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineTimeSerieChart.utils.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/LineTimeSerieChart.utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,qBAAqB,QAA4B,CAAC;AAE/D,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"LineTimeSerieChart.utils.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/LineTimeSerieChart.utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,qBAAqB,QAA4B,CAAC;AAE/D,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC3B,WAAW,MAAM,EACjB,UAAU,MAAM,KACf,MAaF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LineTimeSerieChartTooltipProps } from './LineTimeSerieChart.types';
|
|
3
|
+
/**
|
|
4
|
+
* Formats a numeric value for tooltip display
|
|
5
|
+
* - Non-finite values (NaN, null, undefined) → "-"
|
|
6
|
+
* - Zero → "0" with unit
|
|
7
|
+
* - Large values (>= 1000) → compact notation (1k, 1M)
|
|
8
|
+
* - Normal values (1-999) → up to 2 decimal places
|
|
9
|
+
* - Small values (0.01-0.99) → 2 decimal places
|
|
10
|
+
* - Very small values (< 0.01) → scientific notation (e.g., 4.7e-5)
|
|
11
|
+
*/
|
|
12
|
+
export declare const formatTooltipValue: (value: number, unitLabel?: string) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom tooltip component for LineTimeSerieChart
|
|
15
|
+
* Handles sorting, separator placement for symmetrical charts, and value formatting
|
|
16
|
+
*/
|
|
17
|
+
export declare const LineTimeSerieChartTooltip: React.FC<LineTimeSerieChartTooltipProps>;
|
|
18
|
+
//# sourceMappingURL=LineTimeSerieChartTooltip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LineTimeSerieChartTooltip.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/LineTimeSerieChartTooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,EAAE,8BAA8B,EAAE,MAAM,4BAA4B,CAAC;AAI5E;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC7B,OAAO,MAAM,EACb,YAAY,MAAM,KACjB,MAKF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAC9C,8BAA8B,CAkG7B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { LegendShape } from '../legend/ChartLegend';
|
|
4
|
+
import { ChartTooltipHeader, ChartTooltipItem, ChartTooltipItemsContainer, ChartTooltipPortal, ChartTooltipSeparator, TooltipHeader, } from '../common/ChartTooltip';
|
|
5
|
+
import { getCurrentlyHoveredChartId } from './useChartHover';
|
|
6
|
+
import { formatISONumber } from '../../../utils';
|
|
7
|
+
/**
|
|
8
|
+
* Formats a numeric value for tooltip display
|
|
9
|
+
* - Non-finite values (NaN, null, undefined) → "-"
|
|
10
|
+
* - Zero → "0" with unit
|
|
11
|
+
* - Large values (>= 1000) → compact notation (1k, 1M)
|
|
12
|
+
* - Normal values (1-999) → up to 2 decimal places
|
|
13
|
+
* - Small values (0.01-0.99) → 2 decimal places
|
|
14
|
+
* - Very small values (< 0.01) → scientific notation (e.g., 4.7e-5)
|
|
15
|
+
*/
|
|
16
|
+
export const formatTooltipValue = (value, unitLabel) => {
|
|
17
|
+
if (!Number.isFinite(value))
|
|
18
|
+
return '-';
|
|
19
|
+
const formatted = formatISONumber(value, { fixedDecimals: true, compact: true });
|
|
20
|
+
return `${formatted}${unitLabel ? ` ${unitLabel}` : ''}`;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Custom tooltip component for LineTimeSerieChart
|
|
24
|
+
* Handles sorting, separator placement for symmetrical charts, and value formatting
|
|
25
|
+
*/
|
|
26
|
+
export const LineTimeSerieChartTooltip = ({ unitLabel, duration, tooltipProps, renderTooltip, isSymmetrical, belowSeriesLabels, chartContainerRef, chartId, }) => {
|
|
27
|
+
const { active, payload, label, coordinate } = tooltipProps;
|
|
28
|
+
// Check at render time if this chart is the currently hovered one
|
|
29
|
+
// Using only the module-level variable avoids race conditions with React state updates
|
|
30
|
+
const isActiveChart = getCurrentlyHoveredChartId() === chartId;
|
|
31
|
+
if (!active || !payload || !payload.length || !label || !isActiveChart)
|
|
32
|
+
return null;
|
|
33
|
+
const tooltipContent = renderTooltip ? (renderTooltip(tooltipProps, unitLabel, duration)) : (_jsxs(_Fragment, { children: [_jsx(ChartTooltipHeader, { children: _jsx(TooltipHeader, { duration: duration, value: label }) }), _jsx(ChartTooltipItemsContainer, { children: (() => {
|
|
34
|
+
// Sort payload: above series first (descending), then below series (ascending by absolute value)
|
|
35
|
+
const sortedPayload = [...payload].sort((a, b) => {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
const aIsBelow = (_a = belowSeriesLabels === null || belowSeriesLabels === void 0 ? void 0 : belowSeriesLabels.has(a.name)) !== null && _a !== void 0 ? _a : false;
|
|
38
|
+
const bIsBelow = (_b = belowSeriesLabels === null || belowSeriesLabels === void 0 ? void 0 : belowSeriesLabels.has(b.name)) !== null && _b !== void 0 ? _b : false;
|
|
39
|
+
// Above series come before below series
|
|
40
|
+
if (aIsBelow !== bIsBelow) {
|
|
41
|
+
return aIsBelow ? 1 : -1;
|
|
42
|
+
}
|
|
43
|
+
// Within the same group:
|
|
44
|
+
// - Above series: higher values first (descending)
|
|
45
|
+
// - Below series: higher absolute values last (ascending)
|
|
46
|
+
if (aIsBelow) {
|
|
47
|
+
return Math.abs(a.value) - Math.abs(b.value);
|
|
48
|
+
}
|
|
49
|
+
return Math.abs(b.value) - Math.abs(a.value);
|
|
50
|
+
});
|
|
51
|
+
// Find the transition point between above and below series
|
|
52
|
+
const separatorIndex = sortedPayload.findIndex((entry) => belowSeriesLabels === null || belowSeriesLabels === void 0 ? void 0 : belowSeriesLabels.has(entry.name));
|
|
53
|
+
const hasBothAboveAndBelow = isSymmetrical &&
|
|
54
|
+
belowSeriesLabels &&
|
|
55
|
+
belowSeriesLabels.size > 0 &&
|
|
56
|
+
separatorIndex > 0 &&
|
|
57
|
+
separatorIndex < sortedPayload.length;
|
|
58
|
+
return sortedPayload.map((entry, index) => {
|
|
59
|
+
const legendIcon = (_jsx(LegendShape, { color: entry.color, shape: "line", chartColors: { [entry.color]: entry.color } }));
|
|
60
|
+
const formattedValue = formatTooltipValue(entry.value, unitLabel);
|
|
61
|
+
return (_jsxs(React.Fragment, { children: [hasBothAboveAndBelow && index === separatorIndex && (_jsx(ChartTooltipSeparator, {})), _jsx(ChartTooltipItem, { label: entry.name, value: formattedValue, legendIcon: legendIcon })] }, index));
|
|
62
|
+
});
|
|
63
|
+
})() })] }));
|
|
64
|
+
return (_jsx(ChartTooltipPortal, { coordinate: coordinate, chartContainerRef: chartContainerRef, isVisible: active && isActiveChart, children: tooltipContent }));
|
|
65
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Serie } from './LineTimeSerieChart.types';
|
|
2
|
+
type ChartDataInput = {
|
|
3
|
+
series: Serie[] | {
|
|
4
|
+
above: Serie[] | undefined;
|
|
5
|
+
below: Serie[] | undefined;
|
|
6
|
+
} | undefined;
|
|
7
|
+
startingTimeStamp: number;
|
|
8
|
+
duration: number;
|
|
9
|
+
interval: number;
|
|
10
|
+
yAxisType: 'default' | 'percentage' | 'symmetrical';
|
|
11
|
+
unitRange?: {
|
|
12
|
+
threshold: number;
|
|
13
|
+
label: string;
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
export type LineToRender = {
|
|
17
|
+
key: string;
|
|
18
|
+
dataKey: string;
|
|
19
|
+
stroke: string;
|
|
20
|
+
strokeDasharray?: string;
|
|
21
|
+
};
|
|
22
|
+
type ChartDataOutput = {
|
|
23
|
+
/** Processed data ready for Recharts */
|
|
24
|
+
rechartsData: Record<string, number | null>[];
|
|
25
|
+
/** Maximum value for Y-axis domain */
|
|
26
|
+
topDomain: number;
|
|
27
|
+
/** Value used for tick calculation */
|
|
28
|
+
topValue: number;
|
|
29
|
+
/** Unit label (e.g., "KiB/s", "%") */
|
|
30
|
+
unitLabel: string | undefined;
|
|
31
|
+
/** X-axis tick positions */
|
|
32
|
+
xAxisTicks: number[];
|
|
33
|
+
/** Line configurations ready for rendering */
|
|
34
|
+
linesToRender: LineToRender[];
|
|
35
|
+
/** Set of labels belonging to "below" series (for symmetrical charts) */
|
|
36
|
+
belowSeriesLabels: Set<string> | undefined;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Hook that processes chart data for LineTimeSerieChart.
|
|
40
|
+
* Handles data normalization, unit scaling, empty data handling, and series grouping.
|
|
41
|
+
*/
|
|
42
|
+
export declare function useChartData({ series, startingTimeStamp, duration, interval, yAxisType, unitRange, }: ChartDataInput): ChartDataOutput;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=useChartData.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChartData.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/charts/linetimeseries/useChartData.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAuB,MAAM,4BAA4B,CAAC;AAExE,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,KAAK,EAAE,GAAG;QAAE,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IACzF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;IACpD,SAAS,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC9C,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,4BAA4B;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,8CAA8C;IAC9C,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,yEAAyE;IACzE,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;CAC5C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAS,GACV,EAAE,cAAc,GAAG,eAAe,CA6QlC"}
|