@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.
Files changed (155) hide show
  1. package/dist/components/UnsuccessfulResult.component.d.ts.map +1 -1
  2. package/dist/components/accordion/Accordion.component.d.ts.map +1 -1
  3. package/dist/components/banner/Banner.component.d.ts +6 -1
  4. package/dist/components/banner/Banner.component.d.ts.map +1 -1
  5. package/dist/components/banner/Banner.component.js +30 -9
  6. package/dist/components/breadcrumb/Breadcrumb.component.d.ts.map +1 -1
  7. package/dist/components/buttonv2/CopyButton.component.d.ts.map +1 -1
  8. package/dist/components/charts/MetricsTimeSpanProvider.d.ts.map +1 -1
  9. package/dist/components/charts/barchart/Barchart.d.ts.map +1 -1
  10. package/dist/components/charts/barchart/Barchart.js +29 -19
  11. package/dist/components/charts/barchart/Barchart.utils.d.ts.map +1 -1
  12. package/dist/components/charts/barchart/BarchartTooltip.d.ts.map +1 -1
  13. package/dist/components/charts/common/ChartTooltip.d.ts.map +1 -1
  14. package/dist/components/charts/common/SharedComponents.d.ts +6 -6
  15. package/dist/components/charts/common/SharedComponents.d.ts.map +1 -1
  16. package/dist/components/charts/common/SharedComponents.js +7 -3
  17. package/dist/components/charts/common/chartUtils.d.ts +7 -2
  18. package/dist/components/charts/common/chartUtils.d.ts.map +1 -1
  19. package/dist/components/charts/common/chartUtils.js +55 -20
  20. package/dist/components/charts/globalhealthbar/GlobalHealthBar.hooks.d.ts.map +1 -1
  21. package/dist/components/charts/globalhealthbar/GlobalHealthBar.utils.d.ts +3 -1
  22. package/dist/components/charts/globalhealthbar/GlobalHealthBar.utils.d.ts.map +1 -1
  23. package/dist/components/charts/globalhealthbar/GlobalHealthBarTooltip.d.ts.map +1 -1
  24. package/dist/components/charts/globalhealthbar/HealthBarXAxis.d.ts.map +1 -1
  25. package/dist/components/charts/index.d.ts +1 -1
  26. package/dist/components/charts/index.d.ts.map +1 -1
  27. package/dist/components/charts/legend/ChartLegend.d.ts.map +1 -1
  28. package/dist/components/charts/legend/ChartLegendWrapper.d.ts.map +1 -1
  29. package/dist/components/charts/linetimeseries/LineTimeSerieChart.d.ts +12 -47
  30. package/dist/components/charts/linetimeseries/LineTimeSerieChart.d.ts.map +1 -1
  31. package/dist/components/charts/linetimeseries/LineTimeSerieChart.js +46 -220
  32. package/dist/components/charts/linetimeseries/LineTimeSerieChart.types.d.ts +77 -0
  33. package/dist/components/charts/linetimeseries/LineTimeSerieChart.types.d.ts.map +1 -0
  34. package/dist/components/charts/linetimeseries/LineTimeSerieChart.types.js +6 -0
  35. package/dist/components/charts/linetimeseries/LineTimeSerieChart.utils.d.ts.map +1 -1
  36. package/dist/components/charts/linetimeseries/LineTimeSerieChartTooltip.d.ts +18 -0
  37. package/dist/components/charts/linetimeseries/LineTimeSerieChartTooltip.d.ts.map +1 -0
  38. package/dist/components/charts/linetimeseries/LineTimeSerieChartTooltip.js +65 -0
  39. package/dist/components/charts/linetimeseries/useChartData.d.ts +44 -0
  40. package/dist/components/charts/linetimeseries/useChartData.d.ts.map +1 -0
  41. package/dist/components/charts/linetimeseries/useChartData.js +207 -0
  42. package/dist/components/charts/linetimeseries/useChartHover.d.ts +15 -0
  43. package/dist/components/charts/linetimeseries/useChartHover.d.ts.map +1 -0
  44. package/dist/components/charts/linetimeseries/useChartHover.js +29 -0
  45. package/dist/components/checkbox/Checkbox.component.d.ts.map +1 -1
  46. package/dist/components/checkbox/Checkbox.component.js +15 -7
  47. package/dist/components/constrainedtext/Constrainedtext.component.d.ts.map +1 -1
  48. package/dist/components/constrainedtext/Constrainedtext.component.js +3 -2
  49. package/dist/components/coreuithemeprovider/CoreUiThemeProvider.d.ts.map +1 -1
  50. package/dist/components/date/FormattedDateTime.d.ts.map +1 -1
  51. package/dist/components/dropdown/Dropdown.component.d.ts.map +1 -1
  52. package/dist/components/dropdown/Dropdown.component.js +3 -0
  53. package/dist/components/error-pages/ErrorPage401.component.js +1 -1
  54. package/dist/components/error-pages/ErrorPage404.component.js +1 -1
  55. package/dist/components/error-pages/ErrorPage500.component.js +1 -1
  56. package/dist/components/form/Form.component.d.ts.map +1 -1
  57. package/dist/components/form/Form.component.js +3 -3
  58. package/dist/components/icon/CustomsIcons.d.ts +10 -0
  59. package/dist/components/icon/CustomsIcons.d.ts.map +1 -1
  60. package/dist/components/icon/CustomsIcons.js +8 -0
  61. package/dist/components/icon/Icon.component.d.ts +2 -131
  62. package/dist/components/icon/Icon.component.d.ts.map +1 -1
  63. package/dist/components/icon/Icon.component.js +10 -133
  64. package/dist/components/icon/iconTable.d.ts +138 -0
  65. package/dist/components/icon/iconTable.d.ts.map +1 -0
  66. package/dist/components/icon/iconTable.js +137 -0
  67. package/dist/components/iconhelper/IconHelper.d.ts.map +1 -1
  68. package/dist/components/infomessage/InfoMessage.component.d.ts.map +1 -1
  69. package/dist/components/infomessage/InfoMessage.component.js +1 -1
  70. package/dist/components/infomessage/InfoMessageUtils.d.ts.map +1 -1
  71. package/dist/components/inlineinput/InlineInput.d.ts.map +1 -1
  72. package/dist/components/inputlist/InputButtons.d.ts.map +1 -1
  73. package/dist/components/inputlist/InputList.component.d.ts +2 -0
  74. package/dist/components/inputlist/InputList.component.d.ts.map +1 -1
  75. package/dist/components/inputlist/InputList.component.js +2 -2
  76. package/dist/components/inputv2/inputv2.d.ts +2 -0
  77. package/dist/components/inputv2/inputv2.d.ts.map +1 -1
  78. package/dist/components/inputv2/inputv2.js +6 -2
  79. package/dist/components/layout/v2/panels.d.ts.map +1 -1
  80. package/dist/components/modal/Modal.component.d.ts.map +1 -1
  81. package/dist/components/searchinput/SearchInput.component.d.ts.map +1 -1
  82. package/dist/components/searchinput/SearchInput.component.js +1 -1
  83. package/dist/components/statusicon/StatusIcon.component.d.ts.map +1 -1
  84. package/dist/components/tablev2/MultiSelectableContent.d.ts.map +1 -1
  85. package/dist/components/tablev2/Search.d.ts.map +1 -1
  86. package/dist/components/tablev2/TableCommon.d.ts.map +1 -1
  87. package/dist/components/tablev2/TableUtils.d.ts.map +1 -1
  88. package/dist/components/tablev2/Tablestyle.d.ts.map +1 -1
  89. package/dist/components/tablev2/Tablestyle.js +2 -3
  90. package/dist/components/tablev2/Tablev2.component.d.ts.map +1 -1
  91. package/dist/components/tabsv2/useScrollingTabs.d.ts.map +1 -1
  92. package/dist/components/text/Text.component.d.ts +9 -6
  93. package/dist/components/text/Text.component.d.ts.map +1 -1
  94. package/dist/components/text/Text.component.js +5 -0
  95. package/dist/components/toast/Toast.component.d.ts.map +1 -1
  96. package/dist/components/toast/useMutationsHandler.d.ts.map +1 -1
  97. package/dist/components/tooltip/Tooltip.component.js +1 -1
  98. package/dist/index.d.ts +4 -2
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +1 -0
  101. package/dist/next.d.ts +3 -3
  102. package/dist/next.d.ts.map +1 -1
  103. package/dist/organisms/attachments/AttachmentTable.d.ts.map +1 -1
  104. package/dist/spacing.d.ts.map +1 -1
  105. package/dist/utils.d.ts +16 -0
  106. package/dist/utils.d.ts.map +1 -1
  107. package/dist/utils.js +27 -0
  108. package/jest.config.js +6 -1
  109. package/package.json +7 -7
  110. package/src/lib/components/banner/Banner.component.test.tsx +58 -0
  111. package/src/lib/components/banner/Banner.component.tsx +57 -10
  112. package/src/lib/components/charts/barchart/Barchart.test.tsx +3 -1
  113. package/src/lib/components/charts/barchart/Barchart.tsx +123 -106
  114. package/src/lib/components/charts/common/SharedComponents.tsx +15 -11
  115. package/src/lib/components/charts/common/chartUtils.test.ts +27 -12
  116. package/src/lib/components/charts/common/chartUtils.ts +67 -23
  117. package/src/lib/components/charts/index.ts +1 -1
  118. package/src/lib/components/charts/linetimeseries/LineTimeSerieChart.tsx +136 -516
  119. package/src/lib/components/charts/linetimeseries/LineTimeSerieChart.types.ts +93 -0
  120. package/src/lib/components/charts/linetimeseries/LineTimeSerieChartTooltip.tsx +137 -0
  121. package/src/lib/components/charts/linetimeseries/useChartData.ts +322 -0
  122. package/src/lib/components/charts/linetimeseries/useChartHover.ts +35 -0
  123. package/src/lib/components/checkbox/Checkbox.component.tsx +19 -20
  124. package/src/lib/components/constrainedtext/Constrainedtext.component.tsx +3 -2
  125. package/src/lib/components/dropdown/Dropdown.component.tsx +3 -0
  126. package/src/lib/components/error-pages/ErrorPage401.component.tsx +1 -1
  127. package/src/lib/components/error-pages/ErrorPage404.component.tsx +1 -1
  128. package/src/lib/components/error-pages/ErrorPage500.component.tsx +1 -1
  129. package/src/lib/components/form/Form.component.tsx +5 -19
  130. package/src/lib/components/icon/CustomsIcons.tsx +36 -0
  131. package/src/lib/components/icon/Icon.component.tsx +17 -137
  132. package/src/lib/components/icon/iconTable.ts +137 -0
  133. package/src/lib/components/iconhelper/IconHelper.test.tsx +2 -2
  134. package/src/lib/components/infomessage/InfoMessage.component.tsx +1 -1
  135. package/src/lib/components/inputlist/InputList.component.tsx +4 -2
  136. package/src/lib/components/inputv2/inputv2.tsx +11 -5
  137. package/src/lib/components/searchinput/SearchInput.component.tsx +1 -0
  138. package/src/lib/components/searchinput/SearchInput.test.tsx +6 -6
  139. package/src/lib/components/tablev2/Tablestyle.tsx +2 -4
  140. package/src/lib/components/text/Text.component.tsx +18 -10
  141. package/src/lib/components/tooltip/Tooltip.component.tsx +1 -1
  142. package/src/lib/index.ts +3 -2
  143. package/src/lib/next.ts +3 -3
  144. package/src/lib/utils.ts +42 -0
  145. package/stories/GlobalHealthBar/globalhealthbar.stories.tsx +1 -1
  146. package/stories/banner.stories.tsx +37 -5
  147. package/stories/inputlist.stories.tsx +18 -6
  148. package/stories/linetimeseriechart.stories.tsx +325 -6
  149. package/tsconfig.json +1 -1
  150. package/dist/components/date/FormattedDateTime.spec.d.ts +0 -2
  151. package/dist/components/date/FormattedDateTime.spec.d.ts.map +0 -1
  152. package/dist/components/date/FormattedDateTime.spec.js +0 -161
  153. package/dist/components/date/dateDiffer.spec.d.ts +0 -2
  154. package/dist/components/date/dateDiffer.spec.d.ts.map +0 -1
  155. 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":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AACtE,OAAO,EAML,mBAAmB,EAGpB,MAAM,UAAU,CAAC;AAiClB,MAAM,MAAM,KAAK,GAAG;IAElB,QAAQ,EAAE,MAAM,CAAC;IAEjB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAEzC,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtE,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,SAAS,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;IACrC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;CAC7B,CAAC;AAGF,KAAK,qBAAqB,GAAG;IAC3B,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EACF;QACE,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;QAC3B,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;KAC5B,GACD,SAAS,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,CACzB,wBAAwB,GACxB,qBAAqB,CACxB,GAAG;IACF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,CACd,YAAY,EAAE,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,EACjD,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,KACd,KAAK,CAAC,SAAS,CAAC;CACtB,CAAC;AAiHF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,KAAK,EACL,MAAM,EACN,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,SAAiB,EACjB,UAAwB,EACxB,SAAqB,EACrB,UAAU,EACV,QAAQ,EACR,MAAM,EACN,aAAa,EACb,GAAG,IAAI,EACR,EAAE,cAAc,2CA2VhB"}
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 { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useCallback, useMemo, useRef, useState } from 'react';
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 { ChartTooltipHeader, ChartTooltipItem, ChartTooltipItemsContainer, ChartTooltipPortal, ChartTooltipSeparator, TooltipHeader, } from '../common/ChartTooltip';
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
- * Props for LineTimeSerieChart component
60
- * @param series - The data series to display
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, timeFormat = 'date-time', yAxisType = 'default', yAxisTitle, helpText, syncId, renderTooltip, ...rest }) {
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
- const [isChartActive, setIsChartActive] = useState(false);
73
- const [hoveredValue, setHoveredValue] = useState(undefined);
74
- const chartData = useMemo(() => {
75
- // Guard against empty/undefined series data
76
- if (!series || (Array.isArray(series) && series.length === 0)) {
77
- return [];
78
- }
79
- // Handle symmetrical series with empty above/below arrays
80
- if (isSymmetricalSeries(series)) {
81
- if ((!series.above || series.above.length === 0) &&
82
- (!series.below || series.below.length === 0)) {
83
- return [];
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
- 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("div", { children: _jsx(StyledResponsiveContainer, { width: "100%", height: height, children: _jsxs(LineChart, { data: rechartsData, ref: chartRef, margin: { top: 0, right: 0, bottom: 0, left: 0 }, "aria-label": `Time series chart for ${title}`, syncId: syncId, onMouseEnter: () => setIsChartActive(true), onMouseLeave: () => setIsChartActive(false), accessibilityLayer: true, 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: {
228
- fill: theme.textSecondary,
229
- fontSize: fontSize.smaller,
230
- }, axisLine: { stroke: theme.border } }), _jsx(YAxis, { orientation: "right", label: {
231
- value: yAxisTitle,
232
- angle: 90,
233
- dx: 20,
234
- style: {
235
- fill: theme.textSecondary,
236
- fontSize: fontSize.smaller,
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
- }, tickFormatter: (value) => formatToISONumber(value), ticks: getTicks(topValue, yAxisType === 'symmetrical'), interval: 0 }), _jsx(Tooltip, { content: (props) => (_jsx(LineTimeSerieChartTooltip, { unitLabel: unitLabel, duration: duration, renderTooltip: renderTooltip, isSymmetrical: yAxisType === 'symmetrical', tooltipProps: props, isChartActive: isChartActive, hoveredValue: hoveredValue, chartContainerRef: chartRef })) }), yAxisType === 'symmetrical' && (_jsx(ReferenceLine, { y: 0, stroke: theme.border })), Object.entries(groupedSeries).map(([resource, resourceSeries]) => resourceSeries.map((serie, serieIndex) => {
244
- const label = serie.getTooltipLabel(serie.metricPrefix, serie.resource);
245
- return (_jsx(Line, { type: "monotone", dataKey: label, stroke: colorMapping[resource], dot: false, isAnimationActive: false, strokeDasharray: serie.isLineDashed ? '4 4' : undefined, onMouseEnter: () => setHoveredValue(label), onMouseLeave: () => setHoveredValue(undefined) }, `${title}-${resource}-${serieIndex}`));
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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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Type guard to check if series is symmetrical (has above/below structure)
3
+ */
4
+ export const isSymmetricalSeries = (series) => {
5
+ return 'above' in series && 'below' in series;
6
+ };
@@ -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,cAChB,MAAM,YACP,MAAM,KACf,MAaF,CAAC"}
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"}