@scality/core-ui 0.186.0 → 0.187.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 (171) hide show
  1. package/dist/components/{linetemporalchart/MetricTimespanProvider.d.ts → charts/MetricsTimeSpanProvider.d.ts} +1 -1
  2. package/dist/components/charts/MetricsTimeSpanProvider.d.ts.map +1 -0
  3. package/dist/components/{barchartv2/Barchart.component.d.ts → charts/barchart/Barchart.d.ts} +2 -33
  4. package/dist/components/charts/barchart/Barchart.d.ts.map +1 -0
  5. package/dist/components/charts/barchart/Barchart.js +56 -0
  6. package/dist/components/{barchartv2/utils.d.ts → charts/barchart/Barchart.utils.d.ts} +8 -35
  7. package/dist/components/charts/barchart/Barchart.utils.d.ts.map +1 -0
  8. package/dist/components/{barchartv2/utils.js → charts/barchart/Barchart.utils.js} +7 -88
  9. package/dist/components/{barchartv2 → charts/barchart}/BarchartTooltip.d.ts +2 -1
  10. package/dist/components/charts/barchart/BarchartTooltip.d.ts.map +1 -0
  11. package/dist/components/{barchartv2 → charts/barchart}/BarchartTooltip.js +3 -3
  12. package/dist/components/{charttooltip → charts/common}/ChartTooltip.d.ts +9 -2
  13. package/dist/components/charts/common/ChartTooltip.d.ts.map +1 -0
  14. package/dist/components/{charttooltip → charts/common}/ChartTooltip.js +11 -15
  15. package/dist/components/charts/common/SharedComponents.d.ts +47 -0
  16. package/dist/components/charts/common/SharedComponents.d.ts.map +1 -0
  17. package/dist/components/charts/common/SharedComponents.js +73 -0
  18. package/dist/components/charts/common/chartUtils.d.ts +91 -0
  19. package/dist/components/charts/common/chartUtils.d.ts.map +1 -0
  20. package/dist/components/charts/common/chartUtils.js +243 -0
  21. package/dist/components/{globalhealthbar/GlobalHealthBarRecharts.component.d.ts → charts/globalhealthbar/GlobalHealthBar.d.ts} +2 -2
  22. package/dist/components/charts/globalhealthbar/GlobalHealthBar.d.ts.map +1 -0
  23. package/dist/components/{globalhealthbar/useHealthBarData.d.ts → charts/globalhealthbar/GlobalHealthBar.hooks.d.ts} +1 -1
  24. package/dist/components/charts/globalhealthbar/GlobalHealthBar.hooks.d.ts.map +1 -0
  25. package/dist/components/{globalhealthbar/GlobalHealthBarRecharts.component.js → charts/globalhealthbar/GlobalHealthBar.js} +4 -4
  26. package/dist/components/{globalhealthbar/healthBarUtils.d.ts → charts/globalhealthbar/GlobalHealthBar.utils.d.ts} +1 -1
  27. package/dist/components/charts/globalhealthbar/GlobalHealthBar.utils.d.ts.map +1 -0
  28. package/dist/components/{globalhealthbar/healthBarUtils.js → charts/globalhealthbar/GlobalHealthBar.utils.js} +1 -1
  29. package/dist/components/{globalhealthbar/components → charts/globalhealthbar}/GlobalHealthBarTooltip.d.ts +1 -1
  30. package/dist/components/charts/globalhealthbar/GlobalHealthBarTooltip.d.ts.map +1 -0
  31. package/dist/components/{globalhealthbar/components → charts/globalhealthbar}/GlobalHealthBarTooltip.js +7 -3
  32. package/dist/components/charts/globalhealthbar/HealthBarXAxis.d.ts.map +1 -0
  33. package/dist/components/{globalhealthbar/components → charts/globalhealthbar}/HealthBarXAxis.js +1 -1
  34. package/dist/components/charts/index.d.ts +16 -0
  35. package/dist/components/charts/index.d.ts.map +1 -0
  36. package/dist/components/charts/index.js +15 -0
  37. package/dist/components/{chartlegend → charts/legend}/ChartLegend.d.ts +1 -1
  38. package/dist/components/charts/legend/ChartLegend.d.ts.map +1 -0
  39. package/dist/components/{chartlegend → charts/legend}/ChartLegend.js +2 -2
  40. package/dist/components/{chartlegend → charts/legend}/ChartLegendWrapper.d.ts +1 -1
  41. package/dist/components/charts/legend/ChartLegendWrapper.d.ts.map +1 -0
  42. package/dist/components/{linetimeseriechart/linetimeseriechart.component.d.ts → charts/linetimeseries/LineTimeSerieChart.d.ts} +12 -2
  43. package/dist/components/charts/linetimeseries/LineTimeSerieChart.d.ts.map +1 -0
  44. package/dist/components/{linetimeseriechart/linetimeseriechart.component.js → charts/linetimeseries/LineTimeSerieChart.js} +34 -35
  45. package/dist/components/charts/linetimeseries/LineTimeSerieChart.utils.d.ts +14 -0
  46. package/dist/components/charts/linetimeseries/LineTimeSerieChart.utils.d.ts.map +1 -0
  47. package/dist/components/{linetimeseriechart/utils.js → charts/linetimeseries/LineTimeSerieChart.utils.js} +4 -6
  48. package/dist/components/charts/sparkline/Sparkline.d.ts +23 -0
  49. package/dist/components/charts/sparkline/Sparkline.d.ts.map +1 -0
  50. package/dist/components/{sparkline/sparkline.component.js → charts/sparkline/Sparkline.js} +12 -6
  51. package/dist/components/charts/types.d.ts +34 -0
  52. package/dist/components/charts/types.d.ts.map +1 -0
  53. package/dist/components/charts/types.js +4 -0
  54. package/dist/components/icon/Icon.component.d.ts +1 -0
  55. package/dist/components/icon/Icon.component.d.ts.map +1 -1
  56. package/dist/components/icon/Icon.component.js +2 -2
  57. package/dist/components/textbadge/TextBadge.component.d.ts +1 -1
  58. package/dist/components/textbadge/TextBadge.component.d.ts.map +1 -1
  59. package/dist/index.d.ts +0 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +4 -2
  62. package/dist/next.d.ts +3 -11
  63. package/dist/next.d.ts.map +1 -1
  64. package/dist/next.js +4 -11
  65. package/package.json +2 -6
  66. package/src/lib/components/{barchartv2/Barchart.component.test.tsx → charts/barchart/Barchart.test.tsx} +35 -10
  67. package/src/lib/components/{barchartv2/Barchart.component.tsx → charts/barchart/Barchart.tsx} +42 -207
  68. package/src/lib/components/{barchartv2/utils.test.ts → charts/barchart/Barchart.utils.test.ts} +2 -141
  69. package/src/lib/components/{barchartv2/utils.ts → charts/barchart/Barchart.utils.ts} +17 -143
  70. package/src/lib/components/{barchartv2 → charts/barchart}/BarchartTooltip.tsx +5 -9
  71. package/src/lib/components/{charttooltip → charts/common}/ChartTooltip.tsx +13 -20
  72. package/src/lib/components/charts/common/SharedComponents.tsx +180 -0
  73. package/src/lib/components/charts/common/chartUtils.test.ts +402 -0
  74. package/src/lib/components/charts/common/chartUtils.ts +334 -0
  75. package/src/lib/components/{globalhealthbar/useHealthBarData.spec.tsx → charts/globalhealthbar/GlobalHealthBar.hooks.test.tsx} +1 -1
  76. package/src/lib/components/{globalhealthbar/GlobalHealthBarRecharts.component.tsx → charts/globalhealthbar/GlobalHealthBar.tsx} +4 -4
  77. package/src/lib/components/{globalhealthbar/healthBarUtils.spec.ts → charts/globalhealthbar/GlobalHealthBar.utils.test.ts} +1 -1
  78. package/src/lib/components/{globalhealthbar/healthBarUtils.ts → charts/globalhealthbar/GlobalHealthBar.utils.ts} +1 -1
  79. package/src/lib/components/{globalhealthbar/components → charts/globalhealthbar}/GlobalHealthBarTooltip.tsx +8 -4
  80. package/src/lib/components/{globalhealthbar/components → charts/globalhealthbar}/HealthBarXAxis.tsx +1 -1
  81. package/src/lib/components/charts/index.ts +59 -0
  82. package/src/lib/components/{chartlegend → charts/legend}/ChartLegend.tsx +2 -2
  83. package/src/lib/components/{chartlegend → charts/legend}/ChartLegendWrapper.tsx +1 -1
  84. package/src/lib/components/{linetimeseriechart/linetimeseriechart.test.tsx → charts/linetimeseries/LineTimeSerieChart.test.tsx} +3 -6
  85. package/src/lib/components/{linetimeseriechart/linetimeseriechart.component.tsx → charts/linetimeseries/LineTimeSerieChart.tsx} +48 -44
  86. package/src/lib/components/{linetimeseriechart/utils.test.ts → charts/linetimeseries/LineTimeSerieChart.utils.test.ts} +1 -1
  87. package/src/lib/components/{linetimeseriechart/utils.ts → charts/linetimeseries/LineTimeSerieChart.utils.ts} +4 -6
  88. package/src/lib/components/charts/sparkline/Sparkline.tsx +80 -0
  89. package/src/lib/components/charts/types.ts +36 -0
  90. package/src/lib/components/icon/Icon.component.tsx +12 -8
  91. package/src/lib/components/textbadge/TextBadge.component.tsx +1 -1
  92. package/src/lib/index.ts +4 -2
  93. package/src/lib/next.ts +26 -13
  94. package/stories/BarChart/barchart.stories.tsx +10 -9
  95. package/stories/GlobalHealthBar/{globalhealthbarRecharts.stories.tsx → globalhealthbar.stories.tsx} +3 -21
  96. package/stories/GlobalHealthBar/globalheathbarrecharts.guideline.mdx +2 -2
  97. package/stories/guideline/chart-guideline.mdx +1 -38
  98. package/stories/linetimeseriechart.stories.tsx +4 -6
  99. package/stories/sparkline.stories.tsx +13 -11
  100. package/stories/textbadge.stories.tsx +15 -0
  101. package/dist/components/barchart/BarChart.component.d.ts +0 -17
  102. package/dist/components/barchart/BarChart.component.d.ts.map +0 -1
  103. package/dist/components/barchart/BarChart.component.js +0 -27
  104. package/dist/components/barchartv2/Barchart.component.d.ts.map +0 -1
  105. package/dist/components/barchartv2/Barchart.component.js +0 -122
  106. package/dist/components/barchartv2/BarchartTooltip.d.ts.map +0 -1
  107. package/dist/components/barchartv2/utils.d.ts.map +0 -1
  108. package/dist/components/chartlegend/ChartLegend.d.ts.map +0 -1
  109. package/dist/components/chartlegend/ChartLegendWrapper.d.ts.map +0 -1
  110. package/dist/components/charttooltip/ChartTooltip.d.ts.map +0 -1
  111. package/dist/components/globalhealthbar/GlobalHealthBar.component.d.ts +0 -23
  112. package/dist/components/globalhealthbar/GlobalHealthBar.component.d.ts.map +0 -1
  113. package/dist/components/globalhealthbar/GlobalHealthBar.component.js +0 -173
  114. package/dist/components/globalhealthbar/GlobalHealthBarRecharts.component.d.ts.map +0 -1
  115. package/dist/components/globalhealthbar/components/GlobalHealthBarTooltip.d.ts.map +0 -1
  116. package/dist/components/globalhealthbar/components/HealthBarXAxis.d.ts.map +0 -1
  117. package/dist/components/globalhealthbar/healthBarUtils.d.ts.map +0 -1
  118. package/dist/components/globalhealthbar/healthBarUtils.spec.d.ts +0 -2
  119. package/dist/components/globalhealthbar/healthBarUtils.spec.d.ts.map +0 -1
  120. package/dist/components/globalhealthbar/healthBarUtils.spec.js +0 -391
  121. package/dist/components/globalhealthbar/tooltip/index.d.ts +0 -8
  122. package/dist/components/globalhealthbar/tooltip/index.d.ts.map +0 -1
  123. package/dist/components/globalhealthbar/tooltip/index.js +0 -55
  124. package/dist/components/globalhealthbar/useHealthBarData.d.ts.map +0 -1
  125. package/dist/components/globalhealthbar/useHealthBarData.spec.d.ts +0 -2
  126. package/dist/components/globalhealthbar/useHealthBarData.spec.d.ts.map +0 -1
  127. package/dist/components/globalhealthbar/useHealthBarData.spec.js +0 -209
  128. package/dist/components/linetemporalchart/ChartUtil.d.ts +0 -41
  129. package/dist/components/linetemporalchart/ChartUtil.d.ts.map +0 -1
  130. package/dist/components/linetemporalchart/ChartUtil.js +0 -148
  131. package/dist/components/linetemporalchart/LineTemporalChart.component.d.ts +0 -46
  132. package/dist/components/linetemporalchart/LineTemporalChart.component.d.ts.map +0 -1
  133. package/dist/components/linetemporalchart/LineTemporalChart.component.js +0 -579
  134. package/dist/components/linetemporalchart/MetricTimespanProvider.d.ts.map +0 -1
  135. package/dist/components/linetemporalchart/tooltip/index.d.ts +0 -30
  136. package/dist/components/linetemporalchart/tooltip/index.d.ts.map +0 -1
  137. package/dist/components/linetemporalchart/tooltip/index.js +0 -104
  138. package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts.map +0 -1
  139. package/dist/components/linetimeseriechart/utils.d.ts +0 -16
  140. package/dist/components/linetimeseriechart/utils.d.ts.map +0 -1
  141. package/dist/components/sparkline/sparkline.component.d.ts +0 -17
  142. package/dist/components/sparkline/sparkline.component.d.ts.map +0 -1
  143. package/dist/components/vegachartv2/SyncedCursorCharts.d.ts +0 -12
  144. package/dist/components/vegachartv2/SyncedCursorCharts.d.ts.map +0 -1
  145. package/dist/components/vegachartv2/SyncedCursorCharts.js +0 -15
  146. package/dist/components/vegachartv2/VegaChartV2.component.d.ts +0 -15
  147. package/dist/components/vegachartv2/VegaChartV2.component.d.ts.map +0 -1
  148. package/dist/components/vegachartv2/VegaChartV2.component.js +0 -218
  149. package/src/lib/components/barchart/BarChart.component.tsx +0 -51
  150. package/src/lib/components/globalhealthbar/GlobalHealthBar.component.tsx +0 -204
  151. package/src/lib/components/globalhealthbar/tooltip/index.ts +0 -72
  152. package/src/lib/components/linetemporalchart/ChartUtil.test.ts +0 -250
  153. package/src/lib/components/linetemporalchart/ChartUtil.ts +0 -225
  154. package/src/lib/components/linetemporalchart/LineTemporalChart.component.tsx +0 -800
  155. package/src/lib/components/linetemporalchart/tooltip/index.ts +0 -178
  156. package/src/lib/components/sparkline/sparkline.component.tsx +0 -56
  157. package/src/lib/components/vegachartv2/SyncedCursorCharts.tsx +0 -28
  158. package/src/lib/components/vegachartv2/VegaChartV2.component.tsx +0 -276
  159. package/stories/barchart.stories.tsx +0 -142
  160. package/stories/globalhealthbar.stories.tsx +0 -191
  161. package/stories/guideline/mdxExampleComponents.tsx +0 -57
  162. package/stories/linecharttemporal.stories.tsx +0 -88
  163. /package/dist/components/{linetemporalchart/MetricTimespanProvider.js → charts/MetricsTimeSpanProvider.js} +0 -0
  164. /package/dist/components/{globalhealthbar/useHealthBarData.js → charts/globalhealthbar/GlobalHealthBar.hooks.js} +0 -0
  165. /package/dist/components/{globalhealthbar/components → charts/globalhealthbar}/HealthBarXAxis.d.ts +0 -0
  166. /package/dist/components/{chartlegend → charts/legend}/ChartLegendWrapper.js +0 -0
  167. /package/src/lib/components/{linetemporalchart/MetricTimespanProvider.tsx → charts/MetricsTimeSpanProvider.tsx} +0 -0
  168. /package/src/lib/components/{barchartv2 → charts/barchart}/BarchartTooltip.test.tsx +0 -0
  169. /package/src/lib/components/{globalhealthbar/useHealthBarData.ts → charts/globalhealthbar/GlobalHealthBar.hooks.ts} +0 -0
  170. /package/src/lib/components/{chartlegend → charts/legend}/ChartLegend.test.tsx +0 -0
  171. /package/src/lib/components/{chartlegend → charts/legend}/ChartLegendWrapper.test.tsx +0 -0
