@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,4 +1,4 @@
|
|
|
1
|
-
import { useState, useRef } from 'react';
|
|
1
|
+
import { useState, useRef, useMemo, useCallback } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Bar,
|
|
4
4
|
BarChart as RechartsBarChart,
|
|
@@ -13,7 +13,7 @@ import { Stack } from '../../../spacing';
|
|
|
13
13
|
import { chartColors, ChartColors, fontSize } from '../../../style/theme';
|
|
14
14
|
import { useChartLegend } from '../legend/ChartLegendWrapper';
|
|
15
15
|
import { BarchartTooltip } from './BarchartTooltip';
|
|
16
|
-
import {
|
|
16
|
+
import { formatTickValue, getTicks } from '../common/chartUtils';
|
|
17
17
|
import { useChartData } from './Barchart.utils';
|
|
18
18
|
import {
|
|
19
19
|
ChartHeader,
|
|
@@ -112,15 +112,19 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
112
112
|
} = props;
|
|
113
113
|
|
|
114
114
|
// Create colorSet from ChartLegendWrapper
|
|
115
|
-
const colorSet =
|
|
116
|
-
(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
const colorSet = useMemo(
|
|
116
|
+
() =>
|
|
117
|
+
bars?.reduce(
|
|
118
|
+
(acc, bar) => {
|
|
119
|
+
const color = getColor(bar.label);
|
|
120
|
+
if (color) {
|
|
121
|
+
acc[bar.label] = color;
|
|
122
|
+
}
|
|
123
|
+
return acc;
|
|
124
|
+
},
|
|
125
|
+
{} as Record<string, ChartColors | string>,
|
|
126
|
+
),
|
|
127
|
+
[bars, getColor],
|
|
124
128
|
);
|
|
125
129
|
|
|
126
130
|
const {
|
|
@@ -139,6 +143,113 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
139
143
|
stackedBarSort,
|
|
140
144
|
);
|
|
141
145
|
const titleWithUnit = unitLabel ? `${title} (${unitLabel})` : title;
|
|
146
|
+
|
|
147
|
+
const tickFormatter = useCallback(
|
|
148
|
+
(value: number) => formatTickValue(value, roundReferenceValue),
|
|
149
|
+
[roundReferenceValue],
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const renderChartContent = () => {
|
|
153
|
+
if (isError || (!bars && !isLoading)) {
|
|
154
|
+
return <ChartError height={height} />;
|
|
155
|
+
}
|
|
156
|
+
if (isLoading) {
|
|
157
|
+
return <ChartLoading height={height} />;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<StyledResponsiveContainer ref={chartRef} width="100%" height={height}>
|
|
162
|
+
<RechartsBarChart
|
|
163
|
+
data={rechartsData}
|
|
164
|
+
accessibilityLayer
|
|
165
|
+
barSize={
|
|
166
|
+
type.type === 'category'
|
|
167
|
+
? type.gap === 0
|
|
168
|
+
? undefined
|
|
169
|
+
: CHART_CONSTANTS.BAR_SIZE
|
|
170
|
+
: CHART_CONSTANTS.BAR_SIZE
|
|
171
|
+
}
|
|
172
|
+
height={height}
|
|
173
|
+
margin={CHART_CONSTANTS.CHART_MARGIN}
|
|
174
|
+
barCategoryGap={type.type === 'category' ? type.gap : undefined}
|
|
175
|
+
>
|
|
176
|
+
<CartesianGrid
|
|
177
|
+
vertical={true}
|
|
178
|
+
horizontal={true}
|
|
179
|
+
verticalPoints={[0]}
|
|
180
|
+
horizontalPoints={[0]}
|
|
181
|
+
stroke={theme.border}
|
|
182
|
+
fill={theme.backgroundLevel4}
|
|
183
|
+
strokeWidth={1}
|
|
184
|
+
/>
|
|
185
|
+
{rechartsBars.map((bar) => {
|
|
186
|
+
const { fill, dataKey, stackId } = bar;
|
|
187
|
+
return (
|
|
188
|
+
<Bar
|
|
189
|
+
key={dataKey}
|
|
190
|
+
dataKey={dataKey}
|
|
191
|
+
fill={chartColors[fill] || fill}
|
|
192
|
+
minPointSize={stacked ? 0 : CHART_CONSTANTS.MIN_POINT_SIZE}
|
|
193
|
+
stackId={stackId}
|
|
194
|
+
isAnimationActive={false}
|
|
195
|
+
onMouseOver={() => setHoveredValue(dataKey)}
|
|
196
|
+
onMouseLeave={() => setHoveredValue(undefined)}
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
199
|
+
})}
|
|
200
|
+
|
|
201
|
+
<YAxis
|
|
202
|
+
interval={0}
|
|
203
|
+
domain={[0, topDomain]}
|
|
204
|
+
ticks={getTicks(roundReferenceValue, false)}
|
|
205
|
+
tickFormatter={tickFormatter}
|
|
206
|
+
axisLine={{ stroke: theme.border }}
|
|
207
|
+
tick={{
|
|
208
|
+
fill: theme.textSecondary,
|
|
209
|
+
fontSize: fontSize.smaller,
|
|
210
|
+
}}
|
|
211
|
+
orientation="right"
|
|
212
|
+
/>
|
|
213
|
+
|
|
214
|
+
<XAxis
|
|
215
|
+
dataKey="category"
|
|
216
|
+
tick={(props) => (
|
|
217
|
+
<CustomTick
|
|
218
|
+
{...props}
|
|
219
|
+
type={type}
|
|
220
|
+
tickWidthOffset={CHART_CONSTANTS.TICK_WIDTH_OFFSET}
|
|
221
|
+
/>
|
|
222
|
+
)}
|
|
223
|
+
type="category"
|
|
224
|
+
interval={0}
|
|
225
|
+
allowDataOverflow={true}
|
|
226
|
+
tickLine={{
|
|
227
|
+
stroke: theme.border,
|
|
228
|
+
}}
|
|
229
|
+
axisLine={{
|
|
230
|
+
stroke: theme.border,
|
|
231
|
+
}}
|
|
232
|
+
/>
|
|
233
|
+
|
|
234
|
+
<Tooltip
|
|
235
|
+
content={(props: TooltipContentProps<number, string>) => (
|
|
236
|
+
<BarchartTooltip
|
|
237
|
+
type={type}
|
|
238
|
+
colorSet={colorSet}
|
|
239
|
+
tooltipProps={props}
|
|
240
|
+
hoveredValue={hoveredValue}
|
|
241
|
+
tooltip={tooltip}
|
|
242
|
+
unitLabel={unitLabel}
|
|
243
|
+
chartContainerRef={chartRef}
|
|
244
|
+
/>
|
|
245
|
+
)}
|
|
246
|
+
cursor={false}
|
|
247
|
+
/>
|
|
248
|
+
</RechartsBarChart>
|
|
249
|
+
</StyledResponsiveContainer>
|
|
250
|
+
);
|
|
251
|
+
};
|
|
252
|
+
|
|
142
253
|
return (
|
|
143
254
|
<Stack direction="vertical" style={{ gap: '0' }}>
|
|
144
255
|
<ChartHeader
|
|
@@ -147,101 +258,7 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
147
258
|
helpTooltip={helpTooltip}
|
|
148
259
|
rightTitle={rightTitle}
|
|
149
260
|
/>
|
|
150
|
-
{
|
|
151
|
-
<ChartError height={height} />
|
|
152
|
-
) : isLoading ? (
|
|
153
|
-
<ChartLoading height={height} />
|
|
154
|
-
) : (
|
|
155
|
-
<StyledResponsiveContainer ref={chartRef} width="100%" height={height}>
|
|
156
|
-
<RechartsBarChart
|
|
157
|
-
data={rechartsData}
|
|
158
|
-
accessibilityLayer
|
|
159
|
-
barSize={
|
|
160
|
-
type.type === 'category'
|
|
161
|
-
? type.gap === 0
|
|
162
|
-
? undefined
|
|
163
|
-
: CHART_CONSTANTS.BAR_SIZE
|
|
164
|
-
: CHART_CONSTANTS.BAR_SIZE
|
|
165
|
-
}
|
|
166
|
-
height={height}
|
|
167
|
-
margin={CHART_CONSTANTS.CHART_MARGIN}
|
|
168
|
-
barCategoryGap={type.type === 'category' ? type.gap : undefined}
|
|
169
|
-
>
|
|
170
|
-
<CartesianGrid
|
|
171
|
-
vertical={true}
|
|
172
|
-
horizontal={true}
|
|
173
|
-
verticalPoints={[0]}
|
|
174
|
-
horizontalPoints={[0]}
|
|
175
|
-
stroke={theme.border}
|
|
176
|
-
fill={theme.backgroundLevel4}
|
|
177
|
-
strokeWidth={1}
|
|
178
|
-
/>
|
|
179
|
-
{rechartsBars.map((bar) => {
|
|
180
|
-
const { fill, dataKey, stackId } = bar;
|
|
181
|
-
return (
|
|
182
|
-
<Bar
|
|
183
|
-
key={dataKey}
|
|
184
|
-
dataKey={dataKey}
|
|
185
|
-
fill={chartColors[fill] || fill}
|
|
186
|
-
minPointSize={stacked ? 0 : CHART_CONSTANTS.MIN_POINT_SIZE}
|
|
187
|
-
stackId={stackId}
|
|
188
|
-
isAnimationActive={false}
|
|
189
|
-
onMouseOver={() => setHoveredValue(dataKey)}
|
|
190
|
-
onMouseLeave={() => setHoveredValue(undefined)}
|
|
191
|
-
/>
|
|
192
|
-
);
|
|
193
|
-
})}
|
|
194
|
-
|
|
195
|
-
<YAxis
|
|
196
|
-
interval={0}
|
|
197
|
-
domain={[0, topDomain]}
|
|
198
|
-
ticks={getTicks(roundReferenceValue, false)}
|
|
199
|
-
tickFormatter={(value) => formatToISONumber(value)}
|
|
200
|
-
axisLine={{ stroke: theme.border }}
|
|
201
|
-
tick={{
|
|
202
|
-
fill: theme.textSecondary,
|
|
203
|
-
fontSize: fontSize.smaller,
|
|
204
|
-
}}
|
|
205
|
-
orientation="right"
|
|
206
|
-
/>
|
|
207
|
-
|
|
208
|
-
<XAxis
|
|
209
|
-
dataKey="category"
|
|
210
|
-
tick={(props) => (
|
|
211
|
-
<CustomTick
|
|
212
|
-
{...props}
|
|
213
|
-
type={type}
|
|
214
|
-
tickWidthOffset={CHART_CONSTANTS.TICK_WIDTH_OFFSET}
|
|
215
|
-
/>
|
|
216
|
-
)}
|
|
217
|
-
type="category"
|
|
218
|
-
interval={0}
|
|
219
|
-
allowDataOverflow={true}
|
|
220
|
-
tickLine={{
|
|
221
|
-
stroke: theme.border,
|
|
222
|
-
}}
|
|
223
|
-
axisLine={{
|
|
224
|
-
stroke: theme.border,
|
|
225
|
-
}}
|
|
226
|
-
/>
|
|
227
|
-
|
|
228
|
-
<Tooltip
|
|
229
|
-
content={(props: TooltipContentProps<number, string>) => (
|
|
230
|
-
<BarchartTooltip
|
|
231
|
-
type={type}
|
|
232
|
-
colorSet={colorSet}
|
|
233
|
-
tooltipProps={props}
|
|
234
|
-
hoveredValue={hoveredValue}
|
|
235
|
-
tooltip={tooltip}
|
|
236
|
-
unitLabel={unitLabel}
|
|
237
|
-
chartContainerRef={chartRef}
|
|
238
|
-
/>
|
|
239
|
-
)}
|
|
240
|
-
cursor={false}
|
|
241
|
-
/>
|
|
242
|
-
</RechartsBarChart>
|
|
243
|
-
</StyledResponsiveContainer>
|
|
244
|
-
)}
|
|
261
|
+
{renderChartContent()}
|
|
245
262
|
</Stack>
|
|
246
263
|
);
|
|
247
264
|
};
|
|
@@ -8,7 +8,7 @@ import { Text } from '../../text/Text.component';
|
|
|
8
8
|
import { ConstrainedText } from '../../constrainedtext/Constrainedtext.component';
|
|
9
9
|
import { FormattedDateTime } from '../../date/FormattedDateTime';
|
|
10
10
|
import { formatXAxisDate, maxWidthTooltip } from './chartUtils';
|
|
11
|
-
import { TimeType } from '../types';
|
|
11
|
+
import { TimeType, CategoryType } from '../types';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Styled ResponsiveContainer for charts
|
|
@@ -117,14 +117,14 @@ export const ChartHeader = ({
|
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
interface CustomTickProps {
|
|
120
|
-
x: number;
|
|
121
|
-
y: number;
|
|
120
|
+
x: number | string;
|
|
121
|
+
y: number | string;
|
|
122
122
|
payload: {
|
|
123
123
|
value: number;
|
|
124
124
|
};
|
|
125
|
-
visibleTicksCount
|
|
126
|
-
width
|
|
127
|
-
type: TimeType;
|
|
125
|
+
visibleTicksCount?: number;
|
|
126
|
+
width?: number | string;
|
|
127
|
+
type: TimeType | CategoryType;
|
|
128
128
|
tickWidthOffset?: number;
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -142,20 +142,24 @@ export const CustomTick = ({
|
|
|
142
142
|
tickWidthOffset = 4,
|
|
143
143
|
}: CustomTickProps) => {
|
|
144
144
|
const theme = useTheme();
|
|
145
|
-
const
|
|
146
|
-
const
|
|
145
|
+
const numX = typeof x === 'string' ? parseFloat(x) : x;
|
|
146
|
+
const numY = typeof y === 'string' ? parseFloat(y) : y;
|
|
147
|
+
const numWidth = typeof width === 'string' ? parseFloat(width) : (width ?? 0);
|
|
148
|
+
const tickCount = visibleTicksCount ?? 1;
|
|
149
|
+
const tickWidth = numWidth / tickCount - tickWidthOffset;
|
|
150
|
+
const centerX = numX - tickWidth / 2;
|
|
147
151
|
|
|
148
152
|
const duration =
|
|
149
153
|
type.type === 'time'
|
|
150
154
|
? (type.timeRange.endDate.getTime() -
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
type.timeRange.startDate.getTime()) /
|
|
156
|
+
1000
|
|
153
157
|
: 0;
|
|
154
158
|
|
|
155
159
|
return (
|
|
156
160
|
<foreignObject
|
|
157
161
|
x={centerX}
|
|
158
|
-
y={
|
|
162
|
+
y={numY - 10}
|
|
159
163
|
width={tickWidth}
|
|
160
164
|
height={30}
|
|
161
165
|
style={{
|
|
@@ -23,16 +23,16 @@ describe('getRoundReferenceValue', () => {
|
|
|
23
23
|
expect(getRoundReferenceValue(9)).toBe(9); // 9 → 9.9 → 9 (magnitude 1, remainder 0.9)
|
|
24
24
|
|
|
25
25
|
// Larger values get 10% buffer applied
|
|
26
|
-
expect(getRoundReferenceValue(15)).toBe(
|
|
27
|
-
expect(getRoundReferenceValue(35)).toBe(
|
|
26
|
+
expect(getRoundReferenceValue(15)).toBe(15); // 15 → increment 5, remainder 0, return 15
|
|
27
|
+
expect(getRoundReferenceValue(35)).toBe(35); // 35 → increment 5, remainder 0, return 35
|
|
28
28
|
expect(getRoundReferenceValue(75)).toBe(80); // 75 → 82.5, remainder 5, incremented 80 <= 82.5, so round up to 80
|
|
29
|
-
expect(getRoundReferenceValue(150)).toBe(150); //
|
|
30
|
-
expect(getRoundReferenceValue(350)).toBe(350); //
|
|
31
|
-
expect(getRoundReferenceValue(750)).toBe(
|
|
32
|
-
expect(getRoundReferenceValue(1500)).toBe(1500); //
|
|
33
|
-
expect(getRoundReferenceValue(3500)).toBe(3500); //
|
|
34
|
-
expect(getRoundReferenceValue(7500)).toBe(
|
|
35
|
-
expect(getRoundReferenceValue(15000)).toBe(15000); //
|
|
29
|
+
expect(getRoundReferenceValue(150)).toBe(150); // increment 50, remainder 0
|
|
30
|
+
expect(getRoundReferenceValue(350)).toBe(350); // increment 50, remainder 0
|
|
31
|
+
expect(getRoundReferenceValue(750)).toBe(800); // increment 100, remainder 50, rounds up
|
|
32
|
+
expect(getRoundReferenceValue(1500)).toBe(1500); // increment 500, remainder 0
|
|
33
|
+
expect(getRoundReferenceValue(3500)).toBe(3500); // increment 500, remainder 0
|
|
34
|
+
expect(getRoundReferenceValue(7500)).toBe(8000); // increment 1000, remainder 500, rounds up
|
|
35
|
+
expect(getRoundReferenceValue(15000)).toBe(15000); // increment 5000, remainder 0
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -95,8 +95,23 @@ describe('getUnitLabel', () => {
|
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
describe('addMissingDataPoint', () => {
|
|
98
|
+
it('should generate placeholder timestamps when original data is empty', () => {
|
|
99
|
+
const result = addMissingDataPoint([], 0, 100, 10);
|
|
100
|
+
expect(result).toEqual([
|
|
101
|
+
[0, NAN_STRING],
|
|
102
|
+
[10, NAN_STRING],
|
|
103
|
+
[20, NAN_STRING],
|
|
104
|
+
[30, NAN_STRING],
|
|
105
|
+
[40, NAN_STRING],
|
|
106
|
+
[50, NAN_STRING],
|
|
107
|
+
[60, NAN_STRING],
|
|
108
|
+
[70, NAN_STRING],
|
|
109
|
+
[80, NAN_STRING],
|
|
110
|
+
[90, NAN_STRING],
|
|
111
|
+
]);
|
|
112
|
+
});
|
|
113
|
+
|
|
98
114
|
it('should return empty array for invalid inputs', () => {
|
|
99
|
-
expect(addMissingDataPoint([], 0, 100, 10)).toEqual([]);
|
|
100
115
|
expect(addMissingDataPoint([[10, 5]], undefined, 100, 10)).toEqual([]);
|
|
101
116
|
expect(addMissingDataPoint([[10, 5]], 0, 0, 10)).toEqual([]);
|
|
102
117
|
expect(addMissingDataPoint([[10, 5]], -1, 100, 10)).toEqual([]);
|
|
@@ -264,8 +279,8 @@ describe('normalizeChartDataWithUnits', () => {
|
|
|
264
279
|
);
|
|
265
280
|
|
|
266
281
|
expect(result.unitLabel).toBe('B');
|
|
267
|
-
// 680 / 1 = 680 → getRoundReferenceValue(680) =
|
|
268
|
-
expect(result.topValue).toBe(
|
|
282
|
+
// 680 / 1 = 680 → getRoundReferenceValue(680) = 700 (rounds up since 80 >= 50)
|
|
283
|
+
expect(result.topValue).toBe(700);
|
|
269
284
|
expect(result.rechartsData).toEqual([
|
|
270
285
|
{ category: 'category1', success: 680 },
|
|
271
286
|
]);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NAN_STRING } from '../../constants';
|
|
2
2
|
import { TooltipDateFormat } from './ChartTooltip';
|
|
3
3
|
import { UnitRange } from '../types';
|
|
4
|
+
import { formatISONumber } from '../../../utils';
|
|
4
5
|
|
|
5
6
|
/* -------------------------------------------------------------------------- */
|
|
6
7
|
/* constants */
|
|
@@ -12,6 +13,31 @@ export const maxWidthTooltip = { maxWidth: '20rem' };
|
|
|
12
13
|
/* utils functions */
|
|
13
14
|
/* -------------------------------------------------------------------------- */
|
|
14
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Get the appropriate rounding increment based on value magnitude.
|
|
18
|
+
* - For values < 5 * magnitude: use half magnitude (finer granularity)
|
|
19
|
+
* - For values >= 5 * magnitude: use full magnitude
|
|
20
|
+
*
|
|
21
|
+
* Examples:
|
|
22
|
+
* - 150 → increment 50 (150 < 500, so use 100/2)
|
|
23
|
+
* - 550 → increment 100 (550 >= 500, so use 100)
|
|
24
|
+
* - 1500 → increment 500 (1500 < 5000, so use 1000/2)
|
|
25
|
+
* - 5500 → increment 1000 (5500 >= 5000, so use 1000)
|
|
26
|
+
*/
|
|
27
|
+
const getIncrement = (value: number): number => {
|
|
28
|
+
if (value < 10) return 1;
|
|
29
|
+
|
|
30
|
+
const magnitude = Math.pow(10, Math.floor(Math.log10(value)));
|
|
31
|
+
|
|
32
|
+
// If value is in lower half of magnitude range, use half magnitude
|
|
33
|
+
if (value < 5 * magnitude) {
|
|
34
|
+
return magnitude / 2;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Otherwise use full magnitude
|
|
38
|
+
return magnitude;
|
|
39
|
+
};
|
|
40
|
+
|
|
15
41
|
/**
|
|
16
42
|
* Round a value to a nice number for chart display
|
|
17
43
|
* Used by Barchart and LineTimeSerieChart for Y-axis scaling
|
|
@@ -23,29 +49,29 @@ export const getRoundReferenceValue = (value: number): number => {
|
|
|
23
49
|
const bufferedValue = value * 1.1;
|
|
24
50
|
|
|
25
51
|
if (value >= 10) {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
52
|
+
const increment = getIncrement(value);
|
|
53
|
+
const remainder = value % increment;
|
|
54
|
+
const roundedDown = value - remainder;
|
|
55
|
+
const roundedUp = roundedDown + increment;
|
|
56
|
+
|
|
57
|
+
// If remainder is less than half the increment, round down
|
|
58
|
+
if (remainder < increment / 2) {
|
|
59
|
+
return roundedDown;
|
|
32
60
|
}
|
|
33
61
|
|
|
34
|
-
// If
|
|
35
|
-
if (
|
|
36
|
-
return
|
|
62
|
+
// If rounding up would exceed the buffered max, round down
|
|
63
|
+
if (roundedUp > bufferedValue) {
|
|
64
|
+
return roundedDown;
|
|
37
65
|
}
|
|
38
66
|
|
|
39
|
-
// Otherwise, round up
|
|
40
|
-
return
|
|
67
|
+
// Otherwise, round up
|
|
68
|
+
return roundedUp;
|
|
41
69
|
}
|
|
42
70
|
|
|
71
|
+
// For values < 10, use the magnitude-based approach
|
|
43
72
|
const magnitude = Math.pow(10, Math.floor(Math.log10(value)));
|
|
44
|
-
|
|
45
73
|
const remainder = bufferedValue % magnitude;
|
|
46
74
|
|
|
47
|
-
// Round to nice numbers based on normalized value
|
|
48
|
-
// appearance for small values
|
|
49
75
|
return remainder === 0 ? bufferedValue : bufferedValue - remainder;
|
|
50
76
|
};
|
|
51
77
|
|
|
@@ -53,7 +79,10 @@ export const getRoundReferenceValue = (value: number): number => {
|
|
|
53
79
|
* Generate tick values for Y-axis
|
|
54
80
|
* Used by Barchart and LineTimeSerieChart
|
|
55
81
|
*/
|
|
56
|
-
export const getTicks = (
|
|
82
|
+
export const getTicks = (
|
|
83
|
+
topValue: number,
|
|
84
|
+
isSymmetrical: boolean,
|
|
85
|
+
): number[] => {
|
|
57
86
|
const possibleTickNumbers = [4, 3];
|
|
58
87
|
const numberOfTicks =
|
|
59
88
|
possibleTickNumbers.find((number) => topValue % (number - 1) === 0) || 3; // Default to 3 ticks if no match
|
|
@@ -191,7 +220,7 @@ export const normalizeChartDataWithUnits = <T extends Record<string, any>>(
|
|
|
191
220
|
* Missing data points are only added when the gap between consecutive data points is bigger than 2 intervals
|
|
192
221
|
* Used by LineTimeSerieChart and Sparkline
|
|
193
222
|
*
|
|
194
|
-
* @param
|
|
223
|
+
* @param originalValues - The array of the data points are already sorted according to the time series
|
|
195
224
|
* @param startingTimeStamp - The starting timestamp in seconds
|
|
196
225
|
* @param sampleDuration - The time span value in seconds
|
|
197
226
|
* @param sampleInterval - The time difference between two data points in seconds
|
|
@@ -214,9 +243,17 @@ export function addMissingDataPoint(
|
|
|
214
243
|
return [];
|
|
215
244
|
}
|
|
216
245
|
|
|
217
|
-
// If there are no original values,
|
|
246
|
+
// If there are no original values, generate placeholder timestamps for the entire duration
|
|
218
247
|
if (originalValues.length === 0) {
|
|
219
|
-
|
|
248
|
+
const newValues: [number, number | string | null][] = [];
|
|
249
|
+
for (
|
|
250
|
+
let i = startingTimeStamp;
|
|
251
|
+
i < startingTimeStamp + sampleDuration;
|
|
252
|
+
i += sampleInterval
|
|
253
|
+
) {
|
|
254
|
+
newValues.push([i, NAN_STRING]);
|
|
255
|
+
}
|
|
256
|
+
return newValues;
|
|
220
257
|
}
|
|
221
258
|
|
|
222
259
|
const newValues: [number, number | string | null][] = [];
|
|
@@ -326,9 +363,16 @@ export const getTooltipDateFormat: (duration: number) => TooltipDateFormat = (
|
|
|
326
363
|
}
|
|
327
364
|
};
|
|
328
365
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
366
|
+
/**
|
|
367
|
+
* Formats a tick value for chart Y-axis display.
|
|
368
|
+
* - Fixed decimals for alignment when topValue < 1 (e.g., 0.1 → 0.10)
|
|
369
|
+
* - Compact notation for large values (>= 10k)
|
|
370
|
+
*/
|
|
371
|
+
export const formatTickValue = (value: number, topValue: number): string => {
|
|
372
|
+
const decimals = topValue < 1 ? Math.ceil(-Math.log10(topValue)) + 1 : 2;
|
|
373
|
+
return formatISONumber(value, {
|
|
374
|
+
decimals,
|
|
375
|
+
fixedDecimals: topValue < 1,
|
|
376
|
+
compact: topValue >= 10000,
|
|
377
|
+
});
|
|
334
378
|
};
|
|
@@ -12,7 +12,7 @@ export { LineTimeSerieChart } from './linetimeseries/LineTimeSerieChart';
|
|
|
12
12
|
export type {
|
|
13
13
|
LineChartProps,
|
|
14
14
|
Serie,
|
|
15
|
-
} from './linetimeseries/LineTimeSerieChart';
|
|
15
|
+
} from './linetimeseries/LineTimeSerieChart.types';
|
|
16
16
|
|
|
17
17
|
export { GlobalHealthBar } from './globalhealthbar/GlobalHealthBar';
|
|
18
18
|
export type { GlobalHealthProps } from './globalhealthbar/GlobalHealthBar';
|