layerchart 2.0.0-next.4 → 2.0.0-next.40

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.
Files changed (179) hide show
  1. package/dist/components/AnnotationLine.svelte +15 -2
  2. package/dist/components/AnnotationPoint.svelte +29 -11
  3. package/dist/components/AnnotationRange.svelte +18 -4
  4. package/dist/components/Arc.svelte +5 -5
  5. package/dist/components/Area.svelte +10 -2
  6. package/dist/components/Axis.svelte +175 -58
  7. package/dist/components/Axis.svelte.d.ts +23 -6
  8. package/dist/components/Bar.svelte +20 -15
  9. package/dist/components/Bar.svelte.d.ts +2 -2
  10. package/dist/components/Bars.svelte +4 -4
  11. package/dist/components/Blur.svelte +7 -6
  12. package/dist/components/Blur.svelte.d.ts +2 -5
  13. package/dist/components/BrushContext.svelte +45 -45
  14. package/dist/components/Calendar.svelte +31 -10
  15. package/dist/components/Calendar.svelte.d.ts +2 -1
  16. package/dist/components/Chart.svelte +76 -27
  17. package/dist/components/Chart.svelte.d.ts +26 -8
  18. package/dist/components/ChartClipPath.svelte +1 -1
  19. package/dist/components/Circle.svelte +44 -3
  20. package/dist/components/CircleClipPath.svelte +8 -1
  21. package/dist/components/ClipPath.svelte +1 -2
  22. package/dist/components/ColorRamp.svelte +1 -1
  23. package/dist/components/ComputedStyles.svelte +9 -2
  24. package/dist/components/Connector.svelte +3 -3
  25. package/dist/components/Connector.svelte.d.ts +1 -1
  26. package/dist/components/Ellipse.svelte +228 -0
  27. package/dist/components/Ellipse.svelte.d.ts +64 -0
  28. package/dist/components/ForceSimulation.svelte +184 -50
  29. package/dist/components/ForceSimulation.svelte.d.ts +95 -21
  30. package/dist/components/Frame.svelte +1 -1
  31. package/dist/components/GeoCircle.svelte +1 -1
  32. package/dist/components/GeoEdgeFade.svelte +1 -1
  33. package/dist/components/GeoPath.svelte +30 -8
  34. package/dist/components/GeoPoint.svelte +4 -5
  35. package/dist/components/GeoSpline.svelte +5 -5
  36. package/dist/components/GeoSpline.svelte.d.ts +1 -1
  37. package/dist/components/GeoTile.svelte +1 -1
  38. package/dist/components/Graticule.svelte +5 -5
  39. package/dist/components/Grid.svelte +60 -63
  40. package/dist/components/Group.svelte +13 -8
  41. package/dist/components/Group.svelte.d.ts +10 -3
  42. package/dist/components/Highlight.svelte +55 -28
  43. package/dist/components/Highlight.svelte.d.ts +4 -0
  44. package/dist/components/Hull.svelte +12 -5
  45. package/dist/components/Labels.svelte +24 -13
  46. package/dist/components/Labels.svelte.d.ts +12 -5
  47. package/dist/components/Legend.svelte +143 -70
  48. package/dist/components/Legend.svelte.d.ts +12 -8
  49. package/dist/components/Line.svelte +40 -3
  50. package/dist/components/LinearGradient.svelte +35 -4
  51. package/dist/components/Link.svelte +1 -1
  52. package/dist/components/Marker.svelte +37 -26
  53. package/dist/components/MonthPath.svelte +26 -12
  54. package/dist/components/MonthPath.svelte.d.ts +4 -3
  55. package/dist/components/MotionPath.svelte +1 -1
  56. package/dist/components/Pack.svelte.d.ts +10 -3
  57. package/dist/components/Partition.svelte.d.ts +10 -3
  58. package/dist/components/Pattern.svelte +5 -5
  59. package/dist/components/Pie.svelte +1 -2
  60. package/dist/components/Points.svelte +11 -72
  61. package/dist/components/Points.svelte.d.ts +1 -8
  62. package/dist/components/Polygon.svelte +309 -0
  63. package/dist/components/Polygon.svelte.d.ts +115 -0
  64. package/dist/components/RadialGradient.svelte +4 -6
  65. package/dist/components/Rect.svelte +55 -5
  66. package/dist/components/Rect.svelte.d.ts +2 -2
  67. package/dist/components/RectClipPath.svelte +4 -3
  68. package/dist/components/RectClipPath.svelte.d.ts +2 -2
  69. package/dist/components/Rule.svelte +167 -77
  70. package/dist/components/Rule.svelte.d.ts +7 -2
  71. package/dist/components/Spline.svelte +59 -28
  72. package/dist/components/Spline.svelte.d.ts +12 -4
  73. package/dist/components/Text.svelte +121 -73
  74. package/dist/components/Text.svelte.d.ts +6 -0
  75. package/dist/components/TileImage.svelte +19 -4
  76. package/dist/components/TransformContext.svelte +9 -3
  77. package/dist/components/TransformControls.svelte +89 -38
  78. package/dist/components/Tree.svelte.d.ts +10 -3
  79. package/dist/components/Treemap.svelte +63 -26
  80. package/dist/components/Treemap.svelte.d.ts +21 -14
  81. package/dist/components/Voronoi.svelte +12 -13
  82. package/dist/components/charts/ArcChart.svelte +43 -71
  83. package/dist/components/charts/ArcChart.svelte.d.ts +10 -3
  84. package/dist/components/charts/AreaChart.svelte +29 -59
  85. package/dist/components/charts/AreaChart.svelte.d.ts +10 -3
  86. package/dist/components/charts/BarChart.svelte +79 -71
  87. package/dist/components/charts/BarChart.svelte.d.ts +10 -3
  88. package/dist/components/charts/DefaultTooltip.svelte +3 -3
  89. package/dist/components/charts/DefaultTooltip.svelte.d.ts +1 -1
  90. package/dist/components/charts/LineChart.svelte +69 -75
  91. package/dist/components/charts/LineChart.svelte.d.ts +21 -8
  92. package/dist/components/charts/PieChart.svelte +44 -71
  93. package/dist/components/charts/PieChart.svelte.d.ts +10 -3
  94. package/dist/components/charts/ScatterChart.svelte +10 -39
  95. package/dist/components/charts/ScatterChart.svelte.d.ts +10 -3
  96. package/dist/components/charts/utils.svelte.d.ts +1 -19
  97. package/dist/components/charts/utils.svelte.js +7 -35
  98. package/dist/components/index.d.ts +4 -0
  99. package/dist/components/index.js +5 -1
  100. package/dist/components/layout/Canvas.svelte +96 -69
  101. package/dist/components/layout/Canvas.svelte.d.ts +6 -0
  102. package/dist/components/layout/Html.svelte +15 -9
  103. package/dist/components/layout/Layer.svelte +6 -4
  104. package/dist/components/layout/Layer.svelte.d.ts +6 -4
  105. package/dist/components/layout/Svg.svelte +19 -11
  106. package/dist/components/layout/WebGL.svelte +26 -6
  107. package/dist/components/layout/WebGL.svelte.d.ts +5 -2
  108. package/dist/components/tooltip/Tooltip.svelte +65 -27
  109. package/dist/components/tooltip/Tooltip.svelte.d.ts +10 -3
  110. package/dist/components/tooltip/TooltipContext.svelte +167 -54
  111. package/dist/components/tooltip/TooltipContext.svelte.d.ts +19 -5
  112. package/dist/components/tooltip/TooltipHeader.svelte +32 -18
  113. package/dist/components/tooltip/TooltipHeader.svelte.d.ts +3 -3
  114. package/dist/components/tooltip/TooltipItem.svelte +46 -37
  115. package/dist/components/tooltip/TooltipItem.svelte.d.ts +3 -3
  116. package/dist/components/tooltip/TooltipList.svelte +12 -10
  117. package/dist/components/tooltip/TooltipSeparator.svelte +18 -10
  118. package/dist/components/tooltip/tooltipMetaContext.d.ts +2 -2
  119. package/dist/docs/Blockquote.svelte +6 -4
  120. package/dist/docs/Blockquote.svelte.d.ts +4 -19
  121. package/dist/docs/Code.svelte +70 -28
  122. package/dist/docs/Code.svelte.d.ts +9 -24
  123. package/dist/docs/Header1.svelte +4 -2
  124. package/dist/docs/Header1.svelte.d.ts +4 -28
  125. package/dist/docs/Json.svelte +11 -3
  126. package/dist/docs/Json.svelte.d.ts +9 -21
  127. package/dist/docs/Layout.svelte +10 -7
  128. package/dist/docs/Layout.svelte.d.ts +4 -19
  129. package/dist/docs/Link.svelte +7 -3
  130. package/dist/docs/Link.svelte.d.ts +4 -38
  131. package/dist/docs/Preview.svelte +22 -23
  132. package/dist/docs/Preview.svelte.d.ts +5 -6
  133. package/dist/docs/TilesetField.svelte +20 -19
  134. package/dist/docs/TilesetField.svelte.d.ts +5 -22
  135. package/dist/docs/ViewSourceButton.svelte +10 -7
  136. package/dist/docs/ViewSourceButton.svelte.d.ts +7 -21
  137. package/dist/states/series.svelte.d.ts +30 -0
  138. package/dist/states/series.svelte.js +54 -0
  139. package/dist/styles/daisyui-5.css +6 -0
  140. package/dist/styles/shadcn-svelte.css +11 -0
  141. package/dist/styles/skeleton-3.css +15 -0
  142. package/dist/utils/arcText.svelte.js +4 -4
  143. package/dist/utils/array.d.ts +11 -0
  144. package/dist/utils/array.js +23 -0
  145. package/dist/utils/array.test.d.ts +1 -0
  146. package/dist/utils/array.test.js +200 -0
  147. package/dist/utils/attributes.d.ts +3 -13
  148. package/dist/utils/attributes.js +4 -18
  149. package/dist/utils/canvas.d.ts +77 -0
  150. package/dist/utils/canvas.js +105 -41
  151. package/dist/utils/common.d.ts +9 -0
  152. package/dist/utils/common.js +18 -1
  153. package/dist/utils/common.test.js +26 -1
  154. package/dist/utils/genData.d.ts +22 -8
  155. package/dist/utils/genData.js +34 -14
  156. package/dist/utils/graph/dagre.d.ts +4 -4
  157. package/dist/utils/graph/dagre.js +5 -7
  158. package/dist/utils/index.d.ts +1 -0
  159. package/dist/utils/index.js +1 -0
  160. package/dist/utils/math.d.ts +17 -0
  161. package/dist/utils/math.js +17 -0
  162. package/dist/utils/path.d.ts +10 -0
  163. package/dist/utils/path.js +30 -0
  164. package/dist/utils/rect.svelte.d.ts +2 -2
  165. package/dist/utils/rect.svelte.js +73 -1
  166. package/dist/utils/scales.svelte.d.ts +9 -3
  167. package/dist/utils/scales.svelte.js +47 -4
  168. package/dist/utils/shape.d.ts +43 -0
  169. package/dist/utils/shape.js +59 -0
  170. package/dist/utils/stack.js +1 -1
  171. package/dist/utils/string.d.ts +49 -0
  172. package/dist/utils/string.js +4 -2
  173. package/dist/utils/ticks.d.ts +15 -4
  174. package/dist/utils/ticks.js +140 -159
  175. package/dist/utils/ticks.test.js +16 -26
  176. package/dist/utils/treemap.d.ts +1 -1
  177. package/dist/utils/types.d.ts +15 -2
  178. package/package.json +35 -35
  179. package/dist/utils/object.js +0 -2