@@ -1,26 +1,28 @@
1
1
  import { useState, useRef } from 'react';
2
2
  import {
3
3
  Bar,
4
- BarChart,
4
+ BarChart as RechartsBarChart,
5
5
  CartesianGrid,
6
- ResponsiveContainer,
7
6
  Tooltip,
8
7
  TooltipContentProps,
9
8
  XAxis,
10
9
  YAxis,
11
10
  } from 'recharts';
12
- import styled, { useTheme } from 'styled-components';
13
- import { spacing, Stack, Wrap } from '../../spacing';
14
- import { chartColors, ChartColors, fontSize } from '../../style/theme';
15
- import { Box } from '../box/Box';
16
- import { useChartLegend } from '../chartlegend/ChartLegendWrapper';
17
- import { ConstrainedText } from '../constrainedtext/Constrainedtext.component';
18
- import { FormattedDateTime } from '../date/FormattedDateTime';
19
- import { IconHelp } from '../iconhelper/IconHelper';
20
- import { Loader } from '../loader/Loader.component';
21
- import { Text } from '../text/Text.component';
11
+ import { useTheme } from 'styled-components';
12
+ import { Stack } from '../../../spacing';
13
+ import { chartColors, ChartColors, fontSize } from '../../../style/theme';
14
+ import { useChartLegend } from '../legend/ChartLegendWrapper';
22
15
  import { BarchartTooltip } from './BarchartTooltip';
