@scality/core-ui 0.167.0 → 0.168.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/barchartv2/Barchart.component.d.ts +5 -1
- package/dist/components/barchartv2/Barchart.component.d.ts.map +1 -1
- package/dist/components/barchartv2/Barchart.component.js +6 -2
- package/dist/components/barchartv2/utils.js +2 -2
- package/dist/components/date/FormattedDateTime.d.ts +6 -1
- package/dist/components/date/FormattedDateTime.d.ts.map +1 -1
- package/dist/components/date/FormattedDateTime.js +11 -0
- package/dist/components/linetemporalchart/ChartUtil.d.ts.map +1 -1
- package/dist/components/linetemporalchart/ChartUtil.js +6 -0
- package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts +7 -1
- package/dist/components/linetimeseriechart/linetimeseriechart.component.d.ts.map +1 -1
- package/dist/components/linetimeseriechart/linetimeseriechart.component.js +17 -11
- package/package.json +1 -1
- package/src/lib/components/barchartv2/Barchart.component.test.tsx +11 -7
- package/src/lib/components/barchartv2/Barchart.component.tsx +15 -3
- package/src/lib/components/barchartv2/utils.test.ts +2 -2
- package/src/lib/components/barchartv2/utils.ts +2 -2
- package/src/lib/components/date/FormattedDateTime.tsx +14 -1
- package/src/lib/components/linetemporalchart/ChartUtil.ts +6 -0
- package/src/lib/components/linetimeseriechart/linetimeseriechart.component.tsx +31 -8
- package/src/lib/components/linetimeseriechart/linetimeseriechart.test.tsx +68 -0
- package/stories/BarChart/barchart.stories.tsx +108 -13
- package/stories/linetimeseriechart.stories.tsx +97 -0
|
@@ -7,6 +7,10 @@ export type TimeType = {
|
|
|
7
7
|
interval: number;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
+
export type CategoryType = {
|
|
11
|
+
type: 'category';
|
|
12
|
+
gap?: number;
|
|
13
|
+
};
|
|
10
14
|
export type Point = {
|
|
11
15
|
key: string | number;
|
|
12
16
|
values: {
|
|
@@ -36,7 +40,7 @@ export type BarchartSortFn<T extends BarchartBars> = (pointA: Record<T[number]['
|
|
|
36
40
|
category: string | number;
|
|
37
41
|
}) => 1 | -1 | 0;
|
|
38
42
|
export type BarchartProps<T extends BarchartBars> = {
|
|
39
|
-
type:
|
|
43
|
+
type: CategoryType | TimeType;
|
|
40
44
|
bars?: T;
|
|
41
45
|
tooltip?: BarchartTooltipFn<T>;
|
|
42
46
|
defaultSort?: BarchartSortFn<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Barchart.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/barchartv2/Barchart.component.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAwB,SAAS,EAAgB,MAAM,SAAS,CAAC;AAmBxE,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QACT,SAAS,EAAE,IAAI,CAAC;QAChB,OAAO,EAAE,IAAI,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH,CAAC;AACF,MAAM,MAAM,KAAK,GAAG;IAClB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC;CACvE,EAAE,CAAC;AAEJ,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,YAAY,IAAI,CAAC,YAAY,EAAE;IACrE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,MAAM,EAAE;QAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CAC5E,KAAK,KAAK,CAAC,SAAS,CAAC;AAEtB,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,YAAY,IAAI,CACnD,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAC1E,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,KACvE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAEhB,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,YAAY,IAAI;IAClD,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"Barchart.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/barchartv2/Barchart.component.tsx"],"names":[],"mappings":"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"}
|
|
@@ -94,7 +94,7 @@ export const Barchart = (props) => {
|
|
|
94
94
|
const theme = useTheme();
|
|
95
95
|
const { getColor } = useChartLegend();
|
|
96
96
|
const [hoveredValue, setHoveredValue] = useState();
|
|
97
|
-
const { height = CHART_CONSTANTS.DEFAULT_HEIGHT, bars, type = 'category', unitRange, stacked, stackedBarSort = 'default', defaultSort, tooltip, title, secondaryTitle, helpTooltip, rightTitle, isLoading, isError, } = props;
|
|
97
|
+
const { height = CHART_CONSTANTS.DEFAULT_HEIGHT, bars, type = { type: 'category' }, unitRange, stacked, stackedBarSort = 'default', defaultSort, tooltip, title, secondaryTitle, helpTooltip, rightTitle, isLoading, isError, } = props;
|
|
98
98
|
// Create colorSet from ChartLegendWrapper
|
|
99
99
|
const colorSet = bars === null || bars === void 0 ? void 0 : bars.reduce((acc, bar) => {
|
|
100
100
|
const color = getColor(bar.label);
|
|
@@ -104,7 +104,11 @@ export const Barchart = (props) => {
|
|
|
104
104
|
return acc;
|
|
105
105
|
}, {});
|
|
106
106
|
const { rechartsBars, unitLabel, roundReferenceValue, rechartsData } = useChartData(bars || [], type, colorSet || {}, stacked, defaultSort, unitRange, stackedBarSort);
|
|
107
|
-
return (_jsxs(Stack, { direction: "vertical", gap: "r8", children: [_jsx(ChartHeader, { title: title, secondaryTitle: secondaryTitle, helpTooltip: helpTooltip, rightTitle: rightTitle }), isError || (!bars && !isLoading) ? (_jsx(Error, { height: height })) : isLoading ? (_jsx(Loading, { height: height })) : (_jsx(StyledResponsiveContainer, { width: "100%", height: height, children: _jsxs(BarChart, { data: rechartsData, accessibilityLayer: true, barSize:
|
|
107
|
+
return (_jsxs(Stack, { direction: "vertical", gap: "r8", children: [_jsx(ChartHeader, { title: title, secondaryTitle: secondaryTitle, helpTooltip: helpTooltip, rightTitle: rightTitle }), isError || (!bars && !isLoading) ? (_jsx(Error, { height: height })) : isLoading ? (_jsx(Loading, { height: height })) : (_jsx(StyledResponsiveContainer, { width: "100%", height: height, children: _jsxs(BarChart, { data: rechartsData, accessibilityLayer: true, barSize: type.type === 'category'
|
|
108
|
+
? type.gap === 0
|
|
109
|
+
? undefined
|
|
110
|
+
: CHART_CONSTANTS.BAR_SIZE
|
|
111
|
+
: CHART_CONSTANTS.BAR_SIZE, height: height, margin: CHART_CONSTANTS.CHART_MARGIN, barCategoryGap: type.type === 'category' ? type.gap : undefined, children: [_jsx(CartesianGrid, { vertical: false, horizontal: false, fill: theme.backgroundLevel1 }), rechartsBars.map((bar) => {
|
|
108
112
|
const { fill, dataKey, stackId } = bar;
|
|
109
113
|
return (_jsx(Bar, { dataKey: dataKey, fill: chartColors[fill] || fill, minPointSize: stacked ? 0 : CHART_CONSTANTS.MIN_POINT_SIZE, stackId: stackId, onMouseOver: () => setHoveredValue(dataKey), onMouseLeave: () => setHoveredValue(undefined) }, dataKey));
|
|
110
114
|
}), _jsx(YAxis, { tickCount: 1, unit: ` ${unitLabel}`, domain: [0, roundReferenceValue], tickFormatter: (value) => new Intl.NumberFormat('fr-FR').format(value.toFixed(0)) // Add a space as thousand separator
|
|
@@ -174,10 +174,10 @@ const getRechartsBarsAndBarDataKeys = (bars, colorSet, stacked) => {
|
|
|
174
174
|
*/
|
|
175
175
|
export const formatPrometheusDataToRechartsDataAndBars = (bars, type, colorSet, stacked, defaultSort, legendOrder) => {
|
|
176
176
|
const { rechartsBars, barDataKeys } = getRechartsBarsAndBarDataKeys(bars, colorSet, stacked);
|
|
177
|
-
let data = type !== 'category' && type.type === 'time'
|
|
177
|
+
let data = type.type !== 'category' && type.type === 'time'
|
|
178
178
|
? transformTimeData(bars, type, barDataKeys)
|
|
179
179
|
: transformCategoryData(bars, barDataKeys);
|
|
180
|
-
if (type === 'category' && defaultSort) {
|
|
180
|
+
if (type.type === 'category' && defaultSort) {
|
|
181
181
|
data = applySortingToData(data, barDataKeys, defaultSort);
|
|
182
182
|
}
|
|
183
183
|
const sortedRechartsBars = sortStackedBars(rechartsBars, data, stacked, legendOrder);
|
|
@@ -5,8 +5,13 @@ export declare const TIME_SECOND_FORMATER: Intl.DateTimeFormat;
|
|
|
5
5
|
export declare const TIME_FORMATER: Intl.DateTimeFormat;
|
|
6
6
|
export declare const DAY_MONTH_ABBREVIATED_HOUR_MINUTE_SECOND: Intl.DateTimeFormat;
|
|
7
7
|
export declare const DAY_MONTH_ABBREVIATED_HOUR_MINUTE: Intl.DateTimeFormat;
|
|
8
|
+
/**
|
|
9
|
+
* @description Year month day formatter, without time. Used for describing long term date.
|
|
10
|
+
* @example 2025-01-01
|
|
11
|
+
*/
|
|
12
|
+
export declare const YEAR_MONTH_DAY_FORMATTER: Intl.DateTimeFormat;
|
|
8
13
|
type FormattedDateTimeProps = {
|
|
9
|
-
format: 'date' | 'date-time' | 'date-time-second' | 'time' | 'time-second' | 'relative' | 'day-month-abbreviated-hour-minute' | 'day-month-abbreviated-hour-minute-second' | 'long-date' | 'chart-date';
|
|
14
|
+
format: 'date' | 'date-time' | 'date-time-second' | 'time' | 'time-second' | 'relative' | 'day-month-abbreviated-hour-minute' | 'day-month-abbreviated-hour-minute-second' | 'long-date' | 'chart-date' | 'year-month-day';
|
|
10
15
|
value: Date;
|
|
11
16
|
};
|
|
12
17
|
export declare const FormattedDateTime: ({ format, value, }: FormattedDateTimeProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormattedDateTime.d.ts","sourceRoot":"","sources":["../../../src/lib/components/date/FormattedDateTime.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,qBAK7B,CAAC;AAEH,eAAO,MAAM,aAAa,qBAKxB,CAAC;AAEH,eAAO,MAAM,kBAAkB,qBAI7B,CAAC;AAEH,eAAO,MAAM,oBAAoB,qBAK/B,CAAC;AAEH,eAAO,MAAM,aAAa,qBAIxB,CAAC;AAEH,eAAO,MAAM,wCAAwC,qBAUpD,CAAC;AAEF,eAAO,MAAM,iCAAiC,qBAM5C,CAAC;AAEH,KAAK,sBAAsB,GAAG;IAC5B,MAAM,EACF,MAAM,GACN,WAAW,GACX,kBAAkB,GAClB,MAAM,GACN,aAAa,GACb,UAAU,GACV,mCAAmC,GACnC,0CAA0C,GAC1C,WAAW,GACX,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"FormattedDateTime.d.ts","sourceRoot":"","sources":["../../../src/lib/components/date/FormattedDateTime.tsx"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,qBAK7B,CAAC;AAEH,eAAO,MAAM,aAAa,qBAKxB,CAAC;AAEH,eAAO,MAAM,kBAAkB,qBAI7B,CAAC;AAEH,eAAO,MAAM,oBAAoB,qBAK/B,CAAC;AAEH,eAAO,MAAM,aAAa,qBAIxB,CAAC;AAEH,eAAO,MAAM,wCAAwC,qBAUpD,CAAC;AAEF,eAAO,MAAM,iCAAiC,qBAM5C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,wBAAwB,qBAInC,CAAC;AAEH,KAAK,sBAAsB,GAAG;IAC5B,MAAM,EACF,MAAM,GACN,WAAW,GACX,kBAAkB,GAClB,MAAM,GACN,aAAa,GACb,UAAU,GACV,mCAAmC,GACnC,0CAA0C,GAC1C,WAAW,GACX,YAAY,GACZ,gBAAgB,CAAC;IAErB,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;AAaF,eAAO,MAAM,iBAAiB,uBAG3B,sBAAsB,4CAuHxB,CAAC"}
|
|
@@ -44,6 +44,15 @@ export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE = Intl.DateTimeFormat('en-GB', {
|
|
|
44
44
|
minute: '2-digit',
|
|
45
45
|
hour12: false,
|
|
46
46
|
});
|
|
47
|
+
/**
|
|
48
|
+
* @description Year month day formatter, without time. Used for describing long term date.
|
|
49
|
+
* @example 2025-01-01
|
|
50
|
+
*/
|
|
51
|
+
export const YEAR_MONTH_DAY_FORMATTER = Intl.DateTimeFormat('en-CA', {
|
|
52
|
+
year: 'numeric',
|
|
53
|
+
month: '2-digit',
|
|
54
|
+
day: '2-digit',
|
|
55
|
+
});
|
|
47
56
|
const isItFutureOrIsItPast = (timeDiff, stringToBeFormatted) => {
|
|
48
57
|
if (timeDiff > 0) {
|
|
49
58
|
return `${stringToBeFormatted} ago`;
|
|
@@ -93,6 +102,8 @@ export const FormattedDateTime = ({ format, value, }) => {
|
|
|
93
102
|
return _jsx(_Fragment, { children: LONG_DATE_FORMATER.format(value) });
|
|
94
103
|
case 'chart-date':
|
|
95
104
|
return _jsx(_Fragment, { children: DAY_MONTH_FORMATER.format(value).replace(/[ ,]/g, '') });
|
|
105
|
+
case 'year-month-day':
|
|
106
|
+
return _jsx(_Fragment, { children: YEAR_MONTH_DAY_FORMATTER.format(value) });
|
|
96
107
|
default:
|
|
97
108
|
return _jsx(_Fragment, {});
|
|
98
109
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChartUtil.d.ts","sourceRoot":"","sources":["../../../src/lib/components/linetemporalchart/ChartUtil.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,+BAA+B,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IAEd,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC;IAEtB,eAAe,EAAE,OAAO,CAAC;IAEzB,QAAQ,EAAE,OAAO,CAAC;CACnB,EAAE,CAAC;AAKJ,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,UAEtD;AACD,wBAAgB,gBAAgB,CAC9B,2BAA2B,EAAE,KAAK,EAAE,GACnC,QAAQ,CAqBV;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAU3E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,EAAE,EACH,QAAQ,EAAE,MAAM,GACf;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,
|
|
1
|
+
{"version":3,"file":"ChartUtil.d.ts","sourceRoot":"","sources":["../../../src/lib/components/linetemporalchart/ChartUtil.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,+BAA+B,CAAC;AAEvC,MAAM,MAAM,QAAQ,GAAG;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IAEd,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC;IAEtB,eAAe,EAAE,OAAO,CAAC;IAEzB,QAAQ,EAAE,OAAO,CAAC;CACnB,EAAE,CAAC;AAKJ,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,UAEtD;AACD,wBAAgB,gBAAgB,CAC9B,2BAA2B,EAAE,KAAK,EAAE,GACnC,QAAQ,CAqBV;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAU3E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,EAAE,EACH,QAAQ,EAAE,MAAM,GACf;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAwCA;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,EACjD,iBAAiB,CAAC,EAAE,MAAM,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,cAAc,CAAC,EAAE,MAAM,GACtB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,CA2CpC;AAGD,eAAO,MAAM,gBAAgB,UAAW,MAAM,QAAQ,MAAM,WAE3D,CAAC;AACF,eAAO,MAAM,4BAA4B,GAAI,CAAC,SAAS,CAAC,QAAQ,MAAM,KAAG,CAQxE,CAAC;AACF,eAAO,MAAM,gBAAgB,kBAAmB,MAAM,QAAQ,MAAM,WAEnE,CAAC;AAEF,eAAO,MAAM,eAAe,WAAY,KAAK,EAAE,KAAG,MAAM,EAMvD,CAAC"}
|
|
@@ -43,6 +43,12 @@ export function convertDataBaseValue(data, base) {
|
|
|
43
43
|
* @returns {any}
|
|
44
44
|
*/
|
|
45
45
|
export function getUnitLabel(unitRange, maxValue) {
|
|
46
|
+
if (!unitRange || unitRange.length === 0) {
|
|
47
|
+
return {
|
|
48
|
+
valueBase: 1,
|
|
49
|
+
unitLabel: '',
|
|
50
|
+
};
|
|
51
|
+
}
|
|
46
52
|
// first sort the unitRange
|
|
47
53
|
unitRange.sort((unitA, unitB) => {
|
|
48
54
|
return unitA.threshold - unitB.threshold;
|
|
@@ -27,9 +27,15 @@ export type LineChartProps = (NonSymmetricalChartSerie | SymmetricalChartSerie)
|
|
|
27
27
|
label: string;
|
|
28
28
|
}[];
|
|
29
29
|
isLoading?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The format of the x axis, default is 'date-time' which is like 01 Sep 16:00
|
|
32
|
+
* If you want to display the date only, you can set it to 'date' which is like 2025-09-01
|
|
33
|
+
* This will affect the format of the tooltip as well
|
|
34
|
+
*/
|
|
35
|
+
timeFormat?: 'date-time' | 'date';
|
|
30
36
|
yAxisTitle?: string;
|
|
31
37
|
helpText?: string;
|
|
32
38
|
};
|
|
33
|
-
export declare function LineTimeSerieChart({ series, title, height, startingTimeStamp, interval, duration, unitRange, isLoading, yAxisType, yAxisTitle, helpText, ...rest }: LineChartProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export declare function LineTimeSerieChart({ series, title, height, startingTimeStamp, interval, duration, unitRange, isLoading, timeFormat, yAxisType, yAxisTitle, helpText, ...rest }: LineChartProps): import("react/jsx-runtime").JSX.Element;
|
|
34
40
|
export {};
|
|
35
41
|
//# sourceMappingURL=linetimeseriechart.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linetimeseriechart.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/linetimeseriechart/linetimeseriechart.component.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"linetimeseriechart.component.d.ts","sourceRoot":"","sources":["../../../src/lib/components/linetimeseriechart/linetimeseriechart.component.tsx"],"names":[],"mappings":"AA2FA,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,CAAC;CACjB,CAAC;AAGF,KAAK,qBAAqB,GAAG;IAC3B,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE;QACN,KAAK,EAAE,KAAK,EAAE,CAAC;QACf,KAAK,EAAE,KAAK,EAAE,CAAC;KAChB,CAAC;CACH,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,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;CACnB,CAAC;AAuEF,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,GAAG,IAAI,EACR,EAAE,cAAc,2CA6ShB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Line, LineChart, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis, CartesianGrid, } from 'recharts';
|
|
3
|
-
import { useMemo, useRef } from 'react';
|
|
3
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
4
4
|
import { useTheme } from 'styled-components';
|
|
5
5
|
import { addMissingDataPoint } from '../linetemporalchart/ChartUtil';
|
|
6
6
|
import styled from 'styled-components';
|
|
@@ -12,7 +12,7 @@ import { spacing } from '../../spacing';
|
|
|
12
12
|
import { getUnitLabel } from '../linetemporalchart/ChartUtil';
|
|
13
13
|
import { Icon } from '../icon/Icon.component';
|
|
14
14
|
import { Tooltip as TooltipComponent } from '../tooltip/Tooltip.component';
|
|
15
|
-
import { DAY_MONTH_ABBREVIATED_HOUR_MINUTE, FormattedDateTime, } from '../date/FormattedDateTime';
|
|
15
|
+
import { DAY_MONTH_ABBREVIATED_HOUR_MINUTE, FormattedDateTime, YEAR_MONTH_DAY_FORMATTER, } from '../date/FormattedDateTime';
|
|
16
16
|
const LineTemporalChartWrapper = styled.div `
|
|
17
17
|
display: flex;
|
|
18
18
|
flex-direction: column;
|
|
@@ -67,7 +67,7 @@ const TooltipName = styled.div `
|
|
|
67
67
|
const TooltipInstanceValue = styled.div `
|
|
68
68
|
justify-content: flex-end;
|
|
69
69
|
`;
|
|
70
|
-
const CustomTooltip = ({ active, payload, label, unitLabel, }) => {
|
|
70
|
+
const CustomTooltip = ({ active, payload, label, unitLabel, timeFormat, }) => {
|
|
71
71
|
if (!active || !payload || !payload.length || !label)
|
|
72
72
|
return null;
|
|
73
73
|
// We can't use the default itemSorter method because it's a custom tooltip.
|
|
@@ -83,14 +83,16 @@ const CustomTooltip = ({ active, payload, label, unitLabel, }) => {
|
|
|
83
83
|
}
|
|
84
84
|
return bValue - aValue; // Positives before negatives
|
|
85
85
|
});
|
|
86
|
-
return (_jsxs(TooltipContainer, { children: [_jsx(TooltipTime, { children: _jsx(FormattedDateTime, { format:
|
|
86
|
+
return (_jsxs(TooltipContainer, { children: [_jsx(TooltipTime, { children: _jsx(FormattedDateTime, { format: timeFormat === 'date-time'
|
|
87
|
+
? 'day-month-abbreviated-hour-minute-second'
|
|
88
|
+
: 'long-date', value: new Date(label) }) }), sortedPayload.map((entry, index) => (_jsxs(TooltipValue, { children: [_jsx(TooltipLegend, { color: entry.color }), _jsxs(TooltipContent, { children: [_jsx(TooltipName, { children: entry.name }), _jsx(TooltipInstanceValue, { children: isNaN(Number(entry.value))
|
|
87
89
|
? '-'
|
|
88
90
|
: `${Number(entry.value).toFixed(2)}${unitLabel}` })] })] }, index)))] }));
|
|
89
91
|
};
|
|
90
92
|
const isSymmetricalSeries = (series) => {
|
|
91
93
|
return 'above' in series && 'below' in series;
|
|
92
94
|
};
|
|
93
|
-
export function LineTimeSerieChart({ series, title, height, startingTimeStamp, interval, duration, unitRange, isLoading = false, yAxisType = 'default', yAxisTitle, helpText, ...rest }) {
|
|
95
|
+
export function LineTimeSerieChart({ series, title, height, startingTimeStamp, interval, duration, unitRange, isLoading = false, timeFormat = 'date-time', yAxisType = 'default', yAxisTitle, helpText, ...rest }) {
|
|
94
96
|
const theme = useTheme();
|
|
95
97
|
const { getColor } = useChartLegend();
|
|
96
98
|
const chartRef = useRef(null);
|
|
@@ -217,11 +219,15 @@ export function LineTimeSerieChart({ series, title, height, startingTimeStamp, i
|
|
|
217
219
|
};
|
|
218
220
|
}, [series, getColor]);
|
|
219
221
|
// Format time for display the tick in the x axis
|
|
220
|
-
const
|
|
222
|
+
const formatXAxisLabel = useCallback((timestamp) => {
|
|
221
223
|
const date = new Date(timestamp);
|
|
222
|
-
return
|
|
223
|
-
|
|
224
|
-
|
|
224
|
+
return timeFormat === 'date-time'
|
|
225
|
+
? DAY_MONTH_ABBREVIATED_HOUR_MINUTE.format(date).replace(',', '')
|
|
226
|
+
: timeFormat === 'date'
|
|
227
|
+
? YEAR_MONTH_DAY_FORMATTER.format(date)
|
|
228
|
+
: '';
|
|
229
|
+
}, [timeFormat]);
|
|
230
|
+
return (_jsxs(LineTemporalChartWrapper, { children: [_jsxs(ChartHeader, { children: [_jsxs(ChartTitleText, { children: [title, " ", unitLabel && `(${unitLabel})`] }), helpText && (_jsx(TooltipComponent, { placement: 'right', overlay: _jsx(SmallerText, { children: helpText }), children: _jsx(Icon, { name: "Info", color: theme.buttonSecondary }) })), isLoading && _jsx(Loader, {})] }), _jsx(ResponsiveContainer, { 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}`, 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: formatXAxisLabel, tickCount: 5, tick: {
|
|
225
231
|
fill: theme.textSecondary,
|
|
226
232
|
fontSize: fontSize.smaller,
|
|
227
233
|
}, axisLine: { stroke: theme.border } }), _jsx(YAxis, { orientation: "right", allowDataOverflow: false, label: {
|
|
@@ -240,8 +246,8 @@ export function LineTimeSerieChart({ series, title, height, startingTimeStamp, i
|
|
|
240
246
|
: [0, topValue], axisLine: { stroke: theme.border }, tick: {
|
|
241
247
|
fill: theme.textSecondary,
|
|
242
248
|
fontSize: fontSize.smaller,
|
|
243
|
-
}, tickFormatter: (value) => Math.round(value).toString() }), _jsx(Tooltip, { content: _jsx(CustomTooltip, { unitLabel: unitLabel }) }), yAxisType === 'symmetrical' && (_jsx(ReferenceLine, { y: 0, stroke: theme.border })), Object.entries(groupedSeries).map(([resource, resourceSeries]) => resourceSeries.map((serie, serieIndex) => {
|
|
249
|
+
}, tickFormatter: (value) => Math.round(value).toString() }), _jsx(Tooltip, { content: _jsx(CustomTooltip, { unitLabel: unitLabel, timeFormat: timeFormat }) }), yAxisType === 'symmetrical' && (_jsx(ReferenceLine, { y: 0, stroke: theme.border })), Object.entries(groupedSeries).map(([resource, resourceSeries]) => resourceSeries.map((serie, serieIndex) => {
|
|
244
250
|
const label = serie.getTooltipLabel(serie.metricPrefix, serie.resource);
|
|
245
|
-
return (_jsx(Line, { type: "monotone", dataKey: label, stroke: colorMapping[resource], dot: false }, `${title}-${resource}-${serieIndex}`));
|
|
251
|
+
return (_jsx(Line, { type: "monotone", dataKey: label, stroke: colorMapping[resource], dot: false, isAnimationActive: false }, `${title}-${resource}-${serieIndex}`));
|
|
246
252
|
}))] }) })] }));
|
|
247
253
|
}
|
package/package.json
CHANGED
|
@@ -60,7 +60,7 @@ describe('Barchart', () => {
|
|
|
60
60
|
render(
|
|
61
61
|
<Wrapper>
|
|
62
62
|
<ChartLegendWrapper colorSet={testColorSet}>
|
|
63
|
-
<Barchart type=
|
|
63
|
+
<Barchart type={{ type: 'category' }} bars={testBars} />
|
|
64
64
|
</ChartLegendWrapper>
|
|
65
65
|
</Wrapper>,
|
|
66
66
|
);
|
|
@@ -98,7 +98,7 @@ describe('Barchart', () => {
|
|
|
98
98
|
render(
|
|
99
99
|
<Wrapper>
|
|
100
100
|
<ChartLegendWrapper colorSet={testColorSet}>
|
|
101
|
-
<Barchart type=
|
|
101
|
+
<Barchart type={{ type: 'category' }} bars={[]} isError />
|
|
102
102
|
</ChartLegendWrapper>
|
|
103
103
|
</Wrapper>,
|
|
104
104
|
);
|
|
@@ -111,7 +111,7 @@ describe('Barchart', () => {
|
|
|
111
111
|
render(
|
|
112
112
|
<Wrapper>
|
|
113
113
|
<ChartLegendWrapper colorSet={testColorSet}>
|
|
114
|
-
<Barchart type=
|
|
114
|
+
<Barchart type={{ type: 'category' }} bars={[]} isLoading />
|
|
115
115
|
</ChartLegendWrapper>
|
|
116
116
|
</Wrapper>,
|
|
117
117
|
);
|
|
@@ -122,7 +122,7 @@ describe('Barchart', () => {
|
|
|
122
122
|
render(
|
|
123
123
|
<Wrapper>
|
|
124
124
|
<ChartLegendWrapper colorSet={testColorSet}>
|
|
125
|
-
<Barchart type=
|
|
125
|
+
<Barchart type={{ type: 'category' }} bars={undefined} />
|
|
126
126
|
</ChartLegendWrapper>
|
|
127
127
|
</Wrapper>,
|
|
128
128
|
);
|
|
@@ -316,7 +316,11 @@ describe('Barchart', () => {
|
|
|
316
316
|
render(
|
|
317
317
|
<Wrapper>
|
|
318
318
|
<ChartLegendWrapper colorSet={{ ...testColorSet, Failed: 'red' }}>
|
|
319
|
-
<Barchart
|
|
319
|
+
<Barchart
|
|
320
|
+
type={{ type: 'category' }}
|
|
321
|
+
bars={testStackedBars}
|
|
322
|
+
stacked
|
|
323
|
+
/>
|
|
320
324
|
</ChartLegendWrapper>
|
|
321
325
|
</Wrapper>,
|
|
322
326
|
);
|
|
@@ -344,7 +348,7 @@ describe('Barchart', () => {
|
|
|
344
348
|
<Wrapper>
|
|
345
349
|
<ChartLegendWrapper colorSet={testColorSet}>
|
|
346
350
|
<Barchart
|
|
347
|
-
type=
|
|
351
|
+
type={{ type: 'category' }}
|
|
348
352
|
bars={testBars}
|
|
349
353
|
defaultSort={(pointA, pointB) => {
|
|
350
354
|
const valueA = pointA.Success;
|
|
@@ -369,7 +373,7 @@ describe('Barchart', () => {
|
|
|
369
373
|
<Wrapper>
|
|
370
374
|
<ChartLegendWrapper colorSet={testColorSet}>
|
|
371
375
|
<Barchart
|
|
372
|
-
type=
|
|
376
|
+
type={{ type: 'category' }}
|
|
373
377
|
bars={[]}
|
|
374
378
|
title="Test Title"
|
|
375
379
|
secondaryTitle="Test Secondary Title"
|
|
@@ -45,6 +45,11 @@ export type TimeType = {
|
|
|
45
45
|
interval: number;
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
|
+
|
|
49
|
+
export type CategoryType = {
|
|
50
|
+
type: 'category';
|
|
51
|
+
gap?: number;
|
|
52
|
+
};
|
|
48
53
|
export type Point = {
|
|
49
54
|
key: string | number;
|
|
50
55
|
values: { label: string; value: number }[];
|
|
@@ -70,7 +75,7 @@ export type BarchartSortFn<T extends BarchartBars> = (
|
|
|
70
75
|
) => 1 | -1 | 0;
|
|
71
76
|
|
|
72
77
|
export type BarchartProps<T extends BarchartBars> = {
|
|
73
|
-
type:
|
|
78
|
+
type: CategoryType | TimeType;
|
|
74
79
|
bars?: T;
|
|
75
80
|
tooltip?: BarchartTooltipFn<T>;
|
|
76
81
|
defaultSort?: BarchartSortFn<T>;
|
|
@@ -260,7 +265,7 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
260
265
|
const {
|
|
261
266
|
height = CHART_CONSTANTS.DEFAULT_HEIGHT,
|
|
262
267
|
bars,
|
|
263
|
-
type = 'category',
|
|
268
|
+
type = { type: 'category' },
|
|
264
269
|
unitRange,
|
|
265
270
|
stacked,
|
|
266
271
|
stackedBarSort = 'default',
|
|
@@ -314,9 +319,16 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
|
|
|
314
319
|
<BarChart
|
|
315
320
|
data={rechartsData}
|
|
316
321
|
accessibilityLayer
|
|
317
|
-
barSize={
|
|
322
|
+
barSize={
|
|
323
|
+
type.type === 'category'
|
|
324
|
+
? type.gap === 0
|
|
325
|
+
? undefined
|
|
326
|
+
: CHART_CONSTANTS.BAR_SIZE
|
|
327
|
+
: CHART_CONSTANTS.BAR_SIZE
|
|
328
|
+
}
|
|
318
329
|
height={height}
|
|
319
330
|
margin={CHART_CONSTANTS.CHART_MARGIN}
|
|
331
|
+
barCategoryGap={type.type === 'category' ? type.gap : undefined}
|
|
320
332
|
>
|
|
321
333
|
<CartesianGrid
|
|
322
334
|
vertical={false}
|
|
@@ -570,7 +570,7 @@ describe('formatPrometheusDataToRechartsDataAndBars', () => {
|
|
|
570
570
|
|
|
571
571
|
const result = formatPrometheusDataToRechartsDataAndBars(
|
|
572
572
|
bars,
|
|
573
|
-
'category',
|
|
573
|
+
{ type: 'category' },
|
|
574
574
|
{
|
|
575
575
|
Success: coreUIAvailableThemes.darkRebrand.statusHealthy,
|
|
576
576
|
Failed: coreUIAvailableThemes.darkRebrand.statusCritical,
|
|
@@ -647,7 +647,7 @@ describe('formatPrometheusDataToRechartsDataAndBars', () => {
|
|
|
647
647
|
|
|
648
648
|
const result = formatPrometheusDataToRechartsDataAndBars(
|
|
649
649
|
bars,
|
|
650
|
-
'category',
|
|
650
|
+
{ type: 'category' },
|
|
651
651
|
mockTheme,
|
|
652
652
|
false,
|
|
653
653
|
(pointA, pointB) => {
|
|
@@ -271,11 +271,11 @@ export const formatPrometheusDataToRechartsDataAndBars = <
|
|
|
271
271
|
);
|
|
272
272
|
|
|
273
273
|
let data =
|
|
274
|
-
type !== 'category' && type.type === 'time'
|
|
274
|
+
type.type !== 'category' && type.type === 'time'
|
|
275
275
|
? transformTimeData(bars, type, barDataKeys)
|
|
276
276
|
: transformCategoryData(bars, barDataKeys);
|
|
277
277
|
|
|
278
|
-
if (type === 'category' && defaultSort) {
|
|
278
|
+
if (type.type === 'category' && defaultSort) {
|
|
279
279
|
data = applySortingToData(data, barDataKeys, defaultSort);
|
|
280
280
|
}
|
|
281
281
|
|
|
@@ -54,6 +54,16 @@ export const DAY_MONTH_ABBREVIATED_HOUR_MINUTE = Intl.DateTimeFormat('en-GB', {
|
|
|
54
54
|
hour12: false,
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @description Year month day formatter, without time. Used for describing long term date.
|
|
59
|
+
* @example 2025-01-01
|
|
60
|
+
*/
|
|
61
|
+
export const YEAR_MONTH_DAY_FORMATTER = Intl.DateTimeFormat('en-CA', {
|
|
62
|
+
year: 'numeric',
|
|
63
|
+
month: '2-digit',
|
|
64
|
+
day: '2-digit',
|
|
65
|
+
});
|
|
66
|
+
|
|
57
67
|
type FormattedDateTimeProps = {
|
|
58
68
|
format:
|
|
59
69
|
| 'date'
|
|
@@ -65,7 +75,8 @@ type FormattedDateTimeProps = {
|
|
|
65
75
|
| 'day-month-abbreviated-hour-minute'
|
|
66
76
|
| 'day-month-abbreviated-hour-minute-second'
|
|
67
77
|
| 'long-date'
|
|
68
|
-
| 'chart-date'
|
|
78
|
+
| 'chart-date'
|
|
79
|
+
| 'year-month-day';
|
|
69
80
|
|
|
70
81
|
value: Date;
|
|
71
82
|
};
|
|
@@ -198,6 +209,8 @@ export const FormattedDateTime = ({
|
|
|
198
209
|
return <>{LONG_DATE_FORMATER.format(value)}</>;
|
|
199
210
|
case 'chart-date':
|
|
200
211
|
return <>{DAY_MONTH_FORMATER.format(value).replace(/[ ,]/g, '')}</>;
|
|
212
|
+
case 'year-month-day':
|
|
213
|
+
return <>{YEAR_MONTH_DAY_FORMATTER.format(value)}</>;
|
|
201
214
|
default:
|
|
202
215
|
return <></>;
|
|
203
216
|
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
YAxis,
|
|
9
9
|
CartesianGrid,
|
|
10
10
|
} from 'recharts';
|
|
11
|
-
import { useMemo, useRef } from 'react';
|
|
11
|
+
import { useCallback, useMemo, useRef } from 'react';
|
|
12
12
|
import { useTheme } from 'styled-components';
|
|
13
13
|
import { addMissingDataPoint } from '../linetemporalchart/ChartUtil';
|
|
14
14
|
import styled from 'styled-components';
|
|
@@ -23,6 +23,7 @@ import { Tooltip as TooltipComponent } from '../tooltip/Tooltip.component';
|
|
|
23
23
|
import {
|
|
24
24
|
DAY_MONTH_ABBREVIATED_HOUR_MINUTE,
|
|
25
25
|
FormattedDateTime,
|
|
26
|
+
YEAR_MONTH_DAY_FORMATTER,
|
|
26
27
|
} from '../date/FormattedDateTime';
|
|
27
28
|
|
|
28
29
|
const LineTemporalChartWrapper = styled.div`
|
|
@@ -129,6 +130,12 @@ export type LineChartProps = (
|
|
|
129
130
|
label: string;
|
|
130
131
|
}[];
|
|
131
132
|
isLoading?: boolean;
|
|
133
|
+
/**
|
|
134
|
+
* The format of the x axis, default is 'date-time' which is like 01 Sep 16:00
|
|
135
|
+
* If you want to display the date only, you can set it to 'date' which is like 2025-09-01
|
|
136
|
+
* This will affect the format of the tooltip as well
|
|
137
|
+
*/
|
|
138
|
+
timeFormat?: 'date-time' | 'date';
|
|
132
139
|
yAxisTitle?: string;
|
|
133
140
|
helpText?: string;
|
|
134
141
|
};
|
|
@@ -138,6 +145,7 @@ const CustomTooltip = ({
|
|
|
138
145
|
payload,
|
|
139
146
|
label,
|
|
140
147
|
unitLabel,
|
|
148
|
+
timeFormat,
|
|
141
149
|
}: {
|
|
142
150
|
active?: boolean;
|
|
143
151
|
payload?: Array<{
|
|
@@ -148,6 +156,7 @@ const CustomTooltip = ({
|
|
|
148
156
|
}>;
|
|
149
157
|
label?: string;
|
|
150
158
|
unitLabel?: string;
|
|
159
|
+
timeFormat?: 'date-time' | 'date';
|
|
151
160
|
}) => {
|
|
152
161
|
if (!active || !payload || !payload.length || !label) return null;
|
|
153
162
|
// We can't use the default itemSorter method because it's a custom tooltip.
|
|
@@ -169,7 +178,11 @@ const CustomTooltip = ({
|
|
|
169
178
|
<TooltipContainer>
|
|
170
179
|
<TooltipTime>
|
|
171
180
|
<FormattedDateTime
|
|
172
|
-
format=
|
|
181
|
+
format={
|
|
182
|
+
timeFormat === 'date-time'
|
|
183
|
+
? 'day-month-abbreviated-hour-minute-second'
|
|
184
|
+
: 'long-date'
|
|
185
|
+
}
|
|
173
186
|
value={new Date(label)}
|
|
174
187
|
/>
|
|
175
188
|
</TooltipTime>
|
|
@@ -205,6 +218,7 @@ export function LineTimeSerieChart({
|
|
|
205
218
|
duration,
|
|
206
219
|
unitRange,
|
|
207
220
|
isLoading = false,
|
|
221
|
+
timeFormat = 'date-time',
|
|
208
222
|
yAxisType = 'default',
|
|
209
223
|
yAxisTitle,
|
|
210
224
|
helpText,
|
|
@@ -393,12 +407,16 @@ export function LineTimeSerieChart({
|
|
|
393
407
|
}, [series, getColor]);
|
|
394
408
|
|
|
395
409
|
// Format time for display the tick in the x axis
|
|
396
|
-
const
|
|
397
|
-
(
|
|
410
|
+
const formatXAxisLabel = useCallback(
|
|
411
|
+
(timestamp: number) => {
|
|
398
412
|
const date = new Date(timestamp);
|
|
399
|
-
return
|
|
413
|
+
return timeFormat === 'date-time'
|
|
414
|
+
? DAY_MONTH_ABBREVIATED_HOUR_MINUTE.format(date).replace(',', '')
|
|
415
|
+
: timeFormat === 'date'
|
|
416
|
+
? YEAR_MONTH_DAY_FORMATTER.format(date)
|
|
417
|
+
: '';
|
|
400
418
|
},
|
|
401
|
-
[],
|
|
419
|
+
[timeFormat],
|
|
402
420
|
);
|
|
403
421
|
|
|
404
422
|
return (
|
|
@@ -438,7 +456,7 @@ export function LineTimeSerieChart({
|
|
|
438
456
|
type="number"
|
|
439
457
|
domain={['dataMin', 'dataMax']}
|
|
440
458
|
ticks={xAxisTicks}
|
|
441
|
-
tickFormatter={
|
|
459
|
+
tickFormatter={formatXAxisLabel}
|
|
442
460
|
tickCount={5}
|
|
443
461
|
tick={{
|
|
444
462
|
fill: theme.textSecondary,
|
|
@@ -473,7 +491,11 @@ export function LineTimeSerieChart({
|
|
|
473
491
|
}}
|
|
474
492
|
tickFormatter={(value) => Math.round(value).toString()}
|
|
475
493
|
/>
|
|
476
|
-
<Tooltip
|
|
494
|
+
<Tooltip
|
|
495
|
+
content={
|
|
496
|
+
<CustomTooltip unitLabel={unitLabel} timeFormat={timeFormat} />
|
|
497
|
+
}
|
|
498
|
+
/>
|
|
477
499
|
{/* Add horizontal line at y=0 for symmetrical charts */}
|
|
478
500
|
{yAxisType === 'symmetrical' && (
|
|
479
501
|
<ReferenceLine y={0} stroke={theme.border} />
|
|
@@ -493,6 +515,7 @@ export function LineTimeSerieChart({
|
|
|
493
515
|
dataKey={label}
|
|
494
516
|
stroke={colorMapping[resource]}
|
|
495
517
|
dot={false}
|
|
518
|
+
isAnimationActive={false}
|
|
496
519
|
/>
|
|
497
520
|
);
|
|
498
521
|
}),
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { render } from "@testing-library/react";
|
|
2
|
+
import { LineChartProps, LineTimeSerieChart } from "./linetimeseriechart.component";
|
|
3
|
+
import { ChartLegendWrapper } from "../chartlegend/ChartLegendWrapper";
|
|
4
|
+
import { ThemeProvider } from "styled-components";
|
|
5
|
+
import { coreUIAvailableThemes } from "../../style/theme";
|
|
6
|
+
|
|
7
|
+
const TestSeries = [
|
|
8
|
+
{
|
|
9
|
+
|
|
10
|
+
resource: "Series 1",
|
|
11
|
+
getTooltipLabel: () => `Series 1`,
|
|
12
|
+
data: [
|
|
13
|
+
[1622505600000, 10],
|
|
14
|
+
[1622509200000, 20],
|
|
15
|
+
[1622512800000, 30],
|
|
16
|
+
] as [number, number][],
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
resource: "Series 2",
|
|
20
|
+
getTooltipLabel: () => `Series 2`,
|
|
21
|
+
data: [
|
|
22
|
+
[1622505600000, 15],
|
|
23
|
+
[1622509200000, 25],
|
|
24
|
+
[1622512800000, 35],
|
|
25
|
+
] as [number, number][],
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const ColorSet = {
|
|
30
|
+
"Series 1": "#FF0000",
|
|
31
|
+
"Series 2": "#00FF00",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const renderLineTimeSerieChart = (props: Partial<LineChartProps> = {}) => {
|
|
35
|
+
return render(
|
|
36
|
+
<ThemeProvider theme={coreUIAvailableThemes.artescaLight}>
|
|
37
|
+
<ChartLegendWrapper colorSet={ColorSet}>
|
|
38
|
+
<LineTimeSerieChart
|
|
39
|
+
{
|
|
40
|
+
...{
|
|
41
|
+
title: "Test Chart",
|
|
42
|
+
yAxisType: "default",
|
|
43
|
+
series: TestSeries,
|
|
44
|
+
height: 400,
|
|
45
|
+
startingTimeStamp: TestSeries[0].data[0][0],
|
|
46
|
+
interval: TestSeries[0].data[1][0] - TestSeries[0].data[0][0],
|
|
47
|
+
duration: TestSeries[0].data[TestSeries[0].data.length - 1][0] - TestSeries[0].data[0][0],
|
|
48
|
+
unitRange: [{ label: 'units', value: 1 }],
|
|
49
|
+
...props
|
|
50
|
+
} as LineChartProps
|
|
51
|
+
}
|
|
52
|
+
/>
|
|
53
|
+
</ChartLegendWrapper>
|
|
54
|
+
</ThemeProvider>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
describe('LineTimeSerieChart', () => {
|
|
59
|
+
it('should render when with basic parameters', async () => {
|
|
60
|
+
const { container } = renderLineTimeSerieChart();
|
|
61
|
+
expect(container).toBeInTheDocument();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should render when no unitRange is provided', async () => {
|
|
65
|
+
const { container } = renderLineTimeSerieChart({ unitRange: undefined });
|
|
66
|
+
expect(container).toBeInTheDocument();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -61,7 +61,7 @@ export const Playground: Story = {
|
|
|
61
61
|
}}
|
|
62
62
|
>
|
|
63
63
|
<Stack direction="vertical" gap="r16">
|
|
64
|
-
<Barchart type=
|
|
64
|
+
<Barchart type={{ type: 'category' }} bars={exampleData} />
|
|
65
65
|
<ChartLegend shape="rectangle" direction="horizontal" />
|
|
66
66
|
</Stack>
|
|
67
67
|
</ChartLegendWrapper>
|
|
@@ -332,7 +332,7 @@ export const CapacityWithUnitRange: Story = {
|
|
|
332
332
|
}}
|
|
333
333
|
>
|
|
334
334
|
<Barchart
|
|
335
|
-
type=
|
|
335
|
+
type={{ type: 'category' }}
|
|
336
336
|
bars={capacityDataWithUnitRange}
|
|
337
337
|
unitRange={[
|
|
338
338
|
{
|
|
@@ -402,7 +402,7 @@ export const Stacked: Story = {
|
|
|
402
402
|
}}
|
|
403
403
|
>
|
|
404
404
|
<Stack direction="vertical" gap="r16">
|
|
405
|
-
<Barchart type=
|
|
405
|
+
<Barchart type={{ type: 'category' }} bars={stackedData} stacked />
|
|
406
406
|
<ChartLegend shape="rectangle" />
|
|
407
407
|
</Stack>
|
|
408
408
|
</ChartLegendWrapper>
|
|
@@ -453,7 +453,7 @@ export const DefaultSort: Story = {
|
|
|
453
453
|
}}
|
|
454
454
|
>
|
|
455
455
|
<Barchart
|
|
456
|
-
type=
|
|
456
|
+
type={{ type: 'category' }}
|
|
457
457
|
stacked
|
|
458
458
|
bars={defaultSortData}
|
|
459
459
|
defaultSort={customSort}
|
|
@@ -531,7 +531,7 @@ export const WithCustomTooltip: Story = {
|
|
|
531
531
|
>
|
|
532
532
|
<Stack direction="vertical" gap="r16">
|
|
533
533
|
<Barchart
|
|
534
|
-
type=
|
|
534
|
+
type={{ type: 'category' }}
|
|
535
535
|
bars={exampleData}
|
|
536
536
|
tooltip={customTooltip}
|
|
537
537
|
height={300}
|
|
@@ -602,7 +602,7 @@ export const StatusColors: Story = {
|
|
|
602
602
|
>
|
|
603
603
|
<Stack direction="vertical" gap="r16">
|
|
604
604
|
<Barchart
|
|
605
|
-
type=
|
|
605
|
+
type={{ type: 'category' }}
|
|
606
606
|
bars={statusData}
|
|
607
607
|
stacked
|
|
608
608
|
title="System Health Metrics"
|
|
@@ -656,7 +656,7 @@ export const LegendShapes: Story = {
|
|
|
656
656
|
>
|
|
657
657
|
<Stack direction="vertical" gap="r16">
|
|
658
658
|
<Barchart
|
|
659
|
-
type=
|
|
659
|
+
type={{ type: 'category' }}
|
|
660
660
|
bars={exampleData}
|
|
661
661
|
height={200}
|
|
662
662
|
title="Horizontal Rectangle Legend"
|
|
@@ -673,7 +673,7 @@ export const LegendShapes: Story = {
|
|
|
673
673
|
>
|
|
674
674
|
<Stack direction="vertical" gap="r16">
|
|
675
675
|
<Barchart
|
|
676
|
-
type=
|
|
676
|
+
type={{ type: 'category' }}
|
|
677
677
|
bars={exampleData}
|
|
678
678
|
height={200}
|
|
679
679
|
title="Vertical Line Legend"
|
|
@@ -727,14 +727,14 @@ export const BarchartsWithSingleLegend: Story = {
|
|
|
727
727
|
}}
|
|
728
728
|
>
|
|
729
729
|
<Barchart
|
|
730
|
-
type=
|
|
730
|
+
type={{ type: 'category' }}
|
|
731
731
|
bars={exampleData}
|
|
732
732
|
height={200}
|
|
733
733
|
title="Barchart 1"
|
|
734
734
|
/>
|
|
735
735
|
|
|
736
736
|
<Barchart
|
|
737
|
-
type=
|
|
737
|
+
type={{ type: 'category' }}
|
|
738
738
|
bars={exampleData}
|
|
739
739
|
height={200}
|
|
740
740
|
title="Barchart 2"
|
|
@@ -757,7 +757,7 @@ export const ErrorState: Story = {
|
|
|
757
757
|
}}
|
|
758
758
|
>
|
|
759
759
|
<Barchart
|
|
760
|
-
type=
|
|
760
|
+
type={{ type: 'category' }}
|
|
761
761
|
bars={[]}
|
|
762
762
|
isError
|
|
763
763
|
title="Error State"
|
|
@@ -808,7 +808,7 @@ export const StackedBarSort: Story = {
|
|
|
808
808
|
}}
|
|
809
809
|
>
|
|
810
810
|
<Barchart
|
|
811
|
-
type=
|
|
811
|
+
type={{ type: 'category' }}
|
|
812
812
|
bars={statusesData}
|
|
813
813
|
stacked
|
|
814
814
|
stackedBarSort={sort}
|
|
@@ -883,7 +883,7 @@ export const CompleteExample: Story = {
|
|
|
883
883
|
}}
|
|
884
884
|
>
|
|
885
885
|
<Barchart
|
|
886
|
-
type=
|
|
886
|
+
type={{ type: 'category' }}
|
|
887
887
|
title="Loading BarChart"
|
|
888
888
|
helpTooltip="Click on the button to load or unload data"
|
|
889
889
|
secondaryTitle={isLoading ? 'Loading...' : 'Loaded data'}
|
|
@@ -911,3 +911,98 @@ export const CompleteExample: Story = {
|
|
|
911
911
|
);
|
|
912
912
|
},
|
|
913
913
|
};
|
|
914
|
+
|
|
915
|
+
export const Histogram: Story = {
|
|
916
|
+
render: () => {
|
|
917
|
+
const histogramData = [
|
|
918
|
+
{
|
|
919
|
+
label: 'Success',
|
|
920
|
+
data: [
|
|
921
|
+
['0-10', 1],
|
|
922
|
+
['10-20', 5],
|
|
923
|
+
['20-30', 15],
|
|
924
|
+
['30-40', 40],
|
|
925
|
+
['40-50', 45],
|
|
926
|
+
['50-60', 50],
|
|
927
|
+
['60-70', 40],
|
|
928
|
+
['70-80', 15],
|
|
929
|
+
['80-90', 5],
|
|
930
|
+
['90-100', 1],
|
|
931
|
+
],
|
|
932
|
+
},
|
|
933
|
+
] as const;
|
|
934
|
+
const theme = useTheme() as CoreUITheme;
|
|
935
|
+
return (
|
|
936
|
+
<div style={{ width: '50%', padding: spacing.r16 }}>
|
|
937
|
+
<ChartLegendWrapper
|
|
938
|
+
colorSet={{
|
|
939
|
+
Success: theme.statusHealthy,
|
|
940
|
+
Failed: theme.statusCritical,
|
|
941
|
+
}}
|
|
942
|
+
>
|
|
943
|
+
<Barchart
|
|
944
|
+
type={{ type: 'category', gap: 0 }}
|
|
945
|
+
bars={histogramData}
|
|
946
|
+
title="Histogram"
|
|
947
|
+
/>
|
|
948
|
+
</ChartLegendWrapper>
|
|
949
|
+
</div>
|
|
950
|
+
);
|
|
951
|
+
},
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
export const StackedHistogram: Story = {
|
|
955
|
+
render: () => {
|
|
956
|
+
const histogramData = [
|
|
957
|
+
{
|
|
958
|
+
label: 'Test 1',
|
|
959
|
+
data: [
|
|
960
|
+
['0-10', 1],
|
|
961
|
+
['10-20', 5],
|
|
962
|
+
['20-30', 15],
|
|
963
|
+
['30-40', 40],
|
|
964
|
+
['40-50', 45],
|
|
965
|
+
['50-60', 50],
|
|
966
|
+
['60-70', 40],
|
|
967
|
+
['70-80', 15],
|
|
968
|
+
['80-90', 5],
|
|
969
|
+
['90-100', 1],
|
|
970
|
+
],
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
label: 'Test 2',
|
|
974
|
+
data: [
|
|
975
|
+
['0-10', 1],
|
|
976
|
+
['10-20', 2],
|
|
977
|
+
['20-30', 4],
|
|
978
|
+
['30-40', 4],
|
|
979
|
+
['40-50', 5],
|
|
980
|
+
['50-60', 6],
|
|
981
|
+
['60-70', 6],
|
|
982
|
+
['70-80', 3],
|
|
983
|
+
['80-90', 2],
|
|
984
|
+
['90-100', 1],
|
|
985
|
+
],
|
|
986
|
+
},
|
|
987
|
+
] as const;
|
|
988
|
+
const theme = useTheme() as CoreUITheme;
|
|
989
|
+
return (
|
|
990
|
+
<div style={{ width: '50%', padding: spacing.r16 }}>
|
|
991
|
+
<ChartLegendWrapper
|
|
992
|
+
colorSet={{
|
|
993
|
+
'Test 1': theme.statusHealthy,
|
|
994
|
+
'Test 2': theme.statusWarning,
|
|
995
|
+
}}
|
|
996
|
+
>
|
|
997
|
+
<Barchart
|
|
998
|
+
type={{ type: 'category', gap: 0 }}
|
|
999
|
+
bars={histogramData}
|
|
1000
|
+
title="Stacked Histogram"
|
|
1001
|
+
stacked
|
|
1002
|
+
/>
|
|
1003
|
+
<ChartLegend shape="rectangle" />
|
|
1004
|
+
</ChartLegendWrapper>
|
|
1005
|
+
</div>
|
|
1006
|
+
);
|
|
1007
|
+
},
|
|
1008
|
+
};
|
|
@@ -64,6 +64,10 @@ const meta: Meta<typeof LineTimeSerieChart> = {
|
|
|
64
64
|
options: ['default', 'percentage', 'symmetrical'],
|
|
65
65
|
},
|
|
66
66
|
yAxisTitle: { control: 'text' },
|
|
67
|
+
timeFormat: {
|
|
68
|
+
control: 'select',
|
|
69
|
+
options: ['date-time', 'date'],
|
|
70
|
+
},
|
|
67
71
|
},
|
|
68
72
|
};
|
|
69
73
|
|
|
@@ -405,6 +409,74 @@ const irregularIntervalData = [
|
|
|
405
409
|
[1740424900, '46.92'], // +1100 seconds (18.3 minutes) - under 2 intervals
|
|
406
410
|
];
|
|
407
411
|
|
|
412
|
+
// Data spanning several months - multi-month dataset
|
|
413
|
+
const longTermPrometheusData: [number, string][] = [
|
|
414
|
+
// January 2025
|
|
415
|
+
[1735689600, '42.15'], // Jan 1, 2025
|
|
416
|
+
[1735776000, '38.92'], // Jan 2, 2025
|
|
417
|
+
[1735862400, '55.33'], // Jan 3, 2025
|
|
418
|
+
[1735948800, '67.88'], // Jan 4, 2025
|
|
419
|
+
[1736035200, '44.21'], // Jan 5, 2025
|
|
420
|
+
[1736121600, '72.15'], // Jan 6, 2025
|
|
421
|
+
[1736208000, '39.67'], // Jan 7, 2025
|
|
422
|
+
[1736294400, '58.44'], // Jan 8, 2025
|
|
423
|
+
[1736380800, '63.92'], // Jan 9, 2025
|
|
424
|
+
[1736467200, '41.33'], // Jan 10, 2025
|
|
425
|
+
[1736553600, '76.88'], // Jan 11, 2025
|
|
426
|
+
[1736640000, '52.15'], // Jan 12, 2025
|
|
427
|
+
[1736726400, '48.67'], // Jan 13, 2025
|
|
428
|
+
[1736812800, '69.33'], // Jan 14, 2025
|
|
429
|
+
[1736899200, '35.88'], // Jan 15, 2025
|
|
430
|
+
// February 2025
|
|
431
|
+
[1738368000, '81.15'], // Feb 1, 2025
|
|
432
|
+
[1738454400, '47.67'], // Feb 2, 2025
|
|
433
|
+
[1738540800, '54.33'], // Feb 3, 2025
|
|
434
|
+
[1738627200, '62.88'], // Feb 4, 2025
|
|
435
|
+
[1738713600, '38.15'], // Feb 5, 2025
|
|
436
|
+
[1738800000, '73.67'], // Feb 6, 2025
|
|
437
|
+
[1738886400, '45.33'], // Feb 7, 2025
|
|
438
|
+
[1738972800, '59.88'], // Feb 8, 2025
|
|
439
|
+
[1739059200, '51.15'], // Feb 9, 2025
|
|
440
|
+
[1739145600, '66.67'], // Feb 10, 2025
|
|
441
|
+
[1739232000, '43.33'], // Feb 11, 2025
|
|
442
|
+
[1739318400, '78.88'], // Feb 12, 2025
|
|
443
|
+
[1739404800, '36.15'], // Feb 13, 2025
|
|
444
|
+
[1739491200, '64.67'], // Feb 14, 2025
|
|
445
|
+
[1739577600, '49.33'], // Feb 15, 2025
|
|
446
|
+
// March 2025
|
|
447
|
+
[1740787200, '71.88'], // Mar 1, 2025
|
|
448
|
+
[1740873600, '42.15'], // Mar 2, 2025
|
|
449
|
+
[1740960000, '57.67'], // Mar 3, 2025
|
|
450
|
+
[1741046400, '68.33'], // Mar 4, 2025
|
|
451
|
+
[1741132800, '34.88'], // Mar 5, 2025
|
|
452
|
+
[1741219200, '75.15'], // Mar 6, 2025
|
|
453
|
+
[1741305600, '48.67'], // Mar 7, 2025
|
|
454
|
+
[1741392000, '53.33'], // Mar 8, 2025
|
|
455
|
+
[1741478400, '61.88'], // Mar 9, 2025
|
|
456
|
+
[1741564800, '37.15'], // Mar 10, 2025
|
|
457
|
+
[1741651200, '74.67'], // Mar 11, 2025
|
|
458
|
+
[1741737600, '44.33'], // Mar 12, 2025
|
|
459
|
+
[1741824000, '58.88'], // Mar 13, 2025
|
|
460
|
+
[1741910400, '52.15'], // Mar 14, 2025
|
|
461
|
+
[1741996800, '67.67'], // Mar 15, 2025
|
|
462
|
+
// April 2025
|
|
463
|
+
[1743465600, '41.33'], // Apr 1, 2025
|
|
464
|
+
[1743552000, '76.88'], // Apr 2, 2025
|
|
465
|
+
[1743638400, '35.15'], // Apr 3, 2025
|
|
466
|
+
[1743724800, '63.67'], // Apr 4, 2025
|
|
467
|
+
[1743811200, '50.33'], // Apr 5, 2025
|
|
468
|
+
[1743897600, '72.88'], // Apr 6, 2025
|
|
469
|
+
[1743984000, '39.15'], // Apr 7, 2025
|
|
470
|
+
[1744070400, '56.67'], // Apr 8, 2025
|
|
471
|
+
[1744156800, '65.33'], // Apr 9, 2025
|
|
472
|
+
[1744243200, '33.88'], // Apr 10, 2025
|
|
473
|
+
[1744329600, '77.15'], // Apr 11, 2025
|
|
474
|
+
[1744416000, '46.67'], // Apr 12, 2025
|
|
475
|
+
[1744502400, '54.33'], // Apr 13, 2025
|
|
476
|
+
[1744588800, '60.88'], // Apr 14, 2025
|
|
477
|
+
[1744675200, '49.22'], // Apr 15, 2025
|
|
478
|
+
];
|
|
479
|
+
|
|
408
480
|
export const PercentageChartExample: Story = {
|
|
409
481
|
args: {
|
|
410
482
|
series: [
|
|
@@ -425,6 +497,7 @@ export const PercentageChartExample: Story = {
|
|
|
425
497
|
yAxisTitle: '',
|
|
426
498
|
interval: SAMPLE_FREQUENCY_LAST_TWENTY_FOUR_HOURS,
|
|
427
499
|
duration: SAMPLE_DURATION_LAST_TWENTY_FOUR_HOURS,
|
|
500
|
+
xAxisFormat: 'date-time',
|
|
428
501
|
},
|
|
429
502
|
};
|
|
430
503
|
const UNIT_RANGE_BS = [
|
|
@@ -537,3 +610,27 @@ export const IrregularIntervalsExample: Story = {
|
|
|
537
610
|
duration: SAMPLE_DURATION_LAST_TWENTY_FOUR_HOURS,
|
|
538
611
|
},
|
|
539
612
|
};
|
|
613
|
+
|
|
614
|
+
export const DateFormatExample: Story = {
|
|
615
|
+
args: {
|
|
616
|
+
series: [
|
|
617
|
+
{
|
|
618
|
+
data: longTermPrometheusData,
|
|
619
|
+
resource: 'ip-10-160-122-207.eu-north-1.compute.internal',
|
|
620
|
+
metricPrefix: 'instance:10.160.122.207:9100',
|
|
621
|
+
getTooltipLabel: (prefix, resource) => `${resource}`,
|
|
622
|
+
},
|
|
623
|
+
],
|
|
624
|
+
title: 'Long term data',
|
|
625
|
+
height: 200,
|
|
626
|
+
startingTimeStamp: longTermPrometheusData[0][0],
|
|
627
|
+
isLoading: false,
|
|
628
|
+
isLegendHidden: false,
|
|
629
|
+
helpText: 'This is the help text',
|
|
630
|
+
interval: 60 * 60 * 24, // 1 day
|
|
631
|
+
duration:
|
|
632
|
+
longTermPrometheusData[longTermPrometheusData.length - 1][0] -
|
|
633
|
+
longTermPrometheusData[0][0],
|
|
634
|
+
timeFormat: 'date',
|
|
635
|
+
},
|
|
636
|
+
};
|