@@ -6,13 +6,15 @@
6
6
  const _TooltipContext = new Context<TooltipContextValue>('TooltipContext');
7
7
 
8
8
  type TooltipMode =
9
- | 'bisect-x'
10
- | 'bisect-y'
9
+ | 'bisect-x' // requires values to be sorted
10
+ | 'bisect-y' // requires values to be sorted
11
11
  | 'band'
12
- | 'bisect-band'
12
+ | 'bisect-band' // requires values to be sorted
13
13
  | 'bounds'
14
14
  | 'voronoi'
15
15
  | 'quadtree'
16
+ | 'quadtree-x' // ignores y values (constant 0)
17
+ | 'quadtree-y' // ignores x values (constant 0)
16
18
  | 'manual';
17
19
 
18
20
  export type TooltipContextValue<T = any> = {
@@ -20,7 +22,11 @@
20
22
  y: number;
21
23
  data: T | null;
22
24
  payload: TooltipPayload[];
23
- show(e: PointerEvent, tooltipData?: any, payload?: TooltipPayload): void;
25
+ show(
26
+ e: PointerEvent | MouseEvent | TouchEvent,
27
+ tooltipData?: any,
28
+ payload?: TooltipPayload
29
+ ): void;
24
30
  hide(e?: PointerEvent): void;
25
31
  mode: TooltipMode;
26
32
  isHoveringTooltipArea: boolean;
@@ -71,6 +77,14 @@
71
77
  */
72
78
  locked?: boolean;
73
79
 
80
+ /**
81
+ * Controls the touch event behavior on the tooltip container.
82
+ * By default uses `pan-y` to allow verticle scrolling but horizontal scrubbing.
83
+ * Use `none` to disable all touch events (useful for improved transform/geo charts interactions)
84
+ * @default 'pan-y'
85
+ */
86
+ touchEvents?: 'none' | 'pan-x' | 'pan-y' | 'auto';
87
+
74
88
  /**
75
89
  * quadtree search or voronoi clip radius
76
90
  * @default Infinity
@@ -129,7 +143,7 @@
129
143
  import ChartClipPath from './../ChartClipPath.svelte';
130
144
  import Voronoi from './../Voronoi.svelte';
131
145
 
132
- import { isScaleBand, scaleInvert } from '../../utils/scales.svelte.js';
146
+ import { isScaleBand, isScaleTime, scaleInvert } from '../../utils/scales.svelte.js';
133
147
  import { cartesianToPolar } from '../../utils/math.js';
134
148
  import { quadtreeRects } from '../../utils/quadtree.js';
135
149
  import { raise } from '../../utils/chart.js';
@@ -138,7 +152,6 @@
138
152
  getTooltipPayload,
139
153
  type TooltipPayload,
140
154
  } from './tooltipMetaContext.js';
141
- import { layerClass } from '../../utils/attributes.js';
142
155
 
143
156
  const ctx = getChartContext<any>();
144
157
  const geoCtx = getGeoContext();
@@ -149,6 +162,7 @@
149
162
  findTooltipData = 'closest',
150
163
  hideDelay = 0,
151
164
  locked = false,
165
+ touchEvents = 'pan-y',
152
166
  mode = 'manual',
153
167
  onclick = () => {},
154
168
  radius = Infinity,
@@ -270,7 +284,7 @@
270
284
  }
271
285
  }
272
286
 
273
- function showTooltip(e: PointerEvent, tooltipData?: any) {
287
+ function showTooltip(e: PointerEvent | MouseEvent | TouchEvent, tooltipData?: any) {
274
288
  // Cancel hiding tooltip if from previous event loop
275
289
  if (hideTimeoutId) {
276
290
  clearTimeout(hideTimeoutId);
@@ -298,7 +312,6 @@
298
312
  }
299
313
 
300
314
  // If tooltipData not provided already (voronoi, etc), attempt to find it
301
- // TODO: When using bisect-x/y/band, values should be sorted. Typically they are for `x`, but not `y` (and band depends on if x or y scale)
302
315
  if (tooltipData == null) {
303
316
  switch (mode) {
304
317
  case 'bisect-x': {
@@ -311,6 +324,7 @@
311
324
  xValueAtPoint = scaleInvert(ctx.xScale, point.x - ctx.padding.left);
312
325
  }
313
326
 
327
+ // Requires values to be sorted
314
328
  const index = bisectX(ctx.flatData, xValueAtPoint, 1);
315
329
  const previousValue = ctx.flatData[index - 1];
316
330
  const currentValue = ctx.flatData[index];
@@ -322,6 +336,7 @@
322
336
  // `y` value at pointer coordinate
323
337
  const yValueAtPoint = scaleInvert(ctx.yScale, point.y - ctx.padding.top);
324
338
 
339
+ // Requires values to be sorted
325
340
  const index = bisectY(ctx.flatData, yValueAtPoint, 1);
326
341
  const previousValue = ctx.flatData[index - 1];
327
342
  const currentValue = ctx.flatData[index];
@@ -339,6 +354,7 @@
339
354
  const bandData = ctx.flatData
340
355
  .filter((d) => ctx.x(d) === xValueAtPoint)
341
356
  .sort(sortFunc(ctx.y as () => any)); // sort for bisect
357
+ // Requires values to be sorted
342
358
  const index = bisectY(bandData, yValueAtPoint, 1);
343
359
  const previousValue = bandData[index - 1];
344
360
  const currentValue = bandData[index];
@@ -348,6 +364,7 @@
348
364
  const bandData = ctx.flatData
349
365
  .filter((d) => ctx.y(d) === yValueAtPoint)
350
366
  .sort(sortFunc(ctx.x as () => any)); // sort for bisect
367
+ // Requires values to be sorted
351
368
  const index = bisectX(bandData, xValueAtPoint, 1);
352
369
  const previousValue = bandData[index - 1];
353
370
  const currentValue = bandData[index];
@@ -358,6 +375,8 @@
358
375
  break;
359
376
  }
360
377
 
378
+ case 'quadtree-x':
379
+ case 'quadtree-y':
361
380
  case 'quadtree': {
362
381
  tooltipData = quadtree?.find(
363
382
  point.x - ctx.padding.left,
@@ -406,9 +425,13 @@
406
425
  }
407
426
 
408
427
  const quadtree: Quadtree<[number, number]> | undefined = $derived.by(() => {
409
- if (mode === 'quadtree') {
428
+ if (['quadtree', 'quadtree-x', 'quadtree-y'].includes(mode)) {
410
429
  return d3Quadtree()
411
430
  .x((d) => {
431
+ if (mode === 'quadtree-y') {
432
+ return 0;
433
+ }
434
+
412
435
  if (geoCtx.projection) {
413
436
  const lat = ctx.x(d);
414
437
  const long = ctx.y(d);
@@ -429,6 +452,10 @@
429
452
  }
430
453
  })
431
454
  .y((d) => {
455
+ if (mode === 'quadtree-x') {
456
+ return 0;
457
+ }
458
+
432
459
  if (geoCtx.projection) {
433
460
  const lat = ctx.x(d);
434
461
  const long = ctx.y(d);
@@ -474,14 +501,63 @@
474
501
  const fullHeight = max(ctx.yRange) - min(ctx.yRange);
475
502
 
476
503
  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
- };
504
+ if (isScaleBand(ctx.xScale)) {
505
+ // full band width/height regardless of value
506
+ return {
507
+ x: x - xOffset,
508
+ y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange),
509
+ width: ctx.xScale.step(),
510
+ height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight,
511
+ data: d,
512
+ };
513
+ } else if (isScaleBand(ctx.yScale)) {
514
+ return {
515
+ x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange),
516
+ y: y - yOffset,
517
+ width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth,
518
+ height: ctx.yScale.step(),
519
+ data: d,
520
+ };
521
+ } else if (isScaleTime(ctx.xScale)) {
522
+ // Find width to next data point
523
+ const index = ctx.flatData.findIndex(
524
+ (d2) => Number(ctx.x(d2)) === Number(ctx.x(d))
525
+ );
526
+ const isLastPoint = index + 1 === ctx.flatData.length;
527
+ const nextDataPoint = isLastPoint
528
+ ? max(ctx.xDomain)
529
+ : ctx.x(ctx.flatData[index + 1]);
530
+
531
+ return {
532
+ x: x - xOffset,
533
+ y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange),
534
+ width: (ctx.xScale(nextDataPoint) ?? 0) - (xValue ?? 0),
535
+ height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight,
536
+ data: d,
537
+ };
538
+ } else if (isScaleTime(ctx.yScale)) {
539
+ // Find height to next data point
540
+ const index = ctx.flatData.findIndex(
541
+ (d2) => Number(ctx.y(d2)) === Number(ctx.y(d))
542
+ );
543
+ const isLastPoint = index + 1 === ctx.flatData.length;
544
+ const nextDataPoint = isLastPoint
545
+ ? max(ctx.yDomain)
546
+ : ctx.y(ctx.flatData[index + 1]);
547
+
548
+ return {
549
+ x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange),
550
+ y: y - yOffset,
551
+ width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth,
552
+ height: (ctx.yScale(nextDataPoint) ?? 0) - (yValue ?? 0),
553
+ data: d,
554
+ };
555
+ } else {
556
+ console.warn(
557
+ '[layerchart] TooltipContext band mode requires at least one scale to be band or time.'
558
+ );
559
+ return undefined;
560
+ }
485
561
  } else if (mode === 'bounds') {
486
562
  return {
487
563
  x: isScaleBand(ctx.xScale) || Array.isArray(xValue) ? x - xOffset : min(ctx.xRange),
@@ -509,37 +585,40 @@
509
585
  });
510
586
 
511
587
  const triggerPointerEvents = $derived(
512
- ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode)
588
+ ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree', 'quadtree-x', 'quadtree-y'].includes(mode)
513
589
  );
514
- </script>
515
590
 
516
- <!-- svelte-ignore a11y_no_static_element_interactions -->
517
- <div
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"
522
- class={cls(
523
- layerClass('tooltip-context'),
524
- 'absolute touch-none',
525
- debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
526
- )}
527
- onpointerenter={(e) => {
591
+ function onPointerEnter(e: PointerEvent | MouseEvent | TouchEvent) {
528
592
  isHoveringTooltipArea = true;
529
593
  if (triggerPointerEvents) {
530
594
  showTooltip(e);
531
595
  }
532
- }}
533
- onpointermove={(e) => {
596
+ }
597
+
598
+ function onPointerMove(e: PointerEvent | MouseEvent | TouchEvent) {
534
599
  if (triggerPointerEvents) {
535
600
  showTooltip(e);
536
601
  }
537
- }}
538
- onpointerleave={(e) => {
539
- isHoveringTooltipArea = false;
602
+ }
540
603
 
604
+ function onPointerLeave(e: PointerEvent | MouseEvent | TouchEvent) {
605
+ isHoveringTooltipArea = false;
541
606
  hideTooltip();
542
- }}
607
+ }
608
+ </script>
609
+
610
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
611
+ <div
612
+ style:top="{ctx.padding.top}px"
613
+ style:left="{ctx.padding.left}px"
614
+ style:width="{ctx.width}px"
615
+ style:height="{ctx.height}px"
616
+ style:--touch-action={touchEvents}
617
+ class="lc-tooltip-context"
618
+ class:debug={debug && triggerPointerEvents}
619
+ onpointerenter={onPointerEnter}
620
+ onpointermove={onPointerMove}
621
+ onpointerleave={onPointerLeave}
543
622
  onclick={(e) => {
544
623
  // Ignore clicks without data (triggered from Legend clicks, for example)
545
624
  if (triggerPointerEvents && tooltipContext.data != null) {
@@ -551,7 +630,7 @@
551
630
  >
552
631
  <!-- Rendering slot within TooltipContext to allow pointer events to bubble up (ex. Brush) -->
553
632
  <div
554
- class={cls(layerClass('tooltip-context-container'), 'absolute')}
633
+ class="lc-tooltip-context-container"
555
634
  style:top="-{ctx.padding.top ?? 0}px"
556
635
  style:left="-{ctx.padding.left ?? 0}px"
557
636
  style:width="{ctx.containerWidth}px"
@@ -580,12 +659,12 @@
580
659
  onclick={(e, { data }) => {
581
660
  onclick(e, { data });
582
661
  }}
583
- classes={{ path: cls(debug && 'fill-danger/10 stroke-danger') }}
662
+ classes={{ path: cls('lc-tooltip-voronoi-path', debug && 'debug') }}
584
663
  />
585
664
  </Svg>
586
665
  {:else if mode === 'bounds' || mode === 'band'}
587
666
  <Svg center={ctx.radial}>
588
- <g class={layerClass('tooltip-rects-g')}>
667
+ <g class="lc-tooltip-rects-g">
589
668
  {#each rects as rect}
590
669
  <!-- svelte-ignore a11y_click_events_have_key_events -->
591
670
  {#if ctx.radial}
@@ -594,10 +673,7 @@
594
673
  outerRadius={rect.y + rect.height}
595
674
  startAngle={rect.x}
596
675
  endAngle={rect.x + rect.width}
597
- class={cls(
598
- layerClass('tooltip-rect'),
599
- debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
600
- )}
676
+ class={cls('lc-tooltip-rect', debug && 'debug')}
601
677
  onpointerenter={(e) => showTooltip(e, rect?.data)}
602
678
  onpointermove={(e) => showTooltip(e, rect?.data)}
603
679
  onpointerleave={() => hideTooltip()}
@@ -617,10 +693,7 @@
617
693
  y={rect?.y}
618
694
  width={rect?.width}
619
695
  height={rect?.height}
620
- class={cls(
621
- layerClass('tooltip-rect'),
622
- debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
623
- )}
696
+ class={cls('lc-tooltip-rect', debug && 'debug')}
624
697
  onpointerenter={(e) => showTooltip(e, rect?.data)}
625
698
  onpointermove={(e) => showTooltip(e, rect?.data)}
626
699
  onpointerleave={() => hideTooltip()}
@@ -638,10 +711,10 @@
638
711
  {/each}
639
712
  </g>
640
713
  </Svg>
641
- {:else if mode === 'quadtree' && debug}
714
+ {:else if ['quadtree', 'quadtree-x', 'quadtree-y'].includes(mode) && debug}
642
715
  <Svg pointerEvents={false}>
643
716
  <ChartClipPath>
644
- <g class={layerClass('tooltip-quadtree-g')}>
717
+ <g class="lc-tooltip-quadtree-g">
645
718
  {#if quadtree}
646
719
  {#each quadtreeRects(quadtree, false) as rect}
647
720
  <rect
@@ -649,10 +722,7 @@
649
722
  y={rect.y}
650
723
  width={rect.width}
651
724
  height={rect.height}
652
- class={cls(
653
- layerClass('tooltip-quadtree-rect'),
654
- debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
655
- )}
725
+ class={cls('lc-tooltip-quadtree-rect', debug && 'debug')}
656
726
  />
657
727
  {/each}
658
728
  {/if}
@@ -662,3 +732,46 @@
662
732
  {/if}
663
733
  </div>
664
734
  </div>
735
+
736
+ <style>
737
+ @layer component {
738
+ :where(.lc-tooltip-context-container) {
739
+ position: absolute;
740
+ }
741
+
742
+ :where(.lc-tooltip-context) {
743
+ position: absolute;
744
+ touch-action: var(--touch-action);
745
+
746
+ &.debug {
747
+ outline: 1px solid var(--color-danger);
748
+ background-color: color-mix(in oklab, var(--color-danger) 10%, transparent);
749
+ }
750
+ }
751
+
752
+ :global(:where(.lc-tooltip-voronoi-path)) {
753
+ &.debug {
754
+ stroke: var(--color-danger);
755
+ fill: color-mix(in oklab, var(--color-danger) 10%, transparent);
756
+ }
757
+ }
758
+
759
+ :where(.lc-tooltip-rect) {
760
+ fill: transparent;
761
+
762
+ &.debug {
763
+ stroke: var(--color-danger);
764
+ fill: color-mix(in oklab, var(--color-danger) 10%, transparent);
765
+ }
766
+ }
767
+
768
+ :where(.lc-tooltip-quadtree-rect) {
769
+ fill: transparent;
770
+
771
+ &.debug {
772
+ stroke: var(--color-danger);
773
+ fill: color-mix(in oklab, var(--color-danger) 10%, transparent);
774
+ }
775
+ }
776
+ }
777
+ </style>
@@ -1,12 +1,12 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
2
  import type { Without } from '../../utils/types.js';
3
- type TooltipMode = 'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual';
3
+ type TooltipMode = 'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'quadtree-x' | 'quadtree-y' | 'manual';
4
4
  export type TooltipContextValue<T = any> = {
5
5
  x: number;
6
6
  y: number;
7
7
  data: T | null;
8
8
  payload: TooltipPayload[];
9
- show(e: PointerEvent, tooltipData?: any, payload?: TooltipPayload): void;
9
+ show(e: PointerEvent | MouseEvent | TouchEvent, tooltipData?: any, payload?: TooltipPayload): void;
10
10
  hide(e?: PointerEvent): void;
11
11
  mode: TooltipMode;
12
12
  isHoveringTooltipArea: boolean;
@@ -35,6 +35,13 @@ type TooltipContextPropsWithoutHTML<T = any> = {
35
35
  * @default false
36
36
  */
37
37
  locked?: boolean;
38
+ /**
39
+ * Controls the touch event behavior on the tooltip container.
40
+ * By default uses `pan-y` to allow verticle scrolling but horizontal scrubbing.
41
+ * Use `none` to disable all touch events (useful for improved transform/geo charts interactions)
42
+ * @default 'pan-y'
43
+ */
44
+ touchEvents?: 'none' | 'pan-x' | 'pan-y' | 'auto';
38
45
  /**
39
46
  * quadtree search or voronoi clip radius
40
47
  * @default Infinity
@@ -75,10 +82,17 @@ type TooltipContextPropsWithoutHTML<T = any> = {
75
82
  export type TooltipContextProps<T = any> = TooltipContextPropsWithoutHTML<T> & Without<HTMLAttributes<HTMLElement>, TooltipContextPropsWithoutHTML<T>>;
76
83
  import type { Snippet } from 'svelte';
77
84
  import { type TooltipPayload } from './tooltipMetaContext.js';
85
+ declare function $$render<TData = any>(): {
86
+ props: TooltipContextProps<TData>;
87
+ exports: {};
88
+ bindings: "ref" | "tooltipContext";
89
+ slots: {};
90
+ events: {};
91
+ };
78
92
  declare class __sveltets_Render<TData = any> {
79
- props(): TooltipContextProps<TData>;
80
- events(): {};
81
- slots(): {};
93
+ props(): ReturnType<typeof $$render<TData>>['props'];
94
+ events(): ReturnType<typeof $$render<TData>>['events'];
95
+ slots(): ReturnType<typeof $$render<TData>>['slots'];
82
96
  bindings(): "ref" | "tooltipContext";
83
97
  exports(): {};
84
98
  }
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" module>
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { Snippet } from 'svelte';
4
- import type { Without } from '../../utils/types.js';
4
+ import { asAny, type Without } from '../../utils/types.js';
5
5
 
6
6
  export type TooltipHeaderPropsWithoutHTML = {
7
7
  /**
@@ -13,7 +13,7 @@
13
13
  /**
14
14
  * The format to use when displaying the value.
15
15
  */
16
- format?: FormatType;
16
+ format?: FormatType | FormatConfig;
17
17
 
18
18
  /**
19
19
  * The color to use for the color dot.
@@ -54,9 +54,8 @@
54
54
  </script>
55
55
 
56
56
  <script lang="ts">
57
- import { format as formatUtil, type FormatType } from '@layerstack/utils';
57
+ import { format as formatUtil, type FormatType, type FormatConfig } from '@layerstack/utils';
58
58
  import { cls } from '@layerstack/tailwind';
59
- import { layerClass } from '../../utils/attributes.js';
60
59
 
61
60
  let {
62
61
  ref: refProp = $bindable(),
@@ -89,31 +88,46 @@
89
88
  </script>
90
89
 
91
90
  <div
92
- class={cls(
93
- layerClass('tooltip-header'),
94
- 'font-semibold whitespace-nowrap border-b mb-1 pb-1 flex items-center gap-2',
95
- classes.root,
96
- props.root?.class,
97
- className
98
- )}
91
+ class={cls('lc-tooltip-header', classes.root, props.root?.class, className)}
99
92
  {...restProps}
100
93
  bind:this={ref}
101
94
  >
102
95
  {#if color}
103
96
  <div
104
97
  bind:this={colorRef}
105
- class={cls(
106
- layerClass('tooltip-header-color'),
107
- 'color',
108
- 'inline-block size-2 rounded-full bg-[var(--color)]',
109
- classes.color
110
- )}
98
+ class={cls('lc-tooltip-header-color', classes.color)}
111
99
  style:--color={color}
112
100
  ></div>
113
101
  {/if}
114
102
  {#if children}
115
103
  {@render children?.()}
116
104
  {:else}
117
- {format ? formatUtil(value, format) : value}
105
+ <!-- @ts-expect-error - improve types -->
106
+ {format ? formatUtil(value, asAny(format)) : value}
118
107
  {/if}
119
108
  </div>
109
+
110
+ <style>
111
+ @layer component {
112
+ :where(.lc-tooltip-header) {
113
+ font-weight: 600;
114
+ white-space: nowrap;
115
+ border-bottom: 1px solid
116
+ color-mix(in oklab, var(--color-surface-content, currentColor) 20%, transparent);
117
+ margin-bottom: 4px;
118
+ padding-bottom: 4px;
119
+ display: flex;
120
+ align-items: center;
121
+ gap: 8px;
122
+ }
123
+
124
+ :where(.lc-tooltip-header-color) {
125
+ display: inline-block;
126
+ width: 8px;
127
+ height: 8px;
128
+ border-radius: 9999px; /* rounded-full */
129
+ background-color: var(--color);
130
+ flex-shrink: 0;
131
+ }
132
+ }
133
+ </style>
@@ -1,6 +1,6 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
2
  import type { Snippet } from 'svelte';