23
- import { getTicks, UnitRange, useChartData } from './utils';
16
+ import { formatToISONumber, getTicks } from '../common/chartUtils';
17
+ import { useChartData } from './Barchart.utils';
18
+ import {
19
+ ChartHeader,
20
+ ChartError,
21
+ ChartLoading,
22
+ CustomTick,
23
+ StyledResponsiveContainer,
24
+ } from '../common/SharedComponents';
25
+ import { TimeType, CategoryType, UnitRange } from '../types';
24
26
 
25
27
  const CHART_CONSTANTS = {
26
28
  TICK_WIDTH_OFFSET: 4,
@@ -34,23 +36,9 @@ const CHART_CONSTANTS = {
34
36
  bottom: 0,
35
37
  },
36
38
  };
37
- const maxWidthTooltip = { maxWidth: '20rem' };
38
39
 
39
40
  /* ---------------------------------- TYPE ---------------------------------- */
40
41
 
41
- export type TimeType = {
42
- type: 'time';
43
- timeRange: {
44
- startDate: Date;
45
- endDate: Date;
46
- interval: number;
47
- };
48
- };
49
-
50
- export type CategoryType = {
51
- type: 'category';
52
- gap?: number;
53
- };
54
42
  export type Point = {
55
43
  key: string | number;
56
44
  values: { label: string; value: number }[];
@@ -98,168 +86,6 @@ export type BarchartProps<T extends BarchartBars> = {
98
86
  isError?: boolean;
99
87
  };
100
88
 
101
- interface CustomTickProps {
102
- x: number;
103
- y: number;
104
- payload: {
105
- value: number;
106
- };
107
- visibleTicksCount: number;
108
- width: number;
109
- type: TimeType;
110
- }
111
-
112
- /* ---------------------------------- COMPONENTS ---------------------------------- */
113
-
114
- /**
115
- * Get the format of the date based on the duration
116
- * @param duration - Duration in seconds
117
- * @returns Formatted string
118
- */
119
- export const formatDate = (
120
- duration: number,
121
- ): 'time' | 'day-month-abbreviated' | 'chart-long-term-date' => {
122
- if (duration <= 24 * 60 * 60) {
123
- return 'time';
124
- } else if (duration <= 7 * 24 * 60 * 60) {
125
- return 'day-month-abbreviated';
126
- } else {
127
- return 'chart-long-term-date';
128
- }
129
- };
130
-
131
- export const CustomTick = ({
132
- x,
133
- y,
134
- payload,
135
- visibleTicksCount,
136
- width,
137
- type,
138
- }: CustomTickProps) => {
139
- const theme = useTheme();
140
- const tickWidth =
141
- width / visibleTicksCount - CHART_CONSTANTS.TICK_WIDTH_OFFSET;
142
- const centerX = x - tickWidth / 2;
143
-
144
- const duration =
145
- type.type === 'time'
146
- ? (type.timeRange.endDate.getTime() -
147
- type.timeRange.startDate.getTime()) /
148
- 1000
149
- : 0;
150
-
151
- return (
152
- <foreignObject
153
- x={centerX}
154
- y={y - 8}
155
- width={tickWidth}
156
- color={theme.textSecondary}
157
- overflow="visible"
158
- >
159
- <ConstrainedText
160
- color="textSecondary"
161
- text={
162
- <Text variant="Smaller">
163
- {type.type === 'time' ? (
164
- <FormattedDateTime
165
- format={formatDate(duration)}
166
- value={new Date(payload.value)}
167
- />
168
- ) : (
169
- String(payload.value)
170
- )}
171
- </Text>
172
- }
173
- centered
174
- tooltipStyle={{
175
- backgroundColor: theme.backgroundLevel1,
176
- padding: spacing.r10,
177
- borderRadius: spacing.r8,
178
- border: `1px solid ${theme.border}`,
179
- position: 'absolute',
180
- }}
181
- />
182
- </foreignObject>
183
- );
184
- };
185
-
186
- export const StyledResponsiveContainer = styled(ResponsiveContainer)`
187
- // Avoid tooltip over constrained text to be cut off
188
- & .recharts-surface {
189
- outline: none;
190
- overflow: visible;
191
- }
192
- `;
193
-
194
- const ChartHeader = ({
195
- title,
196
- secondaryTitle,
197
- helpTooltip,
198
- rightTitle,
199
- }: {
200
- title?: string;
201
- secondaryTitle?: string;
202
- helpTooltip?: React.ReactNode;
203
- rightTitle?: React.ReactNode;
204
- }) => {
205
- return (
206
- <Wrap>
207
- <Stack gap="r4">
208
- <Text variant="ChartTitle">{title}</Text>
209
- {helpTooltip && (
210
- <IconHelp
211
- tooltipMessage={helpTooltip}
212
- overlayStyle={maxWidthTooltip}
213
- />
214
- )}
215
-
216
- {secondaryTitle && (
217
- <Text
218
- color="textSecondary"
219
- style={{
220
- marginLeft: spacing.r8,
221
- }}
222
- >
223
- {secondaryTitle}
224
- </Text>
225
- )}
226
- </Stack>
227
-
228
- {rightTitle && <Text>{rightTitle}</Text>}
229
- </Wrap>
230
- );
231
- };
232
-
233
- const Error = ({ height }: { height: number }) => {
234
- return (
235
- <Box
236
- height={height}
237
- style={{
238
- alignItems: 'center',
239
- justifyContent: 'center',
240
- display: 'flex',
241
- }}
242
- >
243
- <Text>Chart data is not available</Text>
244
- </Box>
245
- );
246
- };
247
-
248
- const Loading = ({ height }: { height: number }) => {
249
- return (
250
- <Box
251
- height={height}
252
- style={{
253
- alignItems: 'center',
254
- justifyContent: 'center',
255
- display: 'flex',
256
- }}
257
- >
258
- <Loader size="larger" children={<Text>Loading Chart Data...</Text>} />
259
- </Box>
260
- );
261
- };
262
-
263
89
  /* ---------------------------------- MAIN COMPONENT ---------------------------------- */
264
90
 
265
91
  export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
@@ -297,16 +123,21 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
297
123
  {} as Record<string, ChartColors | string>,
298
124
  );
