@gravity-ui/charts 1.34.0 → 1.34.2
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/AxisX/prepare-axis-data.d.ts +6 -5
- package/dist/cjs/components/AxisX/prepare-axis-data.js +2 -2
- package/dist/cjs/components/AxisY/utils.js +3 -3
- package/dist/cjs/components/ChartInner/index.js +23 -10
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +3 -1
- package/dist/cjs/components/RangeSlider/index.js +1 -0
- package/dist/cjs/hooks/useAxis/x-axis.js +1 -1
- package/dist/cjs/hooks/useBrush/index.js +24 -5
- package/dist/cjs/hooks/useBrush/types.d.ts +1 -0
- package/dist/cjs/hooks/useBrush/utils.d.ts +4 -0
- package/dist/cjs/hooks/useBrush/utils.js +4 -0
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +85 -25
- package/dist/cjs/hooks/useShapes/index.d.ts +3 -0
- package/dist/cjs/hooks/useShapes/index.js +40 -27
- package/dist/cjs/hooks/useShapes/utils.d.ts +10 -0
- package/dist/cjs/hooks/useShapes/utils.js +15 -0
- package/dist/cjs/setup-jsdom.d.ts +0 -0
- package/dist/cjs/setup-jsdom.js +19 -0
- package/dist/cjs/utils/chart/axis/common.d.ts +2 -2
- package/dist/cjs/utils/chart/axis/common.js +2 -2
- package/dist/cjs/utils/chart/axis/x-axis.d.ts +11 -10
- package/dist/cjs/utils/chart/axis/x-axis.js +24 -3
- package/dist/cjs/utils/chart/index.d.ts +2 -29
- package/dist/cjs/utils/chart/index.js +2 -19
- package/dist/cjs/utils/chart/series-type-guards.d.ts +30 -0
- package/dist/cjs/utils/chart/series-type-guards.js +19 -0
- package/dist/esm/components/AxisX/prepare-axis-data.d.ts +6 -5
- package/dist/esm/components/AxisX/prepare-axis-data.js +2 -2
- package/dist/esm/components/AxisY/utils.js +3 -3
- package/dist/esm/components/ChartInner/index.js +23 -10
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +3 -1
- package/dist/esm/components/RangeSlider/index.js +1 -0
- package/dist/esm/hooks/useAxis/x-axis.js +1 -1
- package/dist/esm/hooks/useBrush/index.js +24 -5
- package/dist/esm/hooks/useBrush/types.d.ts +1 -0
- package/dist/esm/hooks/useBrush/utils.d.ts +4 -0
- package/dist/esm/hooks/useBrush/utils.js +4 -0
- package/dist/esm/hooks/useShapes/area/prepare-data.js +85 -25
- package/dist/esm/hooks/useShapes/index.d.ts +3 -0
- package/dist/esm/hooks/useShapes/index.js +40 -27
- package/dist/esm/hooks/useShapes/utils.d.ts +10 -0
- package/dist/esm/hooks/useShapes/utils.js +15 -0
- package/dist/esm/setup-jsdom.d.ts +0 -0
- package/dist/esm/setup-jsdom.js +19 -0
- package/dist/esm/utils/chart/axis/common.d.ts +2 -2
- package/dist/esm/utils/chart/axis/common.js +2 -2
- package/dist/esm/utils/chart/axis/x-axis.d.ts +11 -10
- package/dist/esm/utils/chart/axis/x-axis.js +24 -3
- package/dist/esm/utils/chart/index.d.ts +2 -29
- package/dist/esm/utils/chart/index.js +2 -19
- package/dist/esm/utils/chart/series-type-guards.d.ts +30 -0
- package/dist/esm/utils/chart/series-type-guards.js +19 -0
- package/package.json +1 -1
|
@@ -94,11 +94,13 @@ export const prepareAreaData = async (args) => {
|
|
|
94
94
|
const positiveStackValues = new Map();
|
|
95
95
|
const negativeStackValues = new Map();
|
|
96
96
|
xValues.forEach(([key]) => {
|
|
97
|
-
positiveStackValues.set(key, 0);
|
|
98
|
-
negativeStackValues.set(key, 0);
|
|
97
|
+
positiveStackValues.set(key, { prev: 0, next: 0 });
|
|
98
|
+
negativeStackValues.set(key, { prev: 0, next: 0 });
|
|
99
99
|
});
|
|
100
100
|
const seriesStackData = [];
|
|
101
|
-
|
|
101
|
+
// Process series in reverse order so that the first series in input
|
|
102
|
+
// appears at the top of the stack (furthest from baseline)
|
|
103
|
+
for (let j = seriesStack.length - 1; j >= 0; j--) {
|
|
102
104
|
const s = seriesStack[j];
|
|
103
105
|
const yAxisIndex = s.yAxis;
|
|
104
106
|
const seriesYAxis = yAxis[yAxisIndex];
|
|
@@ -123,40 +125,97 @@ export const prepareAreaData = async (args) => {
|
|
|
123
125
|
: d.x);
|
|
124
126
|
return m.set(key, d);
|
|
125
127
|
}, new Map());
|
|
126
|
-
const points = xValues.reduce((pointsAcc, [x, xValue]) => {
|
|
127
|
-
var _a, _b;
|
|
128
|
+
const points = xValues.reduce((pointsAcc, [x, xValue], index) => {
|
|
129
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
128
130
|
const d = (_a = seriesData.get(x)) !== null && _a !== void 0 ? _a : {
|
|
129
131
|
x,
|
|
130
132
|
y: 0,
|
|
131
133
|
};
|
|
132
134
|
const yDataValue = (_b = d.y) !== null && _b !== void 0 ? _b : null;
|
|
135
|
+
if (s.nullMode === 'connect' && yDataValue === null) {
|
|
136
|
+
return pointsAcc;
|
|
137
|
+
}
|
|
133
138
|
const yValue = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale });
|
|
134
|
-
let y = null;
|
|
135
|
-
let y0 = yAxisTop + yMin;
|
|
136
139
|
if (typeof yDataValue === 'number' && yValue !== null) {
|
|
140
|
+
const prevPoint = seriesData.get((_c = xValues[index - 1]) === null || _c === void 0 ? void 0 : _c[0]);
|
|
141
|
+
const nextPoint = seriesData.get((_d = xValues[index + 1]) === null || _d === void 0 ? void 0 : _d[0]);
|
|
142
|
+
const currentPointStackHeight = Math.abs(yMin - yValue);
|
|
137
143
|
if (yDataValue >= 0) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
const positiveStackHeights = positiveStackValues.get(x);
|
|
145
|
+
let prevSectionStackHeight = (_e = positiveStackHeights === null || positiveStackHeights === void 0 ? void 0 : positiveStackHeights.prev) !== null && _e !== void 0 ? _e : 0;
|
|
146
|
+
let nextSectionStackHeight = (_f = positiveStackHeights === null || positiveStackHeights === void 0 ? void 0 : positiveStackHeights.next) !== null && _f !== void 0 ? _f : 0;
|
|
147
|
+
pointsAcc.push({
|
|
148
|
+
y0: yAxisTop + yMin - prevSectionStackHeight,
|
|
149
|
+
x: xValue,
|
|
150
|
+
y: yAxisTop + yValue - prevSectionStackHeight,
|
|
151
|
+
data: d,
|
|
152
|
+
series: s,
|
|
153
|
+
});
|
|
154
|
+
if (prevSectionStackHeight !== nextSectionStackHeight) {
|
|
155
|
+
pointsAcc.push({
|
|
156
|
+
y0: yAxisTop + yMin - nextSectionStackHeight,
|
|
157
|
+
x: xValue,
|
|
158
|
+
y: yAxisTop + yValue - nextSectionStackHeight,
|
|
159
|
+
data: d,
|
|
160
|
+
series: s,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if ((prevPoint === null || prevPoint === void 0 ? void 0 : prevPoint.y) !== null) {
|
|
164
|
+
prevSectionStackHeight =
|
|
165
|
+
prevSectionStackHeight + currentPointStackHeight;
|
|
166
|
+
}
|
|
167
|
+
if ((nextPoint === null || nextPoint === void 0 ? void 0 : nextPoint.y) !== null) {
|
|
168
|
+
nextSectionStackHeight =
|
|
169
|
+
nextSectionStackHeight + currentPointStackHeight;
|
|
170
|
+
}
|
|
171
|
+
positiveStackValues.set(x, {
|
|
172
|
+
prev: prevSectionStackHeight,
|
|
173
|
+
next: nextSectionStackHeight,
|
|
174
|
+
});
|
|
142
175
|
}
|
|
143
176
|
else {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
177
|
+
const negativeStackHeights = negativeStackValues.get(x);
|
|
178
|
+
let prevSectionStackHeight = (_g = negativeStackHeights === null || negativeStackHeights === void 0 ? void 0 : negativeStackHeights.prev) !== null && _g !== void 0 ? _g : 0;
|
|
179
|
+
let nextSectionStackHeight = (_h = negativeStackHeights === null || negativeStackHeights === void 0 ? void 0 : negativeStackHeights.next) !== null && _h !== void 0 ? _h : 0;
|
|
180
|
+
pointsAcc.push({
|
|
181
|
+
y0: yAxisTop + yMin + prevSectionStackHeight,
|
|
182
|
+
x: xValue,
|
|
183
|
+
y: yAxisTop + yValue + prevSectionStackHeight,
|
|
184
|
+
data: d,
|
|
185
|
+
series: s,
|
|
186
|
+
});
|
|
187
|
+
if (prevSectionStackHeight !== nextSectionStackHeight) {
|
|
188
|
+
pointsAcc.push({
|
|
189
|
+
y0: yAxisTop + yMin + nextSectionStackHeight,
|
|
190
|
+
x: xValue,
|
|
191
|
+
y: yAxisTop + yValue + nextSectionStackHeight,
|
|
192
|
+
data: d,
|
|
193
|
+
series: s,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if ((prevPoint === null || prevPoint === void 0 ? void 0 : prevPoint.y) !== null) {
|
|
197
|
+
prevSectionStackHeight =
|
|
198
|
+
prevSectionStackHeight + currentPointStackHeight;
|
|
199
|
+
}
|
|
200
|
+
if ((nextPoint === null || nextPoint === void 0 ? void 0 : nextPoint.y) !== null) {
|
|
201
|
+
nextSectionStackHeight =
|
|
202
|
+
nextSectionStackHeight + currentPointStackHeight;
|
|
203
|
+
}
|
|
204
|
+
negativeStackValues.set(x, {
|
|
205
|
+
prev: prevSectionStackHeight,
|
|
206
|
+
next: nextSectionStackHeight,
|
|
207
|
+
});
|
|
148
208
|
}
|
|
149
209
|
}
|
|
150
|
-
|
|
151
|
-
|
|
210
|
+
else {
|
|
211
|
+
pointsAcc.push({
|
|
212
|
+
y0: yAxisTop + yMin,
|
|
213
|
+
x: xValue,
|
|
214
|
+
y: null,
|
|
215
|
+
data: d,
|
|
216
|
+
series: s,
|
|
217
|
+
});
|
|
152
218
|
}
|
|
153
|
-
pointsAcc.push({
|
|
154
|
-
y0,
|
|
155
|
-
x: xValue,
|
|
156
|
-
y,
|
|
157
|
-
data: d,
|
|
158
|
-
series: s,
|
|
159
|
-
});
|
|
160
219
|
return pointsAcc;
|
|
161
220
|
}, []);
|
|
162
221
|
const labels = [];
|
|
@@ -197,7 +256,8 @@ export const prepareAreaData = async (args) => {
|
|
|
197
256
|
}
|
|
198
257
|
if (series.some((s) => s.stacking === 'percent')) {
|
|
199
258
|
xValues.forEach(([x], index) => {
|
|
200
|
-
|
|
259
|
+
var _a;
|
|
260
|
+
const stackHeight = ((_a = positiveStackValues.get(x)) === null || _a === void 0 ? void 0 : _a.prev) || 0;
|
|
201
261
|
let acc = 0;
|
|
202
262
|
const ratio = plotHeight / stackHeight;
|
|
203
263
|
seriesStackData.forEach((item) => {
|
|
@@ -5,6 +5,7 @@ import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
|
5
5
|
import type { ChartScale } from '../useAxisScales/types';
|
|
6
6
|
import type { PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
7
7
|
import type { PreparedSplit } from '../useSplit/types';
|
|
8
|
+
import type { ZoomState } from '../useZoom/types';
|
|
8
9
|
import type { PreparedAreaData } from './area/types';
|
|
9
10
|
import type { PreparedBarXData } from './bar-x';
|
|
10
11
|
import type { PreparedBarYData } from './bar-y/types';
|
|
@@ -37,8 +38,10 @@ type Args = {
|
|
|
37
38
|
isRangeSlider?: boolean;
|
|
38
39
|
xScale?: ChartScale;
|
|
39
40
|
yScale?: (ChartScale | undefined)[];
|
|
41
|
+
zoomState?: Partial<ZoomState>;
|
|
40
42
|
};
|
|
41
43
|
export declare const useShapes: (args: Args) => {
|
|
42
44
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
43
45
|
shapesData: ShapeData[];
|
|
46
|
+
shapesReady: boolean;
|
|
44
47
|
};
|
|
@@ -20,6 +20,7 @@ import { prepareSankeyData } from './sankey/prepare-data';
|
|
|
20
20
|
import { ScatterSeriesShape, prepareScatterData } from './scatter';
|
|
21
21
|
import { TreemapSeriesShape } from './treemap';
|
|
22
22
|
import { prepareTreemapData } from './treemap/prepare-data';
|
|
23
|
+
import { getSeriesClipPathId } from './utils';
|
|
23
24
|
import { WaterfallSeriesShapes, prepareWaterfallData } from './waterfall';
|
|
24
25
|
import './styles.css';
|
|
25
26
|
function IS_OUTSIDE_BOUNDS() {
|
|
@@ -30,9 +31,10 @@ function shouldUseClipPathId(seriesType, clipPathBySeriesType) {
|
|
|
30
31
|
return (_a = clipPathBySeriesType === null || clipPathBySeriesType === void 0 ? void 0 : clipPathBySeriesType[seriesType]) !== null && _a !== void 0 ? _a : true;
|
|
31
32
|
}
|
|
32
33
|
export const useShapes = (args) => {
|
|
33
|
-
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, isRangeSlider, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, } = args;
|
|
34
|
+
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, isRangeSlider, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, zoomState, } = args;
|
|
34
35
|
const [shapesElemens, setShapesElements] = React.useState([]);
|
|
35
36
|
const [shapesElemensData, setShapesElemensData] = React.useState([]);
|
|
37
|
+
const shapesReadyRef = React.useRef(false);
|
|
36
38
|
const countedRef = React.useRef(0);
|
|
37
39
|
React.useEffect(() => {
|
|
38
40
|
countedRef.current++;
|
|
@@ -44,7 +46,7 @@ export const useShapes = (args) => {
|
|
|
44
46
|
const shapes = [];
|
|
45
47
|
await Promise.all(
|
|
46
48
|
// eslint-disable-next-line complexity
|
|
47
|
-
Array.from(groupedSeries).map(async (item) => {
|
|
49
|
+
Array.from(groupedSeries).map(async (item, index) => {
|
|
48
50
|
const [seriesType, chartSeries] = item;
|
|
49
51
|
switch (seriesType) {
|
|
50
52
|
case SERIES_TYPE.BarX: {
|
|
@@ -60,8 +62,8 @@ export const useShapes = (args) => {
|
|
|
60
62
|
split,
|
|
61
63
|
isRangeSlider,
|
|
62
64
|
});
|
|
63
|
-
shapes
|
|
64
|
-
shapesData.
|
|
65
|
+
shapes[index] = (React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
66
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
65
67
|
}
|
|
66
68
|
break;
|
|
67
69
|
}
|
|
@@ -77,8 +79,8 @@ export const useShapes = (args) => {
|
|
|
77
79
|
yAxis,
|
|
78
80
|
yScale,
|
|
79
81
|
});
|
|
80
|
-
shapes
|
|
81
|
-
shapesData.
|
|
82
|
+
shapes[index] = (React.createElement(BarYSeriesShapes, { key: SERIES_TYPE.BarY, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
83
|
+
shapesData.splice(index, 0, ...preparedData.shapes);
|
|
82
84
|
}
|
|
83
85
|
break;
|
|
84
86
|
}
|
|
@@ -92,8 +94,8 @@ export const useShapes = (args) => {
|
|
|
92
94
|
yAxis,
|
|
93
95
|
yScale,
|
|
94
96
|
});
|
|
95
|
-
shapes
|
|
96
|
-
shapesData.
|
|
97
|
+
shapes[index] = (React.createElement(WaterfallSeriesShapes, { key: SERIES_TYPE.Waterfall, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
98
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
97
99
|
}
|
|
98
100
|
break;
|
|
99
101
|
}
|
|
@@ -109,8 +111,13 @@ export const useShapes = (args) => {
|
|
|
109
111
|
isOutsideBounds,
|
|
110
112
|
isRangeSlider,
|
|
111
113
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
const resultClipPathId = getSeriesClipPathId({
|
|
115
|
+
clipPathId,
|
|
116
|
+
yAxis,
|
|
117
|
+
zoomState,
|
|
118
|
+
});
|
|
119
|
+
shapes[index] = (React.createElement(LineSeriesShapes, { key: SERIES_TYPE.Line, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: resultClipPathId }));
|
|
120
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
114
121
|
}
|
|
115
122
|
break;
|
|
116
123
|
}
|
|
@@ -127,8 +134,8 @@ export const useShapes = (args) => {
|
|
|
127
134
|
isOutsideBounds,
|
|
128
135
|
isRangeSlider,
|
|
129
136
|
});
|
|
130
|
-
shapes
|
|
131
|
-
shapesData.
|
|
137
|
+
shapes[index] = (React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
138
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
132
139
|
}
|
|
133
140
|
break;
|
|
134
141
|
}
|
|
@@ -142,10 +149,10 @@ export const useShapes = (args) => {
|
|
|
142
149
|
yScale,
|
|
143
150
|
isOutsideBounds,
|
|
144
151
|
});
|
|
145
|
-
shapes
|
|
152
|
+
shapes[index] = (React.createElement(ScatterSeriesShape, { key: SERIES_TYPE.Scatter, clipPathId: shouldUseClipPathId(SERIES_TYPE.Scatter, clipPathBySeriesType)
|
|
146
153
|
? clipPathId
|
|
147
154
|
: undefined, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
148
|
-
shapesData.
|
|
155
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
149
156
|
}
|
|
150
157
|
break;
|
|
151
158
|
}
|
|
@@ -155,8 +162,8 @@ export const useShapes = (args) => {
|
|
|
155
162
|
boundsWidth,
|
|
156
163
|
boundsHeight,
|
|
157
164
|
});
|
|
158
|
-
shapes
|
|
159
|
-
shapesData.
|
|
165
|
+
shapes[index] = (React.createElement(PieSeriesShapes, { key: SERIES_TYPE.Pie, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
166
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
160
167
|
break;
|
|
161
168
|
}
|
|
162
169
|
case SERIES_TYPE.Treemap: {
|
|
@@ -167,8 +174,8 @@ export const useShapes = (args) => {
|
|
|
167
174
|
width: boundsWidth,
|
|
168
175
|
height: boundsHeight,
|
|
169
176
|
});
|
|
170
|
-
shapes
|
|
171
|
-
shapesData.
|
|
177
|
+
shapes[index] = (React.createElement(TreemapSeriesShape, { key: SERIES_TYPE.Treemap, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
178
|
+
shapesData.splice(index, 0, preparedData);
|
|
172
179
|
break;
|
|
173
180
|
}
|
|
174
181
|
case SERIES_TYPE.Sankey: {
|
|
@@ -177,8 +184,8 @@ export const useShapes = (args) => {
|
|
|
177
184
|
width: boundsWidth,
|
|
178
185
|
height: boundsHeight,
|
|
179
186
|
});
|
|
180
|
-
shapes
|
|
181
|
-
shapesData.
|
|
187
|
+
shapes[index] = (React.createElement(SankeySeriesShape, { key: SERIES_TYPE.Sankey, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
188
|
+
shapesData.splice(index, 0, preparedData);
|
|
182
189
|
break;
|
|
183
190
|
}
|
|
184
191
|
case SERIES_TYPE.Radar: {
|
|
@@ -187,8 +194,8 @@ export const useShapes = (args) => {
|
|
|
187
194
|
boundsWidth,
|
|
188
195
|
boundsHeight,
|
|
189
196
|
});
|
|
190
|
-
shapes
|
|
191
|
-
shapesData.
|
|
197
|
+
shapes[index] = (React.createElement(RadarSeriesShapes, { key: SERIES_TYPE.Radar, dispatcher: dispatcher, series: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
198
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
192
199
|
break;
|
|
193
200
|
}
|
|
194
201
|
case SERIES_TYPE.Heatmap: {
|
|
@@ -200,8 +207,8 @@ export const useShapes = (args) => {
|
|
|
200
207
|
yAxis: yAxis[0],
|
|
201
208
|
yScale: yScale[0],
|
|
202
209
|
});
|
|
203
|
-
shapes
|
|
204
|
-
shapesData.
|
|
210
|
+
shapes[index] = (React.createElement(HeatmapSeriesShapes, { key: SERIES_TYPE.Heatmap, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
211
|
+
shapesData.splice(index, 0, preparedData);
|
|
205
212
|
}
|
|
206
213
|
break;
|
|
207
214
|
}
|
|
@@ -211,8 +218,8 @@ export const useShapes = (args) => {
|
|
|
211
218
|
boundsWidth,
|
|
212
219
|
boundsHeight,
|
|
213
220
|
});
|
|
214
|
-
shapes
|
|
215
|
-
shapesData.
|
|
221
|
+
shapes[index] = (React.createElement(FunnelSeriesShapes, { key: "funnel", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
|
|
222
|
+
shapesData.splice(index, 0, preparedData);
|
|
216
223
|
break;
|
|
217
224
|
}
|
|
218
225
|
default: {
|
|
@@ -223,6 +230,7 @@ export const useShapes = (args) => {
|
|
|
223
230
|
}
|
|
224
231
|
}));
|
|
225
232
|
if (countedRef.current === currentRun) {
|
|
233
|
+
shapesReadyRef.current = true;
|
|
226
234
|
setShapesElements(shapes);
|
|
227
235
|
setShapesElemensData(shapesData);
|
|
228
236
|
}
|
|
@@ -243,6 +251,11 @@ export const useShapes = (args) => {
|
|
|
243
251
|
xScale,
|
|
244
252
|
yAxis,
|
|
245
253
|
yScale,
|
|
254
|
+
zoomState,
|
|
246
255
|
]);
|
|
247
|
-
return {
|
|
256
|
+
return {
|
|
257
|
+
shapes: shapesElemens,
|
|
258
|
+
shapesData: shapesElemensData,
|
|
259
|
+
shapesReady: shapesReadyRef.current,
|
|
260
|
+
};
|
|
248
261
|
};
|
|
@@ -2,6 +2,7 @@ import type { BaseType } from 'd3';
|
|
|
2
2
|
import type { BasicInactiveState } from '../../types';
|
|
3
3
|
import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
4
4
|
import type { ChartScale } from '../useAxisScales/types';
|
|
5
|
+
import type { ZoomState } from '../useZoom/types';
|
|
5
6
|
export declare function getXValue(args: {
|
|
6
7
|
point: {
|
|
7
8
|
x?: number | string | null;
|
|
@@ -46,3 +47,12 @@ export declare function getRectBorderPath(args: {
|
|
|
46
47
|
borderWidth: number;
|
|
47
48
|
borderRadius?: number | number[];
|
|
48
49
|
}): string;
|
|
50
|
+
export declare function getClipPathIdByBounds(args: {
|
|
51
|
+
clipPathId: string;
|
|
52
|
+
bounds?: 'horizontal';
|
|
53
|
+
}): string;
|
|
54
|
+
export declare function getSeriesClipPathId(args: {
|
|
55
|
+
clipPathId: string;
|
|
56
|
+
yAxis: PreparedYAxis[];
|
|
57
|
+
zoomState?: Partial<ZoomState>;
|
|
58
|
+
}): string;
|
|
@@ -131,3 +131,18 @@ export function getRectBorderPath(args) {
|
|
|
131
131
|
}).toString();
|
|
132
132
|
return `${outerPath} ${innerPath}`;
|
|
133
133
|
}
|
|
134
|
+
export function getClipPathIdByBounds(args) {
|
|
135
|
+
const { bounds, clipPathId } = args;
|
|
136
|
+
return bounds ? `${clipPathId}-${bounds}` : clipPathId;
|
|
137
|
+
}
|
|
138
|
+
export function getSeriesClipPathId(args) {
|
|
139
|
+
const { clipPathId, yAxis, zoomState } = args;
|
|
140
|
+
const hasMinOrMax = yAxis.some((axis) => {
|
|
141
|
+
return typeof (axis === null || axis === void 0 ? void 0 : axis.min) === 'number' || typeof (axis === null || axis === void 0 ? void 0 : axis.max) === 'number';
|
|
142
|
+
});
|
|
143
|
+
const hasZoom = zoomState && Object.keys(zoomState).length > 0;
|
|
144
|
+
if (!hasZoom && !hasMinOrMax) {
|
|
145
|
+
return getClipPathIdByBounds({ clipPathId, bounds: 'horizontal' });
|
|
146
|
+
}
|
|
147
|
+
return getClipPathIdByBounds({ clipPathId });
|
|
148
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Global mocks for jsdom environment.
|
|
3
|
+
// Guarded by typeof checks so this file is safe to run in the `node` environment too.
|
|
4
|
+
if (typeof document !== 'undefined') {
|
|
5
|
+
// jsdom does not implement document.fonts
|
|
6
|
+
if (!document.fonts) {
|
|
7
|
+
Object.defineProperty(document, 'fonts', {
|
|
8
|
+
value: { ready: Promise.resolve() },
|
|
9
|
+
configurable: true,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (typeof HTMLCanvasElement !== 'undefined') {
|
|
14
|
+
// jsdom does not implement HTMLCanvasElement.prototype.getContext (used for text measurement)
|
|
15
|
+
HTMLCanvasElement.prototype.getContext = (() => ({
|
|
16
|
+
font: '',
|
|
17
|
+
measureText: () => ({ width: 0 }),
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
@@ -3,9 +3,9 @@ import type { ChartScale, PreparedAxis, PreparedAxisPlotBand, PreparedSplit } fr
|
|
|
3
3
|
import type { ChartAxis } from '../../../types';
|
|
4
4
|
import type { AxisDirection } from '../types';
|
|
5
5
|
type Ticks = number[] | string[] | Date[];
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function getTicksCountByPixelInterval({ axis, axisWidth, }: {
|
|
7
7
|
axis: PreparedAxis;
|
|
8
|
-
|
|
8
|
+
axisWidth: number;
|
|
9
9
|
}): number | undefined;
|
|
10
10
|
export declare function isBandScale(scale?: ChartScale | AxisScale<AxisDomain>): scale is ScaleBand<string>;
|
|
11
11
|
export declare function isTimeScale(scale?: ChartScale | AxisScale<AxisDomain>): scale is ScaleTime<number, number>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ascending, descending, reverse, sort } from 'd3';
|
|
2
2
|
import clamp from 'lodash/clamp';
|
|
3
|
-
export function
|
|
3
|
+
export function getTicksCountByPixelInterval({ axis, axisWidth, }) {
|
|
4
4
|
let ticksCount;
|
|
5
5
|
if (axis.ticks.pixelInterval) {
|
|
6
|
-
ticksCount = Math.ceil(
|
|
6
|
+
ticksCount = Math.ceil(axisWidth / axis.ticks.pixelInterval);
|
|
7
7
|
}
|
|
8
8
|
return ticksCount;
|
|
9
9
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { ChartScale, PreparedAxis } from '../../../hooks';
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { ChartScale, PreparedAxis, PreparedSeries } from '../../../hooks';
|
|
2
|
+
import type { ChartSeries } from '../../../types';
|
|
3
|
+
type TickValue = {
|
|
4
|
+
x: number;
|
|
5
|
+
value: number | string | Date;
|
|
6
|
+
};
|
|
7
|
+
export declare function getXAxisTickValues({ axis, labelLineHeight, scale, series, }: {
|
|
4
8
|
axis: PreparedAxis;
|
|
5
9
|
labelLineHeight: number;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
x: number;
|
|
11
|
-
value: string;
|
|
12
|
-
}[];
|
|
10
|
+
scale: ChartScale;
|
|
11
|
+
series?: ChartSeries[] | PreparedSeries[];
|
|
12
|
+
}): TickValue[];
|
|
13
|
+
export {};
|
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import { getMinSpaceBetween } from '../array';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { isSeriesWithNumericalXValues } from '../series-type-guards';
|
|
3
|
+
import { getTicksCountByPixelInterval, isBandScale, thinOut } from './common';
|
|
4
|
+
const DEFAULT_TICKS_COUNT = 10;
|
|
5
|
+
function getTicksCount(args) {
|
|
6
|
+
const { axis, axisWidth, series } = args;
|
|
7
|
+
const result = getTicksCountByPixelInterval({ axis, axisWidth });
|
|
8
|
+
if (typeof result === 'number') {
|
|
9
|
+
return result;
|
|
10
|
+
}
|
|
11
|
+
if (series) {
|
|
12
|
+
const xDataSet = new Set();
|
|
13
|
+
series === null || series === void 0 ? void 0 : series.forEach((item) => {
|
|
14
|
+
if (isSeriesWithNumericalXValues(item)) {
|
|
15
|
+
item.data.forEach((data) => {
|
|
16
|
+
xDataSet.add(data.x);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return xDataSet.size < DEFAULT_TICKS_COUNT ? xDataSet.size : DEFAULT_TICKS_COUNT;
|
|
21
|
+
}
|
|
22
|
+
return DEFAULT_TICKS_COUNT;
|
|
23
|
+
}
|
|
24
|
+
export function getXAxisTickValues({ axis, labelLineHeight, scale, series, }) {
|
|
4
25
|
if ('ticks' in scale && typeof scale.ticks === 'function') {
|
|
5
26
|
const range = scale.range();
|
|
6
27
|
const axisWidth = Math.abs(range[0] - range[1]);
|
|
7
28
|
if (!axisWidth) {
|
|
8
29
|
return [];
|
|
9
30
|
}
|
|
10
|
-
const scaleTicksCount = getTicksCount({ axis,
|
|
31
|
+
const scaleTicksCount = getTicksCount({ axis, axisWidth, series });
|
|
11
32
|
const scaleTicks = scale.ticks(scaleTicksCount);
|
|
12
33
|
const originalTickValues = scaleTicks.map((t) => ({
|
|
13
34
|
x: scale(t),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseTextStyle, ChartSeries, ChartSeriesData } from '../../types';
|
|
2
|
+
import type { UnknownSeries } from './series-type-guards';
|
|
2
3
|
import type { AxisDirection } from './types';
|
|
3
4
|
export * from './axis/common';
|
|
4
5
|
export * from './array';
|
|
@@ -8,41 +9,13 @@ export * from './labels';
|
|
|
8
9
|
export * from './legend';
|
|
9
10
|
export * from './math';
|
|
10
11
|
export * from './series';
|
|
12
|
+
export * from './series-type-guards';
|
|
11
13
|
export * from './symbol';
|
|
12
14
|
export * from './text';
|
|
13
15
|
export * from './time';
|
|
14
16
|
export * from './zoom';
|
|
15
17
|
export declare const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS: ChartSeries['type'][];
|
|
16
18
|
export declare const CHART_SERIES_WITH_VOLUME_ON_X_AXIS: ChartSeries['type'][];
|
|
17
|
-
type UnknownSeries = {
|
|
18
|
-
type: ChartSeries['type'];
|
|
19
|
-
data: unknown;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Checks whether the series should be drawn with axes.
|
|
23
|
-
*
|
|
24
|
-
* @param series - The series object to check.
|
|
25
|
-
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
26
|
-
*/
|
|
27
|
-
export declare function isAxisRelatedSeries(series: UnknownSeries): boolean;
|
|
28
|
-
export declare function isSeriesWithNumericalXValues(series: UnknownSeries): series is {
|
|
29
|
-
type: ChartSeries['type'];
|
|
30
|
-
data: {
|
|
31
|
-
x: number;
|
|
32
|
-
}[];
|
|
33
|
-
};
|
|
34
|
-
export declare function isSeriesWithNumericalYValues(series: UnknownSeries): series is {
|
|
35
|
-
type: ChartSeries['type'];
|
|
36
|
-
data: {
|
|
37
|
-
y: number;
|
|
38
|
-
}[];
|
|
39
|
-
};
|
|
40
|
-
export declare function isSeriesWithCategoryValues(series: UnknownSeries): series is {
|
|
41
|
-
type: ChartSeries['type'];
|
|
42
|
-
data: {
|
|
43
|
-
category: string;
|
|
44
|
-
}[];
|
|
45
|
-
};
|
|
46
19
|
export declare const getDomainDataXBySeries: (series: UnknownSeries[]) => ({} | undefined)[];
|
|
47
20
|
export declare function getDefaultMaxXAxisValue(series: UnknownSeries[]): 0 | undefined;
|
|
48
21
|
export declare function getDefaultMinXAxisValue(series: UnknownSeries[]): number | undefined;
|
|
@@ -5,6 +5,7 @@ import sortBy from 'lodash/sortBy';
|
|
|
5
5
|
import { DEFAULT_AXIS_LABEL_FONT_SIZE, SERIES_TYPE } from '../../constants';
|
|
6
6
|
import { getSeriesStackId } from '../../hooks/useSeries/utils';
|
|
7
7
|
import { getWaterfallPointSubtotal } from './series/waterfall';
|
|
8
|
+
import { isSeriesWithNumericalXValues, isSeriesWithNumericalYValues } from './series-type-guards';
|
|
8
9
|
export * from './axis/common';
|
|
9
10
|
export * from './array';
|
|
10
11
|
export * from './color';
|
|
@@ -13,35 +14,17 @@ export * from './labels';
|
|
|
13
14
|
export * from './legend';
|
|
14
15
|
export * from './math';
|
|
15
16
|
export * from './series';
|
|
17
|
+
export * from './series-type-guards';
|
|
16
18
|
export * from './symbol';
|
|
17
19
|
export * from './text';
|
|
18
20
|
export * from './time';
|
|
19
21
|
export * from './zoom';
|
|
20
|
-
const CHARTS_WITHOUT_AXIS = ['pie', 'treemap', 'sankey', 'radar', 'funnel'];
|
|
21
22
|
export const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS = [
|
|
22
23
|
'bar-x',
|
|
23
24
|
'area',
|
|
24
25
|
'waterfall',
|
|
25
26
|
];
|
|
26
27
|
export const CHART_SERIES_WITH_VOLUME_ON_X_AXIS = ['bar-y'];
|
|
27
|
-
/**
|
|
28
|
-
* Checks whether the series should be drawn with axes.
|
|
29
|
-
*
|
|
30
|
-
* @param series - The series object to check.
|
|
31
|
-
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
32
|
-
*/
|
|
33
|
-
export function isAxisRelatedSeries(series) {
|
|
34
|
-
return !CHARTS_WITHOUT_AXIS.includes(series.type);
|
|
35
|
-
}
|
|
36
|
-
export function isSeriesWithNumericalXValues(series) {
|
|
37
|
-
return isAxisRelatedSeries(series);
|
|
38
|
-
}
|
|
39
|
-
export function isSeriesWithNumericalYValues(series) {
|
|
40
|
-
return isAxisRelatedSeries(series);
|
|
41
|
-
}
|
|
42
|
-
export function isSeriesWithCategoryValues(series) {
|
|
43
|
-
return isAxisRelatedSeries(series);
|
|
44
|
-
}
|
|
45
28
|
function getDomainDataForStackedSeries(seriesList, keyAttr = 'x', valueAttr = 'y') {
|
|
46
29
|
const acc = [];
|
|
47
30
|
const stackedSeries = group(seriesList, getSeriesStackId);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ChartSeries } from '../../types';
|
|
2
|
+
export type UnknownSeries = {
|
|
3
|
+
type: ChartSeries['type'];
|
|
4
|
+
data: unknown;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether the series should be drawn with axes.
|
|
8
|
+
*
|
|
9
|
+
* @param series - The series object to check.
|
|
10
|
+
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isAxisRelatedSeries(series: UnknownSeries): boolean;
|
|
13
|
+
export declare function isSeriesWithNumericalXValues(series: UnknownSeries): series is {
|
|
14
|
+
type: ChartSeries['type'];
|
|
15
|
+
data: {
|
|
16
|
+
x: number;
|
|
17
|
+
}[];
|
|
18
|
+
};
|
|
19
|
+
export declare function isSeriesWithNumericalYValues(series: UnknownSeries): series is {
|
|
20
|
+
type: ChartSeries['type'];
|
|
21
|
+
data: {
|
|
22
|
+
y: number;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
export declare function isSeriesWithCategoryValues(series: UnknownSeries): series is {
|
|
26
|
+
type: ChartSeries['type'];
|
|
27
|
+
data: {
|
|
28
|
+
category: string;
|
|
29
|
+
}[];
|
|
30
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const CHARTS_WITHOUT_AXIS = ['pie', 'treemap', 'sankey', 'radar', 'funnel'];
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether the series should be drawn with axes.
|
|
4
|
+
*
|
|
5
|
+
* @param series - The series object to check.
|
|
6
|
+
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export function isAxisRelatedSeries(series) {
|
|
9
|
+
return !CHARTS_WITHOUT_AXIS.includes(series.type);
|
|
10
|
+
}
|
|
11
|
+
export function isSeriesWithNumericalXValues(series) {
|
|
12
|
+
return isAxisRelatedSeries(series);
|
|
13
|
+
}
|
|
14
|
+
export function isSeriesWithNumericalYValues(series) {
|
|
15
|
+
return isAxisRelatedSeries(series);
|
|
16
|
+
}
|
|
17
|
+
export function isSeriesWithCategoryValues(series) {
|
|
18
|
+
return isAxisRelatedSeries(series);
|
|
19
|
+
}
|