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