299
125
 
300
- const { rechartsBars, unitLabel, roundReferenceValue, rechartsData, topDomain } =
301
- useChartData(
302
- bars || [],
303
- type,
304
- colorSet || {},
305
- stacked,
306
- defaultSort,
307
- unitRange,
308
- stackedBarSort,
309
- );
126
+ const {
127
+ rechartsBars,
128
+ unitLabel,
129
+ roundReferenceValue,
130
+ rechartsData,
131
+ topDomain,
132
+ } = useChartData(
133
+ bars || [],
134
+ type,
135
+ colorSet || {},
136
+ stacked,
137
+ defaultSort,
138
+ unitRange,
139
+ stackedBarSort,
140
+ );
310
141
  const titleWithUnit = unitLabel ? `${title} (${unitLabel})` : title;
311
142
  return (
312
143
  <Stack direction="vertical" style={{ gap: '0' }}>
@@ -317,12 +148,12 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
317
148
  rightTitle={rightTitle}
318
149
  />
319
150
  {isError || (!bars && !isLoading) ? (
320
- <Error height={height} />
151
+ <ChartError height={height} />
321
152
  ) : isLoading ? (
322
- <Loading height={height} />
153
+ <ChartLoading height={height} />
323
154
  ) : (
324
155
  <StyledResponsiveContainer ref={chartRef} width="100%" height={height}>
325
- <BarChart
156
+ <RechartsBarChart
326
157
  data={rechartsData}
327
158
  accessibilityLayer
328
159
  barSize={
@@ -365,9 +196,7 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
365
196
  interval={0}
366
197
  domain={[0, topDomain]}
367
198
  ticks={getTicks(roundReferenceValue, false)}
368
- tickFormatter={
369
- (value) => new Intl.NumberFormat('fr-FR').format(value) // Add a space as thousand separator
370
- }
199
+ tickFormatter={(value) => formatToISONumber(value)}
371
200
  axisLine={{ stroke: theme.border }}
372
201
  tick={{
373
202
  fill: theme.textSecondary,
@@ -378,7 +207,13 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
378
207
 
379
208
  <XAxis
380
209
  dataKey="category"
381
- tick={(props) => <CustomTick {...props} type={type} />}
210
+ tick={(props) => (
211
+ <CustomTick
212
+ {...props}
213
+ type={type}
214
+ tickWidthOffset={CHART_CONSTANTS.TICK_WIDTH_OFFSET}
215
+ />
216
+ )}
382
217
  type="category"
383
218
  interval={0}
384
219
  allowDataOverflow={true}
@@ -404,7 +239,7 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
404
239
  )}
405
240
  cursor={false}
406
241
  />
407
- </BarChart>
242
+ </RechartsBarChart>
408
243
  </StyledResponsiveContainer>
409
244
  )}
410
245
  </Stack>
@@ -1,18 +1,14 @@
1
- import { coreUIAvailableThemes } from '../../style/theme';
1
+ import { coreUIAvailableThemes } from '../../../style/theme';
2
2
  import {
3
3
  applySortingToData,
4
- computeUnitLabelAndRoundReferenceValue,
5
4
  filterChartDataAndBarsByLegendSelection,
6
5
  formatPrometheusDataToRechartsDataAndBars,
7
6
  getCurrentPoint,
8
7
  getMaxBarValue,
9
- getRoundReferenceValue,
10
- getTicks,
11
8
  sortStackedBars,
12
9
  transformCategoryData,
13
10
  transformTimeData,
14
- UnitRange,
15
- } from './utils';
11
+ } from './Barchart.utils';
16
12
 
17
13
  // Test date constants to avoid repetition
18
14
  const TEST_DATES = {
@@ -504,77 +500,6 @@ describe('applySortingToData', () => {
504
500
  });
505
501
  });
