@gravity-ui/charts 1.43.0 → 1.44.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 +3 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
- package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +10 -12
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +8 -4
- package/dist/cjs/components/ChartInner/utils/title.d.ts +3 -2
- package/dist/cjs/components/ChartInner/utils/title.js +19 -14
- package/dist/cjs/components/ChartInner/utils/zoom.js +3 -1
- package/dist/cjs/components/Title/index.d.ts +1 -3
- package/dist/cjs/components/Title/index.js +2 -2
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +31 -6
- package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
- package/dist/cjs/core/constants/chart-types.d.ts +1 -0
- package/dist/cjs/core/constants/chart-types.js +1 -0
- package/dist/cjs/core/constants/defaults/series-options.d.ts +5 -1
- package/dist/cjs/core/constants/defaults/series-options.js +13 -0
- package/dist/cjs/core/constants/index.d.ts +0 -1
- package/dist/cjs/core/constants/index.js +0 -1
- package/dist/cjs/core/i18n/keysets/en.json +2 -1
- package/dist/cjs/core/i18n/keysets/ru.json +2 -1
- package/dist/cjs/core/series/prepare-legend.js +2 -2
- package/dist/cjs/core/series/prepare-x-range.d.ts +11 -0
- package/dist/cjs/core/series/prepare-x-range.js +41 -0
- package/dist/cjs/core/series/prepareSeries.js +9 -0
- package/dist/cjs/core/series/types.d.ts +18 -2
- package/dist/cjs/core/types/chart/area.d.ts +2 -1
- package/dist/cjs/core/types/chart/series.d.ts +29 -2
- package/dist/cjs/core/types/chart/tooltip.d.ts +6 -1
- package/dist/cjs/core/types/chart/x-range.d.ts +59 -0
- package/dist/cjs/core/types/chart/x-range.js +1 -0
- package/dist/cjs/core/types/chart/zoom.d.ts +1 -1
- package/dist/cjs/core/types/index.d.ts +1 -0
- package/dist/cjs/core/types/index.js +1 -0
- package/dist/cjs/core/utils/axis/x-axis.js +9 -1
- package/dist/cjs/core/utils/color.js +6 -0
- package/dist/cjs/core/utils/common.js +10 -0
- package/dist/cjs/core/utils/get-closest-data.js +19 -0
- package/dist/cjs/core/utils/labels.d.ts +1 -1
- package/dist/cjs/core/utils/labels.js +3 -2
- package/dist/cjs/core/validation/index.js +13 -0
- package/dist/cjs/core/zoom/zoom.js +24 -7
- package/dist/cjs/hooks/useSeries/index.js +8 -2
- package/dist/cjs/hooks/useShapes/area/index.js +2 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +19 -18
- package/dist/cjs/hooks/useShapes/area/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +37 -21
- package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
- package/dist/cjs/hooks/useShapes/index.js +35 -5
- package/dist/cjs/hooks/useShapes/line/index.js +7 -16
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +2 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +11 -7
- package/dist/cjs/hooks/useShapes/line/types.d.ts +2 -2
- package/dist/cjs/hooks/useShapes/x-range/index.d.ts +14 -0
- package/dist/cjs/hooks/useShapes/x-range/index.js +115 -0
- package/dist/cjs/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
- package/dist/cjs/hooks/useShapes/x-range/prepare-data.js +147 -0
- package/dist/cjs/hooks/useShapes/x-range/types.d.ts +12 -0
- package/dist/cjs/hooks/useShapes/x-range/types.js +1 -0
- package/dist/cjs/types/chart-ui.d.ts +4 -0
- package/dist/esm/components/ChartInner/index.js +3 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +3 -3
- package/dist/esm/components/ChartInner/useChartInnerHandlers.js +10 -12
- package/dist/esm/components/ChartInner/useChartInnerProps.js +8 -4
- package/dist/esm/components/ChartInner/utils/title.d.ts +3 -2
- package/dist/esm/components/ChartInner/utils/title.js +19 -14
- package/dist/esm/components/ChartInner/utils/zoom.js +3 -1
- package/dist/esm/components/Title/index.d.ts +1 -3
- package/dist/esm/components/Title/index.js +2 -2
- package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +31 -6
- package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +4 -5
- package/dist/esm/core/constants/chart-types.d.ts +1 -0
- package/dist/esm/core/constants/chart-types.js +1 -0
- package/dist/esm/core/constants/defaults/series-options.d.ts +5 -1
- package/dist/esm/core/constants/defaults/series-options.js +13 -0
- package/dist/esm/core/constants/index.d.ts +0 -1
- package/dist/esm/core/constants/index.js +0 -1
- package/dist/esm/core/i18n/keysets/en.json +2 -1
- package/dist/esm/core/i18n/keysets/ru.json +2 -1
- package/dist/esm/core/series/prepare-legend.js +2 -2
- package/dist/esm/core/series/prepare-x-range.d.ts +11 -0
- package/dist/esm/core/series/prepare-x-range.js +41 -0
- package/dist/esm/core/series/prepareSeries.js +9 -0
- package/dist/esm/core/series/types.d.ts +18 -2
- package/dist/esm/core/types/chart/area.d.ts +2 -1
- package/dist/esm/core/types/chart/series.d.ts +29 -2
- package/dist/esm/core/types/chart/tooltip.d.ts +6 -1
- package/dist/esm/core/types/chart/x-range.d.ts +59 -0
- package/dist/esm/core/types/chart/x-range.js +1 -0
- package/dist/esm/core/types/chart/zoom.d.ts +1 -1
- package/dist/esm/core/types/index.d.ts +1 -0
- package/dist/esm/core/types/index.js +1 -0
- package/dist/esm/core/utils/axis/x-axis.js +9 -1
- package/dist/esm/core/utils/color.js +6 -0
- package/dist/esm/core/utils/common.js +10 -0
- package/dist/esm/core/utils/get-closest-data.js +19 -0
- package/dist/esm/core/utils/labels.d.ts +1 -1
- package/dist/esm/core/utils/labels.js +3 -2
- package/dist/esm/core/validation/index.js +13 -0
- package/dist/esm/core/zoom/zoom.js +24 -7
- package/dist/esm/hooks/useSeries/index.js +8 -2
- package/dist/esm/hooks/useShapes/area/index.js +2 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.js +19 -18
- package/dist/esm/hooks/useShapes/area/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/bar-x/index.js +2 -2
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +37 -21
- package/dist/esm/hooks/useShapes/bar-x/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/index.d.ts +2 -1
- package/dist/esm/hooks/useShapes/index.js +35 -5
- package/dist/esm/hooks/useShapes/line/index.js +7 -16
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +2 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +11 -7
- package/dist/esm/hooks/useShapes/line/types.d.ts +2 -2
- package/dist/esm/hooks/useShapes/x-range/index.d.ts +14 -0
- package/dist/esm/hooks/useShapes/x-range/index.js +115 -0
- package/dist/esm/hooks/useShapes/x-range/prepare-data.d.ts +15 -0
- package/dist/esm/hooks/useShapes/x-range/prepare-data.js +147 -0
- package/dist/esm/hooks/useShapes/x-range/types.d.ts +12 -0
- package/dist/esm/hooks/useShapes/x-range/types.js +1 -0
- package/dist/esm/types/chart-ui.d.ts +4 -0
- package/package.json +1 -1
- package/dist/cjs/core/constants/misc.d.ts +0 -1
- package/dist/cjs/core/constants/misc.js +0 -7
- package/dist/esm/core/constants/misc.d.ts +0 -1
- package/dist/esm/core/constants/misc.js +0 -7
|
@@ -22,6 +22,7 @@ import { TreemapSeriesShape } from './treemap';
|
|
|
22
22
|
import { prepareTreemapData } from './treemap/prepare-data';
|
|
23
23
|
import { getSeriesClipPathId } from './utils';
|
|
24
24
|
import { WaterfallSeriesShapes, prepareWaterfallData } from './waterfall';
|
|
25
|
+
import { XRangeSeriesShapes, prepareXRangeData } from './x-range';
|
|
25
26
|
import './styles.css';
|
|
26
27
|
function IS_OUTSIDE_BOUNDS() {
|
|
27
28
|
return false;
|
|
@@ -33,11 +34,20 @@ function shouldUseClipPathId(seriesType, clipPathBySeriesType) {
|
|
|
33
34
|
export async function getShapes(args) {
|
|
34
35
|
const { boundsWidth, boundsHeight, clipPathId, clipPathBySeriesType, dispatcher, htmlLayout, isOutsideBounds = IS_OUTSIDE_BOUNDS, isRangeSlider, series, seriesOptions, split, xAxis, xScale, yAxis, yScale, zoomState, } = args;
|
|
35
36
|
const visibleSeries = getOnlyVisibleSeries(series);
|
|
36
|
-
const groupedSeries = group(visibleSeries, (item) =>
|
|
37
|
+
const groupedSeries = group(visibleSeries, (item) => {
|
|
38
|
+
if (item.type === 'line') {
|
|
39
|
+
return item.id;
|
|
40
|
+
}
|
|
41
|
+
return item.type;
|
|
42
|
+
});
|
|
37
43
|
const shapesData = [];
|
|
38
44
|
const shapes = [];
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
const layers = [];
|
|
46
|
+
const groupedSeriesItems = Array.from(groupedSeries);
|
|
47
|
+
for (let index = groupedSeriesItems.length - 1; index >= 0; index--) {
|
|
48
|
+
const item = groupedSeriesItems[index];
|
|
49
|
+
const [groupId, chartSeries] = item;
|
|
50
|
+
const seriesType = chartSeries[0].type;
|
|
41
51
|
switch (seriesType) {
|
|
42
52
|
case SERIES_TYPE.BarX: {
|
|
43
53
|
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
@@ -54,6 +64,7 @@ export async function getShapes(args) {
|
|
|
54
64
|
});
|
|
55
65
|
shapes[index] = (React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
56
66
|
shapesData.splice(index, 0, ...preparedData);
|
|
67
|
+
layers.push(...preparedData);
|
|
57
68
|
}
|
|
58
69
|
break;
|
|
59
70
|
}
|
|
@@ -100,14 +111,16 @@ export async function getShapes(args) {
|
|
|
100
111
|
split,
|
|
101
112
|
isOutsideBounds,
|
|
102
113
|
isRangeSlider,
|
|
114
|
+
otherLayers: layers,
|
|
103
115
|
});
|
|
104
116
|
const resultClipPathId = getSeriesClipPathId({
|
|
105
117
|
clipPathId,
|
|
106
118
|
yAxis,
|
|
107
119
|
zoomState,
|
|
108
120
|
});
|
|
109
|
-
shapes[index] = (React.createElement(LineSeriesShapes, { key:
|
|
121
|
+
shapes[index] = (React.createElement(LineSeriesShapes, { key: groupId, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: resultClipPathId }));
|
|
110
122
|
shapesData.splice(index, 0, ...preparedData);
|
|
123
|
+
layers.push(...preparedData);
|
|
111
124
|
}
|
|
112
125
|
break;
|
|
113
126
|
}
|
|
@@ -125,6 +138,7 @@ export async function getShapes(args) {
|
|
|
125
138
|
});
|
|
126
139
|
shapes[index] = (React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
127
140
|
shapesData.splice(index, 0, ...preparedData);
|
|
141
|
+
layers.push(...preparedData);
|
|
128
142
|
}
|
|
129
143
|
break;
|
|
130
144
|
}
|
|
@@ -211,13 +225,29 @@ export async function getShapes(args) {
|
|
|
211
225
|
shapesData.splice(index, 0, preparedData);
|
|
212
226
|
break;
|
|
213
227
|
}
|
|
228
|
+
case SERIES_TYPE.XRange: {
|
|
229
|
+
if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
|
|
230
|
+
const preparedData = await prepareXRangeData({
|
|
231
|
+
series: chartSeries,
|
|
232
|
+
xAxis,
|
|
233
|
+
xScale,
|
|
234
|
+
yAxis,
|
|
235
|
+
yScale,
|
|
236
|
+
boundsWidth,
|
|
237
|
+
isRangeSlider,
|
|
238
|
+
});
|
|
239
|
+
shapes[index] = (React.createElement(XRangeSeriesShapes, { key: SERIES_TYPE.XRange, dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout, clipPathId: clipPathId }));
|
|
240
|
+
shapesData.splice(index, 0, ...preparedData);
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
214
244
|
default: {
|
|
215
245
|
throw new ChartError({
|
|
216
246
|
message: `The display method is not defined for a series with type "${seriesType}"`,
|
|
217
247
|
});
|
|
218
248
|
}
|
|
219
249
|
}
|
|
220
|
-
}
|
|
250
|
+
}
|
|
221
251
|
return { shapes, shapesData };
|
|
222
252
|
}
|
|
223
253
|
export const useShapes = (args) => {
|
|
@@ -3,7 +3,7 @@ import { color } from 'd3-color';
|
|
|
3
3
|
import { select } from 'd3-selection';
|
|
4
4
|
import { line as lineGenerator } from 'd3-shape';
|
|
5
5
|
import get from 'lodash/get';
|
|
6
|
-
import {
|
|
6
|
+
import { getLineDashArray } from '../../../core/utils';
|
|
7
7
|
import { block } from '../../../utils';
|
|
8
8
|
import { HtmlLayer } from '../HtmlLayer';
|
|
9
9
|
import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
|
|
@@ -15,9 +15,6 @@ export const LineSeriesShapes = (args) => {
|
|
|
15
15
|
const plotRef = React.useRef(null);
|
|
16
16
|
const markersRef = React.useRef(null);
|
|
17
17
|
const hoverMarkersRef = React.useRef(null);
|
|
18
|
-
const allowOverlapDataLabels = React.useMemo(() => {
|
|
19
|
-
return preparedData.some((d) => d === null || d === void 0 ? void 0 : d.series.dataLabels.allowOverlap);
|
|
20
|
-
}, [preparedData]);
|
|
21
18
|
React.useEffect(() => {
|
|
22
19
|
if (!plotRef.current || !markersRef.current) {
|
|
23
20
|
return () => { };
|
|
@@ -46,12 +43,9 @@ export const LineSeriesShapes = (args) => {
|
|
|
46
43
|
.attr('stroke-dasharray', (d) => getLineDashArray(d.dashStyle, d.lineWidth))
|
|
47
44
|
.attr('opacity', (d) => d.opacity)
|
|
48
45
|
.attr('cursor', (d) => d.series.cursor);
|
|
49
|
-
|
|
50
|
-
return acc.concat(d.
|
|
46
|
+
const dataLabels = preparedData.reduce((acc, d) => {
|
|
47
|
+
return acc.concat(d.svgLabels);
|
|
51
48
|
}, []);
|
|
52
|
-
if (!allowOverlapDataLabels) {
|
|
53
|
-
dataLabels = filterOverlappingLabels(dataLabels);
|
|
54
|
-
}
|
|
55
49
|
const labelsSelection = plotSvgElement
|
|
56
50
|
.selectAll('text')
|
|
57
51
|
.data(dataLabels)
|
|
@@ -175,14 +169,11 @@ export const LineSeriesShapes = (args) => {
|
|
|
175
169
|
return () => {
|
|
176
170
|
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.line', null);
|
|
177
171
|
};
|
|
178
|
-
}, [
|
|
172
|
+
}, [dispatcher, preparedData, seriesOptions]);
|
|
179
173
|
const htmlLayerData = React.useMemo(() => {
|
|
180
|
-
const items = preparedData.map((d) => d === null || d === void 0 ? void 0 : d.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
return { htmlElements: filterOverlappingLabels(items) };
|
|
185
|
-
}, [allowOverlapDataLabels, preparedData]);
|
|
174
|
+
const items = preparedData.map((d) => d === null || d === void 0 ? void 0 : d.htmlLabels).flat();
|
|
175
|
+
return { htmlElements: items };
|
|
176
|
+
}, [preparedData]);
|
|
186
177
|
return (React.createElement(React.Fragment, null,
|
|
187
178
|
React.createElement("g", { ref: plotRef, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
188
179
|
React.createElement("g", { ref: markersRef }),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PreparedSplit } from '../../../core/layout/split-types';
|
|
2
2
|
import type { ChartScale } from '../../../core/scales/types';
|
|
3
|
+
import type { ShapeDataWithLabels } from '../../../types';
|
|
3
4
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
4
5
|
import type { PreparedLineSeries } from '../../useSeries/types';
|
|
5
6
|
import type { PreparedLineData } from './types';
|
|
@@ -12,4 +13,5 @@ export declare const prepareLineData: (args: {
|
|
|
12
13
|
split: PreparedSplit;
|
|
13
14
|
isOutsideBounds: (x: number, y: number) => boolean;
|
|
14
15
|
isRangeSlider?: boolean;
|
|
16
|
+
otherLayers: ShapeDataWithLabels[];
|
|
15
17
|
}) => Promise<PreparedLineData[]>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getLabelsSize, getTextSizeFn } from '../../../core/utils';
|
|
1
|
+
import { filterOverlappingLabels, getLabelsSize, getTextSizeFn } from '../../../core/utils';
|
|
2
2
|
import { getFormattedValue } from '../../../core/utils/format';
|
|
3
3
|
import { getXValue, getYValue } from '../utils';
|
|
4
4
|
async function getHtmlLabel(point, series, xMax) {
|
|
@@ -16,7 +16,7 @@ async function getHtmlLabel(point, series, xMax) {
|
|
|
16
16
|
}
|
|
17
17
|
export const prepareLineData = async (args) => {
|
|
18
18
|
var _a, _b, _c, _d;
|
|
19
|
-
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider } = args;
|
|
19
|
+
const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
|
|
20
20
|
const [_xMin, xRangeMax] = xScale.range();
|
|
21
21
|
const xMax = xRangeMax;
|
|
22
22
|
const acc = [];
|
|
@@ -44,8 +44,8 @@ export const prepareLineData = async (args) => {
|
|
|
44
44
|
series: s,
|
|
45
45
|
};
|
|
46
46
|
});
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
let htmlElements = [];
|
|
48
|
+
let svgLabels = [];
|
|
49
49
|
if (s.dataLabels.enabled && !isRangeSlider) {
|
|
50
50
|
if (s.dataLabels.html) {
|
|
51
51
|
const list = await Promise.all(points.reduce((result, p) => {
|
|
@@ -83,11 +83,15 @@ export const prepareLineData = async (args) => {
|
|
|
83
83
|
series: s,
|
|
84
84
|
active: true,
|
|
85
85
|
};
|
|
86
|
-
|
|
86
|
+
svgLabels.push(labelData);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
if (!s.dataLabels.allowOverlap) {
|
|
92
|
+
svgLabels = filterOverlappingLabels(svgLabels, otherLayers.map((l) => l.svgLabels).flat());
|
|
93
|
+
htmlElements = filterOverlappingLabels(htmlElements, otherLayers.map((l) => l.htmlLabels).flat());
|
|
94
|
+
}
|
|
91
95
|
let markers = [];
|
|
92
96
|
const hasPerPointNormalMarkers = s.data.some((d) => { var _a, _b, _c; return (_c = (_b = (_a = d.marker) === null || _a === void 0 ? void 0 : _a.states) === null || _b === void 0 ? void 0 : _b.normal) === null || _c === void 0 ? void 0 : _c.enabled; });
|
|
93
97
|
if (s.marker.states.normal.enabled || hasPerPointNormalMarkers) {
|
|
@@ -111,12 +115,12 @@ export const prepareLineData = async (args) => {
|
|
|
111
115
|
const result = {
|
|
112
116
|
points,
|
|
113
117
|
markers,
|
|
114
|
-
|
|
118
|
+
svgLabels: svgLabels,
|
|
115
119
|
series: s,
|
|
116
120
|
hovered: false,
|
|
117
121
|
active: true,
|
|
118
122
|
id: s.id,
|
|
119
|
-
htmlElements,
|
|
123
|
+
htmlLabels: htmlElements,
|
|
120
124
|
color: s.color,
|
|
121
125
|
lineWidth: (_c = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _c !== void 0 ? _c : s.lineWidth,
|
|
122
126
|
dashStyle: s.dashStyle,
|
|
@@ -25,8 +25,8 @@ export type PreparedLineData = {
|
|
|
25
25
|
series: PreparedLineSeries;
|
|
26
26
|
hovered: boolean;
|
|
27
27
|
active: boolean;
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
svgLabels: LabelData[];
|
|
29
|
+
htmlLabels: HtmlItem[];
|
|
30
30
|
color: string;
|
|
31
31
|
dashStyle: DashStyle;
|
|
32
32
|
linecap: LineCap;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Dispatch } from 'd3-dispatch';
|
|
3
|
+
import type { PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
|
+
export { prepareXRangeData } from './prepare-data';
|
|
5
|
+
export type { PreparedXRangeData } from './types';
|
|
6
|
+
import type { PreparedXRangeData } from './types';
|
|
7
|
+
type Args = {
|
|
8
|
+
clipPathId: string;
|
|
9
|
+
htmlLayout: HTMLElement | null;
|
|
10
|
+
preparedData: PreparedXRangeData[];
|
|
11
|
+
seriesOptions: PreparedSeriesOptions;
|
|
12
|
+
dispatcher?: Dispatch<object>;
|
|
13
|
+
};
|
|
14
|
+
export declare function XRangeSeriesShapes(args: Args): React.JSX.Element;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { color } from 'd3-color';
|
|
3
|
+
import { select } from 'd3-selection';
|
|
4
|
+
import get from 'lodash/get';
|
|
5
|
+
import { getLineDashArray } from '../../../core/utils';
|
|
6
|
+
import { block } from '../../../utils';
|
|
7
|
+
import { HtmlLayer } from '../HtmlLayer';
|
|
8
|
+
import { getRectPath } from '../utils';
|
|
9
|
+
export { prepareXRangeData } from './prepare-data';
|
|
10
|
+
const b = block('x-range');
|
|
11
|
+
export function XRangeSeriesShapes(args) {
|
|
12
|
+
const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
|
|
13
|
+
const hoveredDataRef = React.useRef(null);
|
|
14
|
+
const ref = React.useRef(null);
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
var _a;
|
|
17
|
+
if (!ref.current) {
|
|
18
|
+
return () => { };
|
|
19
|
+
}
|
|
20
|
+
const svgElement = select(ref.current);
|
|
21
|
+
svgElement.selectAll('*').remove();
|
|
22
|
+
const segmentSelection = svgElement
|
|
23
|
+
.selectAll(`path.${b('segment')}`)
|
|
24
|
+
.data(preparedData)
|
|
25
|
+
.join('path')
|
|
26
|
+
.attr('d', (d) => {
|
|
27
|
+
const borderRadius = Math.min(d.height / 2, d.width / 2, d.series.borderRadius);
|
|
28
|
+
return getRectPath({
|
|
29
|
+
x: d.x,
|
|
30
|
+
y: d.y,
|
|
31
|
+
width: d.width,
|
|
32
|
+
height: d.height,
|
|
33
|
+
borderRadius,
|
|
34
|
+
}).toString();
|
|
35
|
+
})
|
|
36
|
+
.attr('class', b('segment'))
|
|
37
|
+
.attr('fill', (d) => d.color)
|
|
38
|
+
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
39
|
+
.attr('cursor', (d) => d.series.cursor);
|
|
40
|
+
svgElement
|
|
41
|
+
.selectAll(`path.${b('segment-border')}`)
|
|
42
|
+
.data(preparedData.filter((d) => d.series.borderWidth > 0))
|
|
43
|
+
.join('path')
|
|
44
|
+
.attr('d', (d) => {
|
|
45
|
+
const borderRadius = Math.min(d.height / 2, d.width / 2, d.series.borderRadius);
|
|
46
|
+
return getRectPath({
|
|
47
|
+
x: d.x,
|
|
48
|
+
y: d.y,
|
|
49
|
+
width: d.width,
|
|
50
|
+
height: d.height,
|
|
51
|
+
borderRadius,
|
|
52
|
+
}).toString();
|
|
53
|
+
})
|
|
54
|
+
.attr('class', b('segment-border'))
|
|
55
|
+
.attr('fill', 'none')
|
|
56
|
+
.attr('stroke', (d) => d.series.borderColor)
|
|
57
|
+
.attr('stroke-width', (d) => d.series.borderWidth)
|
|
58
|
+
.attr('stroke-dasharray', (d) => getLineDashArray(d.series.borderDashStyle, d.series.borderWidth))
|
|
59
|
+
.attr('opacity', (d) => { var _a; return (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity; })
|
|
60
|
+
.attr('pointer-events', 'none');
|
|
61
|
+
const svgLabels = preparedData.flatMap((d) => d.svgLabels);
|
|
62
|
+
svgElement
|
|
63
|
+
.selectAll(`text.${b('label')}`)
|
|
64
|
+
.data(svgLabels)
|
|
65
|
+
.join('text')
|
|
66
|
+
.attr('class', b('label'))
|
|
67
|
+
.attr('x', (d) => d.x)
|
|
68
|
+
.attr('y', (d) => d.y)
|
|
69
|
+
.attr('text-anchor', (d) => d.textAnchor)
|
|
70
|
+
.attr('dominant-baseline', 'central')
|
|
71
|
+
.attr('pointer-events', 'none')
|
|
72
|
+
.style('font-size', (d) => d.style.fontSize)
|
|
73
|
+
.style('font-weight', (d) => d.style.fontWeight || null)
|
|
74
|
+
.style('fill', (d) => d.style.fontColor || null)
|
|
75
|
+
.html((d) => d.text);
|
|
76
|
+
const hoverOptions = get(seriesOptions, 'x-range.states.hover');
|
|
77
|
+
const inactiveOptions = get(seriesOptions, 'x-range.states.inactive');
|
|
78
|
+
function handleShapeHover(data) {
|
|
79
|
+
hoveredDataRef.current = data;
|
|
80
|
+
if (hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled) {
|
|
81
|
+
const hoveredSet = new Set(data === null || data === void 0 ? void 0 : data.map((d) => d.data));
|
|
82
|
+
segmentSelection.attr('fill', (d) => {
|
|
83
|
+
var _a;
|
|
84
|
+
const fillColor = d.color;
|
|
85
|
+
if (hoveredSet.has(d.data)) {
|
|
86
|
+
return (((_a = color(fillColor)) === null || _a === void 0 ? void 0 : _a.brighter(hoverOptions.brightness).toString()) ||
|
|
87
|
+
fillColor);
|
|
88
|
+
}
|
|
89
|
+
return fillColor;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled) {
|
|
93
|
+
const hoveredSeries = data === null || data === void 0 ? void 0 : data.map((d) => d.series.id);
|
|
94
|
+
segmentSelection.attr('opacity', (d) => {
|
|
95
|
+
var _a, _b;
|
|
96
|
+
if ((hoveredSeries === null || hoveredSeries === void 0 ? void 0 : hoveredSeries.length) && !hoveredSeries.includes(d.series.id)) {
|
|
97
|
+
return inactiveOptions.opacity || null;
|
|
98
|
+
}
|
|
99
|
+
return (_b = (_a = d.data.opacity) !== null && _a !== void 0 ? _a : d.series.opacity) !== null && _b !== void 0 ? _b : null;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (hoveredDataRef.current !== null) {
|
|
104
|
+
handleShapeHover((_a = hoveredDataRef.current) !== null && _a !== void 0 ? _a : undefined);
|
|
105
|
+
}
|
|
106
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.x-range', handleShapeHover);
|
|
107
|
+
return () => {
|
|
108
|
+
dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.x-range', null);
|
|
109
|
+
};
|
|
110
|
+
}, [dispatcher, preparedData, seriesOptions]);
|
|
111
|
+
const htmlLayerData = React.useMemo(() => ({ htmlElements: preparedData.flatMap((d) => d.htmlLabels) }), [preparedData]);
|
|
112
|
+
return (React.createElement(React.Fragment, null,
|
|
113
|
+
React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
|
|
114
|
+
React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
|
|
115
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChartScale } from '../../../core/scales/types';
|
|
2
|
+
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
3
|
+
import type { PreparedXRangeSeries } from '../../useSeries/types';
|
|
4
|
+
import type { PreparedXRangeData } from './types';
|
|
5
|
+
type PrepareXRangeDataArgs = {
|
|
6
|
+
series: PreparedXRangeSeries[];
|
|
7
|
+
xAxis: PreparedXAxis;
|
|
8
|
+
xScale: ChartScale;
|
|
9
|
+
yAxis: PreparedYAxis[];
|
|
10
|
+
yScale: (ChartScale | undefined)[];
|
|
11
|
+
boundsWidth?: number;
|
|
12
|
+
isRangeSlider?: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function prepareXRangeData(args: PrepareXRangeDataArgs): Promise<PreparedXRangeData[]>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import get from 'lodash/get';
|
|
2
|
+
import { getDataCategoryValue, getLabelsSize, getTextSizeFn, getTextWithElipsis } from '../../../core/utils';
|
|
3
|
+
import { getFormattedValue } from '../../../core/utils/format';
|
|
4
|
+
import { MIN_BAR_WIDTH } from '../../constants';
|
|
5
|
+
import { getBandSize } from '../../utils/get-band-size';
|
|
6
|
+
const DEFAULT_BAR_PADDING = 0.2;
|
|
7
|
+
export async function prepareXRangeData(args) {
|
|
8
|
+
var _a;
|
|
9
|
+
const { series, xAxis, xScale, yAxis, yScale: [yScale], boundsWidth, isRangeSlider, } = args;
|
|
10
|
+
if (!yScale) {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
// Collect unique y-domain values
|
|
14
|
+
const domain = [];
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
const categories = get(yAxis[0], 'categories', []);
|
|
17
|
+
series.forEach((s) => {
|
|
18
|
+
s.data.forEach((d) => {
|
|
19
|
+
const key = yAxis[0].type === 'category'
|
|
20
|
+
? getDataCategoryValue({ axisDirection: 'y', categories, data: d })
|
|
21
|
+
: d.y;
|
|
22
|
+
if (key !== undefined && !seen.has(key)) {
|
|
23
|
+
seen.add(key);
|
|
24
|
+
domain.push(key);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
const bandSize = getBandSize({ domain, scale: yScale });
|
|
29
|
+
const barSize = Math.max(MIN_BAR_WIDTH, bandSize * (1 - DEFAULT_BAR_PADDING));
|
|
30
|
+
const result = [];
|
|
31
|
+
series.forEach((s) => {
|
|
32
|
+
s.data.forEach((d) => {
|
|
33
|
+
let center;
|
|
34
|
+
if (yAxis[0].type === 'category') {
|
|
35
|
+
const bandScale = yScale;
|
|
36
|
+
const yCategory = getDataCategoryValue({ axisDirection: 'y', categories, data: d });
|
|
37
|
+
if (!bandScale.domain().includes(yCategory)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
center = (bandScale(yCategory) || 0) + bandSize / 2;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const linearScale = yScale;
|
|
44
|
+
if (d.y === undefined) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
center = linearScale(Number(d.y));
|
|
48
|
+
}
|
|
49
|
+
let xStart;
|
|
50
|
+
let xEnd;
|
|
51
|
+
if (xAxis.type === 'category') {
|
|
52
|
+
// x-range on a category x-axis is unusual but supported
|
|
53
|
+
const xBandScale = xScale;
|
|
54
|
+
const xCategories = get(xAxis, 'categories', []);
|
|
55
|
+
const startCategory = getDataCategoryValue({
|
|
56
|
+
axisDirection: 'x',
|
|
57
|
+
categories: xCategories,
|
|
58
|
+
data: { x: d.x0 },
|
|
59
|
+
});
|
|
60
|
+
const endCategory = getDataCategoryValue({
|
|
61
|
+
axisDirection: 'x',
|
|
62
|
+
categories: xCategories,
|
|
63
|
+
data: { x: d.x1 },
|
|
64
|
+
});
|
|
65
|
+
xStart = xBandScale(startCategory) || 0;
|
|
66
|
+
xEnd = (xBandScale(endCategory) || 0) + xBandScale.bandwidth();
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
const linearScale = xScale;
|
|
70
|
+
xStart = linearScale(Number(d.x0));
|
|
71
|
+
xEnd = linearScale(Number(d.x1));
|
|
72
|
+
}
|
|
73
|
+
const width = xEnd - xStart;
|
|
74
|
+
if (width <= 0) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
result.push({
|
|
78
|
+
x: xStart,
|
|
79
|
+
y: center - barSize / 2,
|
|
80
|
+
width,
|
|
81
|
+
height: barSize,
|
|
82
|
+
color: d.color || s.color,
|
|
83
|
+
data: d,
|
|
84
|
+
series: s,
|
|
85
|
+
htmlLabels: [],
|
|
86
|
+
svgLabels: [],
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
const textSizeFnCache = new Map();
|
|
91
|
+
for (let i = 0; i < result.length; i++) {
|
|
92
|
+
const item = result[i];
|
|
93
|
+
const { dataLabels } = item.series;
|
|
94
|
+
if (!dataLabels.enabled || item.data.label === null || isRangeSlider) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const content = getFormattedValue(Object.assign({ value: item.data.label }, dataLabels));
|
|
98
|
+
const visibleStart = Math.max(0, item.x);
|
|
99
|
+
const visibleEnd = boundsWidth === undefined
|
|
100
|
+
? item.x + item.width
|
|
101
|
+
: Math.min(boundsWidth, item.x + item.width);
|
|
102
|
+
const visibleWidth = visibleEnd - visibleStart;
|
|
103
|
+
const visibleCenterX = visibleStart + visibleWidth / 2;
|
|
104
|
+
if (dataLabels.html) {
|
|
105
|
+
const { maxHeight: height, maxWidth: width } = await getLabelsSize({
|
|
106
|
+
labels: [content],
|
|
107
|
+
style: dataLabels.style,
|
|
108
|
+
html: true,
|
|
109
|
+
});
|
|
110
|
+
const htmlItem = {
|
|
111
|
+
content,
|
|
112
|
+
size: { width, height },
|
|
113
|
+
style: dataLabels.style,
|
|
114
|
+
x: visibleCenterX - width / 2,
|
|
115
|
+
y: item.y + item.height / 2 - height / 2,
|
|
116
|
+
};
|
|
117
|
+
item.htmlLabels.push(htmlItem);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
if (!textSizeFnCache.has(dataLabels.style)) {
|
|
121
|
+
textSizeFnCache.set(dataLabels.style, getTextSizeFn({ style: dataLabels.style }));
|
|
122
|
+
}
|
|
123
|
+
const getTextSize = (_a = textSizeFnCache.get(dataLabels.style)) !== null && _a !== void 0 ? _a : getTextSizeFn({ style: dataLabels.style });
|
|
124
|
+
const availableWidth = Math.max(0, visibleWidth - 2 * dataLabels.padding);
|
|
125
|
+
const text = await getTextWithElipsis({
|
|
126
|
+
text: content,
|
|
127
|
+
getTextWidth: (s) => getTextSize(s).then((r) => r.width),
|
|
128
|
+
maxWidth: availableWidth,
|
|
129
|
+
});
|
|
130
|
+
if (!text) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const { width, height, hangingOffset } = await getTextSize(text);
|
|
134
|
+
const svgItem = {
|
|
135
|
+
text,
|
|
136
|
+
size: { width, height, hangingOffset },
|
|
137
|
+
style: dataLabels.style,
|
|
138
|
+
textAnchor: 'middle',
|
|
139
|
+
x: visibleCenterX,
|
|
140
|
+
y: item.y + item.height / 2,
|
|
141
|
+
series: item.series,
|
|
142
|
+
};
|
|
143
|
+
item.svgLabels.push(svgItem);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HtmlItem, LabelData, TooltipDataChunkXRange } from '../../../types';
|
|
2
|
+
import type { PreparedXRangeSeries } from '../../useSeries/types';
|
|
3
|
+
export type PreparedXRangeData = Omit<TooltipDataChunkXRange, 'series'> & {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
color: string;
|
|
9
|
+
series: PreparedXRangeSeries;
|
|
10
|
+
svgLabels: LabelData[];
|
|
11
|
+
htmlLabels: HtmlItem[];
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -25,6 +25,10 @@ export interface HtmlItem {
|
|
|
25
25
|
};
|
|
26
26
|
style?: BaseTextStyle & React.CSSProperties;
|
|
27
27
|
}
|
|
28
|
+
export interface ShapeDataWithLabels {
|
|
29
|
+
svgLabels: LabelData[];
|
|
30
|
+
htmlLabels: HtmlItem[];
|
|
31
|
+
}
|
|
28
32
|
export interface ShapeDataWithHtmlItems {
|
|
29
33
|
htmlElements: HtmlItem[];
|
|
30
34
|
}
|
|
@@ -71,7 +71,7 @@ export const ChartInner = (props) => {
|
|
|
71
71
|
value: allPreparedSeries,
|
|
72
72
|
delay: DEBOUNCED_VALUE_DELAY,
|
|
73
73
|
});
|
|
74
|
-
const { handleChartClick,
|
|
74
|
+
const { handleChartClick, handlePointerLeave, throttledHandlePointerMove, throttledHandleTouchMove, } = useChartInnerHandlers({
|
|
75
75
|
boundsHeight,
|
|
76
76
|
boundsOffsetLeft,
|
|
77
77
|
boundsOffsetTop,
|
|
@@ -256,7 +256,7 @@ export const ChartInner = (props) => {
|
|
|
256
256
|
React.createElement("rect", { x: 0, y: 0, width: boundsWidth, height: boundsHeight })),
|
|
257
257
|
React.createElement("clipPath", { id: getClipPathIdByBounds({ clipPathId, bounds: 'horizontal' }) },
|
|
258
258
|
React.createElement("rect", { x: 0, y: -boundsHeight, width: boundsWidth, height: boundsHeight * 3 }))),
|
|
259
|
-
preparedTitle && React.createElement(Title, Object.assign({}, preparedTitle
|
|
259
|
+
preparedTitle && React.createElement(Title, Object.assign({}, preparedTitle)),
|
|
260
260
|
React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit === null || preparedSplit === void 0 ? void 0 : preparedSplit.plots.map((plot, index) => {
|
|
261
261
|
return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
|
|
262
262
|
})),
|
|
@@ -283,7 +283,7 @@ export const ChartInner = (props) => {
|
|
|
283
283
|
React.createElement("svg", { ref: svgRef, width: width, height: height,
|
|
284
284
|
// We use onPointerMove here because onMouseMove works incorrectly when the zoom setting is enabled:
|
|
285
285
|
// when starting to select an area, the tooltip remains in the position where the selection began
|
|
286
|
-
onPointerMove:
|
|
286
|
+
onPointerMove: throttledHandlePointerMove, onPointerLeave: handlePointerLeave, onTouchStart: throttledHandleTouchMove, onTouchMove: throttledHandleTouchMove, onClick: handleChartClick }, initialized ? chartContent : null),
|
|
287
287
|
React.createElement("div", { className: b('html-layer'), ref: setHtmlLayout, style: {
|
|
288
288
|
'--g-html-layout-transform': `translate(${boundsOffsetLeft}px, ${boundsOffsetTop}px)`,
|
|
289
289
|
} }),
|
|
@@ -23,8 +23,8 @@ type Props = {
|
|
|
23
23
|
};
|
|
24
24
|
export declare function useChartInnerHandlers(props: Props): {
|
|
25
25
|
handleChartClick: (event: React.MouseEvent<SVGSVGElement>) => void;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throttledHandleTouchMove: import("lodash").DebouncedFuncLeading<React.TouchEventHandler<SVGSVGElement
|
|
26
|
+
handlePointerLeave: React.PointerEventHandler<SVGSVGElement>;
|
|
27
|
+
throttledHandlePointerMove: import("lodash").DebouncedFuncLeading<React.PointerEventHandler<SVGSVGElement>>;
|
|
28
|
+
throttledHandleTouchMove: import("lodash").DebouncedFuncLeading<React.TouchEventHandler<SVGSVGElement>>;
|
|
29
29
|
};
|
|
30
30
|
export {};
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import { pointer } from 'd3-selection';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import throttle from 'lodash/throttle';
|
|
5
|
-
import { IS_TOUCH_ENABLED } from '../../core/constants';
|
|
6
5
|
import { EventType } from '../../core/utils';
|
|
7
6
|
import { getClosestPoints } from '../../core/utils/get-closest-data';
|
|
8
7
|
import { getHoveredPlots } from '../../core/utils/get-hovered-plots';
|
|
@@ -47,18 +46,19 @@ export function useChartInnerHandlers(props) {
|
|
|
47
46
|
hoveredPlotBands: plotBands,
|
|
48
47
|
}, event);
|
|
49
48
|
};
|
|
50
|
-
const
|
|
49
|
+
const handlePointerMove = (event) => {
|
|
50
|
+
if (event.pointerType === 'touch') {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
51
53
|
const [pointerX, pointerY] = pointer(event, svgContainer);
|
|
52
54
|
handleMove([pointerX, pointerY], event);
|
|
53
55
|
};
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
: throttle(handleMouseMove, tooltipThrottle);
|
|
57
|
-
const handleMouseLeave = (event) => {
|
|
56
|
+
const throttledHandlePointerMove = throttle(handlePointerMove, tooltipThrottle);
|
|
57
|
+
const handlePointerLeave = (event) => {
|
|
58
58
|
if (tooltipPinned) {
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
throttledHandlePointerMove.cancel();
|
|
62
62
|
dispatcher.call(EventType.HOVER_SHAPE, {}, undefined);
|
|
63
63
|
dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
|
|
64
64
|
};
|
|
@@ -67,9 +67,7 @@ export function useChartInnerHandlers(props) {
|
|
|
67
67
|
const [pointerX, pointerY] = pointer(touch, svgContainer);
|
|
68
68
|
handleMove([pointerX, pointerY], event);
|
|
69
69
|
};
|
|
70
|
-
const throttledHandleTouchMove =
|
|
71
|
-
? throttle(handleTouchMove, tooltipThrottle)
|
|
72
|
-
: undefined;
|
|
70
|
+
const throttledHandleTouchMove = throttle(handleTouchMove, tooltipThrottle);
|
|
73
71
|
const handleChartClick = (event) => {
|
|
74
72
|
const [pointerX, pointerY] = pointer(event, svgContainer);
|
|
75
73
|
const x = pointerX - boundsOffsetLeft;
|
|
@@ -116,8 +114,8 @@ export function useChartInnerHandlers(props) {
|
|
|
116
114
|
};
|
|
117
115
|
return {
|
|
118
116
|
handleChartClick,
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
handlePointerLeave,
|
|
118
|
+
throttledHandlePointerMove,
|
|
121
119
|
throttledHandleTouchMove,
|
|
122
120
|
};
|
|
123
121
|
}
|