@centreon/ui 25.10.29 → 25.10.30
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/package.json +3 -3
- package/public/mockServiceWorker.js +8 -31
- package/src/Dashboard/Item.tsx +142 -149
- package/src/Form/Inputs/ConnectedAutocomplete.tsx +2 -0
- package/src/Form/Inputs/Grid.tsx +2 -3
- package/src/Form/Inputs/models.ts +2 -0
- package/src/Form/Section/navigateToSection.ts +6 -6
- package/src/Graph/BarChart/BarChart.cypress.spec.tsx +55 -102
- package/src/Graph/BarChart/BarChart.stories.tsx +1 -51
- package/src/Graph/BarChart/BarChart.tsx +1 -1
- package/src/Graph/BarChart/BarGroup.tsx +32 -22
- package/src/Graph/BarChart/BarStack.tsx +26 -15
- package/src/Graph/BarChart/MemoizedGroup.tsx +18 -14
- package/src/Graph/BarChart/ResponsiveBarChart.tsx +6 -7
- package/src/Graph/BarChart/Tooltip/BarChartTooltip.tsx +2 -2
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/index.tsx +5 -4
- package/src/Graph/Chart/BasicComponents/Lines/StackedLines/useStackedLines.ts +45 -18
- package/src/Graph/Chart/BasicComponents/Lines/index.tsx +118 -124
- package/src/Graph/Chart/Chart.cypress.spec.tsx +6 -25
- package/src/Graph/Chart/Chart.stories.tsx +1 -43
- package/src/Graph/Chart/Chart.tsx +13 -9
- package/src/Graph/Chart/InteractiveComponents/GraphValueTooltip/useGraphValueTooltip.ts +4 -2
- package/src/Graph/Chart/Legend/index.tsx +2 -26
- package/src/Graph/Chart/index.tsx +45 -31
- package/src/Graph/Chart/models.ts +1 -6
- package/src/Graph/Chart/translatedLabels.ts +1 -0
- package/src/Graph/Chart/useChartData.ts +24 -3
- package/src/Graph/common/Axes/index.tsx +1 -1
- package/src/Graph/common/BaseChart/BaseChart.tsx +1 -6
- package/src/Graph/common/BaseChart/ChartSvgWrapper.tsx +23 -16
- package/src/Graph/common/Error/NoData.tsx +18 -0
- package/src/Graph/common/Grids/index.tsx +4 -4
- package/src/Graph/common/timeSeries/index.test.ts +4 -24
- package/src/Graph/common/timeSeries/index.ts +120 -184
- package/src/Graph/common/timeSeries/models.ts +1 -1
- package/src/Graph/common/utils.ts +4 -10
- package/src/Graph/index.ts +20 -20
- package/src/InputField/Select/Autocomplete/Connected/index.tsx +3 -3
- package/src/InputField/Select/Autocomplete/Multi/Listbox.tsx +11 -3
- package/src/InputField/Select/Autocomplete/Multi/Multi.tsx +3 -2
- package/src/InputField/Select/index.tsx +2 -1
- package/src/Listing/ActionBar/Pagination.tsx +2 -1
- package/src/Listing/ActionBar/index.tsx +113 -8
- package/src/Listing/index.tsx +19 -2
- package/src/Listing/translatedLabels.ts +4 -0
- package/src/Module/index.tsx +2 -8
- package/src/ThemeProvider/index.tsx +21 -30
- package/src/ThemeProvider/tailwindcss.css +12 -10
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +8 -5
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +0 -1
- package/src/api/useGraphQuery/index.ts +7 -4
- package/src/components/Layout/PageLayout/PageLayout.tsx +3 -9
- package/src/components/Layout/PageLayout/PageLayoutActions.tsx +3 -5
- package/src/components/Layout/PageLayout/PageLayoutBody.tsx +3 -5
- package/src/components/Layout/PageLayout/PageLayoutHeader.tsx +3 -5
- package/src/components/Layout/PageLayout/PageQuickAccess.tsx +44 -25
- package/src/components/Layout/PageLayout/translatedLabels.ts +1 -0
- package/src/components/Menu/Button/MenuButton.styles.ts +27 -0
- package/src/components/Menu/Button/MenuButton.tsx +5 -6
- package/src/components/Menu/Menu.styles.ts +68 -0
- package/src/components/Menu/MenuDivider.tsx +5 -1
- package/src/components/Menu/MenuItem.tsx +5 -1
- package/src/components/Menu/MenuItems.tsx +4 -5
- package/src/components/Modal/Modal.styles.ts +2 -1
- package/src/components/Modal/ModalHeader.tsx +1 -5
- package/src/utils/useInfiniteScrollListing.ts +11 -7
- package/src/utils/useViewportIntersection.ts +3 -4
- package/src/Graph/mockedData/dataWithMissingPoint.json +0 -74
- package/src/Graph/mockedData/pingServiceWithStackedKeys.json +0 -205
|
@@ -5,10 +5,7 @@ import { LineChartData } from '../common/models';
|
|
|
5
5
|
import dataPingService from '../mockedData/pingService.json';
|
|
6
6
|
import dataPingServiceMixedStacked from '../mockedData/pingServiceMixedStacked.json';
|
|
7
7
|
import dataPingServiceStacked from '../mockedData/pingServiceStacked.json';
|
|
8
|
-
import dataPingServiceStackeKey from '../mockedData/pingServiceWithStackedKeys.json';
|
|
9
8
|
|
|
10
|
-
import { ClickAwayListener } from '@mui/material';
|
|
11
|
-
import { useState } from 'react';
|
|
12
9
|
import BarChart from './BarChart';
|
|
13
10
|
|
|
14
11
|
const meta: Meta<typeof BarChart> = {
|
|
@@ -262,51 +259,4 @@ export const mixedStackedMinMax: Story = {
|
|
|
262
259
|
max: 20
|
|
263
260
|
},
|
|
264
261
|
render: Template
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
const LegendSecondaryClick = (args) => {
|
|
268
|
-
const [position, setPosition] = useState<Array<[number, number]> | null>(
|
|
269
|
-
null
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
return (
|
|
273
|
-
<>
|
|
274
|
-
<Template
|
|
275
|
-
{...args}
|
|
276
|
-
legend={{
|
|
277
|
-
secondaryClick: ({ position }) => setPosition(position)
|
|
278
|
-
}}
|
|
279
|
-
/>
|
|
280
|
-
{position && (
|
|
281
|
-
<ClickAwayListener onClickAway={() => setPosition(null)}>
|
|
282
|
-
<div
|
|
283
|
-
className="absolute py-1 px-2 rounded-sm bg-background-widget shadow-md"
|
|
284
|
-
style={{ left: position?.[0], top: position?.[1] }}
|
|
285
|
-
open={Boolean(position)}
|
|
286
|
-
onClose={() => setPosition(null)}
|
|
287
|
-
>
|
|
288
|
-
menu
|
|
289
|
-
</div>
|
|
290
|
-
</ClickAwayListener>
|
|
291
|
-
)}
|
|
292
|
-
</>
|
|
293
|
-
);
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
export const withLegendSecondaryClick: Story = {
|
|
297
|
-
args: defaultArgs,
|
|
298
|
-
render: (args) => (
|
|
299
|
-
<LegendSecondaryClick
|
|
300
|
-
{...args}
|
|
301
|
-
data={dataPingService as unknown as LineChartData}
|
|
302
|
-
/>
|
|
303
|
-
)
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
export const stackKey: Story = {
|
|
307
|
-
args: {
|
|
308
|
-
...defaultArgs,
|
|
309
|
-
data: dataPingServiceStackeKey
|
|
310
|
-
},
|
|
311
|
-
render: Template
|
|
312
|
-
};
|
|
262
|
+
};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { scaleBand, scaleOrdinal } from '@visx/scale';
|
|
2
2
|
import { BarGroupHorizontal, BarGroup as VisxBarGroup } from '@visx/shape';
|
|
3
3
|
import { ScaleLinear } from 'd3-scale';
|
|
4
|
-
import { difference, equals, keys, omit, pick } from 'ramda';
|
|
4
|
+
import { difference, equals, keys, omit, pick, pluck, uniq } from 'ramda';
|
|
5
5
|
import { memo, useMemo } from 'react';
|
|
6
6
|
|
|
7
7
|
import { useDeepMemo } from '../../utils';
|
|
8
8
|
import {
|
|
9
9
|
getSortedStackedLines,
|
|
10
|
-
getStackedLinesTimeSeriesPerStackAndUnit,
|
|
11
10
|
getTime,
|
|
12
11
|
getTimeSeriesForLines,
|
|
13
12
|
getUnits
|
|
@@ -55,18 +54,41 @@ const BarGroup = ({
|
|
|
55
54
|
);
|
|
56
55
|
|
|
57
56
|
const stackedLines = getSortedStackedLines(lines);
|
|
57
|
+
const stackedUnits = uniq(pluck('unit', stackedLines));
|
|
58
58
|
const notStackedLines = difference(lines, stackedLines);
|
|
59
|
+
|
|
60
|
+
const stackedKeys = stackedUnits.reduce(
|
|
61
|
+
(acc, unit) => ({
|
|
62
|
+
...acc,
|
|
63
|
+
[`stacked-${unit}`]: null
|
|
64
|
+
}),
|
|
65
|
+
{}
|
|
66
|
+
);
|
|
67
|
+
const stackedLinesTimeSeriesPerUnit = stackedUnits.reduce(
|
|
68
|
+
(acc, stackedUnit) => {
|
|
69
|
+
const relatedLines = stackedLines.filter(({ unit }) =>
|
|
70
|
+
equals(unit, stackedUnit)
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
...acc,
|
|
75
|
+
[stackedUnit]: {
|
|
76
|
+
lines: relatedLines,
|
|
77
|
+
timeSeries: getTimeSeriesForLines({
|
|
78
|
+
lines: relatedLines,
|
|
79
|
+
timeSeries
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
{}
|
|
85
|
+
);
|
|
86
|
+
|
|
59
87
|
const notStackedTimeSeries = getTimeSeriesForLines({
|
|
60
88
|
lines: notStackedLines,
|
|
61
89
|
timeSeries
|
|
62
90
|
});
|
|
63
91
|
|
|
64
|
-
const { stackedLinesTimeSeriesPerStackKeyAndUnit, stackedKeys } = useMemo(
|
|
65
|
-
() =>
|
|
66
|
-
getStackedLinesTimeSeriesPerStackAndUnit({ stackedLines, timeSeries }),
|
|
67
|
-
[stackedLines, timeSeries]
|
|
68
|
-
);
|
|
69
|
-
|
|
70
92
|
const normalizedTimeSeries = notStackedTimeSeries.map((timeSerie) => ({
|
|
71
93
|
...timeSerie,
|
|
72
94
|
...stackedKeys
|
|
@@ -76,16 +98,6 @@ const BarGroup = ({
|
|
|
76
98
|
deps: [normalizedTimeSeries],
|
|
77
99
|
variable: keys(omit(['timeTick'], normalizedTimeSeries[0]))
|
|
78
100
|
});
|
|
79
|
-
const sortedLineKeys = lineKeys.sort((lineKeyA: string, lineKeyB: string) => {
|
|
80
|
-
if (lineKeyA.startsWith('stacked-') && !lineKeyB.startsWith('stacked-')) {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const lineKeysA = lineKeyA.split('-');
|
|
85
|
-
const lineKeysB = lineKeyB.split('-');
|
|
86
|
-
|
|
87
|
-
return lineKeysA[2] === '' && lineKeysB[2] !== '';
|
|
88
|
-
});
|
|
89
101
|
const colors = useDeepMemo({
|
|
90
102
|
deps: [lineKeys, lines],
|
|
91
103
|
variable: lineKeys.map((key) => {
|
|
@@ -142,7 +154,7 @@ const BarGroup = ({
|
|
|
142
154
|
color={colorScale}
|
|
143
155
|
data={normalizedTimeSeries}
|
|
144
156
|
height={size}
|
|
145
|
-
keys={
|
|
157
|
+
keys={lineKeys}
|
|
146
158
|
{...barComponentBaseProps}
|
|
147
159
|
>
|
|
148
160
|
{(barGroups) =>
|
|
@@ -152,9 +164,7 @@ const BarGroup = ({
|
|
|
152
164
|
key={`bar-group-${barGroup.index}-${barGroup.x0}`}
|
|
153
165
|
barGroup={barGroup}
|
|
154
166
|
barStyle={barStyle}
|
|
155
|
-
|
|
156
|
-
stackedLinesTimeSeriesPerStackKeyAndUnit
|
|
157
|
-
}
|
|
167
|
+
stackedLinesTimeSeriesPerUnit={stackedLinesTimeSeriesPerUnit}
|
|
158
168
|
notStackedTimeSeries={notStackedTimeSeries}
|
|
159
169
|
notStackedLines={notStackedLines}
|
|
160
170
|
isTooltipHidden={isTooltipHidden}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { memo } from 'react';
|
|
1
|
+
import { memo, ReactElement } from 'react';
|
|
2
2
|
|
|
3
3
|
import { ScaleType, scaleBand } from '@visx/scale';
|
|
4
4
|
import { BarRounded } from '@visx/shape';
|
|
@@ -22,6 +22,7 @@ interface Props extends Omit<UseBarStackProps, 'xScale'> {
|
|
|
22
22
|
barWidth: number;
|
|
23
23
|
isTooltipHidden: boolean;
|
|
24
24
|
neutralValue: number;
|
|
25
|
+
isStacked?: boolean;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
const getPadding = ({ padding, size, isNegativeValue }): number => {
|
|
@@ -83,8 +84,9 @@ const BarStack = ({
|
|
|
83
84
|
barIndex,
|
|
84
85
|
isTooltipHidden,
|
|
85
86
|
barStyle = { opacity: 1, radius: 0.2 },
|
|
86
|
-
neutralValue
|
|
87
|
-
|
|
87
|
+
neutralValue,
|
|
88
|
+
isStacked
|
|
89
|
+
}: Props): ReactElement => {
|
|
88
90
|
const {
|
|
89
91
|
BarStackComponent,
|
|
90
92
|
commonBarStackProps,
|
|
@@ -118,6 +120,15 @@ const BarStack = ({
|
|
|
118
120
|
metricId: Number(bar.key)
|
|
119
121
|
}) as BarStyle;
|
|
120
122
|
|
|
123
|
+
const barY =
|
|
124
|
+
isNegativeValue && isStacked && !shouldApplyRadiusOnBottom
|
|
125
|
+
? getPadding({
|
|
126
|
+
isNegativeValue,
|
|
127
|
+
padding: bar.y,
|
|
128
|
+
size: bar.height
|
|
129
|
+
})
|
|
130
|
+
: bar.y;
|
|
131
|
+
|
|
121
132
|
return (
|
|
122
133
|
<BarRounded
|
|
123
134
|
{...barRoundedProps}
|
|
@@ -128,10 +139,10 @@ const BarStack = ({
|
|
|
128
139
|
barWidth,
|
|
129
140
|
y: isHorizontal
|
|
130
141
|
? getPadding({
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
isNegativeValue,
|
|
143
|
+
padding: bar.y,
|
|
144
|
+
size: bar.height
|
|
145
|
+
})
|
|
135
146
|
: barPadding,
|
|
136
147
|
isFirstBar: shouldApplyRadiusOnBottom,
|
|
137
148
|
isHorizontal,
|
|
@@ -146,19 +157,19 @@ const BarStack = ({
|
|
|
146
157
|
isHorizontal
|
|
147
158
|
? barPadding
|
|
148
159
|
: getPadding({
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
160
|
+
isNegativeValue,
|
|
161
|
+
padding: bar.x,
|
|
162
|
+
size: bar.width
|
|
163
|
+
})
|
|
153
164
|
}
|
|
154
|
-
y={isHorizontal ?
|
|
165
|
+
y={isHorizontal ? barY : barPadding}
|
|
155
166
|
onMouseEnter={
|
|
156
167
|
isTooltipHidden
|
|
157
168
|
? undefined
|
|
158
169
|
: hoverBar({
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
170
|
+
barIndex,
|
|
171
|
+
highlightedMetric: Number(bar.key)
|
|
172
|
+
})
|
|
162
173
|
}
|
|
163
174
|
onMouseLeave={isTooltipHidden ? undefined : exitBar}
|
|
164
175
|
/>
|
|
@@ -12,7 +12,7 @@ interface Props {
|
|
|
12
12
|
isTooltipHidden: boolean;
|
|
13
13
|
barStyle: BarStyle;
|
|
14
14
|
yScalesPerUnit: Record<string, ScaleLinear<number, number>>;
|
|
15
|
-
|
|
15
|
+
stackedLinesTimeSeriesPerUnit: Record<
|
|
16
16
|
string,
|
|
17
17
|
{ lines: Array<Line>; timeSeries: Array<TimeValue> }
|
|
18
18
|
>;
|
|
@@ -25,7 +25,7 @@ interface Props {
|
|
|
25
25
|
|
|
26
26
|
const MemoizedGroup = ({
|
|
27
27
|
barGroup,
|
|
28
|
-
|
|
28
|
+
stackedLinesTimeSeriesPerUnit,
|
|
29
29
|
notStackedLines,
|
|
30
30
|
notStackedTimeSeries,
|
|
31
31
|
isHorizontal,
|
|
@@ -38,7 +38,9 @@ const MemoizedGroup = ({
|
|
|
38
38
|
const hasEmptyValues = barGroup.bars.every(({ key, value }) => {
|
|
39
39
|
if (key.startsWith('stacked-')) {
|
|
40
40
|
const timeValueBar =
|
|
41
|
-
|
|
41
|
+
stackedLinesTimeSeriesPerUnit[key.replace('stacked-', '')].timeSeries[
|
|
42
|
+
barIndex
|
|
43
|
+
];
|
|
42
44
|
|
|
43
45
|
return Object.values(omit(['timeTick'], timeValueBar)).every(
|
|
44
46
|
(value) => !value
|
|
@@ -57,19 +59,21 @@ const MemoizedGroup = ({
|
|
|
57
59
|
{barGroup.bars.map((bar) => {
|
|
58
60
|
const isStackedBar = bar.key.startsWith('stacked-');
|
|
59
61
|
const linesBar = isStackedBar
|
|
60
|
-
?
|
|
62
|
+
? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')].lines
|
|
61
63
|
: (notStackedLines.find(({ metric_id }) =>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
equals(metric_id, Number(bar.key))
|
|
65
|
+
) as Line);
|
|
64
66
|
const timeSeriesBar = isStackedBar
|
|
65
|
-
?
|
|
67
|
+
? stackedLinesTimeSeriesPerUnit[bar.key.replace('stacked-', '')]
|
|
68
|
+
.timeSeries
|
|
66
69
|
: notStackedTimeSeries.map((timeSerie) => ({
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
+
timeTick: timeSerie.timeTick,
|
|
71
|
+
[bar.key]: timeSerie[Number(bar.key)]
|
|
72
|
+
}));
|
|
70
73
|
|
|
71
74
|
return isStackedBar ? (
|
|
72
75
|
<BarStack
|
|
76
|
+
isStacked
|
|
73
77
|
key={`bar-${barGroup.index}-${bar.width}-${bar.y}-${bar.height}-${bar.x}`}
|
|
74
78
|
barIndex={barGroup.index}
|
|
75
79
|
barPadding={isHorizontal ? bar.x : bar.y}
|
|
@@ -79,7 +83,7 @@ const MemoizedGroup = ({
|
|
|
79
83
|
isTooltipHidden={isTooltipHidden}
|
|
80
84
|
lines={linesBar as Array<Line>}
|
|
81
85
|
timeSeries={timeSeriesBar}
|
|
82
|
-
yScale={yScalesPerUnit[bar.key.
|
|
86
|
+
yScale={yScalesPerUnit[bar.key.replace('stacked-', '')] ?? undefined}
|
|
83
87
|
neutralValue={neutralValue}
|
|
84
88
|
/>
|
|
85
89
|
) : (
|
|
@@ -93,7 +97,7 @@ const MemoizedGroup = ({
|
|
|
93
97
|
isTooltipHidden={isTooltipHidden}
|
|
94
98
|
lines={[linesBar as Line]}
|
|
95
99
|
timeSeries={timeSeriesBar}
|
|
96
|
-
yScale={yScalesPerUnit[(linesBar as Line).unit]}
|
|
100
|
+
yScale={yScalesPerUnit[(linesBar as Line).unit ?? undefined]}
|
|
97
101
|
neutralValue={neutralValue}
|
|
98
102
|
/>
|
|
99
103
|
);
|
|
@@ -107,8 +111,8 @@ export default memo(
|
|
|
107
111
|
(prevProps, nextProps) =>
|
|
108
112
|
equals(prevProps.barGroup, nextProps.barGroup) &&
|
|
109
113
|
equals(
|
|
110
|
-
prevProps.
|
|
111
|
-
nextProps.
|
|
114
|
+
prevProps.stackedLinesTimeSeriesPerUnit,
|
|
115
|
+
nextProps.stackedLinesTimeSeriesPerUnit
|
|
112
116
|
) &&
|
|
113
117
|
equals(prevProps.notStackedLines, nextProps.notStackedLines) &&
|
|
114
118
|
equals(prevProps.notStackedTimeSeries, nextProps.notStackedTimeSeries) &&
|
|
@@ -68,7 +68,7 @@ const ResponsiveBarChart = ({
|
|
|
68
68
|
|
|
69
69
|
const { classes, cx } = useTooltipStyles();
|
|
70
70
|
|
|
71
|
-
const [linesGraph, setLinesGraph] = useState<Array<Line>>(lines);
|
|
71
|
+
const [linesGraph, setLinesGraph] = useState<Array<Line>>(lines || []);
|
|
72
72
|
const graphSvgRef = useRef<SVGSVGElement | null>(null);
|
|
73
73
|
|
|
74
74
|
const [tooltipData, setTooltipData] = useAtom(tooltipDataAtom);
|
|
@@ -81,7 +81,7 @@ const ResponsiveBarChart = ({
|
|
|
81
81
|
);
|
|
82
82
|
|
|
83
83
|
const [firstUnit, secondUnit] = getUnits(displayedLines);
|
|
84
|
-
const allUnits = getUnits(lines);
|
|
84
|
+
const allUnits = getUnits(lines || []);
|
|
85
85
|
|
|
86
86
|
const { maxLeftAxisCharacters, maxRightAxisCharacters } =
|
|
87
87
|
useComputeYAxisMaxCharacters({
|
|
@@ -156,12 +156,12 @@ const ResponsiveBarChart = ({
|
|
|
156
156
|
]
|
|
157
157
|
);
|
|
158
158
|
|
|
159
|
-
const leftScale = yScalesPerUnit[firstUnit];
|
|
160
|
-
const rightScale = yScalesPerUnit[secondUnit];
|
|
159
|
+
const leftScale = yScalesPerUnit[firstUnit ?? allUnits?.[0]];
|
|
160
|
+
const rightScale = yScalesPerUnit[secondUnit ?? allUnits?.[1]];
|
|
161
161
|
|
|
162
162
|
useEffect(
|
|
163
163
|
() => {
|
|
164
|
-
setLinesGraph(lines);
|
|
164
|
+
setLinesGraph(lines || []);
|
|
165
165
|
},
|
|
166
166
|
useDeepCompare([lines])
|
|
167
167
|
);
|
|
@@ -196,8 +196,7 @@ const ResponsiveBarChart = ({
|
|
|
196
196
|
displayLegend,
|
|
197
197
|
mode: legend?.mode,
|
|
198
198
|
placement: legend?.placement,
|
|
199
|
-
renderExtraComponent: legend?.renderExtraComponent
|
|
200
|
-
secondaryClick: legend?.secondaryClick
|
|
199
|
+
renderExtraComponent: legend?.renderExtraComponent
|
|
201
200
|
}}
|
|
202
201
|
legendRef={legendRef}
|
|
203
202
|
limitLegend={limitLegend}
|
|
@@ -36,7 +36,7 @@ const BarChartTooltip = ({
|
|
|
36
36
|
sortOrder
|
|
37
37
|
}: Props): JSX.Element | null => {
|
|
38
38
|
const { classes } = useBarChartTooltipStyles();
|
|
39
|
-
const {
|
|
39
|
+
const { toDate, toTime } = useLocaleDateTimeFormat();
|
|
40
40
|
const tooltipData = useAtomValue(tooltipDataAtom);
|
|
41
41
|
|
|
42
42
|
if (isNil(tooltipData)) {
|
|
@@ -48,7 +48,7 @@ const BarChartTooltip = ({
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
const date = timeSeries[tooltipData.index].timeTick;
|
|
51
|
-
const formattedDateTime =
|
|
51
|
+
const formattedDateTime = `${toDate(date)} / ${toTime(date)}`;
|
|
52
52
|
|
|
53
53
|
const isSingleMode = equals(mode, 'single');
|
|
54
54
|
|
|
@@ -27,6 +27,7 @@ import { StackValue } from '../../../InteractiveComponents/AnchorPoint/models';
|
|
|
27
27
|
import { getCurveFactory, getFillColor } from '../../../common';
|
|
28
28
|
import { LineStyle } from '../../../models';
|
|
29
29
|
import Point from '../Point';
|
|
30
|
+
import { ReactElement } from 'react';
|
|
30
31
|
|
|
31
32
|
interface Props {
|
|
32
33
|
areaTransparency?: number;
|
|
@@ -56,7 +57,7 @@ const StackLines = ({
|
|
|
56
57
|
lineStyle,
|
|
57
58
|
hasSecondUnit,
|
|
58
59
|
maxLeftAxisCharacters
|
|
59
|
-
}: Props):
|
|
60
|
+
}: Props): ReactElement => {
|
|
60
61
|
const curveType = getCurveFactory(
|
|
61
62
|
(equals(type(lineStyle), 'Array')
|
|
62
63
|
? lineStyle?.[0].curve
|
|
@@ -134,9 +135,9 @@ const StackLines = ({
|
|
|
134
135
|
equals(style?.showArea, false)
|
|
135
136
|
? 'transparent'
|
|
136
137
|
: getFillColor({
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
areaColor: areaColor || lineColor,
|
|
139
|
+
transparency: formattedTransparency
|
|
140
|
+
})
|
|
140
141
|
}
|
|
141
142
|
opacity={highlight === false ? 0.3 : 1}
|
|
142
143
|
stroke={lineColor}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { equals, pluck, uniq } from 'ramda';
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
getInvertedStackedLines,
|
|
3
5
|
getNotInvertedStackedLines,
|
|
4
|
-
|
|
6
|
+
getTimeSeriesForLines
|
|
5
7
|
} from '../../../../common/timeSeries';
|
|
6
8
|
import { LinesData } from '../models';
|
|
7
9
|
|
|
@@ -12,28 +14,53 @@ interface StackedLinesState {
|
|
|
12
14
|
|
|
13
15
|
const useStackedLines = ({ lines, timeSeries }): StackedLinesState => {
|
|
14
16
|
const regularStackedLines = getNotInvertedStackedLines(lines);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
const regularStackedUnits = uniq(pluck('unit', regularStackedLines));
|
|
18
|
+
const regularStackedLinesTimeSeriesPerUnit = regularStackedUnits.reduce(
|
|
19
|
+
(acc, stackedUnit) => {
|
|
20
|
+
const relatedLines = regularStackedLines.filter(({ unit }) =>
|
|
21
|
+
equals(unit, stackedUnit)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
...acc,
|
|
26
|
+
[stackedUnit]: {
|
|
27
|
+
lines: relatedLines,
|
|
28
|
+
timeSeries: getTimeSeriesForLines({
|
|
29
|
+
lines: relatedLines,
|
|
30
|
+
timeSeries
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
{}
|
|
36
|
+
);
|
|
22
37
|
|
|
23
38
|
const invertedStackedLines = getInvertedStackedLines(lines);
|
|
39
|
+
const invertedStackedUnits = uniq(pluck('unit', invertedStackedLines));
|
|
40
|
+
const invertedStackedLinesTimeSeriesPerUnit = invertedStackedUnits.reduce(
|
|
41
|
+
(acc, stackedUnit) => {
|
|
42
|
+
const relatedLines = invertedStackedLines.filter(({ unit }) =>
|
|
43
|
+
equals(unit, stackedUnit)
|
|
44
|
+
);
|
|
24
45
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
46
|
+
return {
|
|
47
|
+
...acc,
|
|
48
|
+
[stackedUnit]: {
|
|
49
|
+
lines: relatedLines,
|
|
50
|
+
timeSeries: getTimeSeriesForLines({
|
|
51
|
+
invert: true,
|
|
52
|
+
lines: relatedLines,
|
|
53
|
+
timeSeries
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
{}
|
|
59
|
+
);
|
|
33
60
|
|
|
34
61
|
return {
|
|
35
|
-
invertedStackedLinesData:
|
|
36
|
-
stackedLinesData:
|
|
62
|
+
invertedStackedLinesData: invertedStackedLinesTimeSeriesPerUnit,
|
|
63
|
+
stackedLinesData: regularStackedLinesTimeSeriesPerUnit
|
|
37
64
|
};
|
|
38
65
|
};
|
|
39
66
|
|