@gravity-ui/charts 1.51.1 → 1.51.5
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/index.js +25 -17
- package/dist/cjs/core/series/plugin.d.ts +14 -0
- package/dist/cjs/core/series/plugin.js +1 -0
- package/dist/cjs/core/series/prepareSeries.d.ts +3 -10
- package/dist/cjs/core/series/prepareSeries.js +3 -126
- package/dist/cjs/core/series/seriesRegistry.d.ts +3 -0
- package/dist/cjs/core/series/seriesRegistry.js +12 -0
- package/dist/cjs/core/shapes/area/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/area/get-tooltip-data.js +19 -0
- package/dist/cjs/core/shapes/bar-x/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/bar-x/get-tooltip-data.js +20 -0
- package/dist/cjs/core/shapes/bar-y/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/bar-y/get-tooltip-data.js +32 -0
- package/dist/cjs/core/shapes/funnel/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/funnel/get-tooltip-data.js +21 -0
- package/dist/cjs/core/shapes/funnel/prepare-data.js +6 -4
- package/dist/cjs/core/shapes/heatmap/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/heatmap/get-tooltip-data.js +21 -0
- package/dist/cjs/core/shapes/line/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/line/get-tooltip-data.js +18 -0
- package/dist/cjs/core/shapes/pie/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/pie/get-tooltip-data.js +27 -0
- package/dist/cjs/core/shapes/radar/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/radar/get-tooltip-data.js +35 -0
- package/dist/cjs/core/shapes/sankey/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/sankey/get-tooltip-data.js +32 -0
- package/dist/cjs/core/shapes/scatter/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/scatter/get-tooltip-data.js +19 -0
- package/dist/cjs/core/shapes/treemap/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/treemap/get-tooltip-data.js +18 -0
- package/dist/cjs/core/shapes/waterfall/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/waterfall/get-tooltip-data.js +15 -0
- package/dist/cjs/core/shapes/x-range/get-tooltip-data.d.ts +3 -0
- package/dist/cjs/core/shapes/x-range/get-tooltip-data.js +22 -0
- package/dist/cjs/core/types/chart/funnel.d.ts +9 -4
- package/dist/cjs/core/utils/get-closest-data.d.ts +2 -11
- package/dist/cjs/core/utils/get-closest-data.js +47 -326
- package/dist/cjs/core/utils/tooltip-helpers.d.ts +43 -0
- package/dist/cjs/core/utils/tooltip-helpers.js +72 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/plugins/area/index.d.ts +3 -0
- package/dist/cjs/plugins/area/index.js +5 -0
- package/dist/cjs/{core/series/prepare-area.d.ts → plugins/area/prepare.d.ts} +2 -2
- package/dist/cjs/{core/series/prepare-area.js → plugins/area/prepare.js} +4 -4
- package/dist/cjs/plugins/bar-x/index.d.ts +3 -0
- package/dist/cjs/plugins/bar-x/index.js +5 -0
- package/dist/{esm/core/series/prepare-bar-x.d.ts → cjs/plugins/bar-x/prepare.d.ts} +1 -1
- package/dist/{esm/core/series/prepare-bar-x.js → cjs/plugins/bar-x/prepare.js} +4 -4
- package/dist/cjs/plugins/bar-y/index.d.ts +3 -0
- package/dist/cjs/plugins/bar-y/index.js +5 -0
- package/dist/cjs/{core/series/prepare-bar-y.d.ts → plugins/bar-y/prepare.d.ts} +2 -2
- package/dist/cjs/{core/series/prepare-bar-y.js → plugins/bar-y/prepare.js} +4 -4
- package/dist/cjs/plugins/funnel/index.d.ts +3 -0
- package/dist/cjs/plugins/funnel/index.js +5 -0
- package/dist/cjs/{core/series/prepare-funnel.d.ts → plugins/funnel/prepare.d.ts} +2 -2
- package/dist/{esm/core/series/prepare-funnel.js → cjs/plugins/funnel/prepare.js} +15 -9
- package/dist/cjs/plugins/heatmap/index.d.ts +3 -0
- package/dist/cjs/plugins/heatmap/index.js +10 -0
- package/dist/{esm/core/series/prepare-heatmap.d.ts → cjs/plugins/heatmap/prepare.d.ts} +1 -1
- package/dist/{esm/core/series/prepare-heatmap.js → cjs/plugins/heatmap/prepare.js} +4 -4
- package/dist/cjs/plugins/index.d.ts +1 -0
- package/dist/cjs/plugins/index.js +27 -0
- package/dist/cjs/plugins/line/index.d.ts +3 -0
- package/dist/cjs/plugins/line/index.js +5 -0
- package/dist/cjs/{core/series/prepare-line.d.ts → plugins/line/prepare.d.ts} +2 -2
- package/dist/cjs/{core/series/prepare-line.js → plugins/line/prepare.js} +3 -3
- package/dist/cjs/plugins/pie/index.d.ts +3 -0
- package/dist/cjs/plugins/pie/index.js +5 -0
- package/dist/cjs/{core/series/prepare-pie.d.ts → plugins/pie/prepare.d.ts} +2 -2
- package/dist/cjs/plugins/pie/prepare.js +84 -0
- package/dist/cjs/plugins/radar/index.d.ts +3 -0
- package/dist/cjs/plugins/radar/index.js +5 -0
- package/dist/cjs/{core/series/prepare-radar.d.ts → plugins/radar/prepare.d.ts} +2 -2
- package/dist/cjs/{core/series/prepare-radar.js → plugins/radar/prepare.js} +4 -4
- package/dist/cjs/plugins/sankey/index.d.ts +3 -0
- package/dist/cjs/plugins/sankey/index.js +5 -0
- package/dist/cjs/{core/series/prepare-sankey.d.ts → plugins/sankey/prepare.d.ts} +1 -1
- package/dist/cjs/{core/series/prepare-sankey.js → plugins/sankey/prepare.js} +3 -3
- package/dist/cjs/plugins/scatter/index.d.ts +3 -0
- package/dist/cjs/plugins/scatter/index.js +10 -0
- package/dist/cjs/{core/series/prepare-scatter.d.ts → plugins/scatter/prepare.d.ts} +1 -1
- package/dist/{esm/core/series/prepare-scatter.js → cjs/plugins/scatter/prepare.js} +4 -4
- package/dist/cjs/plugins/treemap/index.d.ts +3 -0
- package/dist/cjs/plugins/treemap/index.js +5 -0
- package/dist/{esm/core/series/prepare-treemap.d.ts → cjs/plugins/treemap/prepare.d.ts} +1 -1
- package/dist/cjs/{core/series/prepare-treemap.js → plugins/treemap/prepare.js} +4 -4
- package/dist/cjs/plugins/waterfall/index.d.ts +3 -0
- package/dist/cjs/plugins/waterfall/index.js +5 -0
- package/dist/cjs/{core/series/prepare-waterfall.d.ts → plugins/waterfall/prepare.d.ts} +1 -1
- package/dist/{esm/core/series/prepare-waterfall.js → cjs/plugins/waterfall/prepare.js} +4 -4
- package/dist/cjs/plugins/x-range/index.d.ts +3 -0
- package/dist/cjs/plugins/x-range/index.js +5 -0
- package/dist/cjs/{core/series/prepare-x-range.d.ts → plugins/x-range/prepare.d.ts} +1 -1
- package/dist/cjs/{core/series/prepare-x-range.js → plugins/x-range/prepare.js} +4 -4
- package/dist/cjs/setup-jsdom.d.ts +1 -0
- package/dist/cjs/setup-jsdom.js +30 -4
- package/dist/esm/components/index.js +25 -17
- package/dist/esm/core/series/plugin.d.ts +14 -0
- package/dist/esm/core/series/plugin.js +1 -0
- package/dist/esm/core/series/prepareSeries.d.ts +3 -10
- package/dist/esm/core/series/prepareSeries.js +3 -126
- package/dist/esm/core/series/seriesRegistry.d.ts +3 -0
- package/dist/esm/core/series/seriesRegistry.js +12 -0
- package/dist/esm/core/shapes/area/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/area/get-tooltip-data.js +19 -0
- package/dist/esm/core/shapes/bar-x/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/bar-x/get-tooltip-data.js +20 -0
- package/dist/esm/core/shapes/bar-y/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/bar-y/get-tooltip-data.js +32 -0
- package/dist/esm/core/shapes/funnel/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/funnel/get-tooltip-data.js +21 -0
- package/dist/esm/core/shapes/funnel/prepare-data.js +6 -4
- package/dist/esm/core/shapes/heatmap/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/heatmap/get-tooltip-data.js +21 -0
- package/dist/esm/core/shapes/line/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/line/get-tooltip-data.js +18 -0
- package/dist/esm/core/shapes/pie/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/pie/get-tooltip-data.js +27 -0
- package/dist/esm/core/shapes/radar/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/radar/get-tooltip-data.js +35 -0
- package/dist/esm/core/shapes/sankey/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/sankey/get-tooltip-data.js +32 -0
- package/dist/esm/core/shapes/scatter/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/scatter/get-tooltip-data.js +19 -0
- package/dist/esm/core/shapes/treemap/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/treemap/get-tooltip-data.js +18 -0
- package/dist/esm/core/shapes/waterfall/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/waterfall/get-tooltip-data.js +15 -0
- package/dist/esm/core/shapes/x-range/get-tooltip-data.d.ts +3 -0
- package/dist/esm/core/shapes/x-range/get-tooltip-data.js +22 -0
- package/dist/esm/core/types/chart/funnel.d.ts +9 -4
- package/dist/esm/core/utils/get-closest-data.d.ts +2 -11
- package/dist/esm/core/utils/get-closest-data.js +47 -326
- package/dist/esm/core/utils/tooltip-helpers.d.ts +43 -0
- package/dist/esm/core/utils/tooltip-helpers.js +72 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugins/area/index.d.ts +3 -0
- package/dist/esm/plugins/area/index.js +5 -0
- package/dist/esm/{core/series/prepare-area.d.ts → plugins/area/prepare.d.ts} +2 -2
- package/dist/esm/{core/series/prepare-area.js → plugins/area/prepare.js} +4 -4
- package/dist/esm/plugins/bar-x/index.d.ts +3 -0
- package/dist/esm/plugins/bar-x/index.js +5 -0
- package/dist/{cjs/core/series/prepare-bar-x.d.ts → esm/plugins/bar-x/prepare.d.ts} +1 -1
- package/dist/{cjs/core/series/prepare-bar-x.js → esm/plugins/bar-x/prepare.js} +4 -4
- package/dist/esm/plugins/bar-y/index.d.ts +3 -0
- package/dist/esm/plugins/bar-y/index.js +5 -0
- package/dist/esm/{core/series/prepare-bar-y.d.ts → plugins/bar-y/prepare.d.ts} +5 -5
- package/dist/esm/{core/series/prepare-bar-y.js → plugins/bar-y/prepare.js} +4 -4
- package/dist/esm/plugins/funnel/index.d.ts +3 -0
- package/dist/esm/plugins/funnel/index.js +5 -0
- package/dist/esm/{core/series/prepare-funnel.d.ts → plugins/funnel/prepare.d.ts} +2 -2
- package/dist/{cjs/core/series/prepare-funnel.js → esm/plugins/funnel/prepare.js} +15 -9
- package/dist/esm/plugins/heatmap/index.d.ts +3 -0
- package/dist/esm/plugins/heatmap/index.js +10 -0
- package/dist/{cjs/core/series/prepare-heatmap.d.ts → esm/plugins/heatmap/prepare.d.ts} +1 -1
- package/dist/{cjs/core/series/prepare-heatmap.js → esm/plugins/heatmap/prepare.js} +4 -4
- package/dist/esm/plugins/index.d.ts +1 -0
- package/dist/esm/plugins/index.js +27 -0
- package/dist/esm/plugins/line/index.d.ts +3 -0
- package/dist/esm/plugins/line/index.js +5 -0
- package/dist/esm/{core/series/prepare-line.d.ts → plugins/line/prepare.d.ts} +2 -2
- package/dist/esm/{core/series/prepare-line.js → plugins/line/prepare.js} +3 -3
- package/dist/esm/plugins/pie/index.d.ts +3 -0
- package/dist/esm/plugins/pie/index.js +5 -0
- package/dist/esm/{core/series/prepare-pie.d.ts → plugins/pie/prepare.d.ts} +2 -2
- package/dist/esm/plugins/pie/prepare.js +84 -0
- package/dist/esm/plugins/radar/index.d.ts +3 -0
- package/dist/esm/plugins/radar/index.js +5 -0
- package/dist/esm/{core/series/prepare-radar.d.ts → plugins/radar/prepare.d.ts} +2 -2
- package/dist/esm/{core/series/prepare-radar.js → plugins/radar/prepare.js} +4 -4
- package/dist/esm/plugins/sankey/index.d.ts +3 -0
- package/dist/esm/plugins/sankey/index.js +5 -0
- package/dist/esm/{core/series/prepare-sankey.d.ts → plugins/sankey/prepare.d.ts} +1 -1
- package/dist/esm/{core/series/prepare-sankey.js → plugins/sankey/prepare.js} +3 -3
- package/dist/esm/plugins/scatter/index.d.ts +3 -0
- package/dist/esm/plugins/scatter/index.js +10 -0
- package/dist/esm/{core/series/prepare-scatter.d.ts → plugins/scatter/prepare.d.ts} +1 -1
- package/dist/{cjs/core/series/prepare-scatter.js → esm/plugins/scatter/prepare.js} +4 -4
- package/dist/esm/plugins/treemap/index.d.ts +3 -0
- package/dist/esm/plugins/treemap/index.js +5 -0
- package/dist/{cjs/core/series/prepare-treemap.d.ts → esm/plugins/treemap/prepare.d.ts} +1 -1
- package/dist/esm/{core/series/prepare-treemap.js → plugins/treemap/prepare.js} +4 -4
- package/dist/esm/plugins/waterfall/index.d.ts +3 -0
- package/dist/esm/plugins/waterfall/index.js +5 -0
- package/dist/esm/{core/series/prepare-waterfall.d.ts → plugins/waterfall/prepare.d.ts} +1 -1
- package/dist/{cjs/core/series/prepare-waterfall.js → esm/plugins/waterfall/prepare.js} +4 -4
- package/dist/esm/plugins/x-range/index.d.ts +3 -0
- package/dist/esm/plugins/x-range/index.js +5 -0
- package/dist/esm/{core/series/prepare-x-range.d.ts → plugins/x-range/prepare.d.ts} +1 -1
- package/dist/esm/{core/series/prepare-x-range.js → plugins/x-range/prepare.js} +4 -4
- package/dist/esm/setup-jsdom.d.ts +1 -0
- package/dist/esm/setup-jsdom.js +30 -4
- package/package.json +4 -2
- package/dist/cjs/core/series/prepare-pie.js +0 -83
- package/dist/esm/core/series/prepare-pie.js +0 -83
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { sort } from 'd3-array';
|
|
2
|
+
export function getTooltipData(args) {
|
|
3
|
+
const { data, position } = args;
|
|
4
|
+
const [pointerX, pointerY] = position;
|
|
5
|
+
const pointsInRange = data.filter((d) => pointerX >= d.x &&
|
|
6
|
+
pointerX <= d.x + d.width &&
|
|
7
|
+
pointerY >= d.y &&
|
|
8
|
+
pointerY <= d.y + d.height);
|
|
9
|
+
if (pointsInRange.length === 0) {
|
|
10
|
+
return { chunks: [] };
|
|
11
|
+
}
|
|
12
|
+
const closestByX = pointsInRange.length === 1
|
|
13
|
+
? pointsInRange[0]
|
|
14
|
+
: sort(pointsInRange, (d) => Math.abs(d.x + d.width / 2 - pointerX))[0];
|
|
15
|
+
return {
|
|
16
|
+
chunks: pointsInRange.map((d) => ({
|
|
17
|
+
data: d.data,
|
|
18
|
+
series: d.series,
|
|
19
|
+
closest: d === closestByX,
|
|
20
|
+
})),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -34,18 +34,23 @@ export interface FunnelSeries<T = MeaningfulAny> extends Omit<BaseSeries, 'dataL
|
|
|
34
34
|
* width alone, exaggerating differences between large and small values. Use only for
|
|
35
35
|
* decorative purposes or when visual familiarity with the funnel metaphor is more
|
|
36
36
|
* important than analytical precision.
|
|
37
|
-
*
|
|
38
37
|
* @default 'rectangle'
|
|
39
38
|
*/
|
|
40
39
|
shape?: 'rectangle' | 'trapezoid';
|
|
41
40
|
/** Lines or areas connecting the funnel segments. */
|
|
42
41
|
connectors?: {
|
|
43
42
|
enabled?: boolean;
|
|
44
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* The height of the connector area between funnel segments.
|
|
45
|
+
* Accepts a pixel number, a pixel string (e.g. `'10px'`), or a percentage string
|
|
46
|
+
* (e.g. `'25%'`) relative to the segment band height.
|
|
47
|
+
*
|
|
48
|
+
* Defaults to `0` for `'trapezoid'` and `'25%'` for `'rectangle'`.
|
|
49
|
+
*/
|
|
45
50
|
height?: string | number;
|
|
46
51
|
/** Option for line stroke style */
|
|
47
52
|
lineDashStyle?: DashStyle;
|
|
48
|
-
/** Opacity for the connector line. */
|
|
53
|
+
/** Opacity for the connector line. Defaults to `0` for `'trapezoid'`, `1` for `'rectangle'`. */
|
|
49
54
|
lineOpacity?: number;
|
|
50
55
|
/** Connector line color. */
|
|
51
56
|
lineColor?: string;
|
|
@@ -53,7 +58,7 @@ export interface FunnelSeries<T = MeaningfulAny> extends Omit<BaseSeries, 'dataL
|
|
|
53
58
|
lineWidth?: number;
|
|
54
59
|
/** Connector area color. */
|
|
55
60
|
areaColor?: string;
|
|
56
|
-
/** Opacity for the connector area. */
|
|
61
|
+
/** Opacity for the connector area fill. Defaults to `0` for `'trapezoid'`, `0.25` for `'rectangle'`. */
|
|
57
62
|
areaOpacity?: number;
|
|
58
63
|
};
|
|
59
64
|
dataLabels?: Omit<BaseDataLabels, 'allowOverlap'> & {
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import type { ShapeData } from '../../hooks/useShapes';
|
|
2
|
-
import type {
|
|
2
|
+
import type { TooltipDataChunk } from '../../types';
|
|
3
3
|
type GetClosestPointsArgs = {
|
|
4
4
|
position: [number, number];
|
|
5
5
|
shapesData: ShapeData[];
|
|
6
6
|
boundsHeight: number;
|
|
7
7
|
boundsWidth: number;
|
|
8
8
|
};
|
|
9
|
-
export type ShapePoint
|
|
10
|
-
x: number;
|
|
11
|
-
y0: number;
|
|
12
|
-
y1: number;
|
|
13
|
-
data: ChartSeriesData;
|
|
14
|
-
series: ChartSeries;
|
|
15
|
-
subTotal?: number;
|
|
16
|
-
sourceX?: number;
|
|
17
|
-
};
|
|
9
|
+
export type { ShapePoint } from './tooltip-helpers';
|
|
18
10
|
export declare function getClosestPoints(args: GetClosestPointsArgs): TooltipDataChunk[];
|
|
19
|
-
export {};
|
|
@@ -1,56 +1,34 @@
|
|
|
1
|
-
import { bisector, sort } from 'd3-array';
|
|
2
|
-
import { Delaunay } from 'd3-delaunay';
|
|
3
1
|
import get from 'lodash/get';
|
|
4
2
|
import groupBy from 'lodash/groupBy';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const sortedByY = sort(items, (p) => p.y0);
|
|
35
|
-
const index = getClosestYIndex(sortedByY, y);
|
|
36
|
-
return sortedByY[index === -1 ? 0 : index];
|
|
37
|
-
});
|
|
38
|
-
const closestPoints = sort(groupedBySeries, (p) => p.y0);
|
|
39
|
-
const pointsWithSourceX = closestPoints.filter((p) => p.sourceX !== undefined);
|
|
40
|
-
const uniqueSourceX = new Set(pointsWithSourceX.map((p) => p.sourceX));
|
|
41
|
-
if (pointsWithSourceX.length > 1 && uniqueSourceX.size > 1) {
|
|
42
|
-
const sortedBySourceX = sort(pointsWithSourceX, (p) => { var _a; return (_a = p.sourceX) !== null && _a !== void 0 ? _a : 0; });
|
|
43
|
-
const closestSourceXIdx = bisector((p) => { var _a; return (_a = p.sourceX) !== null && _a !== void 0 ? _a : 0; }).center(sortedBySourceX, x);
|
|
44
|
-
const closestSourceX = (_a = sortedBySourceX[closestSourceXIdx]) === null || _a === void 0 ? void 0 : _a.sourceX;
|
|
45
|
-
const candidates = closestPoints.filter((p) => p.sourceX === undefined || p.sourceX === closestSourceX);
|
|
46
|
-
const sortedCandidates = sort(candidates, (p) => p.y0);
|
|
47
|
-
const winnerIdx = getClosestYIndex(sortedCandidates, y);
|
|
48
|
-
const winner = sortedCandidates[winnerIdx === -1 ? 0 : winnerIdx];
|
|
49
|
-
return closestPoints.map((p) => (Object.assign(Object.assign({}, p), { closest: p === winner })));
|
|
50
|
-
}
|
|
51
|
-
const closestYIndex = getClosestYIndex(closestPoints, y);
|
|
52
|
-
return closestPoints.map((p, i) => (Object.assign(Object.assign({}, p), { closest: i === closestYIndex })));
|
|
53
|
-
}
|
|
3
|
+
import { getTooltipData as areaGetTooltipData } from '../shapes/area/get-tooltip-data';
|
|
4
|
+
import { getTooltipData as barXGetTooltipData } from '../shapes/bar-x/get-tooltip-data';
|
|
5
|
+
import { getTooltipData as barYGetTooltipData } from '../shapes/bar-y/get-tooltip-data';
|
|
6
|
+
import { getTooltipData as funnelGetTooltipData } from '../shapes/funnel/get-tooltip-data';
|
|
7
|
+
import { getTooltipData as heatmapGetTooltipData } from '../shapes/heatmap/get-tooltip-data';
|
|
8
|
+
import { getTooltipData as lineGetTooltipData } from '../shapes/line/get-tooltip-data';
|
|
9
|
+
import { getTooltipData as pieGetTooltipData } from '../shapes/pie/get-tooltip-data';
|
|
10
|
+
import { getTooltipData as radarGetTooltipData } from '../shapes/radar/get-tooltip-data';
|
|
11
|
+
import { getTooltipData as sankeyGetTooltipData } from '../shapes/sankey/get-tooltip-data';
|
|
12
|
+
import { getTooltipData as scatterGetTooltipData } from '../shapes/scatter/get-tooltip-data';
|
|
13
|
+
import { getTooltipData as treemapGetTooltipData } from '../shapes/treemap/get-tooltip-data';
|
|
14
|
+
import { getTooltipData as waterfallGetTooltipData } from '../shapes/waterfall/get-tooltip-data';
|
|
15
|
+
import { getTooltipData as xRangeGetTooltipData } from '../shapes/x-range/get-tooltip-data';
|
|
16
|
+
import { getClosestPointsByXValue } from './tooltip-helpers';
|
|
17
|
+
const tooltipFnByType = {
|
|
18
|
+
line: lineGetTooltipData,
|
|
19
|
+
area: areaGetTooltipData,
|
|
20
|
+
'bar-x': barXGetTooltipData,
|
|
21
|
+
'bar-y': barYGetTooltipData,
|
|
22
|
+
waterfall: waterfallGetTooltipData,
|
|
23
|
+
scatter: scatterGetTooltipData,
|
|
24
|
+
pie: pieGetTooltipData,
|
|
25
|
+
treemap: treemapGetTooltipData,
|
|
26
|
+
heatmap: heatmapGetTooltipData,
|
|
27
|
+
sankey: sankeyGetTooltipData,
|
|
28
|
+
radar: radarGetTooltipData,
|
|
29
|
+
funnel: funnelGetTooltipData,
|
|
30
|
+
'x-range': xRangeGetTooltipData,
|
|
31
|
+
};
|
|
54
32
|
function getSeriesType(shapeData) {
|
|
55
33
|
return (get(shapeData, 'series.type') ||
|
|
56
34
|
get(shapeData, 'point.series.type') ||
|
|
@@ -60,283 +38,26 @@ export function getClosestPoints(args) {
|
|
|
60
38
|
const { position, shapesData, boundsHeight, boundsWidth } = args;
|
|
61
39
|
const [pointerX, pointerY] = position;
|
|
62
40
|
const result = [];
|
|
41
|
+
const xLookupPoints = [];
|
|
63
42
|
const groups = groupBy(shapesData, getSeriesType);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
return accPoints;
|
|
81
|
-
}, []));
|
|
82
|
-
return acc;
|
|
83
|
-
}, []);
|
|
84
|
-
closestPointsByXValue.push(...linePoints);
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
case 'area': {
|
|
88
|
-
const areaPoints = list.reduce((acc, d) => {
|
|
89
|
-
for (const p of d.points) {
|
|
90
|
-
if (p.y === null || p.hiddenInLine) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
acc.push({
|
|
94
|
-
data: p.data,
|
|
95
|
-
series: p.series,
|
|
96
|
-
x: p.x,
|
|
97
|
-
y0: p.y0,
|
|
98
|
-
y1: p.y,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
return acc;
|
|
102
|
-
}, []);
|
|
103
|
-
closestPointsByXValue.push(...areaPoints);
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
case 'bar-x': {
|
|
107
|
-
const barXList = list;
|
|
108
|
-
const barXGroups = groupBy(barXList, (d) => String(d.data.x));
|
|
109
|
-
const barXPoints = [];
|
|
110
|
-
Object.values(barXGroups).forEach((group) => {
|
|
111
|
-
const groupCenterX = group.reduce((sum, d) => sum + d.x + d.width / 2, 0) / group.length;
|
|
112
|
-
group.forEach((d) => {
|
|
113
|
-
barXPoints.push({
|
|
114
|
-
data: d.data,
|
|
115
|
-
series: d.series,
|
|
116
|
-
x: groupCenterX,
|
|
117
|
-
y0: d.y,
|
|
118
|
-
y1: d.y + d.height,
|
|
119
|
-
sourceX: d.x + d.width / 2,
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
closestPointsByXValue.push(...barXPoints);
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
case 'waterfall': {
|
|
127
|
-
const points = list.map((d) => ({
|
|
128
|
-
data: d.data,
|
|
129
|
-
series: d.series,
|
|
130
|
-
x: d.x + d.width / 2,
|
|
131
|
-
y0: d.y,
|
|
132
|
-
y1: d.y + d.height,
|
|
133
|
-
subTotal: d.subTotal,
|
|
134
|
-
}));
|
|
135
|
-
result.push(...getClosestPointsByXValue(pointerX, pointerY, points));
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
case 'bar-y': {
|
|
139
|
-
const points = list;
|
|
140
|
-
const sorted = sort(points, (p) => p.y);
|
|
141
|
-
const closestYIndex = bisector((p) => p.y + p.height / 2).center(sorted, pointerY);
|
|
142
|
-
const closestYPoint = sorted[closestYIndex];
|
|
143
|
-
let selectedPoints = [];
|
|
144
|
-
let closestPointXValue = -1;
|
|
145
|
-
if (closestYPoint) {
|
|
146
|
-
selectedPoints = points.filter((p) => p.data.y === closestYPoint.data.y);
|
|
147
|
-
const closestPoints = sort(selectedPoints.filter((p) => p.y === closestYPoint.y), (p) => p.x);
|
|
148
|
-
const lastPoint = closestPoints[closestPoints.length - 1];
|
|
149
|
-
if (pointerX < ((_a = closestPoints[0]) === null || _a === void 0 ? void 0 : _a.x)) {
|
|
150
|
-
closestPointXValue = closestPoints[0].x;
|
|
151
|
-
}
|
|
152
|
-
else if (lastPoint && pointerX > lastPoint.x + lastPoint.width) {
|
|
153
|
-
closestPointXValue = lastPoint.x;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
closestPointXValue = (_b = closestPoints.find((p) => pointerX > p.x && pointerX < p.x + p.width)) === null || _b === void 0 ? void 0 : _b.x;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
result.push(...selectedPoints.map((p) => ({
|
|
160
|
-
data: p.data,
|
|
161
|
-
series: p.series,
|
|
162
|
-
closest: p.x === closestPointXValue && p.y === closestYPoint.y,
|
|
163
|
-
})));
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
case 'scatter': {
|
|
167
|
-
const points = list;
|
|
168
|
-
const delaunayX = Delaunay.from(points, (d) => d.point.x, (d) => d.point.y);
|
|
169
|
-
const closestPoint = points[delaunayX.find(pointerX, pointerY)];
|
|
170
|
-
if (closestPoint) {
|
|
171
|
-
result.push({
|
|
172
|
-
data: closestPoint.point.data,
|
|
173
|
-
series: closestPoint.point.series,
|
|
174
|
-
closest: true,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
case 'pie': {
|
|
180
|
-
const points = list.map((d) => d.segments).flat();
|
|
181
|
-
const closestPoint = points.find((p) => {
|
|
182
|
-
const { center } = p.data.pie;
|
|
183
|
-
const x = pointerX - center[0];
|
|
184
|
-
const y = pointerY - center[1];
|
|
185
|
-
let angle = Math.atan2(y, x) + 0.5 * Math.PI;
|
|
186
|
-
angle = angle < 0 ? Math.PI * 2 + angle : angle;
|
|
187
|
-
const polarRadius = getRadius({ center, pointer: [pointerX, pointerY] });
|
|
188
|
-
return (angle >= p.startAngle && angle <= p.endAngle && polarRadius < p.data.radius);
|
|
189
|
-
});
|
|
190
|
-
if (closestPoint) {
|
|
191
|
-
result.push({
|
|
192
|
-
data: closestPoint.data.series.data,
|
|
193
|
-
series: closestPoint.data.series,
|
|
194
|
-
closest: true,
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
case 'treemap': {
|
|
200
|
-
const data = list;
|
|
201
|
-
const closestPoint = (_c = data[0]) === null || _c === void 0 ? void 0 : _c.leaves.find((l) => {
|
|
202
|
-
return (pointerX >= l.x0 && pointerX <= l.x1 && pointerY >= l.y0 && pointerY <= l.y1);
|
|
203
|
-
});
|
|
204
|
-
if (closestPoint) {
|
|
205
|
-
result.push({
|
|
206
|
-
data: closestPoint.data,
|
|
207
|
-
series: data[0].series,
|
|
208
|
-
closest: true,
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
case 'heatmap': {
|
|
214
|
-
const data = list;
|
|
215
|
-
const closestPoint = (_d = data[0]) === null || _d === void 0 ? void 0 : _d.items.find((cell) => {
|
|
216
|
-
return (pointerX >= cell.x &&
|
|
217
|
-
pointerX <= cell.x + cell.width &&
|
|
218
|
-
pointerY >= cell.y &&
|
|
219
|
-
pointerY <= cell.y + cell.height);
|
|
220
|
-
});
|
|
221
|
-
if (closestPoint) {
|
|
222
|
-
result.push({
|
|
223
|
-
data: closestPoint.data,
|
|
224
|
-
series: data[0].series,
|
|
225
|
-
closest: true,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
break;
|
|
229
|
-
}
|
|
230
|
-
case 'sankey': {
|
|
231
|
-
const [data] = list;
|
|
232
|
-
const closestLink = data.links.find((d) => {
|
|
233
|
-
var _a;
|
|
234
|
-
return isInsidePath({
|
|
235
|
-
path: (_a = d.path) !== null && _a !== void 0 ? _a : '',
|
|
236
|
-
strokeWidth: d.strokeWidth,
|
|
237
|
-
point: [pointerX, pointerY],
|
|
238
|
-
width: boundsWidth,
|
|
239
|
-
height: boundsHeight,
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
if (closestLink) {
|
|
243
|
-
result.push({
|
|
244
|
-
data: closestLink.source,
|
|
245
|
-
target: closestLink.target,
|
|
246
|
-
series: data.series,
|
|
247
|
-
closest: true,
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
case 'radar': {
|
|
253
|
-
const [radarData] = list;
|
|
254
|
-
const radius = getRadius({ center: radarData.center, pointer: [pointerX, pointerY] });
|
|
255
|
-
if (radius <= radarData.radius) {
|
|
256
|
-
const radarShapes = radarData.shapes.filter((shape) => isInsidePath({
|
|
257
|
-
path: shape.path,
|
|
258
|
-
point: [pointerX, pointerY],
|
|
259
|
-
width: boundsWidth,
|
|
260
|
-
height: boundsHeight,
|
|
261
|
-
strokeWidth: shape.borderWidth,
|
|
262
|
-
}));
|
|
263
|
-
const points = radarShapes.map((shape) => shape.points).flat();
|
|
264
|
-
const delaunayX = Delaunay.from(points, (d) => d.position[0], (d) => d.position[1]);
|
|
265
|
-
const closestPoint = points[delaunayX.find(pointerX, pointerY)];
|
|
266
|
-
if (closestPoint) {
|
|
267
|
-
radarData.shapes.forEach((shape) => {
|
|
268
|
-
result.push({
|
|
269
|
-
data: shape.points[closestPoint.index].data,
|
|
270
|
-
series: shape.series,
|
|
271
|
-
category: shape.series.categories[closestPoint.index],
|
|
272
|
-
closest: shape.series === closestPoint.series,
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
case 'funnel': {
|
|
280
|
-
const data = list;
|
|
281
|
-
const closestPoint = (_e = data[0]) === null || _e === void 0 ? void 0 : _e.items.find((item) => {
|
|
282
|
-
return (pointerX >= item.x &&
|
|
283
|
-
pointerX <= item.x + item.width &&
|
|
284
|
-
pointerY >= item.y &&
|
|
285
|
-
pointerY <= item.y + item.height);
|
|
286
|
-
});
|
|
287
|
-
if (closestPoint) {
|
|
288
|
-
result.push({
|
|
289
|
-
data: closestPoint.data,
|
|
290
|
-
series: closestPoint.series,
|
|
291
|
-
closest: true,
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
case 'x-range': {
|
|
297
|
-
const data = list;
|
|
298
|
-
const pointsInXRange = data.filter((d) => pointerX >= d.x &&
|
|
299
|
-
pointerX <= d.x + d.width &&
|
|
300
|
-
pointerY >= d.y &&
|
|
301
|
-
pointerY <= d.y + d.height);
|
|
302
|
-
if (pointsInXRange.length === 0) {
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
const closestByX = pointsInXRange.length === 1
|
|
306
|
-
? pointsInXRange[0]
|
|
307
|
-
: sort(pointsInXRange, (d) => Math.abs(d.x + d.width / 2 - pointerX))[0];
|
|
308
|
-
result.push(...pointsInXRange.map((d) => ({
|
|
309
|
-
data: d.data,
|
|
310
|
-
series: d.series,
|
|
311
|
-
closest: d === closestByX,
|
|
312
|
-
})));
|
|
313
|
-
break;
|
|
314
|
-
}
|
|
43
|
+
for (const [seriesType, list] of Object.entries(groups)) {
|
|
44
|
+
const fn = tooltipFnByType[seriesType];
|
|
45
|
+
if (!fn) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const { chunks, xLookupPoints: seriesXLookupPoints } = fn({
|
|
49
|
+
data: list,
|
|
50
|
+
position,
|
|
51
|
+
boundsWidth,
|
|
52
|
+
boundsHeight,
|
|
53
|
+
});
|
|
54
|
+
result.push(...chunks);
|
|
55
|
+
if (seriesXLookupPoints) {
|
|
56
|
+
xLookupPoints.push(...seriesXLookupPoints);
|
|
315
57
|
}
|
|
316
|
-
});
|
|
317
|
-
if (closestPointsByXValue.length) {
|
|
318
|
-
result.push(...getClosestPointsByXValue(pointerX, pointerY, closestPointsByXValue));
|
|
319
58
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
function isInsidePath(args) {
|
|
323
|
-
const { path, point, width, height, strokeWidth } = args;
|
|
324
|
-
const canvas = document.createElement('canvas');
|
|
325
|
-
canvas.width = width;
|
|
326
|
-
canvas.height = height;
|
|
327
|
-
const ctx = canvas.getContext('2d');
|
|
328
|
-
if (ctx) {
|
|
329
|
-
ctx.lineWidth = strokeWidth;
|
|
330
|
-
const path2D = new Path2D(path);
|
|
331
|
-
ctx.stroke(path2D);
|
|
332
|
-
return ctx.isPointInPath(path2D, ...point) || ctx.isPointInStroke(path2D, ...point);
|
|
59
|
+
if (xLookupPoints.length) {
|
|
60
|
+
result.push(...getClosestPointsByXValue(pointerX, pointerY, xLookupPoints));
|
|
333
61
|
}
|
|
334
|
-
return
|
|
335
|
-
}
|
|
336
|
-
function getRadius(args) {
|
|
337
|
-
const { pointer, center } = args;
|
|
338
|
-
const x = pointer[0] - center[0];
|
|
339
|
-
const y = pointer[1] - center[1];
|
|
340
|
-
const polarRadius = Math.sqrt(x * x + y * y);
|
|
341
|
-
return polarRadius;
|
|
62
|
+
return result;
|
|
342
63
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ChartSeries, ChartSeriesData, MeaningfulAny, TooltipDataChunk } from '../../types';
|
|
2
|
+
export type ShapePoint = {
|
|
3
|
+
x: number;
|
|
4
|
+
y0: number;
|
|
5
|
+
y1: number;
|
|
6
|
+
data: ChartSeriesData;
|
|
7
|
+
series: ChartSeries;
|
|
8
|
+
subTotal?: number;
|
|
9
|
+
sourceX?: number;
|
|
10
|
+
};
|
|
11
|
+
export interface GetTooltipDataArgs<TShapeData = unknown> {
|
|
12
|
+
data: TShapeData[];
|
|
13
|
+
position: [number, number];
|
|
14
|
+
boundsWidth: number;
|
|
15
|
+
boundsHeight: number;
|
|
16
|
+
}
|
|
17
|
+
export interface GetTooltipDataResult {
|
|
18
|
+
chunks: TooltipDataChunk[];
|
|
19
|
+
xLookupPoints?: ShapePoint[];
|
|
20
|
+
}
|
|
21
|
+
export type GetTooltipDataFn = (args: GetTooltipDataArgs<MeaningfulAny>) => GetTooltipDataResult;
|
|
22
|
+
export declare function getClosestYIndex(items: ShapePoint[], y: number): number;
|
|
23
|
+
export declare function getClosestPointsByXValue(x: number, y: number, points: ShapePoint[]): {
|
|
24
|
+
closest: boolean;
|
|
25
|
+
x: number;
|
|
26
|
+
y0: number;
|
|
27
|
+
y1: number;
|
|
28
|
+
data: ChartSeriesData;
|
|
29
|
+
series: ChartSeries;
|
|
30
|
+
subTotal?: number;
|
|
31
|
+
sourceX?: number;
|
|
32
|
+
}[];
|
|
33
|
+
export declare function isInsidePath(args: {
|
|
34
|
+
path: string;
|
|
35
|
+
point: [number, number];
|
|
36
|
+
width: number;
|
|
37
|
+
height: number;
|
|
38
|
+
strokeWidth: number;
|
|
39
|
+
}): boolean | null;
|
|
40
|
+
export declare function getRadius(args: {
|
|
41
|
+
pointer: [number, number];
|
|
42
|
+
center: [number, number];
|
|
43
|
+
}): number;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { bisector, sort } from 'd3-array';
|
|
2
|
+
import get from 'lodash/get';
|
|
3
|
+
import groupBy from 'lodash/groupBy';
|
|
4
|
+
export function getClosestYIndex(items, y) {
|
|
5
|
+
var _a, _b, _c, _d;
|
|
6
|
+
let closestYIndex = -1;
|
|
7
|
+
if (y < ((_a = items[0]) === null || _a === void 0 ? void 0 : _a.y0)) {
|
|
8
|
+
closestYIndex = 0;
|
|
9
|
+
}
|
|
10
|
+
else if (y > ((_b = items[items.length - 1]) === null || _b === void 0 ? void 0 : _b.y1)) {
|
|
11
|
+
closestYIndex = items.length - 1;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
closestYIndex = items.findIndex((p) => y > p.y0 && y < p.y1);
|
|
15
|
+
if (closestYIndex === -1) {
|
|
16
|
+
const sortedY = sort(items.map((p, index) => ({ index, y: p.y1 + (p.y0 - p.y1) / 2 })), (p) => p.y);
|
|
17
|
+
const sortedYIndex = bisector((p) => p.y).center(sortedY, y);
|
|
18
|
+
closestYIndex = (_d = (_c = sortedY[sortedYIndex]) === null || _c === void 0 ? void 0 : _c.index) !== null && _d !== void 0 ? _d : -1;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return closestYIndex;
|
|
22
|
+
}
|
|
23
|
+
export function getClosestPointsByXValue(x, y, points) {
|
|
24
|
+
var _a;
|
|
25
|
+
const sorted = sort(points, (p) => p.x);
|
|
26
|
+
const closestXIndex = bisector((p) => p.x).center(sorted, x);
|
|
27
|
+
if (sorted.length === 0 || closestXIndex === -1) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const closestX = Math.round(sorted[closestXIndex].x);
|
|
31
|
+
const filtered = points.filter((p) => Math.round(p.x) === closestX);
|
|
32
|
+
const groupedBySeries = Object.values(groupBy(filtered, (p) => get(p.series, 'id'))).map((items) => {
|
|
33
|
+
const sortedByY = sort(items, (p) => p.y0);
|
|
34
|
+
const index = getClosestYIndex(sortedByY, y);
|
|
35
|
+
return sortedByY[index === -1 ? 0 : index];
|
|
36
|
+
});
|
|
37
|
+
const closestPoints = sort(groupedBySeries, (p) => p.y0);
|
|
38
|
+
const pointsWithSourceX = closestPoints.filter((p) => p.sourceX !== undefined);
|
|
39
|
+
const uniqueSourceX = new Set(pointsWithSourceX.map((p) => p.sourceX));
|
|
40
|
+
if (pointsWithSourceX.length > 1 && uniqueSourceX.size > 1) {
|
|
41
|
+
const sortedBySourceX = sort(pointsWithSourceX, (p) => { var _a; return (_a = p.sourceX) !== null && _a !== void 0 ? _a : 0; });
|
|
42
|
+
const closestSourceXIdx = bisector((p) => { var _a; return (_a = p.sourceX) !== null && _a !== void 0 ? _a : 0; }).center(sortedBySourceX, x);
|
|
43
|
+
const closestSourceX = (_a = sortedBySourceX[closestSourceXIdx]) === null || _a === void 0 ? void 0 : _a.sourceX;
|
|
44
|
+
const candidates = closestPoints.filter((p) => p.sourceX === undefined || p.sourceX === closestSourceX);
|
|
45
|
+
const sortedCandidates = sort(candidates, (p) => p.y0);
|
|
46
|
+
const winnerIdx = getClosestYIndex(sortedCandidates, y);
|
|
47
|
+
const winner = sortedCandidates[winnerIdx === -1 ? 0 : winnerIdx];
|
|
48
|
+
return closestPoints.map((p) => (Object.assign(Object.assign({}, p), { closest: p === winner })));
|
|
49
|
+
}
|
|
50
|
+
const closestYIndex = getClosestYIndex(closestPoints, y);
|
|
51
|
+
return closestPoints.map((p, i) => (Object.assign(Object.assign({}, p), { closest: i === closestYIndex })));
|
|
52
|
+
}
|
|
53
|
+
export function isInsidePath(args) {
|
|
54
|
+
const { path, point, width, height, strokeWidth } = args;
|
|
55
|
+
const canvas = document.createElement('canvas');
|
|
56
|
+
canvas.width = width;
|
|
57
|
+
canvas.height = height;
|
|
58
|
+
const ctx = canvas.getContext('2d');
|
|
59
|
+
if (ctx) {
|
|
60
|
+
ctx.lineWidth = strokeWidth;
|
|
61
|
+
const path2D = new Path2D(path);
|
|
62
|
+
ctx.stroke(path2D);
|
|
63
|
+
return ctx.isPointInPath(path2D, ...point) || ctx.isPointInStroke(path2D, ...point);
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
export function getRadius(args) {
|
|
68
|
+
const { pointer, center } = args;
|
|
69
|
+
const x = pointer[0] - center[0];
|
|
70
|
+
const y = pointer[1] - center[1];
|
|
71
|
+
return Math.sqrt(x * x + y * y);
|
|
72
|
+
}
|
package/dist/cjs/index.d.ts
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ScaleOrdinal } from 'd3-scale';
|
|
2
|
+
import type { PreparedAreaSeries, PreparedLegend } from '../../core/series/types';
|
|
2
3
|
import type { AreaSeries, ChartSeriesOptions } from '../../types';
|
|
3
|
-
import type { PreparedAreaSeries, PreparedLegend } from './types';
|
|
4
4
|
export declare const DEFAULT_LINE_WIDTH = 1;
|
|
5
5
|
export declare const DEFAULT_MARKER: {
|
|
6
6
|
enabled: boolean;
|
|
7
|
-
symbol: `${import("
|
|
7
|
+
symbol: `${import("../../core/constants").SymbolType}`;
|
|
8
8
|
borderColor: string;
|
|
9
9
|
borderWidth: number;
|
|
10
10
|
radius: number;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import get from 'lodash/get';
|
|
2
2
|
import merge from 'lodash/merge';
|
|
3
|
-
import { DEFAULT_DATALABELS_STYLE, seriesRangeSliderOptionsDefaults } from '
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { DEFAULT_DATALABELS_STYLE, seriesRangeSliderOptionsDefaults } from '../../core/constants';
|
|
4
|
+
import { DEFAULT_DATALABELS_PADDING, DEFAULT_HALO_OPTIONS, DEFAULT_POINT_MARKER_OPTIONS, } from '../../core/series/constants';
|
|
5
|
+
import { getSeriesStackId, prepareLegendSymbol } from '../../core/series/utils';
|
|
6
|
+
import { getUniqId } from '../../core/utils';
|
|
7
7
|
export const DEFAULT_LINE_WIDTH = 1;
|
|
8
8
|
export const DEFAULT_MARKER = Object.assign(Object.assign({}, DEFAULT_POINT_MARKER_OPTIONS), { enabled: false });
|
|
9
9
|
function prepareMarker(series, seriesOptions) {
|