@fundar/data-chart-telling 0.0.12 → 0.0.13

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.
@@ -219,7 +219,7 @@
219
219
  </Plot>
220
220
 
221
221
  {#if tooltip && ctrl.showTooltip && ctrl.tooltipPosition}
222
- <Tooltip x={ctrl.tooltipPosition?.x ?? 0} y={ctrl.tooltipPosition?.y ?? 0}>
222
+ <Tooltip x={ctrl.tooltipPosition?.x ?? 0} y={ctrl.tooltipPosition?.y ?? 0} bounds={{ width, height }}>
223
223
  {#if tooltip.content}
224
224
  {@render tooltip.content({ rows: ctrl.matchedRows.map((p) => p.row) })}
225
225
  {:else}
@@ -6,6 +6,11 @@
6
6
  * parent. It is styled entirely from the `--dct-tooltip-*` variables that
7
7
  * {@link ChartContainer} stamps from the config, so it themes for free. Plots
8
8
  * that implement hovering can render this with their own content snippet.
9
+ *
10
+ * Placement is boundary-aware: it prefers sitting centered above the point,
11
+ * but flips below when it would overflow the top and shifts horizontally
12
+ * when it would overflow the left/right, so it always stays clear of the
13
+ * `bounds` box (typically the plot's own width/height).
9
14
  */
10
15
  let {
11
16
  x,
@@ -13,6 +18,7 @@
13
18
  visible = true,
14
19
  background,
15
20
  color,
21
+ bounds,
16
22
  children,
17
23
  }: {
18
24
  x: number;
@@ -20,15 +26,39 @@
20
26
  visible?: boolean;
21
27
  background?: string;
22
28
  color?: string;
29
+ /** Box the tooltip must stay within — usually the hosting plot's width/height. */
30
+ bounds?: { width: number; height: number };
23
31
  children: Snippet;
24
32
  } = $props();
33
+
34
+ const GAP = 10;
35
+ const EDGE_MARGIN = 6;
36
+
37
+ let boxWidth = $state(0);
38
+ let boxHeight = $state(0);
39
+
40
+ const placement = $derived.by(() => {
41
+ const boundsWidth = bounds?.width ?? Infinity;
42
+ const boundsHeight = bounds?.height ?? Infinity;
43
+
44
+ let top = y - GAP - boxHeight;
45
+ if (top < EDGE_MARGIN) top = y + GAP;
46
+ top = Math.min(Math.max(top, EDGE_MARGIN), Math.max(EDGE_MARGIN, boundsHeight - boxHeight - EDGE_MARGIN));
47
+
48
+ let left = x - boxWidth / 2;
49
+ left = Math.min(Math.max(left, EDGE_MARGIN), Math.max(EDGE_MARGIN, boundsWidth - boxWidth - EDGE_MARGIN));
50
+
51
+ return { left, top };
52
+ });
25
53
  </script>
26
54
 
27
55
  {#if visible}
28
56
  <div
29
57
  class="dct-tooltip"
30
- style:left="{x}px"
31
- style:top="{y}px"
58
+ bind:clientWidth={boxWidth}
59
+ bind:clientHeight={boxHeight}
60
+ style:left="{placement.left}px"
61
+ style:top="{placement.top}px"
32
62
  style:background={background}
33
63
  style:color={color}
34
64
  >
@@ -40,7 +70,6 @@
40
70
  .dct-tooltip {
41
71
  position: absolute;
42
72
  z-index: 10;
43
- transform: translate(-50%, -110%);
44
73
  pointer-events: none;
45
74
  background: var(--dct-tooltip-bg, #111827);
46
75
  color: var(--dct-tooltip-color, #fff);
@@ -5,6 +5,11 @@ type $$ComponentProps = {
5
5
  visible?: boolean;
6
6
  background?: string;
7
7
  color?: string;
8
+ /** Box the tooltip must stay within — usually the hosting plot's width/height. */
9
+ bounds?: {
10
+ width: number;
11
+ height: number;
12
+ };
8
13
  children: Snippet;
9
14
  };
10
15
  declare const Tooltip: import("svelte").Component<$$ComponentProps, {}, "">;
@@ -47,7 +47,7 @@ export function createHoverController(args) {
47
47
  return cursor != null;
48
48
  return h.sync;
49
49
  });
50
- const tooltipText = $derived(matchedRows.length ? matchedRows.map((p) => args.format()(p.row)).join('\n\n') : '');
50
+ const tooltipText = $derived(matchedRows.length ? matchedRows.map((p) => args.format()(p.row)).join('\n') : '');
51
51
  function onPointer(data) {
52
52
  const h = args.hover();
53
53
  if (data.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fundar/data-chart-telling",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"