506
502
 
507
- describe('getRoundReferenceValue', () => {
508
- it('should return appropriate rounded values with 10% buffer', () => {
509
- // Small values (< 10)
510
- expect(getRoundReferenceValue(0.1)).toBe(0.1); // 0.1 → 0.11 → 0.1 (magnitude 0.1, remainder 0.01)
511
- expect(getRoundReferenceValue(1)).toBe(1); // 1 → 1.1 → 1 (magnitude 1, remainder 0.1)
512
- expect(getRoundReferenceValue(2)).toBe(2); // 2 → 2.2 → 2 (magnitude 1, remainder 0.2)
513
- expect(getRoundReferenceValue(3)).toBe(3); // 3 → 3.3 → 3 (magnitude 1, remainder 0.3)
514
-
515
- // Values 5-10 range
516
- expect(getRoundReferenceValue(6)).toBe(6); // 6 → 6.6 → 6 (magnitude 1, remainder 0.6)
517
- expect(getRoundReferenceValue(9)).toBe(9); // 9 → 9.9 → 9 (magnitude 1, remainder 0.9)
518
-
519
- // Larger values get 10% buffer applied
520
- expect(getRoundReferenceValue(15)).toBe(10); // 15 → 16.5, remainder 5, incremented 20 > 16.5, so round down to 10
521
- expect(getRoundReferenceValue(35)).toBe(30); // 35 → 38.5, remainder 5, incremented 40 > 38.5, so round down to 30
522
- expect(getRoundReferenceValue(75)).toBe(80); // 75 → 82.5, remainder 5, incremented 80 <= 82.5, so round up to 80
523
- expect(getRoundReferenceValue(150)).toBe(150); // 150 → 165, remainder 0, so return 150
524
- expect(getRoundReferenceValue(350)).toBe(350); // 350 → 385, remainder 0, so return 350
525
- expect(getRoundReferenceValue(750)).toBe(750); // 750 → 825, remainder 0, so return 750
526
- expect(getRoundReferenceValue(1500)).toBe(1500); // 1500 → 1650, remainder 0, so return 1500
527
- expect(getRoundReferenceValue(3500)).toBe(3500); // 3500 → 3850, remainder 0, so return 3500
528
- expect(getRoundReferenceValue(7500)).toBe(7500); // 7500 → 8250, remainder 0, so return 7500
529
- expect(getRoundReferenceValue(15000)).toBe(15000); // 15000 → 16500, remainder 0, so return 15000
530
- });
531
- });
532
-
533
- describe('getTicks', () => {
534
- describe('small values (< 10)', () => {
535
- it('should return 2 ticks for non-symmetrical small values', () => {
536
- expect(getTicks(1, false)).toEqual([0, 0.5, 1]); // 1 % 2 != 0, defaults to 3 ticks
537
- expect(getTicks(2, false)).toEqual([0, 1, 2]); // 2 % (3-1) == 0, uses 3 ticks
538
- expect(getTicks(5, false)).toEqual([0, 2.5, 5]); // 5 % 2 != 0 and 5 % 3 != 0, defaults to 3 ticks
539
- });
540
-
541
- it('should return 3 ticks for symmetrical small values', () => {
542
- expect(getTicks(1, true)).toEqual([-1, -0.5, 0, 0.5, 1]); // 1 % 2 != 0, defaults to 3 ticks, symmetrical adds negatives
543
- expect(getTicks(2, true)).toEqual([-2, -1, 0, 1, 2]); // 2 % (3-1) == 0, uses 3 ticks, symmetrical adds negatives
544
- expect(getTicks(5, true)).toEqual([-5, -2.5, 0, 2.5, 5]); // 5 % 2 != 0 and 5 % 3 != 0, defaults to 3 ticks, symmetrical adds negatives
545
- });
546
- });
547
-
548
- describe('even topValue (divisible by 2)', () => {
549
- it('should return 3 ticks for non-symmetrical even values', () => {
550
- expect(getTicks(10, false)).toEqual([0, 5, 10]);
551
- expect(getTicks(20, false)).toEqual([0, 10, 20]);
552
- expect(getTicks(40, false)).toEqual([0, 20, 40]);
553
- expect(getTicks(50, false)).toEqual([0, 25, 50]);
554
- expect(getTicks(100, false)).toEqual([0, 50, 100]);
555
- expect(getTicks(1000, false)).toEqual([0, 500, 1000]);
556
- });
557
-
558
- it('should return 5 ticks for symmetrical even values', () => {
559
- expect(getTicks(10, true)).toEqual([-10, -5, 0, 5, 10]);
560
- expect(getTicks(100, true)).toEqual([-100, -50, 0, 50, 100]);
561
- });
562
- });
563
-
564
- describe('odd topValue (not divisible by 2) - 7.5 multiples', () => {
565
- it('should return 4 ticks for non-symmetrical values from 7.5 × magnitude', () => {
566
- expect(getTicks(75, false)).toEqual([0, 25, 50, 75]);
567
- expect(getTicks(750, false)).toEqual([0, 250, 500, 750]);
568
- expect(getTicks(7500, false)).toEqual([0, 2500, 5000, 7500]);
569
- });
570
-
571
- it('should return 7 ticks for symmetrical values from 7.5 × magnitude', () => {
572
- expect(getTicks(75, true)).toEqual([-75, -50, -25, 0, 25, 50, 75]);
573
- expect(getTicks(750, true)).toEqual([-750, -500, -250, 0, 250, 500, 750]);
574
- });
575
- });
576
- });
577
-
578
503
  describe('getMaxBarValue', () => {
579
504
  it('should return the maximum value from chart data', () => {
580
505
  const data = [
@@ -716,70 +641,6 @@ describe('formatPrometheusDataToRechartsDataAndBars', () => {
716
641
  });
717
642
  });
718
643
 
719
- describe('computeUnitLabelAndRoundReferenceValue', () => {
720
- it('should compute the unit label and round reference value correctly when reaching threshold', () => {
721
- const data = [
722
- {
723
- category: 'category1',
724
- success: 1680,
725
- },
726
- ];
727
- const maxValue = 1680;
728
- const unitRange: UnitRange = [
729
- {
730
- threshold: 1000,
731
- label: 'kB',
732
- },
733
- ];
734
- const result = computeUnitLabelAndRoundReferenceValue(
735
- data,
736
- maxValue,
737
- unitRange,
738
- );
739
-
740
- expect(result.unitLabel).toBe('kB');
741
- // 1680 / 1000 = 1.68, with buffer: 1.848 → rounds to 1 (magnitude 1, remainder 0.848)
742
- expect(result.roundReferenceValue).toBe(1);
743
- expect(result.rechartsData).toEqual([
744
- {
745
- category: 'category1',
746
- success: 1.68,
747
- },
748
- ]);
749
- });
750
- it('should compute the unit label and round reference value correctly when threshold is 0', () => {
751
- const data = [
752
- {
753
- category: 'category1',
754
- success: 680,
755
- },
756
- ];
757
- const maxValue = 680;
758
- const unitRange: UnitRange = [
759
- {
760
- threshold: 0,
761
- label: 'B',
762
- },
763
- {
764
- threshold: 1000,
765
- label: 'kB',
766
- },
767
- ];
768
- const result = computeUnitLabelAndRoundReferenceValue(
769
- data,
770
- maxValue,
771
- unitRange,
772
- );
773
-
774
- expect(result.unitLabel).toBe('B');
775
- // 680 with buffer: 748 → rounds to 680 (value >= 10, remainder 0, rounds down)
776
- expect(result.roundReferenceValue).toBe(680);
777
- expect(result.rechartsData).toEqual([
778
- { category: 'category1', success: 680 },
779
- ]);
780
- });
781
- });
782
-
783
644
  describe('sortStackedBars', () => {
784
645
  const bars = [
785
646
  { dataKey: 'bar1', fill: 'blue' },
@@ -1,58 +1,9 @@
1
- import { BarchartProps, BarchartBars } from './Barchart.component';
1
+ import { BarchartProps, BarchartBars } from './Barchart';
2
2
  import { TooltipContentProps } from 'recharts';
3
- import { chartColors, ChartColors } from '../../style/theme';
4
- import { useChartLegend } from '../chartlegend/ChartLegendWrapper';
5
-
6
- export const getRoundReferenceValue = (value: number): number => {
7
- if (value <= 0) return 1; // Default for zero or negative values
8
-
9
- // Buffer the value by 10% to avoid being too close to the edge of the chart
10
- const bufferedValue = value * 1.1;
11
-
12
- if (value >= 10) {
13
- const remainder = value % 10;
14
- const incremented = value + (10 - remainder);
15
-
16
- // If the remainder is less than 5, round down to the nearest 10
17
- if (remainder < 5) {
18
- return value - remainder;
19
- }
20
-
21
- // If incrementing would exceed the buffered max, also round down
22
- if (incremented > bufferedValue) {
23
- return value - remainder;
24
- }
25
-
26
- // Otherwise, round up to the next 10
27
- return incremented;
28
- }
29
-
30
- const magnitude = Math.pow(10, Math.floor(Math.log10(value)));
31
-
32
- const remainder = bufferedValue % magnitude;
33
-
34
- return remainder === 0 ? bufferedValue : bufferedValue - remainder;
35
- };
36
-
37
- export const getTicks = (topValue: number, isSymmetrical: boolean) => {
38
- const possibleTickNumbers = [4, 3];
39
- const numberOfTicks =
40
- possibleTickNumbers.find((number) => topValue % (number - 1) === 0) || 3; // Default to 2 ticks if no match
41
- const tickInterval = topValue / (numberOfTicks - 1);
42
- const ticks = Array.from(
43
- { length: numberOfTicks },
44
- (_, index) => index * tickInterval,
45
- );
46
- if (isSymmetrical) {
47
- // Create negative ticks in order without 0
48
- const negativeTicks = Array.from(
49
- { length: numberOfTicks - 1 },
50
- (_, index) => -(numberOfTicks - 1 - index) * tickInterval,
51
- );
52
- ticks.unshift(...negativeTicks);
53
- }
54
- return ticks;
55
- };
3
+ import { chartColors, ChartColors } from '../../../style/theme';
4
+ import { useChartLegend } from '../legend/ChartLegendWrapper';
5
+ import { normalizeChartDataWithUnits } from '../common/chartUtils';
6
+ import { UnitRange } from '../types';
56
7
 
57
8
  export const getMaxBarValue = (
58
9
  data: { [key: string]: string | number }[],
@@ -225,14 +176,19 @@ export const applySortingToData = <T extends BarchartBars>(
225
176
  defaultSort: BarchartProps<T>['defaultSort'],
226
177
  ) => {
227
178
  const points = data.map((item) => {
228
- const point: any = { category: item.category };
179
+ const point: Record<string, string | number> = { category: item.category };
229
180
  barDataKeys.forEach((dataKey) => {
230
181
  point[dataKey] = Number(item[dataKey]) || 0;
231
182
  });
232
183
  return point;
233
184
  });
234
185
 
235
- points.sort(defaultSort);
186
+ points.sort(
187
+ defaultSort as (
188
+ a: Record<string, string | number>,
189
+ b: Record<string, string | number>,
190
+ ) => number,
191
+ );
236
192
 
237
193
  return points.map((point) => {
238
194
  const dataItem: { [key: string]: string | number } = {
@@ -319,88 +275,6 @@ export const formatPrometheusDataToRechartsDataAndBars = <
319
275
  };
320
276
  };
321
277
 
322
- export type UnitRange = {
323
- threshold: number;
324
- label: string;
325
- }[];
326
-
327
- export const computeUnitLabelAndRoundReferenceValue = (
328
- data: any,
329
- maxValue: number,
330
- unitRange: UnitRange | undefined,
331
- ) => {
332
- if (!unitRange) {
333
- const roundReferenceValue = getRoundReferenceValue(maxValue);
334
- return { unitLabel: undefined, roundReferenceValue, rechartsData: data, topDomain: maxValue * 1.1 };
335
- }
336
-
337
- const { valueBase, unitLabel } = getUnitLabel(unitRange, maxValue);
338
- const topValue = maxValue / valueBase;
339
- const roundReferenceValue = getRoundReferenceValue(topValue);
340
- const rechartsData = data.map((dataPoint) => {
341
- const normalizedDataPoint = { ...dataPoint };
342
- Object.entries(dataPoint).forEach(([key, value]) => {
343
- if (key !== 'category' && typeof value === 'number') {
344
- normalizedDataPoint[key] = value / valueBase;
345
- }
346
- });
347
- return normalizedDataPoint;
348
- });
349
- return { unitLabel, roundReferenceValue, rechartsData, topDomain: topValue * 1.1 };
350
- };
351
-
352
- /**
353
- * Return the unit label base on the current dataset, and the valueBase which is used to convert the data
354
- * @param {any} unitRange
355
- * @param {any} maxValue the maximum value among the data set
356
- * @returns {any}
357
- */
358
- export function getUnitLabel(
359
- unitRange: {
360
- threshold: number;
361
- label: string;
362
- }[],
363
- maxValue: number,
364
- ): {
365
- valueBase: number;
366
- unitLabel: string;
367
- } {
368
- // first sort the unitRange
369
- unitRange.sort(
370
- (
371
- unitA: {
372
- threshold: number;
373
- label: string;
374
- },
375
- unitB: {
376
- threshold: number;
377
- label: string;
378
- },
379
- ) => {
380
- return unitA.threshold - unitB.threshold;
381
- },
382
- );
383
- let index = unitRange.findIndex((range) => range.threshold > maxValue);
384
-
385
- // last unit
386
- if (index === -1) {
387
- index = unitRange.length;
388
- }
389
-
390
- if (index === 0) {
391
- return {
392
- valueBase: unitRange[index].threshold,
393
- unitLabel: unitRange[index].label,
394
- };
395
- }
396
-
397
- return {
398
- // if the threshold is 0, we use 1 as the value base to avoid division by 0
399
- valueBase: unitRange[index - 1].threshold || 1,
400
- unitLabel: unitRange[index - 1].label,
401
- };
402
- }
403
-
404
278
  // Sort stacked bars by their average values in descending order or by legend order
405
279
  // This ensures the largest bars appear at the bottom of the stack (default) or follow legend order
406
280
  export const sortStackedBars = (
@@ -526,15 +400,15 @@ export const useChartData = <T extends BarchartBars>(
526
400
 
527
401
  const maxValue = getMaxBarValue(filteredData, stacked);
528
402
 
529
- const { unitLabel, roundReferenceValue, rechartsData, topDomain } =
530
- computeUnitLabelAndRoundReferenceValue(filteredData, maxValue, unitRange);
403
+ const { unitLabel, topValue, rechartsData, topDomain } =
404
+ normalizeChartDataWithUnits(filteredData, maxValue, unitRange, 'category');
531
405
 
532
406
  return {
533
407
  rechartsBars: filteredRechartsBars,
534
- unitLabel,
535
- topDomain,
536
- roundReferenceValue,
408
+ unitLabel: unitLabel,
409
+ roundReferenceValue: topValue,
537
410
  rechartsData,
411
+ topDomain,
538
412
  };
539
413
  };
540
414
 
@@ -1,19 +1,15 @@
1
1
  import { TooltipContentProps } from 'recharts';
2
- import { LegendShape } from '../chartlegend/ChartLegend';
2
+ import { LegendShape } from '../legend/ChartLegend';
3
3
  import {
4
4
  ChartTooltipPortal,
5
5
  ChartTooltipHeader,
6
6
  ChartTooltipItem,
7
7
  ChartTooltipItemsContainer,
8
8
  TooltipHeader,
9
- } from '../charttooltip/ChartTooltip';
10
- import {
11
- BarchartBars,
12
- BarchartTooltipFn,
13
- CategoryType,
14
- TimeType,
15
- } from './Barchart.component';
16
- import { getCurrentPoint } from './utils';
9
+ } from '../common/ChartTooltip';
10
+ import { BarchartBars, BarchartTooltipFn } from './Barchart';
11
+ import { CategoryType, TimeType } from '../types';
12
+ import { getCurrentPoint } from './Barchart.utils';
17
13
 
18
14
  export const BarchartTooltip = <T extends BarchartBars>({
19
15
  type,