3
- import type { Without } from '../../utils/types.js';
3
+ import { type Without } from '../../utils/types.js';
4
4
  export type TooltipHeaderPropsWithoutHTML = {
5
5
  /**
6
6
  * The value to display in the tooltip header when the `children`
@@ -10,7 +10,7 @@ export type TooltipHeaderPropsWithoutHTML = {
10
10
  /**
11
11
  * The format to use when displaying the value.
12
12
  */
13
- format?: FormatType;
13
+ format?: FormatType | FormatConfig;
14
14
  /**
15
15
  * The color to use for the color dot.
16
16
  */
@@ -40,7 +40,7 @@ export type TooltipHeaderPropsWithoutHTML = {
40
40
  children?: Snippet;
41
41
  };
42
42
  export type TooltipHeaderProps = TooltipHeaderPropsWithoutHTML & Without<HTMLAttributes<HTMLElement>, TooltipHeaderPropsWithoutHTML>;
43
- import { type FormatType } from '@layerstack/utils';
43
+ import { type FormatType, type FormatConfig } from '@layerstack/utils';
44
44
  declare const TooltipHeader: import("svelte").Component<TooltipHeaderProps, {}, "ref" | "colorRef">;
45
45
  type TooltipHeader = ReturnType<typeof TooltipHeader>;
46
46
  export default TooltipHeader;