@internetstiftelsen/charts 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,7 @@ A framework-agnostic, composable charting library built on D3.js with TypeScript
11
11
  - **Divergent Bar Support** - Bar charts automatically render from zero and diverge around `0` for mixed positive/negative values
12
12
  - **Mirrored Bar Sides** - Horizontal bars can mirror a series to the left for population-pyramid style charts without changing source data
13
13
  - **Custom Value Labels** - XY, pie, donut, and gauge charts support configurable labels with formatters, max-width overflow behavior, and forced rendering when labels would otherwise be hidden
14
+ - **Axis Label Overflow** - X/Y tick labels and grouped X-axis labels support max-width overflow behavior
14
15
  - **Optional XY Animation** - Animate XY series on first render and `chart.update(...)` with `animate`
15
16
  - **Optional Radial Animation** - Animate pie and donut segments on first render and `chart.update(...)` with `animate`
16
17
  - **Optional Gauge Animation** - Animate gauge value transitions with `gauge.animate`
@@ -349,6 +350,9 @@ const chart = new XYChart({
349
350
  });
350
351
  ```
351
352
 
353
+ The exported `defaultResponsiveConfig` also switches tooltip components to
354
+ `mode: 'shared'` at its `sm` breakpoint for compact XY charts.
355
+
352
356
  ## Word Cloud
353
357
 
354
358
  ```javascript
package/dist/theme.js CHANGED
@@ -325,6 +325,12 @@ export const defaultResponsiveConfig = {
325
325
  tooltip: { fontSize: 11 },
326
326
  valueLabel: { fontSize: 10 },
327
327
  },
328
+ components: [
329
+ {
330
+ match: { type: 'tooltip' },
331
+ override: { mode: 'shared' },
332
+ },
333
+ ],
328
334
  },
