layerchart 2.0.0-next.0 → 2.0.0-next.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/actions/movable.d.ts +28 -0
- package/dist/actions/movable.js +91 -0
- package/dist/components/AnnotationLine.svelte +155 -0
- package/dist/components/AnnotationLine.svelte.d.ts +28 -0
- package/dist/components/AnnotationPoint.svelte +121 -0
- package/dist/components/AnnotationPoint.svelte.d.ts +32 -0
- package/dist/components/AnnotationRange.svelte +147 -0
- package/dist/components/AnnotationRange.svelte.d.ts +40 -0
- package/dist/components/Arc.svelte +344 -151
- package/dist/components/Arc.svelte.d.ts +138 -0
- package/dist/components/Area.svelte +165 -149
- package/dist/components/Area.svelte.d.ts +45 -0
- package/dist/components/Axis.svelte +287 -174
- package/dist/components/Axis.svelte.d.ts +116 -0
- package/dist/components/Bar.svelte +163 -107
- package/dist/components/Bar.svelte.d.ts +48 -0
- package/dist/components/Bars.svelte +54 -68
- package/dist/components/Bars.svelte.d.ts +27 -0
- package/dist/components/Blur.svelte +31 -7
- package/dist/components/Blur.svelte.d.ts +23 -21
- package/dist/components/Bounds.svelte +49 -19
- package/dist/components/Bounds.svelte.d.ts +24 -50
- package/dist/components/BrushContext.svelte +296 -168
- package/dist/components/BrushContext.svelte.d.ts +97 -65
- package/dist/components/Calendar.svelte +116 -59
- package/dist/components/Calendar.svelte.d.ts +50 -31
- package/dist/components/Chart.svelte +1289 -398
- package/dist/components/Chart.svelte.d.ts +535 -410
- package/dist/components/ChartClipPath.svelte +37 -15
- package/dist/components/ChartClipPath.svelte.d.ts +21 -19
- package/dist/components/Circle.svelte +124 -85
- package/dist/components/Circle.svelte.d.ts +52 -0
- package/dist/components/CircleClipPath.svelte +76 -16
- package/dist/components/CircleClipPath.svelte.d.ts +46 -0
- package/dist/components/ClipPath.svelte +60 -15
- package/dist/components/ClipPath.svelte.d.ts +40 -27
- package/dist/components/ColorRamp.svelte +75 -9
- package/dist/components/ColorRamp.svelte.d.ts +37 -19
- package/dist/components/ComputedStyles.svelte +17 -5
- package/dist/components/ComputedStyles.svelte.d.ts +11 -19
- package/dist/components/Connector.svelte +149 -0
- package/dist/components/Connector.svelte.d.ts +51 -0
- package/dist/components/Dagre.svelte +211 -122
- package/dist/components/Dagre.svelte.d.ts +119 -56
- package/dist/components/ForceSimulation.svelte +215 -90
- package/dist/components/ForceSimulation.svelte.d.ts +82 -35
- package/dist/components/Frame.svelte +33 -13
- package/dist/components/Frame.svelte.d.ts +13 -17
- package/dist/components/GeoCircle.svelte +29 -16
- package/dist/components/GeoCircle.svelte.d.ts +22 -24
- package/dist/components/GeoContext.svelte +113 -72
- package/dist/components/GeoContext.svelte.d.ts +49 -41
- package/dist/components/GeoEdgeFade.svelte +47 -12
- package/dist/components/GeoEdgeFade.svelte.d.ts +17 -19
- package/dist/components/GeoPath.svelte +157 -127
- package/dist/components/GeoPath.svelte.d.ts +48 -36
- package/dist/components/GeoPoint.svelte +52 -20
- package/dist/components/GeoPoint.svelte.d.ts +25 -22
- package/dist/components/GeoSpline.svelte +75 -26
- package/dist/components/GeoSpline.svelte.d.ts +29 -20
- package/dist/components/GeoTile.svelte +100 -49
- package/dist/components/GeoTile.svelte.d.ts +38 -23
- package/dist/components/GeoVisible.svelte +17 -9
- package/dist/components/GeoVisible.svelte.d.ts +10 -18
- package/dist/components/Graticule.svelte +28 -13
- package/dist/components/Graticule.svelte.d.ts +11 -52
- package/dist/components/Grid.svelte +226 -114
- package/dist/components/Grid.svelte.d.ts +70 -0
- package/dist/components/Group.svelte +132 -105
- package/dist/components/Group.svelte.d.ts +53 -0
- package/dist/components/Highlight.svelte +409 -307
- package/dist/components/Highlight.svelte.d.ts +107 -0
- package/dist/components/Hull.svelte +96 -45
- package/dist/components/Hull.svelte.d.ts +40 -30
- package/dist/components/Labels.svelte +125 -46
- package/dist/components/Labels.svelte.d.ts +70 -27
- package/dist/components/Legend.svelte +374 -190
- package/dist/components/Legend.svelte.d.ts +95 -44
- package/dist/components/Line.svelte +163 -125
- package/dist/components/Line.svelte.d.ts +75 -0
- package/dist/components/LinearGradient.svelte +153 -78
- package/dist/components/LinearGradient.svelte.d.ts +66 -31
- package/dist/components/Link.svelte +160 -104
- package/dist/components/Link.svelte.d.ts +54 -0
- package/dist/components/Marker.svelte +100 -39
- package/dist/components/Marker.svelte.d.ts +59 -27
- package/dist/components/MarkerWrapper.svelte +35 -0
- package/dist/components/MarkerWrapper.svelte.d.ts +18 -0
- package/dist/components/MonthPath.svelte +65 -20
- package/dist/components/MonthPath.svelte.d.ts +23 -17
- package/dist/components/MotionPath.svelte +80 -24
- package/dist/components/MotionPath.svelte.d.ts +46 -27
- package/dist/components/Pack.svelte +53 -17
- package/dist/components/Pack.svelte.d.ts +42 -21
- package/dist/components/Partition.svelte +64 -22
- package/dist/components/Partition.svelte.d.ts +49 -26
- package/dist/components/Pattern.svelte +297 -11
- package/dist/components/Pattern.svelte.d.ts +103 -19
- package/dist/components/Pie.svelte +122 -76
- package/dist/components/Pie.svelte.d.ts +65 -51
- package/dist/components/Point.svelte +20 -9
- package/dist/components/Point.svelte.d.ts +16 -20
- package/dist/components/Points.svelte +148 -137
- package/dist/components/Points.svelte.d.ts +45 -34
- package/dist/components/RadialGradient.svelte +143 -70
- package/dist/components/RadialGradient.svelte.d.ts +69 -31
- package/dist/components/Rect.svelte +121 -102
- package/dist/components/Rect.svelte.d.ts +36 -0
- package/dist/components/RectClipPath.svelte +82 -18
- package/dist/components/RectClipPath.svelte.d.ts +55 -0
- package/dist/components/Rule.svelte +105 -62
- package/dist/components/Rule.svelte.d.ts +40 -19
- package/dist/components/Sankey.svelte +132 -55
- package/dist/components/Sankey.svelte.d.ts +61 -31
- package/dist/components/Spline.svelte +281 -218
- package/dist/components/Spline.svelte.d.ts +95 -0
- package/dist/components/Text.svelte +437 -176
- package/dist/components/Text.svelte.d.ts +130 -0
- package/dist/components/Threshold.svelte +48 -16
- package/dist/components/Threshold.svelte.d.ts +29 -31
- package/dist/components/TileImage.svelte +103 -30
- package/dist/components/TileImage.svelte.d.ts +48 -23
- package/dist/components/TransformContext.svelte +365 -171
- package/dist/components/TransformControls.svelte +50 -26
- package/dist/components/TransformControls.svelte.d.ts +27 -19
- package/dist/components/Tree.svelte +74 -33
- package/dist/components/Tree.svelte.d.ts +42 -30
- package/dist/components/Treemap.svelte +119 -42
- package/dist/components/Treemap.svelte.d.ts +75 -27
- package/dist/components/Voronoi.svelte +106 -75
- package/dist/components/Voronoi.svelte.d.ts +40 -41
- package/dist/components/charts/ArcChart.svelte +464 -0
- package/dist/components/charts/ArcChart.svelte.d.ts +90 -0
- package/dist/components/charts/AreaChart.svelte +450 -393
- package/dist/components/charts/AreaChart.svelte.d.ts +61 -0
- package/dist/components/charts/BarChart.svelte +454 -389
- package/dist/components/charts/BarChart.svelte.d.ts +76 -0
- package/dist/components/charts/ChartAnnotations.svelte +37 -0
- package/dist/components/charts/ChartAnnotations.svelte.d.ts +10 -0
- package/dist/components/charts/DefaultTooltip.svelte +60 -0
- package/dist/components/charts/DefaultTooltip.svelte.d.ts +10 -0
- package/dist/components/charts/LineChart.svelte +369 -314
- package/dist/components/charts/LineChart.svelte.d.ts +53 -0
- package/dist/components/charts/PieChart.svelte +458 -316
- package/dist/components/charts/PieChart.svelte.d.ts +137 -353
- package/dist/components/charts/ScatterChart.svelte +334 -296
- package/dist/components/charts/ScatterChart.svelte.d.ts +39 -0
- package/dist/components/charts/index.d.ts +8 -0
- package/dist/components/charts/index.js +7 -0
- package/dist/components/charts/types.d.ts +253 -0
- package/dist/components/charts/utils.svelte.d.ts +30 -0
- package/dist/components/charts/utils.svelte.js +55 -0
- package/dist/components/index.d.ts +76 -4
- package/dist/components/index.js +76 -5
- package/dist/components/layout/Canvas.svelte +321 -155
- package/dist/components/layout/Canvas.svelte.d.ts +104 -55
- package/dist/components/layout/Html.svelte +82 -42
- package/dist/components/layout/Html.svelte.d.ts +39 -28
- package/dist/components/layout/Layer.svelte +39 -0
- package/dist/components/layout/Layer.svelte.d.ts +17 -0
- package/dist/components/layout/Svg.svelte +122 -70
- package/dist/components/layout/Svg.svelte.d.ts +53 -34
- package/dist/components/layout/WebGL.svelte +135 -0
- package/dist/components/layout/WebGL.svelte.d.ts +50 -0
- package/dist/components/tooltip/Tooltip.svelte +246 -78
- package/dist/components/tooltip/Tooltip.svelte.d.ts +149 -31
- package/dist/components/tooltip/TooltipContext.svelte +409 -271
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +86 -55
- package/dist/components/tooltip/TooltipHeader.svelte +100 -11
- package/dist/components/tooltip/TooltipHeader.svelte.d.ts +43 -23
- package/dist/components/tooltip/TooltipItem.svelte +167 -27
- package/dist/components/tooltip/TooltipItem.svelte.d.ts +63 -31
- package/dist/components/tooltip/TooltipList.svelte +22 -3
- package/dist/components/tooltip/TooltipList.svelte.d.ts +6 -17
- package/dist/components/tooltip/TooltipSeparator.svelte +27 -1
- package/dist/components/tooltip/TooltipSeparator.svelte.d.ts +6 -15
- package/dist/components/tooltip/index.d.ts +6 -0
- package/dist/components/tooltip/index.js +6 -0
- package/dist/components/tooltip/tooltipMetaContext.d.ts +79 -0
- package/dist/components/tooltip/tooltipMetaContext.js +139 -0
- package/dist/components/types.d.ts +1 -0
- package/dist/components/types.js +1 -0
- package/dist/docs/Blockquote.svelte.d.ts +18 -14
- package/dist/docs/Code.svelte.d.ts +26 -22
- package/dist/docs/ConnectorSweepMenuField.svelte +17 -0
- package/dist/docs/ConnectorSweepMenuField.svelte.d.ts +7 -0
- package/dist/docs/ConnectorTypeMenuField.svelte +17 -0
- package/dist/docs/ConnectorTypeMenuField.svelte.d.ts +7 -0
- package/dist/docs/CurveMenuField.svelte +14 -3
- package/dist/docs/CurveMenuField.svelte.d.ts +9 -18
- package/dist/docs/GeoDebug.svelte +47 -42
- package/dist/docs/GeoDebug.svelte.d.ts +4 -16
- package/dist/docs/Header1.svelte.d.ts +27 -16
- package/dist/docs/Json.svelte.d.ts +20 -16
- package/dist/docs/Layout.svelte.d.ts +18 -13
- package/dist/docs/Link.svelte.d.ts +33 -21
- package/dist/docs/PathDataMenuField.svelte +14 -10
- package/dist/docs/PathDataMenuField.svelte.d.ts +8 -18
- package/dist/docs/Preview.svelte +20 -7
- package/dist/docs/Preview.svelte.d.ts +12 -22
- package/dist/docs/TilesetField.svelte.d.ts +21 -17
- package/dist/docs/TransformDebug.svelte +5 -6
- package/dist/docs/TransformDebug.svelte.d.ts +18 -14
- package/dist/docs/ViewSourceButton.svelte.d.ts +21 -17
- package/dist/types/d3-shape-extentions.d.ts +7 -0
- package/dist/utils/afterTick.d.ts +5 -0
- package/dist/utils/afterTick.js +8 -0
- package/dist/utils/arcText.svelte.d.ts +57 -0
- package/dist/utils/arcText.svelte.js +262 -0
- package/dist/utils/array.d.ts +9 -1
- package/dist/utils/array.js +13 -0
- package/dist/utils/attributes.d.ts +29 -0
- package/dist/utils/attributes.js +40 -0
- package/dist/utils/canvas.js +47 -10
- package/dist/utils/chart.d.ts +78 -0
- package/dist/utils/chart.js +512 -0
- package/dist/utils/color.d.ts +1 -0
- package/dist/utils/color.js +8 -0
- package/dist/utils/common.d.ts +3 -5
- package/dist/utils/common.js +3 -2
- package/dist/utils/connectorUtils.d.ts +21 -0
- package/dist/utils/connectorUtils.js +111 -0
- package/dist/utils/createId.d.ts +7 -0
- package/dist/utils/createId.js +9 -0
- package/dist/utils/debug.d.ts +1 -0
- package/dist/utils/debug.js +84 -0
- package/dist/utils/filterObject.d.ts +9 -0
- package/dist/utils/filterObject.js +12 -0
- package/dist/utils/graph/dagre.d.ts +34 -0
- package/dist/utils/graph/dagre.js +78 -0
- package/dist/utils/graph/dagre.test.d.ts +1 -0
- package/dist/utils/{graph.test.js → graph/dagre.test.js} +19 -33
- package/dist/utils/graph/sankey.d.ts +28 -0
- package/dist/utils/{graph.js → graph/sankey.js} +13 -41
- package/dist/utils/index.d.ts +3 -1
- package/dist/utils/index.js +3 -1
- package/dist/utils/key.svelte.d.ts +3 -0
- package/dist/utils/key.svelte.js +11 -0
- package/dist/utils/legendPayload.d.ts +7 -0
- package/dist/utils/legendPayload.js +8 -0
- package/dist/utils/motion.svelte.d.ts +140 -0
- package/dist/utils/motion.svelte.js +180 -0
- package/dist/utils/motion.test.d.ts +1 -0
- package/dist/utils/motion.test.js +213 -0
- package/dist/utils/{rect.d.ts → rect.svelte.d.ts} +7 -4
- package/dist/utils/rect.svelte.js +105 -0
- package/dist/utils/scales.svelte.d.ts +90 -0
- package/dist/utils/{scales.js → scales.svelte.js} +100 -39
- package/dist/utils/stack.d.ts +2 -3
- package/dist/utils/stack.js +1 -1
- package/dist/utils/string.js +87 -0
- package/dist/utils/ticks.d.ts +8 -2
- package/dist/utils/ticks.js +28 -0
- package/dist/utils/ticks.test.d.ts +1 -0
- package/dist/utils/ticks.test.js +67 -0
- package/dist/utils/types.d.ts +81 -0
- package/package.json +25 -24
- package/dist/components/ChartContext.svelte +0 -295
- package/dist/components/ChartContext.svelte.d.ts +0 -139
- package/dist/components/TransformContext.svelte.d.ts +0 -158
- package/dist/stores/motionStore.d.ts +0 -30
- package/dist/stores/motionStore.js +0 -62
- package/dist/utils/graph.d.ts +0 -37
- package/dist/utils/rect.js +0 -107
- package/dist/utils/scales.d.ts +0 -66
- /package/dist/{utils/graph.test.d.ts → components/charts/types.js} +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
<script lang="ts"
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { Context } from 'runed';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { Without } from '../../utils/types.js';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const _TooltipContext = new Context<TooltipContextValue>('TooltipContext');
|
|
6
7
|
|
|
7
8
|
type TooltipMode =
|
|
8
9
|
| 'bisect-x'
|
|
@@ -14,124 +15,214 @@
|
|
|
14
15
|
| 'quadtree'
|
|
15
16
|
| 'manual';
|
|
16
17
|
|
|
17
|
-
export type TooltipContextValue = {
|
|
18
|
+
export type TooltipContextValue<T = any> = {
|
|
18
19
|
x: number;
|
|
19
20
|
y: number;
|
|
20
|
-
data:
|
|
21
|
-
|
|
21
|
+
data: T | null;
|
|
22
|
+
payload: TooltipPayload[];
|
|
23
|
+
show(e: PointerEvent, tooltipData?: any, payload?: TooltipPayload): void;
|
|
22
24
|
hide(e?: PointerEvent): void;
|
|
23
25
|
mode: TooltipMode;
|
|
26
|
+
isHoveringTooltipArea: boolean;
|
|
27
|
+
isHoveringTooltipContent: boolean;
|
|
24
28
|
};
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export function
|
|
37
|
-
return
|
|
30
|
+
// const defaultContext = {
|
|
31
|
+
// x: 0,
|
|
32
|
+
// y: 0,
|
|
33
|
+
// data: null as any,
|
|
34
|
+
// payload: [],
|
|
35
|
+
// show: () => {},
|
|
36
|
+
// hide: () => {},
|
|
37
|
+
// mode: 'manual',
|
|
38
|
+
// } as TooltipContextValue;
|
|
39
|
+
|
|
40
|
+
export function getTooltipContext<T = any>() {
|
|
41
|
+
return _TooltipContext.get() as TooltipContextValue<T>;
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
function setTooltipContext(tooltip:
|
|
41
|
-
|
|
44
|
+
function setTooltipContext<T = any>(tooltip: TooltipContextValue<T>) {
|
|
45
|
+
return _TooltipContext.set(tooltip) as TooltipContextValue<T>;
|
|
42
46
|
}
|
|
47
|
+
|
|
48
|
+
type TooltipContextPropsWithoutHTML<T = any> = {
|
|
49
|
+
/**
|
|
50
|
+
* The tooltip interaction mode
|
|
51
|
+
* @default 'manual'
|
|
52
|
+
*/
|
|
53
|
+
mode?: TooltipMode;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Method to find tooltip data
|
|
57
|
+
* @default 'closest'
|
|
58
|
+
*/
|
|
59
|
+
findTooltipData?: 'closest' | 'left' | 'right';
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so
|
|
63
|
+
* to be the top-most element
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
raiseTarget?: boolean;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
locked?: boolean;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* quadtree search radius
|
|
76
|
+
* @default Infinity
|
|
77
|
+
*/
|
|
78
|
+
radius?: number;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Enable debug view (show hit targets, etc)
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
debug?: boolean;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Click handler for the tooltip
|
|
88
|
+
* @default () => {}
|
|
89
|
+
*/
|
|
90
|
+
onclick?: (e: MouseEvent, { data }: { data: any }) => any;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Exposed to allow binding in Chart
|
|
94
|
+
* @default { x: 0, y: 0, data: null, show: showTooltip, hide: hideTooltip, mode }
|
|
95
|
+
*/
|
|
96
|
+
tooltipContext?: TooltipContextValue<T>;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Delay in ms before hiding tooltip
|
|
100
|
+
* @default 0
|
|
101
|
+
*/
|
|
102
|
+
hideDelay?: number;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* A reference to the tooltip container element.
|
|
106
|
+
*
|
|
107
|
+
* @bindable
|
|
108
|
+
*/
|
|
109
|
+
ref?: HTMLElement;
|
|
110
|
+
|
|
111
|
+
children?: Snippet<[{ tooltipContext: TooltipContextValue<T> }]>;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export type TooltipContextProps<T = any> = TooltipContextPropsWithoutHTML<T> &
|
|
115
|
+
Without<HTMLAttributes<HTMLElement>, TooltipContextPropsWithoutHTML<T>>;
|
|
43
116
|
</script>
|
|
44
117
|
|
|
45
|
-
<script lang="ts">
|
|
46
|
-
import { raise } from 'layercake';
|
|
47
|
-
import { writable } from 'svelte/store';
|
|
118
|
+
<script lang="ts" generics="TData = any">
|
|
48
119
|
import { bisector, max, min } from 'd3-array';
|
|
49
120
|
import { quadtree as d3Quadtree, type Quadtree } from 'd3-quadtree';
|
|
50
121
|
import { sortFunc, localPoint } from '@layerstack/utils';
|
|
51
122
|
import { cls } from '@layerstack/tailwind';
|
|
52
123
|
|
|
53
124
|
import Svg from './../layout/Svg.svelte';
|
|
54
|
-
import
|
|
125
|
+
import Arc from '../Arc.svelte';
|
|
55
126
|
import ChartClipPath from './../ChartClipPath.svelte';
|
|
56
127
|
import Voronoi from './../Voronoi.svelte';
|
|
57
128
|
|
|
58
|
-
import { isScaleBand, scaleInvert } from '../../utils/scales.js';
|
|
129
|
+
import { isScaleBand, scaleInvert } from '../../utils/scales.svelte.js';
|
|
59
130
|
import { cartesianToPolar } from '../../utils/math.js';
|
|
60
131
|
import { quadtreeRects } from '../../utils/quadtree.js';
|
|
132
|
+
import { raise } from '../../utils/chart.js';
|
|
133
|
+
import { getChartContext } from '../Chart.svelte';
|
|
134
|
+
import type { Snippet } from 'svelte';
|
|
135
|
+
import {
|
|
136
|
+
getTooltipMetaContext,
|
|
137
|
+
getTooltipPayload,
|
|
138
|
+
type TooltipPayload,
|
|
139
|
+
} from './tooltipMetaContext.js';
|
|
140
|
+
import { layerClass } from '../../utils/attributes.js';
|
|
141
|
+
|
|
142
|
+
const ctx = getChartContext<any>();
|
|
143
|
+
|
|
144
|
+
let {
|
|
145
|
+
ref: refProp = $bindable(),
|
|
146
|
+
debug = false,
|
|
147
|
+
findTooltipData = 'closest',
|
|
148
|
+
hideDelay = 0,
|
|
149
|
+
locked = false,
|
|
150
|
+
mode = 'manual',
|
|
151
|
+
onclick = () => {},
|
|
152
|
+
radius = Infinity,
|
|
153
|
+
raiseTarget = false,
|
|
154
|
+
tooltipContext: tooltipContextProp = $bindable() as TooltipContextValue<TData>,
|
|
155
|
+
children,
|
|
156
|
+
}: TooltipContextProps<TData> = $props();
|
|
157
|
+
|
|
158
|
+
let ref = $state<HTMLElement>();
|
|
159
|
+
$effect.pre(() => {
|
|
160
|
+
refProp = ref;
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
let x = $state(0);
|
|
164
|
+
let y = $state(0);
|
|
165
|
+
let data = $state(null);
|
|
166
|
+
let payload = $state<TooltipPayload[]>([]);
|
|
61
167
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
168
|
+
/**
|
|
169
|
+
* If we're hovering the tooltip area on the chart
|
|
170
|
+
*/
|
|
171
|
+
let isHoveringTooltipArea = $state(false);
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* If we're hovering the tooltip content container
|
|
175
|
+
*/
|
|
176
|
+
let isHoveringTooltipContent = $state(false);
|
|
177
|
+
|
|
178
|
+
const metaCtx = getTooltipMetaContext();
|
|
179
|
+
|
|
180
|
+
const tooltipContext: TooltipContextValue = {
|
|
181
|
+
get x() {
|
|
182
|
+
return x;
|
|
183
|
+
},
|
|
184
|
+
get y() {
|
|
185
|
+
return y;
|
|
186
|
+
},
|
|
187
|
+
get data() {
|
|
188
|
+
return data;
|
|
189
|
+
},
|
|
190
|
+
get payload() {
|
|
191
|
+
return payload;
|
|
192
|
+
},
|
|
193
|
+
show: showTooltip,
|
|
194
|
+
hide: hideTooltip,
|
|
195
|
+
get mode() {
|
|
196
|
+
return mode;
|
|
197
|
+
},
|
|
198
|
+
get isHoveringTooltipArea() {
|
|
199
|
+
return isHoveringTooltipArea;
|
|
200
|
+
},
|
|
201
|
+
get isHoveringTooltipContent() {
|
|
202
|
+
return isHoveringTooltipContent;
|
|
203
|
+
},
|
|
204
|
+
set isHoveringTooltipContent(value) {
|
|
205
|
+
isHoveringTooltipContent = value;
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
tooltipContextProp = tooltipContext;
|
|
79
209
|
|
|
80
210
|
/*
|
|
81
211
|
TODO: Defaults to consider (if possible to detect scale type, which might not be possible)
|
|
82
212
|
- scaleTime / scaleLinear: bisect
|
|
83
|
-
- scaleTime / scaleLinear (multi/stack): bisect
|
|
213
|
+
- scaleTime / scaleLinear (multi/stack): bisect
|
|
84
214
|
- scaleTime / scaleBand: bisect (or band)
|
|
85
215
|
- scaleTime (multi) / scaleBand: bounds (or possible band if not overlapping)
|
|
86
216
|
- scaleBand, scaleLinear: band (or bounds)
|
|
87
217
|
- scaleBand, scaleLinear: band (or bounds) - multiple (overlapping) bars
|
|
88
218
|
- scaleLinear, scaleLinear: voronoi (or quadtree)
|
|
89
219
|
*/
|
|
220
|
+
setTooltipContext(tooltipContext);
|
|
90
221
|
|
|
91
|
-
|
|
92
|
-
* @type {'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual'}
|
|
93
|
-
*/
|
|
94
|
-
export let mode: TooltipMode = 'manual';
|
|
95
|
-
/**
|
|
96
|
-
* @type {'closest' | 'left' | 'right'}
|
|
97
|
-
*/
|
|
98
|
-
export let findTooltipData: 'closest' | 'left' | 'right' = 'closest';
|
|
99
|
-
|
|
100
|
-
/** Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so to be the top-most element */
|
|
101
|
-
export let raiseTarget = false;
|
|
102
|
-
|
|
103
|
-
/** Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip */
|
|
104
|
-
export let locked = false;
|
|
105
|
-
|
|
106
|
-
/** quadtree search radius
|
|
107
|
-
* @type {number}
|
|
108
|
-
*/
|
|
109
|
-
export let radius: number = Infinity;
|
|
110
|
-
/** Enable debug view (show hit targets, etc) */
|
|
111
|
-
export let debug = false;
|
|
112
|
-
|
|
113
|
-
export let onclick: (e: MouseEvent, { data }: { data: any }) => any = () => {};
|
|
114
|
-
|
|
115
|
-
/** Exposed to allow binding in Chart */
|
|
116
|
-
export let tooltip = writable({
|
|
117
|
-
x: 0,
|
|
118
|
-
y: 0,
|
|
119
|
-
data: null as any,
|
|
120
|
-
show: showTooltip,
|
|
121
|
-
hide: hideTooltip,
|
|
122
|
-
mode,
|
|
123
|
-
});
|
|
124
|
-
setTooltipContext(tooltip);
|
|
125
|
-
|
|
126
|
-
/** Delay in ms before hiding tooltip */
|
|
127
|
-
export let hideDelay = 0;
|
|
222
|
+
let hideTimeoutId: ReturnType<typeof setTimeout>;
|
|
128
223
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
let tooltipContextNode: HTMLDivElement;
|
|
132
|
-
|
|
133
|
-
$: bisectX = bisector((d: any) => {
|
|
134
|
-
const value = $x(d);
|
|
224
|
+
const bisectX = bisector((d: any) => {
|
|
225
|
+
const value = ctx.x(d);
|
|
135
226
|
if (Array.isArray(value)) {
|
|
136
227
|
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
137
228
|
// Using first value. Consider using average, max, etc
|
|
@@ -143,8 +234,8 @@
|
|
|
143
234
|
}
|
|
144
235
|
}).left;
|
|
145
236
|
|
|
146
|
-
|
|
147
|
-
const value =
|
|
237
|
+
const bisectY = bisector((d: any) => {
|
|
238
|
+
const value = ctx.y(d);
|
|
148
239
|
if (Array.isArray(value)) {
|
|
149
240
|
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
150
241
|
// Using first value. Consider using average, max, etc
|
|
@@ -188,15 +279,16 @@
|
|
|
188
279
|
return;
|
|
189
280
|
}
|
|
190
281
|
|
|
191
|
-
const containerNode = (e.target as Element).closest('.
|
|
282
|
+
const containerNode = (e.target as Element).closest('.lc-root-container')!;
|
|
192
283
|
const point = localPoint(e, containerNode);
|
|
193
284
|
|
|
194
285
|
if (
|
|
286
|
+
ref !== undefined &&
|
|
195
287
|
tooltipData == null && // mode !== 'manual' but support annotations
|
|
196
|
-
(point.x <
|
|
197
|
-
point.x >
|
|
198
|
-
point.y <
|
|
199
|
-
point.y >
|
|
288
|
+
(point.x < ref.offsetLeft ||
|
|
289
|
+
point.x > ref.offsetLeft + ref.offsetWidth ||
|
|
290
|
+
point.y < ref.offsetTop ||
|
|
291
|
+
point.y > ref.offsetTop + ref.offsetHeight)
|
|
200
292
|
) {
|
|
201
293
|
// Ignore if within padding of chart
|
|
202
294
|
hideTooltip();
|
|
@@ -209,55 +301,55 @@
|
|
|
209
301
|
switch (mode) {
|
|
210
302
|
case 'bisect-x': {
|
|
211
303
|
let xValueAtPoint: any;
|
|
212
|
-
if (
|
|
304
|
+
if (ctx.radial) {
|
|
213
305
|
// Assume radial is always centered
|
|
214
|
-
const { radians } = cartesianToPolar(point.x -
|
|
215
|
-
xValueAtPoint = scaleInvert(
|
|
306
|
+
const { radians } = cartesianToPolar(point.x - ctx.width / 2, point.y - ctx.height / 2);
|
|
307
|
+
xValueAtPoint = scaleInvert(ctx.xScale, radians);
|
|
216
308
|
} else {
|
|
217
|
-
xValueAtPoint = scaleInvert(
|
|
309
|
+
xValueAtPoint = scaleInvert(ctx.xScale, point.x - ctx.padding.left);
|
|
218
310
|
}
|
|
219
311
|
|
|
220
|
-
const index = bisectX(
|
|
221
|
-
const previousValue =
|
|
222
|
-
const currentValue =
|
|
223
|
-
tooltipData = findData(previousValue, currentValue, xValueAtPoint,
|
|
312
|
+
const index = bisectX(ctx.flatData, xValueAtPoint, 1);
|
|
313
|
+
const previousValue = ctx.flatData[index - 1];
|
|
314
|
+
const currentValue = ctx.flatData[index];
|
|
315
|
+
tooltipData = findData(previousValue, currentValue, xValueAtPoint, ctx.x);
|
|
224
316
|
break;
|
|
225
317
|
}
|
|
226
318
|
|
|
227
319
|
case 'bisect-y': {
|
|
228
320
|
// `y` value at pointer coordinate
|
|
229
|
-
const yValueAtPoint = scaleInvert(
|
|
321
|
+
const yValueAtPoint = scaleInvert(ctx.yScale, point.y - ctx.padding.top);
|
|
230
322
|
|
|
231
|
-
const index = bisectY(
|
|
232
|
-
const previousValue =
|
|
233
|
-
const currentValue =
|
|
234
|
-
tooltipData = findData(previousValue, currentValue, yValueAtPoint,
|
|
323
|
+
const index = bisectY(ctx.flatData, yValueAtPoint, 1);
|
|
324
|
+
const previousValue = ctx.flatData[index - 1];
|
|
325
|
+
const currentValue = ctx.flatData[index];
|
|
326
|
+
tooltipData = findData(previousValue, currentValue, yValueAtPoint, ctx.y);
|
|
235
327
|
break;
|
|
236
328
|
}
|
|
237
329
|
|
|
238
330
|
case 'bisect-band': {
|
|
239
331
|
// `x` and `y` values at pointer coordinate
|
|
240
|
-
const xValueAtPoint = scaleInvert(
|
|
241
|
-
const yValueAtPoint = scaleInvert(
|
|
332
|
+
const xValueAtPoint = scaleInvert(ctx.xScale, point.x);
|
|
333
|
+
const yValueAtPoint = scaleInvert(ctx.yScale, point.y);
|
|
242
334
|
|
|
243
|
-
if (isScaleBand(
|
|
335
|
+
if (isScaleBand(ctx.xScale)) {
|
|
244
336
|
// Find point closest to pointer within the x band
|
|
245
|
-
const bandData =
|
|
246
|
-
.filter((d) =>
|
|
247
|
-
.sort(sortFunc(
|
|
337
|
+
const bandData = ctx.flatData
|
|
338
|
+
.filter((d) => ctx.x(d) === xValueAtPoint)
|
|
339
|
+
.sort(sortFunc(ctx.y as () => any)); // sort for bisect
|
|
248
340
|
const index = bisectY(bandData, yValueAtPoint, 1);
|
|
249
341
|
const previousValue = bandData[index - 1];
|
|
250
342
|
const currentValue = bandData[index];
|
|
251
|
-
tooltipData = findData(previousValue, currentValue, yValueAtPoint,
|
|
252
|
-
} else if (isScaleBand(
|
|
343
|
+
tooltipData = findData(previousValue, currentValue, yValueAtPoint, ctx.y);
|
|
344
|
+
} else if (isScaleBand(ctx.yScale)) {
|
|
253
345
|
// Find point closest to pointer within the y band
|
|
254
|
-
const bandData =
|
|
255
|
-
.filter((d) =>
|
|
256
|
-
.sort(sortFunc(
|
|
346
|
+
const bandData = ctx.flatData
|
|
347
|
+
.filter((d) => ctx.y(d) === yValueAtPoint)
|
|
348
|
+
.sort(sortFunc(ctx.x as () => any)); // sort for bisect
|
|
257
349
|
const index = bisectX(bandData, xValueAtPoint, 1);
|
|
258
350
|
const previousValue = bandData[index - 1];
|
|
259
351
|
const currentValue = bandData[index];
|
|
260
|
-
tooltipData = findData(previousValue, currentValue, xValueAtPoint,
|
|
352
|
+
tooltipData = findData(previousValue, currentValue, xValueAtPoint, ctx.x);
|
|
261
353
|
} else {
|
|
262
354
|
// TODO: Support `bisect-band` without band? Fallback to bisect?
|
|
263
355
|
}
|
|
@@ -265,7 +357,7 @@
|
|
|
265
357
|
}
|
|
266
358
|
|
|
267
359
|
case 'quadtree': {
|
|
268
|
-
tooltipData = quadtree
|
|
360
|
+
tooltipData = quadtree?.find(point.x, point.y, radius);
|
|
269
361
|
break;
|
|
270
362
|
}
|
|
271
363
|
}
|
|
@@ -276,12 +368,12 @@
|
|
|
276
368
|
raise(e.target as Element);
|
|
277
369
|
}
|
|
278
370
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
371
|
+
const payloadData = getTooltipPayload({ ctx, tooltipData, metaCtx });
|
|
372
|
+
|
|
373
|
+
x = point.x;
|
|
374
|
+
y = point.y;
|
|
375
|
+
data = tooltipData;
|
|
376
|
+
payload = payloadData;
|
|
285
377
|
} else {
|
|
286
378
|
// Hide tooltip if unable to locate
|
|
287
379
|
hideTooltip();
|
|
@@ -294,149 +386,162 @@
|
|
|
294
386
|
return;
|
|
295
387
|
}
|
|
296
388
|
|
|
297
|
-
|
|
389
|
+
isHoveringTooltipArea = false;
|
|
390
|
+
|
|
391
|
+
// Wait an event loop tick in case `showTooltip` is called immediately on another element,
|
|
392
|
+
// to allow tweening (ex. moving between bands/bars)
|
|
298
393
|
// Additional hideDelay can be configured to extend this delay further
|
|
299
394
|
hideTimeoutId = setTimeout(() => {
|
|
300
|
-
if (!
|
|
301
|
-
|
|
395
|
+
if (!isHoveringTooltipArea && !isHoveringTooltipContent) {
|
|
396
|
+
data = null;
|
|
397
|
+
payload = [];
|
|
302
398
|
}
|
|
303
399
|
}, hideDelay);
|
|
304
400
|
}
|
|
305
401
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
402
|
+
const quadtree: Quadtree<[number, number]> | undefined = $derived.by(() => {
|
|
403
|
+
if (mode === 'quadtree') {
|
|
404
|
+
return d3Quadtree()
|
|
405
|
+
.extent([
|
|
406
|
+
[0, 0],
|
|
407
|
+
[ctx.width, ctx.height],
|
|
408
|
+
])
|
|
409
|
+
.x((d) => {
|
|
410
|
+
const value = ctx.xGet(d);
|
|
411
|
+
|
|
412
|
+
if (Array.isArray(value)) {
|
|
413
|
+
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
414
|
+
// Using first value. Consider using average, max, etc
|
|
415
|
+
// const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
|
|
416
|
+
// return midpoint;
|
|
417
|
+
return min(value);
|
|
418
|
+
} else {
|
|
419
|
+
return value;
|
|
420
|
+
}
|
|
421
|
+
})
|
|
422
|
+
.y((d) => {
|
|
423
|
+
const value = ctx.yGet(d);
|
|
424
|
+
|
|
425
|
+
if (Array.isArray(value)) {
|
|
426
|
+
// `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
|
|
427
|
+
// Using first value. Consider using average, max, etc
|
|
428
|
+
// const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
|
|
429
|
+
// return midpoint;
|
|
430
|
+
return min(value);
|
|
431
|
+
} else {
|
|
432
|
+
return value;
|
|
433
|
+
}
|
|
434
|
+
})
|
|
435
|
+
.addAll(ctx.flatData as [number, number][]);
|
|
436
|
+
}
|
|
437
|
+
});
|
|
341
438
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
439
|
+
const rects: Array<{ x: number; y: number; width: number; height: number; data: any }> =
|
|
440
|
+
$derived.by(() => {
|
|
441
|
+
if (mode === 'bounds' || mode === 'band') {
|
|
442
|
+
return ctx.flatData
|
|
443
|
+
.map((d) => {
|
|
444
|
+
const xValue = ctx.xGet(d);
|
|
445
|
+
const yValue = ctx.yGet(d);
|
|
446
|
+
|
|
447
|
+
const x = Array.isArray(xValue) ? xValue[0] : xValue;
|
|
448
|
+
const y = Array.isArray(yValue) ? yValue[0] : yValue;
|
|
449
|
+
|
|
450
|
+
const xOffset = isScaleBand(ctx.xScale)
|
|
451
|
+
? (ctx.xScale.padding() * ctx.xScale.step()) / 2
|
|
452
|
+
: 0;
|
|
453
|
+
const yOffset = isScaleBand(ctx.yScale)
|
|
454
|
+
? (ctx.yScale.padding() * ctx.yScale.step()) / 2
|
|
455
|
+
: 0;
|
|
456
|
+
|
|
457
|
+
const fullWidth = max(ctx.xRange) - min(ctx.xRange);
|
|
458
|
+
const fullHeight = max(ctx.yRange) - min(ctx.yRange);
|
|
459
|
+
|
|
460
|
+
if (mode === 'band') {
|
|
461
|
+
// full band width/height regardless of value
|
|
462
|
+
return {
|
|
463
|
+
x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange),
|
|
464
|
+
y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange),
|
|
465
|
+
width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth,
|
|
466
|
+
height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight,
|
|
467
|
+
data: d,
|
|
468
|
+
};
|
|
469
|
+
} else if (mode === 'bounds') {
|
|
470
|
+
return {
|
|
471
|
+
x: isScaleBand(ctx.xScale) || Array.isArray(xValue) ? x - xOffset : min(ctx.xRange),
|
|
472
|
+
// y: isScaleBand($yScale) || Array.isArray(yValue) ? y - yOffset : min($yRange),
|
|
473
|
+
y: y - yOffset,
|
|
474
|
+
|
|
475
|
+
width: Array.isArray(xValue)
|
|
476
|
+
? xValue[1] - xValue[0]
|
|
477
|
+
: isScaleBand(ctx.xScale)
|
|
478
|
+
? ctx.xScale.step()
|
|
479
|
+
: min(ctx.xRange) + x,
|
|
480
|
+
height: Array.isArray(yValue)
|
|
481
|
+
? yValue[1] - yValue[0]
|
|
482
|
+
: isScaleBand(ctx.yScale)
|
|
483
|
+
? ctx.yScale.step()
|
|
484
|
+
: max(ctx.yRange) - y,
|
|
485
|
+
data: d,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
})
|
|
489
|
+
.filter((x) => x !== undefined) // make typescript happy
|
|
490
|
+
.sort(sortFunc('x'));
|
|
491
|
+
}
|
|
492
|
+
return [];
|
|
493
|
+
});
|
|
393
494
|
|
|
394
|
-
|
|
495
|
+
const triggerPointerEvents = $derived(
|
|
496
|
+
['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode)
|
|
497
|
+
);
|
|
395
498
|
</script>
|
|
396
499
|
|
|
397
|
-
<!-- svelte-ignore
|
|
398
|
-
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
|
500
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
399
501
|
<div
|
|
400
|
-
style:top="{
|
|
401
|
-
style:left="{
|
|
402
|
-
style:width="{
|
|
403
|
-
style:height="{
|
|
502
|
+
style:top="{ctx.padding.top}px"
|
|
503
|
+
style:left="{ctx.padding.left}px"
|
|
504
|
+
style:width="{ctx.width}px"
|
|
505
|
+
style:height="{ctx.height}px"
|
|
404
506
|
class={cls(
|
|
405
|
-
'
|
|
507
|
+
layerClass('tooltip-context'),
|
|
508
|
+
'absolute touch-none',
|
|
406
509
|
debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
|
|
407
510
|
)}
|
|
408
|
-
|
|
409
|
-
|
|
511
|
+
onpointerenter={(e) => {
|
|
512
|
+
isHoveringTooltipArea = true;
|
|
410
513
|
if (triggerPointerEvents) {
|
|
411
514
|
showTooltip(e);
|
|
412
515
|
}
|
|
413
516
|
}}
|
|
414
|
-
|
|
517
|
+
onpointermove={(e) => {
|
|
415
518
|
if (triggerPointerEvents) {
|
|
416
519
|
showTooltip(e);
|
|
417
520
|
}
|
|
418
521
|
}}
|
|
419
|
-
|
|
420
|
-
|
|
522
|
+
onpointerleave={(e) => {
|
|
523
|
+
isHoveringTooltipArea = false;
|
|
524
|
+
|
|
421
525
|
hideTooltip();
|
|
422
526
|
}}
|
|
423
|
-
|
|
527
|
+
onclick={(e) => {
|
|
424
528
|
// Ignore clicks without data (triggered from Legend clicks, for example)
|
|
425
|
-
if (triggerPointerEvents &&
|
|
426
|
-
onclick(e, { data:
|
|
529
|
+
if (triggerPointerEvents && tooltipContext.data != null) {
|
|
530
|
+
onclick(e, { data: tooltipContext.data });
|
|
427
531
|
}
|
|
428
532
|
}}
|
|
429
|
-
|
|
533
|
+
onkeydown={() => {}}
|
|
534
|
+
bind:this={ref}
|
|
430
535
|
>
|
|
431
536
|
<!-- Rendering slot within TooltipContext to allow pointer events to bubble up (ex. Brush) -->
|
|
432
537
|
<div
|
|
433
|
-
class=
|
|
434
|
-
style:top="-{
|
|
435
|
-
style:left="-{
|
|
436
|
-
style:width="{
|
|
437
|
-
style:height="{
|
|
538
|
+
class={cls(layerClass('tooltip-context-container'), 'absolute')}
|
|
539
|
+
style:top="-{ctx.padding.top ?? 0}px"
|
|
540
|
+
style:left="-{ctx.padding.left ?? 0}px"
|
|
541
|
+
style:width="{ctx.containerWidth}px"
|
|
542
|
+
style:height="{ctx.containerHeight}px"
|
|
438
543
|
>
|
|
439
|
-
|
|
544
|
+
{@render children?.({ tooltipContext: tooltipContext })}
|
|
440
545
|
|
|
441
546
|
{#if mode === 'voronoi'}
|
|
442
547
|
<Svg>
|
|
@@ -447,7 +552,7 @@
|
|
|
447
552
|
onpointermove={(e, { data }) => {
|
|
448
553
|
showTooltip(e, data);
|
|
449
554
|
}}
|
|
450
|
-
onpointerleave={hideTooltip}
|
|
555
|
+
onpointerleave={() => hideTooltip()}
|
|
451
556
|
onpointerdown={(e) => {
|
|
452
557
|
// @ts-expect-error
|
|
453
558
|
if (e.target?.hasPointerCapture(e.pointerId)) {
|
|
@@ -462,45 +567,78 @@
|
|
|
462
567
|
/>
|
|
463
568
|
</Svg>
|
|
464
569
|
{:else if mode === 'bounds' || mode === 'band'}
|
|
465
|
-
<Svg>
|
|
466
|
-
<g class=
|
|
570
|
+
<Svg center={ctx.radial}>
|
|
571
|
+
<g class={layerClass('tooltip-rects-g')}>
|
|
467
572
|
{#each rects as rect}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
573
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
574
|
+
{#if ctx.radial}
|
|
575
|
+
<Arc
|
|
576
|
+
innerRadius={rect.y}
|
|
577
|
+
outerRadius={rect.y + rect.height}
|
|
578
|
+
startAngle={rect.x}
|
|
579
|
+
endAngle={rect.x + rect.width}
|
|
580
|
+
class={cls(
|
|
581
|
+
layerClass('tooltip-rect'),
|
|
582
|
+
debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
|
|
583
|
+
)}
|
|
584
|
+
onpointerenter={(e) => showTooltip(e, rect?.data)}
|
|
585
|
+
onpointermove={(e) => showTooltip(e, rect?.data)}
|
|
586
|
+
onpointerleave={() => hideTooltip()}
|
|
587
|
+
onpointerdown={(e) => {
|
|
588
|
+
const target = e.target as Element;
|
|
589
|
+
if (target?.hasPointerCapture(e.pointerId)) {
|
|
590
|
+
target.releasePointerCapture(e.pointerId);
|
|
591
|
+
}
|
|
592
|
+
}}
|
|
593
|
+
onclick={(e) => {
|
|
594
|
+
onclick(e, { data: rect?.data });
|
|
595
|
+
}}
|
|
596
|
+
/>
|
|
597
|
+
{:else}
|
|
598
|
+
<rect
|
|
599
|
+
x={rect?.x}
|
|
600
|
+
y={rect?.y}
|
|
601
|
+
width={rect?.width}
|
|
602
|
+
height={rect?.height}
|
|
603
|
+
class={cls(
|
|
604
|
+
layerClass('tooltip-rect'),
|
|
605
|
+
debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
|
|
606
|
+
)}
|
|
607
|
+
onpointerenter={(e) => showTooltip(e, rect?.data)}
|
|
608
|
+
onpointermove={(e) => showTooltip(e, rect?.data)}
|
|
609
|
+
onpointerleave={() => hideTooltip()}
|
|
610
|
+
onpointerdown={(e) => {
|
|
611
|
+
const target = e.target as Element;
|
|
612
|
+
if (target?.hasPointerCapture(e.pointerId)) {
|
|
613
|
+
target.releasePointerCapture(e.pointerId);
|
|
614
|
+
}
|
|
615
|
+
}}
|
|
616
|
+
onclick={(e) => {
|
|
617
|
+
onclick(e, { data: rect?.data });
|
|
618
|
+
}}
|
|
619
|
+
/>
|
|
620
|
+
{/if}
|
|
488
621
|
{/each}
|
|
489
622
|
</g>
|
|
490
623
|
</Svg>
|
|
491
624
|
{:else if mode === 'quadtree' && debug}
|
|
492
625
|
<Svg pointerEvents={false}>
|
|
493
626
|
<ChartClipPath>
|
|
494
|
-
<g class=
|
|
495
|
-
{#
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
627
|
+
<g class={layerClass('tooltip-quadtree-g')}>
|
|
628
|
+
{#if quadtree}
|
|
629
|
+
{#each quadtreeRects(quadtree, false) as rect}
|
|
630
|
+
<rect
|
|
631
|
+
x={rect.x}
|
|
632
|
+
y={rect.y}
|
|
633
|
+
width={rect.width}
|
|
634
|
+
height={rect.height}
|
|
635
|
+
class={cls(
|
|
636
|
+
layerClass('tooltip-quadtree-rect'),
|
|
637
|
+
debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
|
|
638
|
+
)}
|
|
639
|
+
/>
|
|
640
|
+
{/each}
|
|
641
|
+
{/if}
|
|
504
642
|
</g>
|
|
505
643
|
</ChartClipPath>
|
|
506
644
|
</Svg>
|