@gravity-ui/charts 1.21.0 → 1.23.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/cjs/components/ChartInner/index.js +7 -3
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +16 -2
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +2 -3
- package/dist/cjs/components/ChartInner/utils.d.ts +10 -1
- package/dist/cjs/components/ChartInner/utils.js +60 -0
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.d.ts +2 -2
- package/dist/cjs/constants/index.d.ts +1 -0
- package/dist/cjs/constants/index.js +1 -0
- package/dist/cjs/constants/zoom.d.ts +6 -0
- package/dist/cjs/constants/zoom.js +5 -0
- package/dist/cjs/hooks/useBrush/index.js +7 -6
- package/dist/cjs/hooks/useBrush/types.d.ts +3 -2
- package/dist/cjs/hooks/useChartOptions/chart.js +1 -77
- package/dist/cjs/hooks/useChartOptions/zoom.d.ts +11 -0
- package/dist/cjs/hooks/useChartOptions/zoom.js +88 -0
- package/dist/cjs/hooks/useSeries/prepare-area.js +15 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-x.js +13 -1
- package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -2
- package/dist/cjs/hooks/useSeries/prepare-bar-y.js +13 -1
- package/dist/cjs/hooks/useSeries/prepare-heatmap.js +13 -1
- package/dist/cjs/hooks/useSeries/prepare-legend.js +1 -1
- package/dist/cjs/hooks/useSeries/prepare-line.js +15 -1
- package/dist/cjs/hooks/useSeries/prepare-pie.js +15 -2
- package/dist/cjs/hooks/useSeries/prepare-scatter.js +16 -1
- package/dist/cjs/hooks/useSeries/prepare-waterfall.js +18 -2
- package/dist/cjs/hooks/useShapes/area/index.js +2 -0
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +37 -22
- package/dist/cjs/hooks/useShapes/area/types.d.ts +5 -2
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +8 -2
- package/dist/cjs/hooks/useShapes/bar-y/index.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/index.js +19 -22
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +24 -5
- package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-y/utils.d.ts +3 -0
- package/dist/cjs/hooks/useShapes/bar-y/utils.js +44 -0
- package/dist/cjs/hooks/useShapes/heatmap/prepare-data.js +7 -3
- package/dist/cjs/hooks/useShapes/line/index.js +1 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +41 -16
- package/dist/cjs/hooks/useShapes/line/types.d.ts +7 -3
- package/dist/cjs/hooks/useShapes/pie/prepare-data.js +8 -4
- package/dist/cjs/hooks/useShapes/scatter/prepare-data.js +1 -1
- package/dist/cjs/hooks/useShapes/utils.d.ts +14 -6
- package/dist/cjs/hooks/useShapes/utils.js +66 -18
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +18 -8
- package/dist/cjs/hooks/useTooltip/index.js +8 -4
- package/dist/cjs/hooks/useZoom/index.js +2 -0
- package/dist/cjs/hooks/useZoom/utils.d.ts +3 -2
- package/dist/cjs/hooks/useZoom/utils.js +4 -3
- package/dist/cjs/hooks/utils/bar-y.d.ts +8 -1
- package/dist/cjs/hooks/utils/bar-y.js +4 -0
- package/dist/cjs/i18n/keysets/en.json +2 -2
- package/dist/cjs/i18n/keysets/ru.json +2 -2
- package/dist/cjs/types/chart/area.d.ts +11 -1
- package/dist/cjs/types/chart/bar-x.d.ts +10 -1
- package/dist/cjs/types/chart/bar-y.d.ts +10 -1
- package/dist/cjs/types/chart/heatmap.d.ts +10 -1
- package/dist/cjs/types/chart/line.d.ts +11 -1
- package/dist/cjs/types/chart/pie.d.ts +10 -1
- package/dist/cjs/types/chart/scatter.d.ts +11 -2
- package/dist/cjs/types/chart/waterfall.d.ts +10 -1
- package/dist/cjs/types/chart/zoom.d.ts +31 -1
- package/dist/cjs/utils/chart/get-closest-data.js +12 -7
- package/dist/cjs/utils/chart/series/sorting.js +17 -4
- package/dist/cjs/utils/chart/text.js +24 -21
- package/dist/cjs/utils/chart/zoom.js +4 -2
- package/dist/cjs/validation/index.js +3 -3
- package/dist/esm/components/ChartInner/index.js +7 -3
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +16 -2
- package/dist/esm/components/ChartInner/useChartInnerProps.js +2 -3
- package/dist/esm/components/ChartInner/utils.d.ts +10 -1
- package/dist/esm/components/ChartInner/utils.js +60 -0
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.d.ts +2 -2
- package/dist/esm/constants/index.d.ts +1 -0
- package/dist/esm/constants/index.js +1 -0
- package/dist/esm/constants/zoom.d.ts +6 -0
- package/dist/esm/constants/zoom.js +5 -0
- package/dist/esm/hooks/useBrush/index.js +7 -6
- package/dist/esm/hooks/useBrush/types.d.ts +3 -2
- package/dist/esm/hooks/useChartOptions/chart.js +1 -77
- package/dist/esm/hooks/useChartOptions/zoom.d.ts +11 -0
- package/dist/esm/hooks/useChartOptions/zoom.js +88 -0
- package/dist/esm/hooks/useSeries/prepare-area.js +15 -1
- package/dist/esm/hooks/useSeries/prepare-bar-x.js +13 -1
- package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +2 -2
- package/dist/esm/hooks/useSeries/prepare-bar-y.js +13 -1
- package/dist/esm/hooks/useSeries/prepare-heatmap.js +13 -1
- package/dist/esm/hooks/useSeries/prepare-legend.js +1 -1
- package/dist/esm/hooks/useSeries/prepare-line.js +15 -1
- package/dist/esm/hooks/useSeries/prepare-pie.js +15 -2
- package/dist/esm/hooks/useSeries/prepare-scatter.js +16 -1
- package/dist/esm/hooks/useSeries/prepare-waterfall.js +18 -2
- package/dist/esm/hooks/useShapes/area/index.js +2 -0
- package/dist/esm/hooks/useShapes/area/prepare-data.js +37 -22
- package/dist/esm/hooks/useShapes/area/types.d.ts +5 -2
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +8 -2
- package/dist/esm/hooks/useShapes/bar-y/index.d.ts +1 -1
- package/dist/esm/hooks/useShapes/bar-y/index.js +19 -22
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +24 -5
- package/dist/esm/hooks/useShapes/bar-y/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-y/utils.d.ts +3 -0
- package/dist/esm/hooks/useShapes/bar-y/utils.js +44 -0
- package/dist/esm/hooks/useShapes/heatmap/prepare-data.js +7 -3
- package/dist/esm/hooks/useShapes/line/index.js +1 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +41 -16
- package/dist/esm/hooks/useShapes/line/types.d.ts +7 -3
- package/dist/esm/hooks/useShapes/pie/prepare-data.js +8 -4
- package/dist/esm/hooks/useShapes/scatter/prepare-data.js +1 -1
- package/dist/esm/hooks/useShapes/utils.d.ts +14 -6
- package/dist/esm/hooks/useShapes/utils.js +66 -18
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +18 -8
- package/dist/esm/hooks/useTooltip/index.js +8 -4
- package/dist/esm/hooks/useZoom/index.js +2 -0
- package/dist/esm/hooks/useZoom/utils.d.ts +3 -2
- package/dist/esm/hooks/useZoom/utils.js +4 -3
- package/dist/esm/hooks/utils/bar-y.d.ts +8 -1
- package/dist/esm/hooks/utils/bar-y.js +4 -0
- package/dist/esm/i18n/keysets/en.json +2 -2
- package/dist/esm/i18n/keysets/ru.json +2 -2
- package/dist/esm/types/chart/area.d.ts +11 -1
- package/dist/esm/types/chart/bar-x.d.ts +10 -1
- package/dist/esm/types/chart/bar-y.d.ts +10 -1
- package/dist/esm/types/chart/heatmap.d.ts +10 -1
- package/dist/esm/types/chart/line.d.ts +11 -1
- package/dist/esm/types/chart/pie.d.ts +10 -1
- package/dist/esm/types/chart/scatter.d.ts +11 -2
- package/dist/esm/types/chart/waterfall.d.ts +10 -1
- package/dist/esm/types/chart/zoom.d.ts +31 -1
- package/dist/esm/utils/chart/get-closest-data.js +12 -7
- package/dist/esm/utils/chart/series/sorting.js +17 -4
- package/dist/esm/utils/chart/text.js +24 -21
- package/dist/esm/utils/chart/zoom.js +4 -2
- package/dist/esm/validation/index.js +3 -3
- package/package.json +1 -1
|
@@ -14,13 +14,14 @@ import { Tooltip } from '../Tooltip';
|
|
|
14
14
|
import { useChartInnerHandlers } from './useChartInnerHandlers';
|
|
15
15
|
import { useChartInnerProps } from './useChartInnerProps';
|
|
16
16
|
import { useChartInnerState } from './useChartInnerState';
|
|
17
|
-
import { useAsyncState } from './utils';
|
|
17
|
+
import { getResetZoomButtonStyle, useAsyncState } from './utils';
|
|
18
18
|
import './styles.css';
|
|
19
19
|
const b = block('chart');
|
|
20
20
|
export const ChartInner = (props) => {
|
|
21
21
|
var _a, _b, _c, _d;
|
|
22
22
|
const { width, height, data } = props;
|
|
23
23
|
const svgRef = React.useRef(null);
|
|
24
|
+
const resetZoomButtonRef = React.useRef(null);
|
|
24
25
|
const [htmlLayout, setHtmlLayout] = React.useState(null);
|
|
25
26
|
const plotRef = React.useRef(null);
|
|
26
27
|
const plotBeforeRef = React.useRef(null);
|
|
@@ -39,7 +40,7 @@ export const ChartInner = (props) => {
|
|
|
39
40
|
dispatcher,
|
|
40
41
|
tooltip: preparedTooltip,
|
|
41
42
|
});
|
|
42
|
-
const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedSeries, preparedSplit, preparedLegend, prevHeight, prevWidth, shapes, shapesData, title, xAxis, xScale, yAxis, yScale,
|
|
43
|
+
const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedSeries, preparedSplit, preparedLegend, preparedZoom, prevHeight, prevWidth, shapes, shapesData, svgXPos, title, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
43
44
|
dispatcher,
|
|
44
45
|
htmlLayout, plotNode: plotRef.current, svgContainer: svgRef.current, updateZoomState,
|
|
45
46
|
zoomState }));
|
|
@@ -143,7 +144,10 @@ export const ChartInner = (props) => {
|
|
|
143
144
|
React.createElement("div", { className: b('html-layer'), ref: setHtmlLayout, style: {
|
|
144
145
|
'--g-html-layout-transform': `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
145
146
|
} }),
|
|
146
|
-
Object.keys(zoomState).length > 0 && (React.createElement(Button, {
|
|
147
|
+
Object.keys(zoomState).length > 0 && preparedZoom && (React.createElement(Button, { onClick: () => updateZoomState({}), ref: resetZoomButtonRef, style: getResetZoomButtonStyle(Object.assign({ boundsHeight,
|
|
148
|
+
boundsOffsetLeft,
|
|
149
|
+
boundsOffsetTop,
|
|
150
|
+
boundsWidth, node: resetZoomButtonRef.current, titleHeight: title === null || title === void 0 ? void 0 : title.height }, preparedZoom.resetButton)) },
|
|
147
151
|
React.createElement(ButtonIcon, null,
|
|
148
152
|
React.createElement(ArrowRotateLeft, null)))),
|
|
149
153
|
React.createElement(Tooltip, { dispatcher: dispatcher, tooltip: preparedTooltip, svgContainer: svgRef.current, xAxis: xAxis, yAxis: yAxis[0], onOutsideClick: unpinTooltip, tooltipPinned: tooltipPinned })));
|
|
@@ -12,8 +12,6 @@ type Props = ChartInnerProps & {
|
|
|
12
12
|
zoomState: Partial<ZoomState>;
|
|
13
13
|
};
|
|
14
14
|
export declare function useChartInnerProps(props: Props): {
|
|
15
|
-
svgBottomPos: number | undefined;
|
|
16
|
-
svgTopPos: number | undefined;
|
|
17
15
|
svgXPos: number | undefined;
|
|
18
16
|
boundsHeight: number;
|
|
19
17
|
boundsOffsetLeft: number;
|
|
@@ -38,6 +36,22 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
38
36
|
preparedLegend: import("../../hooks").PreparedLegend | null;
|
|
39
37
|
preparedSeries: import("../../hooks").PreparedSeries[];
|
|
40
38
|
preparedSplit: import("../../hooks").PreparedSplit;
|
|
39
|
+
preparedZoom: Required<{
|
|
40
|
+
type?: import("../../constants").ZoomType | undefined;
|
|
41
|
+
brush?: Required<{
|
|
42
|
+
style?: Required<{
|
|
43
|
+
fillOpacity?: number | undefined;
|
|
44
|
+
} | undefined>;
|
|
45
|
+
} | undefined>;
|
|
46
|
+
resetButton?: Required<{
|
|
47
|
+
align?: ("bottom-left" | "bottom-right" | "top-left" | "top-right") | undefined;
|
|
48
|
+
offset?: Required<{
|
|
49
|
+
x?: number | undefined;
|
|
50
|
+
y?: number | undefined;
|
|
51
|
+
} | undefined>;
|
|
52
|
+
relativeTo?: ("chart-box" | "plot-box") | undefined;
|
|
53
|
+
} | undefined>;
|
|
54
|
+
}> | null;
|
|
41
55
|
prevHeight: number | undefined;
|
|
42
56
|
prevWidth: number | undefined;
|
|
43
57
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
@@ -138,10 +138,8 @@ export function useChartInnerProps(props) {
|
|
|
138
138
|
}
|
|
139
139
|
return acc;
|
|
140
140
|
}, 0);
|
|
141
|
-
const {
|
|
141
|
+
const { x } = (_a = svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {};
|
|
142
142
|
return {
|
|
143
|
-
svgBottomPos: bottom,
|
|
144
|
-
svgTopPos: top,
|
|
145
143
|
svgXPos: x,
|
|
146
144
|
boundsHeight,
|
|
147
145
|
boundsOffsetLeft,
|
|
@@ -154,6 +152,7 @@ export function useChartInnerProps(props) {
|
|
|
154
152
|
preparedLegend,
|
|
155
153
|
preparedSeries,
|
|
156
154
|
preparedSplit,
|
|
155
|
+
preparedZoom: chart.zoom,
|
|
157
156
|
prevHeight,
|
|
158
157
|
prevWidth,
|
|
159
158
|
shapes,
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import type { PreparedSeries } from '../../hooks';
|
|
2
|
-
import type { PreparedAxis } from '../../hooks/useChartOptions/types';
|
|
3
|
+
import type { PreparedAxis, PreparedZoom } from '../../hooks/useChartOptions/types';
|
|
3
4
|
export declare function hasAtLeastOneSeriesDataPerPlot(seriesData: PreparedSeries[], yAxes?: PreparedAxis[]): boolean;
|
|
4
5
|
export declare function useAsyncState<T>(value: T, setState: () => Promise<T>): T;
|
|
6
|
+
export declare function getResetZoomButtonStyle(args: {
|
|
7
|
+
boundsHeight: number;
|
|
8
|
+
boundsOffsetLeft: number;
|
|
9
|
+
boundsOffsetTop: number;
|
|
10
|
+
boundsWidth: number;
|
|
11
|
+
node: HTMLElement | null;
|
|
12
|
+
titleHeight?: number;
|
|
13
|
+
} & PreparedZoom['resetButton']): React.CSSProperties;
|
|
@@ -47,3 +47,63 @@ export function useAsyncState(value, setState) {
|
|
|
47
47
|
}, [setState]);
|
|
48
48
|
return stateValue;
|
|
49
49
|
}
|
|
50
|
+
export function getResetZoomButtonStyle(args) {
|
|
51
|
+
const { align, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, node, offset, relativeTo, titleHeight, } = args;
|
|
52
|
+
const style = {
|
|
53
|
+
position: 'absolute',
|
|
54
|
+
transform: `translate(${offset.x}px, ${offset.y}px)`,
|
|
55
|
+
};
|
|
56
|
+
switch (relativeTo) {
|
|
57
|
+
case 'chart-box': {
|
|
58
|
+
switch (align) {
|
|
59
|
+
case 'bottom-left': {
|
|
60
|
+
style.bottom = 0;
|
|
61
|
+
style.left = 0;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case 'bottom-right': {
|
|
65
|
+
style.bottom = 0;
|
|
66
|
+
style.right = 0;
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case 'top-left': {
|
|
70
|
+
style.top = 0;
|
|
71
|
+
style.left = 0;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case 'top-right': {
|
|
75
|
+
style.top = 0;
|
|
76
|
+
style.right = 0;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case 'plot-box': {
|
|
83
|
+
switch (align) {
|
|
84
|
+
case 'bottom-left': {
|
|
85
|
+
style.left = boundsOffsetLeft;
|
|
86
|
+
style.top = boundsHeight - ((node === null || node === void 0 ? void 0 : node.clientHeight) || 0) + (titleHeight || 0);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case 'bottom-right': {
|
|
90
|
+
style.left = boundsWidth + boundsOffsetLeft - ((node === null || node === void 0 ? void 0 : node.clientWidth) || 0);
|
|
91
|
+
style.top = boundsHeight - ((node === null || node === void 0 ? void 0 : node.clientHeight) || 0) + (titleHeight || 0);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case 'top-left': {
|
|
95
|
+
style.left = boundsOffsetLeft;
|
|
96
|
+
style.top = boundsOffsetTop;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'top-right': {
|
|
100
|
+
style.left = boundsWidth + boundsOffsetLeft - ((node === null || node === void 0 ? void 0 : node.clientWidth) || 0);
|
|
101
|
+
style.top = boundsOffsetTop;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return style;
|
|
109
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChartSeriesData, ChartTooltip, ChartTooltipTotalsAggregationValue, ChartTooltipTotalsBuiltInAggregation, ChartXAxis, ChartYAxis, TooltipDataChunk, ValueFormat } from '../../../types';
|
|
2
2
|
export type HoveredValue = string | number | null | undefined;
|
|
3
|
-
export declare function getXRowData(data: ChartSeriesData, xAxis?: ChartXAxis | null): string | number | undefined;
|
|
3
|
+
export declare function getXRowData(data: ChartSeriesData, xAxis?: ChartXAxis | null): string | number | null | undefined;
|
|
4
4
|
export declare function getDefaultValueFormat({ axis, closestPointsRange, }: {
|
|
5
5
|
axis?: ChartXAxis | ChartYAxis | null;
|
|
6
6
|
closestPointsRange?: number;
|
|
@@ -14,7 +14,7 @@ export declare const getMeasureValue: ({ data, xAxis, yAxis, headerFormat, }: {
|
|
|
14
14
|
value: string | null;
|
|
15
15
|
formattedValue?: undefined;
|
|
16
16
|
} | {
|
|
17
|
-
value: string | number | undefined;
|
|
17
|
+
value: string | number | null | undefined;
|
|
18
18
|
formattedValue: string;
|
|
19
19
|
} | null;
|
|
20
20
|
export declare function getHoveredValues(args: {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { brush, brushX, brushY, select } from 'd3';
|
|
3
|
+
import { ZOOM_TYPE } from '../../constants';
|
|
3
4
|
import { block } from '../../utils';
|
|
4
5
|
import './styles.css';
|
|
5
6
|
const b = block('brush');
|
|
6
7
|
export function useBrush(props) {
|
|
7
|
-
const { areas, brushOptions, node, type, onBrushStart, onBrush, onBrushEnd } = props;
|
|
8
|
+
const { areas, brushOptions, disabled, node, type, onBrushStart, onBrush, onBrushEnd } = props;
|
|
8
9
|
React.useEffect(() => {
|
|
9
|
-
if (!node || !areas.length) {
|
|
10
|
+
if (!node || !areas.length || disabled) {
|
|
10
11
|
return () => { };
|
|
11
12
|
}
|
|
12
13
|
const brushes = [];
|
|
@@ -15,15 +16,15 @@ export function useBrush(props) {
|
|
|
15
16
|
areas.forEach((area) => {
|
|
16
17
|
let brushFn;
|
|
17
18
|
switch (type) {
|
|
18
|
-
case
|
|
19
|
+
case ZOOM_TYPE.X: {
|
|
19
20
|
brushFn = brushX;
|
|
20
21
|
break;
|
|
21
22
|
}
|
|
22
|
-
case
|
|
23
|
+
case ZOOM_TYPE.Y: {
|
|
23
24
|
brushFn = brushY;
|
|
24
25
|
break;
|
|
25
26
|
}
|
|
26
|
-
case
|
|
27
|
+
case ZOOM_TYPE.XY:
|
|
27
28
|
default: {
|
|
28
29
|
brushFn = brush;
|
|
29
30
|
break;
|
|
@@ -66,5 +67,5 @@ export function useBrush(props) {
|
|
|
66
67
|
selection === null || selection === void 0 ? void 0 : selection.remove();
|
|
67
68
|
});
|
|
68
69
|
};
|
|
69
|
-
}, [areas, brushOptions, node, type, onBrushStart, onBrush, onBrushEnd]);
|
|
70
|
+
}, [areas, brushOptions, disabled, node, type, onBrushStart, onBrush, onBrushEnd]);
|
|
70
71
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BrushBehavior } from 'd3';
|
|
2
|
+
import type { ZoomType } from '../../constants';
|
|
2
3
|
import type { PreparedZoom } from '../useChartOptions/types';
|
|
3
|
-
type BrushType = PreparedZoom['type'];
|
|
4
4
|
type BrushSelection = [number, number] | [[number, number], [number, number]];
|
|
5
5
|
export interface BrushArea {
|
|
6
6
|
/**
|
|
@@ -15,8 +15,9 @@ export interface BrushArea {
|
|
|
15
15
|
export interface UseBrushProps {
|
|
16
16
|
areas: BrushArea[];
|
|
17
17
|
node: SVGGElement | null;
|
|
18
|
-
type?:
|
|
18
|
+
type?: ZoomType;
|
|
19
19
|
brushOptions?: PreparedZoom['brush'];
|
|
20
|
+
disabled?: boolean;
|
|
20
21
|
onBrushStart?: (this: SVGGElement, brushInstance: BrushBehavior<unknown>) => void;
|
|
21
22
|
onBrush?: (this: SVGGElement, brushInstance: BrushBehavior<unknown>, selection: BrushSelection) => void;
|
|
22
23
|
onBrushEnd?: (this: SVGGElement, brushInstance: BrushBehavior<unknown>, selection: BrushSelection | null) => void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
|
-
import
|
|
3
|
-
import { SeriesType } from '../../constants';
|
|
2
|
+
import { getPreparedZoom } from './zoom';
|
|
4
3
|
const getMarginTop = (args) => {
|
|
5
4
|
const { chart, preparedTitle } = args;
|
|
6
5
|
let marginTop = get(chart, 'margin.top', 0);
|
|
@@ -13,81 +12,6 @@ const getMarginRight = (args) => {
|
|
|
13
12
|
const { chart } = args;
|
|
14
13
|
return get(chart, 'margin.right', 0);
|
|
15
14
|
};
|
|
16
|
-
function mapSeriesTypeToZoomType(seriesType) {
|
|
17
|
-
switch (seriesType) {
|
|
18
|
-
case SeriesType.Area: {
|
|
19
|
-
return ['x', 'y', 'xy'];
|
|
20
|
-
}
|
|
21
|
-
case SeriesType.BarX: {
|
|
22
|
-
return ['x'];
|
|
23
|
-
}
|
|
24
|
-
case SeriesType.BarY: {
|
|
25
|
-
return ['y'];
|
|
26
|
-
}
|
|
27
|
-
case SeriesType.Line: {
|
|
28
|
-
return ['x', 'y', 'xy'];
|
|
29
|
-
}
|
|
30
|
-
case SeriesType.Scatter: {
|
|
31
|
-
return ['x', 'y', 'xy'];
|
|
32
|
-
}
|
|
33
|
-
case SeriesType.Waterfall: {
|
|
34
|
-
return ['x', 'y', 'xy'];
|
|
35
|
-
}
|
|
36
|
-
default: {
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
function getDefaultZoomType(seriesType) {
|
|
42
|
-
switch (seriesType) {
|
|
43
|
-
case SeriesType.BarY: {
|
|
44
|
-
return 'y';
|
|
45
|
-
}
|
|
46
|
-
case SeriesType.Scatter: {
|
|
47
|
-
return 'xy';
|
|
48
|
-
}
|
|
49
|
-
default: {
|
|
50
|
-
return 'x';
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function getZoomType(args) {
|
|
55
|
-
const { seriesData, zoomType } = args;
|
|
56
|
-
const possibleDefaultZoomTypes = seriesData.map((s) => {
|
|
57
|
-
return getDefaultZoomType(s.type);
|
|
58
|
-
});
|
|
59
|
-
const availableDefaultZoomTypes = intersection(possibleDefaultZoomTypes);
|
|
60
|
-
if (zoomType) {
|
|
61
|
-
const possibleZoomTypes = seriesData.map((s) => {
|
|
62
|
-
return mapSeriesTypeToZoomType(s.type);
|
|
63
|
-
});
|
|
64
|
-
const availableZoomTypes = intersection(...possibleZoomTypes);
|
|
65
|
-
if (availableZoomTypes.includes(zoomType)) {
|
|
66
|
-
return zoomType;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (availableDefaultZoomTypes.length) {
|
|
70
|
-
return availableDefaultZoomTypes[0];
|
|
71
|
-
}
|
|
72
|
-
return undefined;
|
|
73
|
-
}
|
|
74
|
-
function getPreparedZoom(args) {
|
|
75
|
-
var _a;
|
|
76
|
-
const { zoom, seriesData } = args;
|
|
77
|
-
if (!(zoom === null || zoom === void 0 ? void 0 : zoom.enabled)) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
const type = getZoomType({ seriesData, zoomType: zoom.type });
|
|
81
|
-
if (!type) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
type,
|
|
86
|
-
brush: {
|
|
87
|
-
style: Object.assign({ fillOpacity: 1 }, (_a = zoom === null || zoom === void 0 ? void 0 : zoom.brush) === null || _a === void 0 ? void 0 : _a.style),
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
15
|
export const getPreparedChart = (args) => {
|
|
92
16
|
const { chart, preparedTitle, seriesData } = args;
|
|
93
17
|
const marginTop = getMarginTop({ chart, preparedTitle });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ZoomType } from '../../constants';
|
|
2
|
+
import type { ChartSeries, ChartZoom } from '../../types';
|
|
3
|
+
import type { PreparedZoom } from './types';
|
|
4
|
+
export declare function getZoomType(args: {
|
|
5
|
+
seriesData: ChartSeries[];
|
|
6
|
+
zoomType?: ZoomType;
|
|
7
|
+
}): ZoomType | undefined;
|
|
8
|
+
export declare function getPreparedZoom(args: {
|
|
9
|
+
zoom?: ChartZoom;
|
|
10
|
+
seriesData: ChartSeries[];
|
|
11
|
+
}): PreparedZoom | null;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import intersection from 'lodash/intersection';
|
|
2
|
+
import { SeriesType, ZOOM_TYPE } from '../../constants';
|
|
3
|
+
function mapSeriesTypeToZoomType(seriesType) {
|
|
4
|
+
switch (seriesType) {
|
|
5
|
+
case SeriesType.Area: {
|
|
6
|
+
return [ZOOM_TYPE.X, ZOOM_TYPE.XY, ZOOM_TYPE.Y];
|
|
7
|
+
}
|
|
8
|
+
case SeriesType.BarX: {
|
|
9
|
+
return [ZOOM_TYPE.X];
|
|
10
|
+
}
|
|
11
|
+
case SeriesType.BarY: {
|
|
12
|
+
return [ZOOM_TYPE.Y];
|
|
13
|
+
}
|
|
14
|
+
case SeriesType.Line: {
|
|
15
|
+
return [ZOOM_TYPE.X, ZOOM_TYPE.XY, ZOOM_TYPE.Y];
|
|
16
|
+
}
|
|
17
|
+
case SeriesType.Scatter: {
|
|
18
|
+
return [ZOOM_TYPE.X, ZOOM_TYPE.XY, ZOOM_TYPE.Y];
|
|
19
|
+
}
|
|
20
|
+
case SeriesType.Waterfall: {
|
|
21
|
+
return [ZOOM_TYPE.X, ZOOM_TYPE.XY, ZOOM_TYPE.Y];
|
|
22
|
+
}
|
|
23
|
+
default: {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function getDefaultZoomType(seriesType) {
|
|
29
|
+
switch (seriesType) {
|
|
30
|
+
case SeriesType.BarY: {
|
|
31
|
+
return ZOOM_TYPE.Y;
|
|
32
|
+
}
|
|
33
|
+
case SeriesType.Scatter: {
|
|
34
|
+
return ZOOM_TYPE.XY;
|
|
35
|
+
}
|
|
36
|
+
case SeriesType.Area:
|
|
37
|
+
case SeriesType.BarX:
|
|
38
|
+
case SeriesType.Line:
|
|
39
|
+
case SeriesType.Waterfall: {
|
|
40
|
+
return ZOOM_TYPE.X;
|
|
41
|
+
}
|
|
42
|
+
default: {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function getZoomType(args) {
|
|
48
|
+
const { seriesData, zoomType } = args;
|
|
49
|
+
const possibleZoomTypes = seriesData.map((s) => {
|
|
50
|
+
return mapSeriesTypeToZoomType(s.type);
|
|
51
|
+
});
|
|
52
|
+
const availableZoomTypes = intersection(...possibleZoomTypes);
|
|
53
|
+
if (zoomType && availableZoomTypes.includes(zoomType)) {
|
|
54
|
+
return zoomType;
|
|
55
|
+
}
|
|
56
|
+
const possibleDefaultZoomTypes = seriesData
|
|
57
|
+
.map((s) => {
|
|
58
|
+
return getDefaultZoomType(s.type);
|
|
59
|
+
})
|
|
60
|
+
.filter(Boolean);
|
|
61
|
+
const availableDefaultZoomTypes = intersection(possibleDefaultZoomTypes, ...possibleZoomTypes);
|
|
62
|
+
if (availableDefaultZoomTypes.length) {
|
|
63
|
+
return availableDefaultZoomTypes[0];
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
export function getPreparedZoom(args) {
|
|
68
|
+
var _a, _b, _c, _d;
|
|
69
|
+
const { zoom, seriesData } = args;
|
|
70
|
+
if (!(zoom === null || zoom === void 0 ? void 0 : zoom.enabled)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const type = getZoomType({ seriesData, zoomType: zoom.type });
|
|
74
|
+
if (!type) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
type,
|
|
79
|
+
brush: {
|
|
80
|
+
style: Object.assign({ fillOpacity: 1 }, (_a = zoom === null || zoom === void 0 ? void 0 : zoom.brush) === null || _a === void 0 ? void 0 : _a.style),
|
|
81
|
+
},
|
|
82
|
+
resetButton: {
|
|
83
|
+
align: ((_b = zoom === null || zoom === void 0 ? void 0 : zoom.resetButton) === null || _b === void 0 ? void 0 : _b.align) || 'top-right',
|
|
84
|
+
offset: Object.assign({ x: 0, y: 0 }, (_c = zoom === null || zoom === void 0 ? void 0 : zoom.resetButton) === null || _c === void 0 ? void 0 : _c.offset),
|
|
85
|
+
relativeTo: ((_d = zoom === null || zoom === void 0 ? void 0 : zoom.resetButton) === null || _d === void 0 ? void 0 : _d.relativeTo) || 'chart-box',
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -24,6 +24,20 @@ function prepareMarker(series, seriesOptions) {
|
|
|
24
24
|
},
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
+
function prepareSeriesData(series) {
|
|
28
|
+
var _a;
|
|
29
|
+
const nullMode = (_a = series.nullMode) !== null && _a !== void 0 ? _a : 'skip';
|
|
30
|
+
const data = series.data;
|
|
31
|
+
switch (nullMode) {
|
|
32
|
+
case 'zero':
|
|
33
|
+
return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { y: (_a = p.y) !== null && _a !== void 0 ? _a : 0 })); });
|
|
34
|
+
case 'connect':
|
|
35
|
+
return data.filter((p) => p.y !== null);
|
|
36
|
+
case 'skip':
|
|
37
|
+
default:
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
27
41
|
export function prepareArea(args) {
|
|
28
42
|
const { colorScale, series: seriesList, seriesOptions, legend } = args;
|
|
29
43
|
const defaultAreaWidth = get(seriesOptions, 'area.lineWidth', DEFAULT_LINE_WIDTH);
|
|
@@ -45,7 +59,7 @@ export function prepareArea(args) {
|
|
|
45
59
|
enabled: get(series, 'legend.enabled', legend.enabled),
|
|
46
60
|
symbol: prepareLegendSymbol(series),
|
|
47
61
|
},
|
|
48
|
-
data: series
|
|
62
|
+
data: prepareSeriesData(series),
|
|
49
63
|
stacking: series.stacking,
|
|
50
64
|
stackId: getSeriesStackId(series),
|
|
51
65
|
dataLabels: {
|
|
@@ -3,6 +3,18 @@ import { DEFAULT_DATALABELS_STYLE } from '../../constants';
|
|
|
3
3
|
import { getUniqId } from '../../utils';
|
|
4
4
|
import { DEFAULT_DATALABELS_PADDING } from './constants';
|
|
5
5
|
import { getSeriesStackId, prepareLegendSymbol } from './utils';
|
|
6
|
+
function prepareSeriesData(series) {
|
|
7
|
+
var _a;
|
|
8
|
+
const nullMode = (_a = series.nullMode) !== null && _a !== void 0 ? _a : 'skip';
|
|
9
|
+
const data = series.data;
|
|
10
|
+
switch (nullMode) {
|
|
11
|
+
case 'zero':
|
|
12
|
+
return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { y: (_a = p.y) !== null && _a !== void 0 ? _a : 0 })); });
|
|
13
|
+
case 'skip':
|
|
14
|
+
default:
|
|
15
|
+
return data.filter((p) => p.y !== null);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
6
18
|
export function prepareBarXSeries(args) {
|
|
7
19
|
const { colorScale, series: seriesList, seriesOptions, legend } = args;
|
|
8
20
|
return seriesList.map((series) => {
|
|
@@ -19,7 +31,7 @@ export function prepareBarXSeries(args) {
|
|
|
19
31
|
enabled: get(series, 'legend.enabled', legend.enabled),
|
|
20
32
|
symbol: prepareLegendSymbol(series),
|
|
21
33
|
},
|
|
22
|
-
data: series
|
|
34
|
+
data: prepareSeriesData(series),
|
|
23
35
|
stacking: series.stacking,
|
|
24
36
|
stackId: getSeriesStackId(series),
|
|
25
37
|
dataLabels: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ScaleOrdinal } from 'd3';
|
|
2
|
-
import type { BarYSeries, ChartSeriesOptions } from '../../types';
|
|
2
|
+
import type { BarYSeries, BarYSeriesData, ChartSeriesOptions } from '../../types';
|
|
3
3
|
import type { PreparedLegend } from './types';
|
|
4
4
|
type PrepareBarYSeriesArgs = {
|
|
5
5
|
colorScale: ScaleOrdinal<string, string>;
|
|
@@ -9,7 +9,7 @@ type PrepareBarYSeriesArgs = {
|
|
|
9
9
|
};
|
|
10
10
|
export declare function prepareBarYSeries(args: PrepareBarYSeriesArgs): Promise<({
|
|
11
11
|
type: BarYSeries["type"];
|
|
12
|
-
data:
|
|
12
|
+
data: BarYSeriesData[];
|
|
13
13
|
stackId: string;
|
|
14
14
|
stacking: BarYSeries["stacking"];
|
|
15
15
|
dataLabels: {
|
|
@@ -3,6 +3,18 @@ import { DEFAULT_DATALABELS_STYLE } from '../../constants';
|
|
|
3
3
|
import { getLabelsSize, getUniqId } from '../../utils';
|
|
4
4
|
import { getFormattedValue } from '../../utils/chart/format';
|
|
5
5
|
import { getSeriesStackId, prepareLegendSymbol } from './utils';
|
|
6
|
+
function prepareSeriesData(series) {
|
|
7
|
+
var _a;
|
|
8
|
+
const nullMode = (_a = series.nullMode) !== null && _a !== void 0 ? _a : 'skip';
|
|
9
|
+
const data = series.data;
|
|
10
|
+
switch (nullMode) {
|
|
11
|
+
case 'zero':
|
|
12
|
+
return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { x: (_a = p.x) !== null && _a !== void 0 ? _a : 0 })); });
|
|
13
|
+
case 'skip':
|
|
14
|
+
default:
|
|
15
|
+
return data.filter((p) => p.x !== null);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
6
18
|
async function prepareDataLabels(series) {
|
|
7
19
|
var _a, _b, _c, _d;
|
|
8
20
|
const enabled = get(series, 'dataLabels.enabled', false);
|
|
@@ -46,7 +58,7 @@ export function prepareBarYSeries(args) {
|
|
|
46
58
|
enabled: get(series, 'legend.enabled', legend.enabled),
|
|
47
59
|
symbol: prepareLegendSymbol(series),
|
|
48
60
|
},
|
|
49
|
-
data: series
|
|
61
|
+
data: prepareSeriesData(series),
|
|
50
62
|
stacking: series.stacking,
|
|
51
63
|
stackId: getSeriesStackId(series),
|
|
52
64
|
dataLabels: await prepareDataLabels(series),
|
|
@@ -3,6 +3,18 @@ import { DEFAULT_DATALABELS_STYLE } from '../../constants';
|
|
|
3
3
|
import { getUniqId } from '../../utils';
|
|
4
4
|
import { DEFAULT_DATALABELS_PADDING } from './constants';
|
|
5
5
|
import { prepareLegendSymbol } from './utils';
|
|
6
|
+
function prepareSeriesData(series) {
|
|
7
|
+
var _a;
|
|
8
|
+
const nullMode = (_a = series.nullMode) !== null && _a !== void 0 ? _a : 'skip';
|
|
9
|
+
const data = series.data;
|
|
10
|
+
switch (nullMode) {
|
|
11
|
+
case 'zero':
|
|
12
|
+
return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { value: (_a = p.value) !== null && _a !== void 0 ? _a : 0 })); });
|
|
13
|
+
case 'skip':
|
|
14
|
+
default:
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
6
18
|
export function prepareHeatmapSeries(args) {
|
|
7
19
|
const { colorScale, series: seriesList, seriesOptions, legend } = args;
|
|
8
20
|
return seriesList.map((series) => {
|
|
@@ -19,7 +31,7 @@ export function prepareHeatmapSeries(args) {
|
|
|
19
31
|
enabled: get(series, 'legend.enabled', legend.enabled),
|
|
20
32
|
symbol: prepareLegendSymbol(series),
|
|
21
33
|
},
|
|
22
|
-
data: series
|
|
34
|
+
data: prepareSeriesData(series),
|
|
23
35
|
dataLabels: {
|
|
24
36
|
enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
|
|
25
37
|
style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.style),
|
|
@@ -150,7 +150,7 @@ function getPagination(args) {
|
|
|
150
150
|
if (!pages[currentPageIndex]) {
|
|
151
151
|
pages[currentPageIndex] = { start: i, end: i };
|
|
152
152
|
}
|
|
153
|
-
const legendLineHeight = Math.max(...item.map((
|
|
153
|
+
const legendLineHeight = Math.max(...item.map(({ height }) => height));
|
|
154
154
|
currentHeight += legendLineHeight;
|
|
155
155
|
if (currentHeight > maxLegendHeight - paginatorHeight) {
|
|
156
156
|
pages[currentPageIndex].end = i;
|
|
@@ -41,6 +41,20 @@ function prepareMarker(series, seriesOptions) {
|
|
|
41
41
|
},
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
+
function prepareSeriesData(series) {
|
|
45
|
+
var _a;
|
|
46
|
+
const nullMode = (_a = series.nullMode) !== null && _a !== void 0 ? _a : 'skip';
|
|
47
|
+
const data = series.data;
|
|
48
|
+
switch (nullMode) {
|
|
49
|
+
case 'zero':
|
|
50
|
+
return data.map((p) => { var _a; return (Object.assign(Object.assign({}, p), { y: (_a = p.y) !== null && _a !== void 0 ? _a : 0 })); });
|
|
51
|
+
case 'connect':
|
|
52
|
+
return data.filter((p) => p.y !== null);
|
|
53
|
+
case 'skip':
|
|
54
|
+
default:
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
44
58
|
export function prepareLineSeries(args) {
|
|
45
59
|
const { colorScale, series: seriesList, seriesOptions, legend } = args;
|
|
46
60
|
const defaultLineWidth = get(seriesOptions, 'line.lineWidth', DEFAULT_LINE_WIDTH);
|
|
@@ -62,7 +76,7 @@ export function prepareLineSeries(args) {
|
|
|
62
76
|
enabled: get(series, 'legend.enabled', legend.enabled),
|
|
63
77
|
symbol: prepareLineLegendSymbol(series, seriesOptions),
|
|
64
78
|
},
|
|
65
|
-
data: series
|
|
79
|
+
data: prepareSeriesData(series),
|
|
66
80
|
dataLabels: {
|
|
67
81
|
enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
|
|
68
82
|
style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.style),
|