@gravity-ui/charts 1.10.2 → 1.11.1
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/Axis/AxisY.js +3 -0
- package/dist/cjs/components/ChartInner/index.js +8 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +2 -1
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +1 -5
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +2 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +11 -3
- package/dist/cjs/components/ChartInner/utils.d.ts +1 -1
- package/dist/cjs/components/ChartInner/utils.js +3 -3
- package/dist/cjs/components/Legend/index.js +4 -1
- package/dist/cjs/hooks/hooks-utils/zoom.d.ts +1 -1
- package/dist/cjs/hooks/hooks-utils/zoom.js +2 -2
- package/dist/cjs/hooks/useAxisScales/index.js +49 -18
- package/dist/cjs/hooks/useChartOptions/x-axis.js +3 -14
- package/dist/cjs/hooks/useChartOptions/y-axis.js +5 -24
- package/dist/cjs/hooks/useSeries/prepare-area.js +2 -1
- package/dist/cjs/hooks/useSeries/prepare-legend.js +2 -2
- package/dist/cjs/hooks/useShapes/area/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/area/index.js +13 -9
- package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +4 -3
- package/dist/cjs/hooks/useShapes/area/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-x/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/cjs/hooks/useShapes/bar-y/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/bar-y/index.js +2 -2
- package/dist/cjs/hooks/useShapes/index.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/index.js +146 -137
- package/dist/cjs/hooks/useShapes/line/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/line/index.js +16 -12
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +2 -1
- package/dist/cjs/hooks/useShapes/line/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/marker.js +6 -0
- package/dist/cjs/hooks/useShapes/scatter/prepare-data.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/scatter/prepare-data.js +6 -3
- package/dist/cjs/hooks/useShapes/scatter/types.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/waterfall/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/waterfall/index.js +2 -2
- package/dist/cjs/hooks/useZoom/index.js +1 -1
- package/dist/cjs/hooks/useZoom/utils.d.ts +1 -1
- package/dist/cjs/hooks/useZoom/utils.js +3 -3
- package/dist/cjs/types/chart/axis.d.ts +4 -5
- package/dist/cjs/utils/chart/axis-generators/bottom.js +3 -1
- package/dist/cjs/utils/chart/index.d.ts +2 -0
- package/dist/cjs/utils/chart/index.js +31 -0
- package/dist/esm/components/Axis/AxisY.js +3 -0
- package/dist/esm/components/ChartInner/index.js +8 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +2 -1
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +1 -5
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +2 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +11 -3
- package/dist/esm/components/ChartInner/utils.d.ts +1 -1
- package/dist/esm/components/ChartInner/utils.js +3 -3
- package/dist/esm/components/Legend/index.js +4 -1
- package/dist/esm/hooks/hooks-utils/zoom.d.ts +1 -1
- package/dist/esm/hooks/hooks-utils/zoom.js +2 -2
- package/dist/esm/hooks/useAxisScales/index.js +49 -18
- package/dist/esm/hooks/useChartOptions/x-axis.js +3 -14
- package/dist/esm/hooks/useChartOptions/y-axis.js +5 -24
- package/dist/esm/hooks/useSeries/prepare-area.js +2 -1
- package/dist/esm/hooks/useSeries/prepare-legend.js +2 -2
- package/dist/esm/hooks/useShapes/area/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/area/index.js +13 -9
- package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +1 -0
- package/dist/esm/hooks/useShapes/area/prepare-data.js +4 -3
- package/dist/esm/hooks/useShapes/area/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-x/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/esm/hooks/useShapes/bar-y/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/bar-y/index.js +2 -2
- package/dist/esm/hooks/useShapes/index.d.ts +2 -0
- package/dist/esm/hooks/useShapes/index.js +146 -137
- package/dist/esm/hooks/useShapes/line/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/line/index.js +16 -12
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +1 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +2 -1
- package/dist/esm/hooks/useShapes/line/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/marker.js +6 -0
- package/dist/esm/hooks/useShapes/scatter/prepare-data.d.ts +1 -0
- package/dist/esm/hooks/useShapes/scatter/prepare-data.js +6 -3
- package/dist/esm/hooks/useShapes/scatter/types.d.ts +1 -0
- package/dist/esm/hooks/useShapes/waterfall/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/waterfall/index.js +2 -2
- package/dist/esm/hooks/useZoom/index.js +1 -1
- package/dist/esm/hooks/useZoom/utils.d.ts +1 -1
- package/dist/esm/hooks/useZoom/utils.js +3 -3
- package/dist/esm/types/chart/axis.d.ts +4 -5
- package/dist/esm/utils/chart/axis-generators/bottom.js +3 -1
- package/dist/esm/utils/chart/index.d.ts +2 -0
- package/dist/esm/utils/chart/index.js +31 -0
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@ import { getRectPath } from '../utils';
|
|
|
7
7
|
export { prepareBarYData } from './prepare-data';
|
|
8
8
|
const b = block('bar-y');
|
|
9
9
|
export const BarYSeriesShapes = (args) => {
|
|
10
|
-
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
10
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
11
11
|
const hoveredDataRef = React.useRef(null);
|
|
12
12
|
const ref = React.useRef(null);
|
|
13
13
|
React.useEffect(() => {
|
|
@@ -99,6 +99,6 @@ export const BarYSeriesShapes = (args) => {
|
|
|
99
99
|
};
|
|
100
100
|
}, [dispatcher, preparedData, seriesOptions]);
|
|
101
101
|
return (React.createElement(React.Fragment, null,
|
|
102
|
-
React.createElement("g", { ref: ref, className: b() }),
|
|
102
|
+
React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
103
103
|
React.createElement(HtmlLayer, { preparedData: preparedData, htmlLayout: htmlLayout })));
|
|
104
104
|
};
|
|
@@ -28,6 +28,8 @@ type Args = {
|
|
|
28
28
|
yScale?: ChartScale[];
|
|
29
29
|
split: PreparedSplit;
|
|
30
30
|
htmlLayout: HTMLElement | null;
|
|
31
|
+
clipPathId: string;
|
|
32
|
+
isOutsideBounds: (x: number, y: number) => boolean;
|
|
31
33
|
};
|
|
32
34
|
export declare const useShapes: (args: Args) => {
|
|
33
35
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
@@ -20,160 +20,170 @@ import { prepareTreemapData } from './treemap/prepare-data';
|
|
|
20
20
|
import { WaterfallSeriesShapes, prepareWaterfallData } from './waterfall';
|
|
21
21
|
import './styles.css';
|
|
22
22
|
export const useShapes = (args) => {
|
|
23
|
-
const { boundsWidth, boundsHeight, dispatcher, series, seriesOptions, xAxis, xScale, yAxis, yScale, split, htmlLayout, } = args;
|
|
23
|
+
const { boundsWidth, boundsHeight, dispatcher, series, seriesOptions, xAxis, xScale, yAxis, yScale, split, htmlLayout, clipPathId, isOutsideBounds, } = args;
|
|
24
24
|
const [shapesElemens, setShapesElements] = React.useState([]);
|
|
25
25
|
const [shapesElemensData, setShapesElemensData] = React.useState([]);
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
26
|
+
const countedRef = React.useRef(0);
|
|
27
|
+
React.useEffect(() => {
|
|
28
|
+
countedRef.current++;
|
|
29
|
+
(async () => {
|
|
30
|
+
const currentRun = countedRef.current;
|
|
31
|
+
const visibleSeries = getOnlyVisibleSeries(series);
|
|
32
|
+
const groupedSeries = group(visibleSeries, (item) => item.type);
|
|
33
|
+
const shapesData = [];
|
|
34
|
+
const shapes = [];
|
|
35
|
+
await Promise.all(
|
|
36
|
+
// eslint-disable-next-line complexity
|
|
37
|
+
Array.from(groupedSeries).map(async (item) => {
|
|
38
|
+
const [seriesType, chartSeries] = item;
|
|
39
|
+
switch (seriesType) {
|
|
40
|
+
case 'bar-x': {
|
|
41
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
42
|
+
const preparedData = await prepareBarXData({
|
|
43
|
+
series: chartSeries,
|
|
44
|
+
seriesOptions,
|
|
45
|
+
xAxis,
|
|
46
|
+
xScale,
|
|
47
|
+
yAxis,
|
|
48
|
+
yScale,
|
|
49
|
+
boundsHeight,
|
|
50
|
+
});
|
|
51
|
+
shapes.push(React.createElement(BarXSeriesShapes, { key: "bar-x", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
52
|
+
shapesData.push(...preparedData);
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
49
55
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
case 'bar-y': {
|
|
57
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
58
|
+
const preparedData = await prepareBarYData({
|
|
59
|
+
series: chartSeries,
|
|
60
|
+
seriesOptions,
|
|
61
|
+
xAxis,
|
|
62
|
+
xScale,
|
|
63
|
+
yAxis,
|
|
64
|
+
yScale,
|
|
65
|
+
});
|
|
66
|
+
shapes.push(React.createElement(BarYSeriesShapes, { key: "bar-y", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
67
|
+
shapesData.push(...preparedData);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case 'waterfall': {
|
|
72
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
73
|
+
const preparedData = await prepareWaterfallData({
|
|
74
|
+
series: chartSeries,
|
|
75
|
+
seriesOptions,
|
|
76
|
+
xAxis,
|
|
77
|
+
xScale,
|
|
78
|
+
yAxis,
|
|
79
|
+
yScale,
|
|
80
|
+
});
|
|
81
|
+
shapes.push(React.createElement(WaterfallSeriesShapes, { key: "waterfall", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
82
|
+
shapesData.push(...preparedData);
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'line': {
|
|
87
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
88
|
+
const preparedData = await prepareLineData({
|
|
89
|
+
series: chartSeries,
|
|
90
|
+
xAxis,
|
|
91
|
+
xScale,
|
|
92
|
+
yAxis,
|
|
93
|
+
yScale,
|
|
94
|
+
split,
|
|
95
|
+
isOutsideBounds,
|
|
96
|
+
});
|
|
97
|
+
shapes.push(React.createElement(LineSeriesShapes, { key: "line", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
98
|
+
shapesData.push(...preparedData);
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case 'area': {
|
|
103
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
104
|
+
const preparedData = await prepareAreaData({
|
|
105
|
+
series: chartSeries,
|
|
106
|
+
xAxis,
|
|
107
|
+
xScale,
|
|
108
|
+
yAxis,
|
|
109
|
+
yScale,
|
|
110
|
+
boundsHeight,
|
|
111
|
+
isOutsideBounds,
|
|
112
|
+
});
|
|
113
|
+
shapes.push(React.createElement(AreaSeriesShapes, { key: "area", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
114
|
+
shapesData.push(...preparedData);
|
|
115
|
+
}
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case 'scatter': {
|
|
119
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
120
|
+
const preparedData = prepareScatterData({
|
|
121
|
+
series: chartSeries,
|
|
122
|
+
xAxis,
|
|
123
|
+
xScale,
|
|
124
|
+
yAxis,
|
|
125
|
+
yScale,
|
|
126
|
+
isOutsideBounds,
|
|
127
|
+
});
|
|
128
|
+
shapes.push(React.createElement(ScatterSeriesShape, { key: "scatter", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
129
|
+
shapesData.push(...preparedData);
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case 'pie': {
|
|
134
|
+
const preparedData = await preparePieData({
|
|
55
135
|
series: chartSeries,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
xScale,
|
|
59
|
-
yAxis,
|
|
60
|
-
yScale,
|
|
136
|
+
boundsWidth,
|
|
137
|
+
boundsHeight,
|
|
61
138
|
});
|
|
62
|
-
shapes.push(React.createElement(
|
|
139
|
+
shapes.push(React.createElement(PieSeriesShapes, { key: "pie", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
63
140
|
shapesData.push(...preparedData);
|
|
141
|
+
break;
|
|
64
142
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
xAxis,
|
|
73
|
-
xScale,
|
|
74
|
-
yAxis,
|
|
75
|
-
yScale,
|
|
143
|
+
case 'treemap': {
|
|
144
|
+
const preparedData = await prepareTreemapData({
|
|
145
|
+
// We should have exactly one series with "treemap" type
|
|
146
|
+
// Otherwise data validation should emit an error
|
|
147
|
+
series: chartSeries[0],
|
|
148
|
+
width: boundsWidth,
|
|
149
|
+
height: boundsHeight,
|
|
76
150
|
});
|
|
77
|
-
shapes.push(React.createElement(
|
|
78
|
-
shapesData.push(
|
|
151
|
+
shapes.push(React.createElement(TreemapSeriesShape, { key: "treemap", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
152
|
+
shapesData.push(preparedData);
|
|
153
|
+
break;
|
|
79
154
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
series: chartSeries,
|
|
86
|
-
xAxis,
|
|
87
|
-
xScale,
|
|
88
|
-
yAxis,
|
|
89
|
-
yScale,
|
|
90
|
-
split,
|
|
155
|
+
case 'sankey': {
|
|
156
|
+
const preparedData = prepareSankeyData({
|
|
157
|
+
series: chartSeries[0],
|
|
158
|
+
width: boundsWidth,
|
|
159
|
+
height: boundsHeight,
|
|
91
160
|
});
|
|
92
|
-
shapes.push(React.createElement(
|
|
93
|
-
shapesData.push(
|
|
161
|
+
shapes.push(React.createElement(SankeySeriesShape, { key: "sankey", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
162
|
+
shapesData.push(preparedData);
|
|
163
|
+
break;
|
|
94
164
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
case 'area': {
|
|
98
|
-
if (xAxis && xScale && yScale) {
|
|
99
|
-
const preparedData = await prepareAreaData({
|
|
165
|
+
case 'radar': {
|
|
166
|
+
const preparedData = await prepareRadarData({
|
|
100
167
|
series: chartSeries,
|
|
101
|
-
|
|
102
|
-
xScale,
|
|
103
|
-
yAxis,
|
|
104
|
-
yScale,
|
|
168
|
+
boundsWidth,
|
|
105
169
|
boundsHeight,
|
|
106
170
|
});
|
|
107
|
-
shapes.push(React.createElement(
|
|
171
|
+
shapes.push(React.createElement(RadarSeriesShapes, { key: "radar", dispatcher: dispatcher, series: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
108
172
|
shapesData.push(...preparedData);
|
|
173
|
+
break;
|
|
109
174
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (xAxis && xScale && yScale) {
|
|
114
|
-
const preparedData = prepareScatterData({
|
|
115
|
-
series: chartSeries,
|
|
116
|
-
xAxis,
|
|
117
|
-
xScale,
|
|
118
|
-
yAxis,
|
|
119
|
-
yScale,
|
|
175
|
+
default: {
|
|
176
|
+
throw new ChartError({
|
|
177
|
+
message: `The display method is not defined for a series with type "${seriesType}"`,
|
|
120
178
|
});
|
|
121
|
-
shapes.push(React.createElement(ScatterSeriesShape, { key: "scatter", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
122
|
-
shapesData.push(...preparedData);
|
|
123
179
|
}
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
case 'pie': {
|
|
127
|
-
const preparedData = await preparePieData({
|
|
128
|
-
series: chartSeries,
|
|
129
|
-
boundsWidth,
|
|
130
|
-
boundsHeight,
|
|
131
|
-
});
|
|
132
|
-
shapes.push(React.createElement(PieSeriesShapes, { key: "pie", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
133
|
-
shapesData.push(...preparedData);
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
case 'treemap': {
|
|
137
|
-
const preparedData = await prepareTreemapData({
|
|
138
|
-
// We should have exactly one series with "treemap" type
|
|
139
|
-
// Otherwise data validation should emit an error
|
|
140
|
-
series: chartSeries[0],
|
|
141
|
-
width: boundsWidth,
|
|
142
|
-
height: boundsHeight,
|
|
143
|
-
});
|
|
144
|
-
shapes.push(React.createElement(TreemapSeriesShape, { key: "treemap", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
145
|
-
shapesData.push(preparedData);
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
case 'sankey': {
|
|
149
|
-
const preparedData = prepareSankeyData({
|
|
150
|
-
series: chartSeries[0],
|
|
151
|
-
width: boundsWidth,
|
|
152
|
-
height: boundsHeight,
|
|
153
|
-
});
|
|
154
|
-
shapes.push(React.createElement(SankeySeriesShape, { key: "sankey", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
155
|
-
shapesData.push(preparedData);
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
case 'radar': {
|
|
159
|
-
const preparedData = await prepareRadarData({
|
|
160
|
-
series: chartSeries,
|
|
161
|
-
boundsWidth,
|
|
162
|
-
boundsHeight,
|
|
163
|
-
});
|
|
164
|
-
shapes.push(React.createElement(RadarSeriesShapes, { key: "radar", dispatcher: dispatcher, series: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
165
|
-
shapesData.push(...preparedData);
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
default: {
|
|
169
|
-
throw new ChartError({
|
|
170
|
-
message: `The display method is not defined for a series with type "${seriesType}"`,
|
|
171
|
-
});
|
|
172
180
|
}
|
|
181
|
+
}));
|
|
182
|
+
if (countedRef.current === currentRun) {
|
|
183
|
+
setShapesElements(shapes);
|
|
184
|
+
setShapesElemensData(shapesData);
|
|
173
185
|
}
|
|
174
|
-
}));
|
|
175
|
-
setShapesElements(shapes);
|
|
176
|
-
setShapesElemensData(shapesData);
|
|
186
|
+
})();
|
|
177
187
|
}, [
|
|
178
188
|
boundsHeight,
|
|
179
189
|
boundsWidth,
|
|
@@ -186,9 +196,8 @@ export const useShapes = (args) => {
|
|
|
186
196
|
xScale,
|
|
187
197
|
yAxis,
|
|
188
198
|
yScale,
|
|
199
|
+
clipPathId,
|
|
200
|
+
isOutsideBounds,
|
|
189
201
|
]);
|
|
190
|
-
React.useEffect(() => {
|
|
191
|
-
setShapes();
|
|
192
|
-
}, [setShapes]);
|
|
193
202
|
return { shapes: shapesElemens, shapesData: shapesElemensData };
|
|
194
203
|
};
|
|
@@ -7,22 +7,25 @@ import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarke
|
|
|
7
7
|
import { setActiveState } from '../utils';
|
|
8
8
|
const b = block('line');
|
|
9
9
|
export const LineSeriesShapes = (args) => {
|
|
10
|
-
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
10
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
11
11
|
const hoveredDataRef = React.useRef(null);
|
|
12
|
-
const
|
|
12
|
+
const plotRef = React.useRef(null);
|
|
13
|
+
const markersRef = React.useRef(null);
|
|
13
14
|
React.useEffect(() => {
|
|
14
15
|
var _a;
|
|
15
|
-
if (!
|
|
16
|
+
if (!plotRef.current || !markersRef.current) {
|
|
16
17
|
return () => { };
|
|
17
18
|
}
|
|
18
|
-
const
|
|
19
|
+
const plotSvgElement = select(plotRef.current);
|
|
20
|
+
const markersSvgElement = select(markersRef.current);
|
|
19
21
|
const hoverOptions = get(seriesOptions, 'line.states.hover');
|
|
20
22
|
const inactiveOptions = get(seriesOptions, 'line.states.inactive');
|
|
21
23
|
const line = lineGenerator()
|
|
22
24
|
.x((d) => d.x)
|
|
23
25
|
.y((d) => d.y);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
plotSvgElement.selectAll('*').remove();
|
|
27
|
+
markersSvgElement.selectAll('*').remove();
|
|
28
|
+
const lineSelection = plotSvgElement
|
|
26
29
|
.selectAll('path')
|
|
27
30
|
.data(preparedData)
|
|
28
31
|
.join('path')
|
|
@@ -41,7 +44,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
41
44
|
if (!((_a = preparedData[0]) === null || _a === void 0 ? void 0 : _a.series.dataLabels.allowOverlap)) {
|
|
42
45
|
dataLabels = filterOverlappingLabels(dataLabels);
|
|
43
46
|
}
|
|
44
|
-
const labelsSelection =
|
|
47
|
+
const labelsSelection = plotSvgElement
|
|
45
48
|
.selectAll('text')
|
|
46
49
|
.data(dataLabels)
|
|
47
50
|
.join('text')
|
|
@@ -54,7 +57,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
54
57
|
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
55
58
|
.style('fill', (d) => d.style.fontColor || null);
|
|
56
59
|
const markers = preparedData.reduce((acc, d) => acc.concat(d.markers), []);
|
|
57
|
-
const markerSelection =
|
|
60
|
+
const markerSelection = markersSvgElement
|
|
58
61
|
.selectAll('marker')
|
|
59
62
|
.data(markers)
|
|
60
63
|
.join('g')
|
|
@@ -71,10 +74,10 @@ export const LineSeriesShapes = (args) => {
|
|
|
71
74
|
const hovered = Boolean(hoverEnabled && selectedSeriesIds.includes(d.id));
|
|
72
75
|
if (d.hovered !== hovered) {
|
|
73
76
|
d.hovered = hovered;
|
|
74
|
-
elementSelection.attr('stroke', (
|
|
77
|
+
elementSelection.attr('stroke', (dSelection) => {
|
|
75
78
|
var _a;
|
|
76
|
-
const initialColor =
|
|
77
|
-
if (
|
|
79
|
+
const initialColor = dSelection.color || '';
|
|
80
|
+
if (dSelection.hovered) {
|
|
78
81
|
return (((_a = color(initialColor)) === null || _a === void 0 ? void 0 : _a.brighter(hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.brightness).toString()) || initialColor);
|
|
79
82
|
}
|
|
80
83
|
return initialColor;
|
|
@@ -131,6 +134,7 @@ export const LineSeriesShapes = (args) => {
|
|
|
131
134
|
};
|
|
132
135
|
}, [dispatcher, preparedData, seriesOptions]);
|
|
133
136
|
return (React.createElement(React.Fragment, null,
|
|
134
|
-
React.createElement("g", { ref:
|
|
137
|
+
React.createElement("g", { ref: plotRef, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
138
|
+
React.createElement("g", { ref: markersRef }),
|
|
135
139
|
React.createElement(HtmlLayer, { preparedData: preparedData, htmlLayout: htmlLayout })));
|
|
136
140
|
};
|
|
@@ -40,7 +40,7 @@ async function getHtmlLabel(point, series, xMax) {
|
|
|
40
40
|
}
|
|
41
41
|
export const prepareLineData = async (args) => {
|
|
42
42
|
var _a;
|
|
43
|
-
const { series, xAxis, yAxis, xScale, yScale, split } = args;
|
|
43
|
+
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds } = args;
|
|
44
44
|
const [_xMin, xRangeMax] = xScale.range();
|
|
45
45
|
const xMax = xRangeMax / (1 - xAxis.maxPadding);
|
|
46
46
|
const acc = [];
|
|
@@ -74,6 +74,7 @@ export const prepareLineData = async (args) => {
|
|
|
74
74
|
point: p,
|
|
75
75
|
active: true,
|
|
76
76
|
hovered: false,
|
|
77
|
+
clipped: isOutsideBounds(p.x, p.y),
|
|
77
78
|
}));
|
|
78
79
|
}
|
|
79
80
|
const result = {
|
|
@@ -16,6 +16,9 @@ export function renderMarker(selection) {
|
|
|
16
16
|
.append('path')
|
|
17
17
|
.attr('class', haloClassName)
|
|
18
18
|
.attr('d', (d) => {
|
|
19
|
+
if ('clipped' in d && d.clipped) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
19
22
|
const series = d.point.series;
|
|
20
23
|
const type = series.marker.states.normal.symbol;
|
|
21
24
|
const radius = get(d.point.data, 'radius', series.marker.states.hover.radius);
|
|
@@ -53,6 +56,9 @@ export function getMarkerHaloVisibility(d) {
|
|
|
53
56
|
export function setMarker(selection, state) {
|
|
54
57
|
selection
|
|
55
58
|
.attr('d', (d) => {
|
|
59
|
+
if ('clipped' in d && d.clipped) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
56
62
|
const series = d.point.series;
|
|
57
63
|
const type = series.marker.states.normal.symbol;
|
|
58
64
|
const radius = get(d.point.data, 'radius', series.marker.states[state].radius);
|
|
@@ -4,7 +4,7 @@ const getFilteredLinearScatterData = (data) => {
|
|
|
4
4
|
return data.filter((d) => typeof d.x === 'number' && typeof d.y === 'number');
|
|
5
5
|
};
|
|
6
6
|
export const prepareScatterData = (args) => {
|
|
7
|
-
const { series, xAxis, xScale, yAxis, yScale } = args;
|
|
7
|
+
const { series, xAxis, xScale, yAxis, yScale, isOutsideBounds } = args;
|
|
8
8
|
return series.reduce((acc, s) => {
|
|
9
9
|
const yAxisIndex = get(s, 'yAxis', 0);
|
|
10
10
|
const seriesYAxis = yAxis[yAxisIndex];
|
|
@@ -14,18 +14,21 @@ export const prepareScatterData = (args) => {
|
|
|
14
14
|
: getFilteredLinearScatterData(s.data);
|
|
15
15
|
filteredData.forEach((d) => {
|
|
16
16
|
var _a;
|
|
17
|
+
const x = getXValue({ point: d, xAxis, xScale });
|
|
18
|
+
const y = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale });
|
|
17
19
|
acc.push({
|
|
18
20
|
point: {
|
|
19
21
|
data: d,
|
|
20
22
|
series: s,
|
|
21
|
-
x
|
|
22
|
-
y
|
|
23
|
+
x,
|
|
24
|
+
y,
|
|
23
25
|
opacity: get(d, 'opacity', null),
|
|
24
26
|
color: (_a = d.color) !== null && _a !== void 0 ? _a : s.color,
|
|
25
27
|
},
|
|
26
28
|
hovered: false,
|
|
27
29
|
active: true,
|
|
28
30
|
htmlElements: [],
|
|
31
|
+
clipped: isOutsideBounds(x, y),
|
|
29
32
|
});
|
|
30
33
|
});
|
|
31
34
|
return acc;
|
|
@@ -8,7 +8,7 @@ export { prepareWaterfallData } from './prepare-data';
|
|
|
8
8
|
export * from './types';
|
|
9
9
|
const b = block('waterfall');
|
|
10
10
|
export const WaterfallSeriesShapes = (args) => {
|
|
11
|
-
const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
|
|
11
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
12
12
|
const hoveredDataRef = React.useRef(null);
|
|
13
13
|
const ref = React.useRef(null);
|
|
14
14
|
const connectorSelector = `.${b('connector')}`;
|
|
@@ -127,6 +127,6 @@ export const WaterfallSeriesShapes = (args) => {
|
|
|
127
127
|
};
|
|
128
128
|
}, [dispatcher, preparedData, seriesOptions]);
|
|
129
129
|
return (React.createElement(React.Fragment, null,
|
|
130
|
-
React.createElement("g", { ref: ref, className: b() }),
|
|
130
|
+
React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
131
131
|
React.createElement(HtmlLayer, { preparedData: preparedData, htmlLayout: htmlLayout })));
|
|
132
132
|
};
|
|
@@ -6,7 +6,7 @@ export declare function selectionToZoomBounds(args: {
|
|
|
6
6
|
selection: BrushSelection;
|
|
7
7
|
xAxis: PreparedAxis;
|
|
8
8
|
xScale: ChartScale;
|
|
9
|
-
|
|
9
|
+
yAxes: PreparedAxis[];
|
|
10
10
|
yScales: ChartScale[];
|
|
11
11
|
zoomType: PreparedZoom['type'];
|
|
12
12
|
}): Partial<ZoomState>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function selectionToZoomBounds(args) {
|
|
2
|
-
const { selection, xAxis, xScale,
|
|
2
|
+
const { selection, xAxis, xScale, yAxes, yScales, zoomType } = args;
|
|
3
3
|
const zoomState = {};
|
|
4
4
|
switch (zoomType) {
|
|
5
5
|
case 'x': {
|
|
@@ -9,7 +9,7 @@ export function selectionToZoomBounds(args) {
|
|
|
9
9
|
}
|
|
10
10
|
case 'y': {
|
|
11
11
|
const [y1, y0] = selection;
|
|
12
|
-
|
|
12
|
+
yAxes.forEach((yAxis, index) => {
|
|
13
13
|
if (!Array.isArray(zoomState.y)) {
|
|
14
14
|
zoomState.y = [];
|
|
15
15
|
}
|
|
@@ -25,7 +25,7 @@ export function selectionToZoomBounds(args) {
|
|
|
25
25
|
const [x0, y0] = selection[0];
|
|
26
26
|
const [x1, y1] = selection[1];
|
|
27
27
|
zoomState.x = selectionXToZoomBounds({ xAxis, xScale, selection: [x0, x1] });
|
|
28
|
-
|
|
28
|
+
yAxes.forEach((yAxis, index) => {
|
|
29
29
|
if (!Array.isArray(zoomState.y)) {
|
|
30
30
|
zoomState.y = [];
|
|
31
31
|
}
|
|
@@ -53,6 +53,8 @@ export interface ChartAxis {
|
|
|
53
53
|
};
|
|
54
54
|
/** The minimum value of the axis. If undefined the min value is automatically calculate. */
|
|
55
55
|
min?: number;
|
|
56
|
+
/** The maximum value of the axis. If undefined the max value is automatically calculate. */
|
|
57
|
+
max?: number;
|
|
56
58
|
/** The grid lines settings. */
|
|
57
59
|
grid?: {
|
|
58
60
|
/** Enable or disable the grid lines.
|
|
@@ -130,11 +132,8 @@ export interface AxisCrosshair extends Omit<AxisPlotLine, 'value'> {
|
|
|
130
132
|
enabled?: boolean;
|
|
131
133
|
}
|
|
132
134
|
export interface ChartYAxis extends ChartAxis {
|
|
133
|
-
/** Axis location.
|
|
134
|
-
* Possible values - 'left' and 'right'.
|
|
135
|
-
* */
|
|
135
|
+
/** Axis location. */
|
|
136
136
|
position?: 'left' | 'right';
|
|
137
|
-
/** Property for splitting charts. Determines which area the axis is located in.
|
|
138
|
-
* */
|
|
137
|
+
/** Property for splitting charts. Determines which area the axis is located in. */
|
|
139
138
|
plotIndex?: number;
|
|
140
139
|
}
|
|
@@ -106,6 +106,7 @@ export async function axisBottom(args) {
|
|
|
106
106
|
.remove();
|
|
107
107
|
// add an ellipsis to the labels that go beyond the boundaries of the chart
|
|
108
108
|
labels.each(function (_d, i, nodes) {
|
|
109
|
+
var _a;
|
|
109
110
|
if (i === 0) {
|
|
110
111
|
const currentElement = this;
|
|
111
112
|
const text = select(currentElement);
|
|
@@ -113,7 +114,8 @@ export async function axisBottom(args) {
|
|
|
113
114
|
const nextElement = nodes[i + 1];
|
|
114
115
|
const nextElementPosition = nextElement === null || nextElement === void 0 ? void 0 : nextElement.getBoundingClientRect();
|
|
115
116
|
if (currentElementPosition.left < leftmostLimit) {
|
|
116
|
-
const
|
|
117
|
+
const rightmostPossiblePoint = (_a = nextElementPosition === null || nextElementPosition === void 0 ? void 0 : nextElementPosition.left) !== null && _a !== void 0 ? _a : right;
|
|
118
|
+
const remainSpace = rightmostPossiblePoint -
|
|
117
119
|
currentElementPosition.right +
|
|
118
120
|
x -
|
|
119
121
|
labelsMargin;
|