329
335
  md: {
330
336
  minWidth: 480,
@@ -0,0 +1,56 @@
1
+ import type { ChartTheme, TooltipTransitionConfig } from '../types.js';
2
+ import { type TooltipAnchor, type TooltipArrowEdge, type TooltipDivSelection } from './types.js';
3
+ type TooltipDomConfig = {
4
+ id: string;
5
+ splitTooltipOwner: string;
6
+ maxWidth: number;
7
+ transition: Required<TooltipTransitionConfig>;
8
+ };
9
+ export declare class TooltipDom {
10
+ private readonly id;
11
+ private readonly splitTooltipOwner;
12
+ private readonly maxWidth;
13
+ private readonly transition;
14
+ private readonly tooltipStyleKeys;
15
+ private readonly tooltipTransitionFrameIds;
16
+ private tooltipDiv;
17
+ private tooltipTheme;
18
+ constructor(config: TooltipDomConfig);
19
+ initialize(theme: ChartTheme): void;
20
+ getRootTooltip(): TooltipDivSelection | null;
21
+ setContent(content: string): void;
22
+ getBounds(): DOMRect | null;
23
+ showAt(left: number, top: number): void;
24
+ hide(): void;
25
+ cleanup(): void;
26
+ measureTooltip(tooltip: TooltipDivSelection, content: string): {
27
+ width: number;
28
+ height: number;
29
+ } | null;
30
+ renderTooltipWithConnector(tooltip: TooltipDivSelection, arrowEdge: TooltipArrowEdge, left: number, top: number, tooltipWidth: number, tooltipHeight: number, targetX: number, targetY: number, anchor: TooltipAnchor): void;
31
+ renderTooltipWithoutConnector(tooltip: TooltipDivSelection, left: number, top: number): void;
32
+ hideTooltipSelection(tooltip: TooltipDivSelection): void;
33
+ getSplitTooltip(index: number, theme: ChartTheme): TooltipDivSelection;
34
+ hideSplitTooltips(): void;
35
+ hideUnusedSplitTooltips(visibleTooltips: TooltipDivSelection[]): void;
36
+ private applyTooltipStylesIfNeeded;
37
+ private getTooltipStyleKey;
38
+ private writeTooltipStyles;
39
+ private showTooltipAt;
40
+ private showTooltipSelection;
41
+ private hideTooltipElement;
42
+ private getTooltipTransitionStyle;
43
+ private isTooltipVisible;
44
+ private getTooltipPosition;
45
+ private hasVisibleSlideOffset;
46
+ private slideTooltipFromOffset;
47
+ private requestTooltipTransitionFrame;
48
+ private cancelTooltipTransitionFrame;
49
+ private setTooltipMarkup;
50
+ private appendTooltipConnector;
51
+ private appendTooltipArrow;
52
+ private appendTooltipArrowTriangle;
53
+ private removeSplitTooltips;
54
+ private removeRootTooltip;
55
+ }
56
+ export {};
@@ -0,0 +1,438 @@
1
+ import { select } from 'd3';
2
+ import { resolveTooltipArrowPosition, resolveTooltipConnectorLayout, } from './geometry.js';
3
+ import { TOOLTIP_ARROW_BORDER_Z_INDEX, TOOLTIP_ARROW_FILL_Z_INDEX, TOOLTIP_BODY_Z_INDEX, TOOLTIP_BORDER_WIDTH_PX, TOOLTIP_BOX_ARROW_HALF_HEIGHT_PX, TOOLTIP_BOX_ARROW_LENGTH_PX, TOOLTIP_CONNECTOR_Z_INDEX, TOOLTIP_HIDDEN_TRANSFORM, TOOLTIP_ROOT_Z_INDEX, TOOLTIP_VISIBLE_TRANSFORM, } from './types.js';
4
+ export class TooltipDom {
5
+ constructor(config) {
6
+ Object.defineProperty(this, "id", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: void 0
11
+ });
12
+ Object.defineProperty(this, "splitTooltipOwner", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: void 0
17
+ });
18
+ Object.defineProperty(this, "maxWidth", {
19
+ enumerable: true,
20
+ configurable: true,
21
+ writable: true,
22
+ value: void 0
23
+ });
24
+ Object.defineProperty(this, "transition", {
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true,
28
+ value: void 0
29
+ });
30
+ Object.defineProperty(this, "tooltipStyleKeys", {
31
+ enumerable: true,
32
+ configurable: true,
33
+ writable: true,
34
+ value: new WeakMap()
35
+ });
36
+ Object.defineProperty(this, "tooltipTransitionFrameIds", {
37
+ enumerable: true,
38
+ configurable: true,
39
+ writable: true,
40
+ value: new WeakMap()
41
+ });
42
+ Object.defineProperty(this, "tooltipDiv", {
43
+ enumerable: true,
44
+ configurable: true,
45
+ writable: true,
46
+ value: null
47
+ });
48
+ Object.defineProperty(this, "tooltipTheme", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: null
53
+ });
54
+ this.id = config.id;
55
+ this.splitTooltipOwner = config.splitTooltipOwner;
56
+ this.maxWidth = config.maxWidth;
57
+ this.transition = config.transition;
58
+ }
59
+ initialize(theme) {
60
+ const existingTooltip = select(`#${this.id}`);
61
+ const tooltip = existingTooltip.empty()
62
+ ? select('body')
63
+ .append('div')
64
+ .attr('class', 'chart-tooltip')
65
+ .attr('id', this.id)
66
+ : existingTooltip;
67
+ this.removeSplitTooltips();
68
+ this.applyTooltipStylesIfNeeded(tooltip, theme);
69
+ this.tooltipDiv = tooltip;
70
+ this.hideTooltipSelection(tooltip);
71
+ }
72
+ getRootTooltip() {
73
+ return this.tooltipDiv;
74
+ }
75
+ setContent(content) {
76
+ if (!this.tooltipDiv) {
77
+ return;
78
+ }
79
+ this.setTooltipMarkup(this.tooltipDiv, content);
80
+ }
81
+ getBounds() {
82
+ const node = this.tooltipDiv?.node();
83
+ if (!node) {
84
+ return null;
85
+ }
86
+ return node.getBoundingClientRect();
87
+ }
88
+ showAt(left, top) {
89
+ if (!this.tooltipDiv) {
90
+ return;
91
+ }
92
+ if (!Number.isFinite(left) || !Number.isFinite(top)) {
93
+ this.hide();
94
+ return;
95
+ }
96
+ this.showTooltipAt(this.tooltipDiv, left, top);
97
+ }
98
+ hide() {
99
+ const tooltip = this.tooltipDiv ?? select(`#${this.id}`);
100
+ if (!tooltip.empty()) {
101
+ this.hideTooltipSelection(tooltip);
102
+ }
103
+ this.hideSplitTooltips();
104
+ }
105
+ cleanup() {
106
+ this.removeRootTooltip();
107
+ this.removeSplitTooltips();
108
+ this.tooltipDiv = null;
109
+ }
110
+ measureTooltip(tooltip, content) {
111
+ this.setTooltipMarkup(tooltip, content);
112
+ const tooltipNode = tooltip.node();
113
+ if (!tooltipNode) {
114
+ return null;
115
+ }
116
+ if (!this.isTooltipVisible(tooltipNode)) {
117
+ tooltip.style('left', '-9999px').style('top', '-9999px');
118
+ this.hideTooltipSelection(tooltip);
119
+ }
120
+ const tooltipRect = tooltipNode.getBoundingClientRect();
121
+ if (!Number.isFinite(tooltipRect.width) ||
122
+ !Number.isFinite(tooltipRect.height)) {
123
+ return null;
124
+ }
125
+ return {
126
+ width: tooltipRect.width,
127
+ height: tooltipRect.height,
128
+ };
129
+ }
130
+ renderTooltipWithConnector(tooltip, arrowEdge, left, top, tooltipWidth, tooltipHeight, targetX, targetY, anchor) {
131
+ if (!Number.isFinite(left) ||
132
+ !Number.isFinite(top) ||
133
+ !Number.isFinite(targetX) ||
134
+ !Number.isFinite(targetY)) {
135
+ this.hideTooltipSelection(tooltip);
136
+ return;
137
+ }
138
+ const connectorLayout = resolveTooltipConnectorLayout(arrowEdge, left, top, tooltipWidth, tooltipHeight, targetX, targetY, anchor);
139
+ if (!connectorLayout) {
140
+ this.hideTooltipSelection(tooltip);
141
+ return;
142
+ }
143
+ this.appendTooltipConnector(tooltip, connectorLayout);
144
+ this.appendTooltipArrow(tooltip, connectorLayout);
145
+ this.showTooltipAt(tooltip, left, top);
146
+ }
147
+ renderTooltipWithoutConnector(tooltip, left, top) {
148
+ if (!Number.isFinite(left) || !Number.isFinite(top)) {
149
+ this.hideTooltipSelection(tooltip);
150
+ return;
151
+ }
152
+ this.showTooltipAt(tooltip, left, top);
153
+ }
154
+ hideTooltipSelection(tooltip) {
155
+ const node = tooltip.node();
156
+ if (!node) {
157
+ return;
158
+ }
159
+ this.hideTooltipElement(node);
160
+ }
161
+ getSplitTooltip(index, theme) {
162
+ const tooltipId = `${this.splitTooltipOwner}-${index}`;
163
+ const existingTooltip = select(`#${tooltipId}`);
164
+ const tooltip = existingTooltip.empty()
165
+ ? select('body')
166
+ .append('div')
167
+ .attr('class', 'chart-tooltip chart-tooltip--split')
168
+ .attr('id', tooltipId)
169
+ .attr('data-chart-tooltip-owner', this.splitTooltipOwner)
170
+ .attr('data-chart-tooltip-index', String(index))
171
+ : existingTooltip;
172
+ this.applyTooltipStylesIfNeeded(tooltip, theme);
173
+ return tooltip;
174
+ }
175
+ hideSplitTooltips() {
176
+ document
177
+ .querySelectorAll(`[data-chart-tooltip-owner="${this.splitTooltipOwner}"]`)
178
+ .forEach((node) => {
179
+ this.hideTooltipElement(node);
180
+ });
181
+ }
182
+ hideUnusedSplitTooltips(visibleTooltips) {
183
+ const visibleNodes = new Set(visibleTooltips
184
+ .map((tooltip) => tooltip.node())
185
+ .filter((node) => Boolean(node)));
186
+ document
187
+ .querySelectorAll(`[data-chart-tooltip-owner="${this.splitTooltipOwner}"]`)
188
+ .forEach((node) => {
189
+ if (visibleNodes.has(node)) {
190
+ return;
191
+ }
192
+ this.hideTooltipElement(node);
193
+ });
194
+ }
195
+ applyTooltipStylesIfNeeded(tooltip, theme) {
196
+ const node = tooltip.node();
197
+ if (!node) {
198
+ return;
199
+ }
200
+ const styleKey = this.getTooltipStyleKey(theme);
201
+ if (this.tooltipStyleKeys.get(node) === styleKey) {
202
+ this.tooltipTheme = theme.tooltip;
203
+ return;
204
+ }
205
+ this.tooltipStyleKeys.set(node, styleKey);
206
+ this.writeTooltipStyles(tooltip, theme);
207
+ }
208
+ getTooltipStyleKey(theme) {
209
+ return [
210
+ theme.tooltip.background,
211
+ theme.tooltip.border,
212
+ theme.tooltip.color,
213
+ theme.tooltip.fontFamily,
214
+ theme.tooltip.fontSize,
215
+ theme.tooltip.fontWeight,
216
+ this.maxWidth,
217
+ this.transition.show,
218
+ this.transition.duration,
219
+ this.transition.easing,
220
+ ].join('|');
221
+ }
222
+ writeTooltipStyles(tooltip, theme) {
223
+ this.tooltipTheme = theme.tooltip;
224
+ tooltip
225
+ .style('position', 'absolute')
226
+ .style('background-color', theme.tooltip.background)
227
+ .style('border', `${TOOLTIP_BORDER_WIDTH_PX}px solid ${theme.tooltip.border}`)
228
+ .style('border-radius', '4px')
229
+ .style('padding', '8px')
230
+ .style('box-shadow', '0 2px 4px rgba(0,0,0,0.1)')
231
+ .style('color', theme.tooltip.color)
232
+ .style('font-family', theme.tooltip.fontFamily)
233
+ .style('font-size', `${theme.tooltip.fontSize}px`)
234
+ .style('font-weight', theme.tooltip.fontWeight)
235
+ .style('box-sizing', 'border-box')
236
+ .style('overflow-wrap', 'break-word')
237
+ .style('overflow', 'visible')
238
+ .style('isolation', 'isolate')
239
+ .style('pointer-events', 'none')
240
+ .style('z-index', String(TOOLTIP_ROOT_Z_INDEX));
241
+ tooltip.style('max-width', `${this.maxWidth}px`);
242
+ if (this.transition.show) {
243
+ tooltip
244
+ .style('transition', this.getTooltipTransitionStyle())
245
+ .style('will-change', 'opacity, transform');
246
+ return;
247
+ }
248
+ tooltip
249
+ .style('opacity', null)
250
+ .style('transform', null)
251
+ .style('transition', null)
252
+ .style('will-change', null);
253
+ }
254
+ showTooltipAt(tooltip, left, top) {
255
+ const tooltipNode = tooltip.node();
256
+ const previousPosition = tooltipNode && this.isTooltipVisible(tooltipNode)
257
+ ? this.getTooltipPosition(tooltipNode)
258
+ : null;
259
+ tooltip.style('left', `${left}px`).style('top', `${top}px`);
260
+ this.showTooltipSelection(tooltip, previousPosition
261
+ ? {
262
+ x: previousPosition.left - left,
263
+ y: previousPosition.top - top,
264
+ }
265
+ : null);
266
+ }
267
+ showTooltipSelection(tooltip, slideOffset = null) {
268
+ tooltip.style('visibility', 'visible');
269
+ if (!this.transition.show) {
270
+ return;
271
+ }
272
+ tooltip.style('opacity', '1');
273
+ const node = tooltip.node();
274
+ if (!node) {
275
+ return;
276
+ }
277
+ if (!slideOffset || !this.hasVisibleSlideOffset(slideOffset)) {
278
+ this.cancelTooltipTransitionFrame(node);
279
+ tooltip.style('transform', TOOLTIP_VISIBLE_TRANSFORM);
280
+ return;
281
+ }
282
+ this.slideTooltipFromOffset(node, slideOffset);
283
+ }
284
+ hideTooltipElement(node) {
285
+ this.cancelTooltipTransitionFrame(node);
286
+ if (!this.transition.show) {
287
+ node.style.visibility = 'hidden';
288
+ return;
289
+ }
290
+ node.style.visibility = 'visible';
291
+ node.style.opacity = '0';
292
+ node.style.transform = TOOLTIP_HIDDEN_TRANSFORM;
293
+ }
294
+ getTooltipTransitionStyle() {
295
+ return `opacity ${this.transition.duration}ms ${this.transition.easing}, transform ${this.transition.duration}ms ${this.transition.easing}`;
296
+ }
297
+ isTooltipVisible(node) {
298
+ return (node.style.visibility === 'visible' && node.style.opacity !== '0');
299
+ }
300
+ getTooltipPosition(node) {
301
+ const left = Number.parseFloat(node.style.left || '0');
302
+ const top = Number.parseFloat(node.style.top || '0');
303
+ if (!Number.isFinite(left) || !Number.isFinite(top)) {
304
+ return null;
305
+ }
306
+ return { left, top };
307
+ }
308
+ hasVisibleSlideOffset(offset) {
309
+ return Math.abs(offset.x) > 0.5 || Math.abs(offset.y) > 0.5;
310
+ }
311
+ slideTooltipFromOffset(node, offset) {
312
+ const transition = node.style.transition || this.getTooltipTransitionStyle();
313
+ this.cancelTooltipTransitionFrame(node);
314
+ node.style.setProperty('transition', 'none');
315
+ node.style.setProperty('transform', `translate(${offset.x}px, ${offset.y}px)`);
316
+ node.getBoundingClientRect();
317
+ node.style.setProperty('transition', transition);
318
+ const frameId = this.requestTooltipTransitionFrame(() => {
319
+ this.tooltipTransitionFrameIds.delete(node);
320
+ node.style.setProperty('transform', TOOLTIP_VISIBLE_TRANSFORM);
321
+ });
322
+ this.tooltipTransitionFrameIds.set(node, frameId);
323
+ }
324
+ requestTooltipTransitionFrame(callback) {
325
+ if (typeof window.requestAnimationFrame === 'function') {
326
+ return window.requestAnimationFrame(callback);
327
+ }
328
+ return window.setTimeout(() => {
329
+ callback(window.performance.now());
330
+ }, 16);
331
+ }
332
+ cancelTooltipTransitionFrame(node) {
333
+ const frameId = this.tooltipTransitionFrameIds.get(node);
334
+ if (frameId === undefined) {
335
+ return;
336
+ }
337
+ if (typeof window.cancelAnimationFrame === 'function') {
338
+ window.cancelAnimationFrame(frameId);
339
+ }
340
+ else {
341
+ window.clearTimeout(frameId);
342
+ }
343
+ this.tooltipTransitionFrameIds.delete(node);
344
+ }
345
+ setTooltipMarkup(tooltip, content) {
346
+ tooltip.html(`<div data-chart-tooltip-body="true">${content}</div>`);
347
+ const body = tooltip.select('[data-chart-tooltip-body]');
348
+ if (body.empty()) {
349
+ return;
350
+ }
351
+ body.style('position', 'relative').style('z-index', String(TOOLTIP_BODY_Z_INDEX));
352
+ }
353
+ appendTooltipConnector(tooltip, connectorLayout) {
354
+ const tooltipBorder = this.tooltipTheme?.border ?? '#dddddd';
355
+ const connector = tooltip
356
+ .append('svg')
357
+ .attr('data-chart-tooltip-connector', 'true')
358
+ .attr('data-chart-tooltip-arrow-edge', connectorLayout.arrowEdge)
359
+ .attr('aria-hidden', 'true')
360
+ .attr('width', connectorLayout.width)
361
+ .attr('height', connectorLayout.height)
362
+ .attr('viewBox', `0 0 ${connectorLayout.width} ${connectorLayout.height}`)
363
+ .style('position', 'absolute')
364
+ .style('left', `${connectorLayout.left}px`)
365
+ .style('top', `${connectorLayout.top}px`)
366
+ .style('pointer-events', 'none')
367
+ .style('overflow', 'visible')
368
+ .style('z-index', String(TOOLTIP_CONNECTOR_Z_INDEX));
369
+ connector
370
+ .append('path')
371
+ .attr('data-chart-tooltip-connector-path', 'true')
372
+ .attr('d', connectorLayout.path)
373
+ .attr('fill', 'none')
374
+ .attr('stroke', tooltipBorder)
375
+ .attr('stroke-width', 1.25)
376
+ .attr('stroke-linecap', 'round')
377
+ .attr('stroke-linejoin', 'round');
378
+ }
379
+ appendTooltipArrow(tooltip, connectorLayout) {
380
+ const tooltipBackground = this.tooltipTheme?.background ?? '#ffffff';
381
+ const tooltipBorder = this.tooltipTheme?.border ?? '#dddddd';
382
+ this.appendTooltipArrowTriangle(tooltip, connectorLayout, 'data-chart-tooltip-arrow', tooltipBorder, TOOLTIP_BOX_ARROW_LENGTH_PX, TOOLTIP_BOX_ARROW_HALF_HEIGHT_PX, TOOLTIP_ARROW_BORDER_Z_INDEX);
383
+ this.appendTooltipArrowTriangle(tooltip, connectorLayout, 'data-chart-tooltip-arrow-fill', tooltipBackground, TOOLTIP_BOX_ARROW_LENGTH_PX - 1, TOOLTIP_BOX_ARROW_HALF_HEIGHT_PX - 1, TOOLTIP_ARROW_FILL_Z_INDEX);
384
+ }
385
+ appendTooltipArrowTriangle(tooltip, connectorLayout, dataAttribute, color, length, halfHeight, zIndex) {
386
+ const position = resolveTooltipArrowPosition(connectorLayout.arrowEdge, connectorLayout.arrowX, connectorLayout.arrowY, length, halfHeight);
387
+ const arrow = tooltip
388
+ .append('div')
389
+ .attr(dataAttribute, 'true')
390
+ .attr('data-chart-tooltip-arrow-edge', connectorLayout.arrowEdge)
391
+ .attr('aria-hidden', 'true')
392
+ .style('position', 'absolute')
393
+ .style('left', `${position.left}px`)
394
+ .style('top', `${position.top}px`)
395
+ .style('width', '0')
396
+ .style('height', '0')
397
+ .style('pointer-events', 'none')
398
+ .style('z-index', String(zIndex));
399
+ if (connectorLayout.arrowEdge === 'left') {
400
+ arrow
401
+ .style('border-top', `${halfHeight}px solid transparent`)
402
+ .style('border-bottom', `${halfHeight}px solid transparent`)
403
+ .style('border-right', `${length}px solid ${color}`);
404
+ return;
405
+ }
406
+ if (connectorLayout.arrowEdge === 'right') {
407
+ arrow
408
+ .style('border-top', `${halfHeight}px solid transparent`)
409
+ .style('border-bottom', `${halfHeight}px solid transparent`)
410
+ .style('border-left', `${length}px solid ${color}`);
411
+ return;
412
+ }
413
+ if (connectorLayout.arrowEdge === 'top') {
414
+ arrow
415
+ .style('border-left', `${halfHeight}px solid transparent`)
416
+ .style('border-right', `${halfHeight}px solid transparent`)
417
+ .style('border-bottom', `${length}px solid ${color}`);
418
+ return;
419
+ }
420
+ arrow
421
+ .style('border-left', `${halfHeight}px solid transparent`)
422
+ .style('border-right', `${halfHeight}px solid transparent`)
423
+ .style('border-top', `${length}px solid ${color}`);
424
+ }
425
+ removeSplitTooltips() {
426
+ document
427
+ .querySelectorAll(`[data-chart-tooltip-owner="${this.splitTooltipOwner}"]`)
428
+ .forEach((node) => {
429
+ node.remove();
430
+ });
431
+ }
432
+ removeRootTooltip() {
433
+ const tooltip = this.tooltipDiv ?? select(`#${this.id}`);
434
+ if (!tooltip.empty()) {
435
+ tooltip.remove();
436
+ }
437
+ }
438
+ }
@@ -0,0 +1,18 @@
1
+ import type { TooltipBarAnchorPosition, TooltipPosition } from '../types.js';
2
+ import { type SplitTooltipLayout, type SplitTooltipViewportBounds, type TooltipAnchor, type TooltipArrowEdge, type TooltipConnectorLayout, type TooltipTarget, type XYTooltipSeries } from './types.js';
3
+ export declare function getSplitTooltipViewportBounds(): SplitTooltipViewportBounds;
4
+ export declare function resolveTooltipArrowEdge(position: TooltipPosition, anchor: TooltipAnchor, target: TooltipTarget, tooltipWidth: number, tooltipHeight: number): TooltipArrowEdge;
5
+ export declare function resolveSidePlacementArrowEdge(anchor: TooltipAnchor, tooltipWidth: number, bounds?: SplitTooltipViewportBounds): TooltipArrowEdge;
6
+ export declare function resolveVerticalPlacementArrowEdge(target: TooltipTarget, tooltipHeight: number, bounds?: SplitTooltipViewportBounds): TooltipArrowEdge;
7
+ export declare function resolveSharedTooltipTarget(anchor: TooltipAnchor): TooltipTarget;
8
+ export declare function resolveSplitTooltipTarget(currentSeries: XYTooltipSeries, anchor: TooltipAnchor, barAnchorPosition: TooltipBarAnchorPosition): TooltipTarget;
9
+ export declare function getAnchoredTooltipPosition(anchor: TooltipAnchor, target: TooltipTarget, tooltipWidth: number, tooltipHeight: number, arrowEdge: TooltipArrowEdge): {
10
+ left: number;
11
+ top: number;
12
+ } | null;
13
+ export declare function resolveTooltipConnectorLayout(arrowEdge: TooltipArrowEdge, tooltipLeft: number, tooltipTop: number, tooltipWidth: number, tooltipHeight: number, targetX: number, targetY: number, anchor: TooltipAnchor): TooltipConnectorLayout | null;
14
+ export declare function resolveTooltipArrowPosition(arrowEdge: TooltipArrowEdge, boxX: number, boxY: number, length: number, halfHeight: number): {
15
+ left: number;
16
+ top: number;
17
+ };
18
+ export declare function resolveSplitTooltipPositions(layouts: SplitTooltipLayout[], position: TooltipPosition): void;