layerchart 2.0.0-next.61 → 2.0.0-next.63

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 (182) hide show
  1. package/dist/canvas.d.ts +6 -2
  2. package/dist/canvas.js +6 -2
  3. package/dist/components/Arc/Arc.base.svelte +49 -11
  4. package/dist/components/Arc/Arc.shared.svelte.d.ts +2 -0
  5. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-full-circle--360-degree-range--1.png +0 -0
  6. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-full-circle--360-degree-range--2.png +0 -0
  7. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-innerRadius-of-0--pie-slice--1.png +0 -0
  8. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-innerRadius-of-0--pie-slice--2.png +0 -0
  9. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-negative-domain-values-1.png +0 -0
  10. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-negative-domain-values-2.png +0 -0
  11. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-partial-arc--e-g---180-degrees--1.png +0 -0
  12. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-partial-arc--e-g---180-degrees--2.png +0 -0
  13. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-at-max-domain-1.png +0 -0
  14. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-at-max-domain-2.png +0 -0
  15. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-below-domain-min-1.png +0 -0
  16. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-below-domain-min-2.png +0 -0
  17. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-exceeding-domain-max-1.png +0 -0
  18. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-exceeding-domain-max-2.png +0 -0
  19. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-of-0-1.png +0 -0
  20. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-edge-cases-should-handle-value-of-0-2.png +0 -0
  21. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-enter-events-1.png +0 -0
  22. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-enter-events-2.png +0 -0
  23. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-move-events-1.png +0 -0
  24. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-pointer-move-events-2.png +0 -0
  25. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-touch-move-events-1.png +0 -0
  26. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-events-should-handle-touch-move-events-2.png +0 -0
  27. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-custom-class-1.png +0 -0
  28. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-custom-class-2.png +0 -0
  29. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fill-color-1.png +0 -0
  30. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fill-color-2.png +0 -0
  31. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fillOpacity-1.png +0 -0
  32. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-fillOpacity-2.png +0 -0
  33. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-offset-to-arc-position-1.png +0 -0
  34. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-offset-to-arc-position-2.png +0 -0
  35. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-opacity-1.png +0 -0
  36. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-opacity-2.png +0 -0
  37. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-stroke-color-1.png +0 -0
  38. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-stroke-color-2.png +0 -0
  39. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-strokeWidth-1.png +0 -0
  40. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-strokeWidth-2.png +0 -0
  41. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-zero-offset-by-default-1.png +0 -0
  42. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-apply-zero-offset-by-default-2.png +0 -0
  43. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-hide-on-pointer-leave-1.png +0 -0
  44. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-hide-on-pointer-leave-2.png +0 -0
  45. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-show-on-pointer-enter-with-data-1.png +0 -0
  46. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-call-tooltip-show-on-pointer-enter-with-data-2.png +0 -0
  47. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-handle-custom-start-angle-in-range-1.png +0 -0
  48. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-handle-custom-start-angle-in-range-2.png +0 -0
  49. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-have-stroke--none--by-default-1.png +0 -0
  50. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-have-stroke--none--by-default-2.png +0 -0
  51. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-an-arc-path-with-value-1.png +0 -0
  52. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-an-arc-path-with-value-2.png +0 -0
  53. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-when-track-prop-is-provided-1.png +0 -0
  54. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-when-track-prop-is-provided-2.png +0 -0
  55. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-custom-class-1.png +0 -0
  56. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-custom-class-2.png +0 -0
  57. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackCornerRadius-1.png +0 -0
  58. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackCornerRadius-2.png +0 -0
  59. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackEndAngle-1.png +0 -0
  60. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackEndAngle-2.png +0 -0
  61. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-1.png +0 -0
  62. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-2.png +0 -0
  63. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-and-trackOuterRadius-1.png +0 -0
  64. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackInnerRadius-and-trackOuterRadius-2.png +0 -0
  65. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackOuterRadius-1.png +0 -0
  66. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackOuterRadius-2.png +0 -0
  67. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackPadAngle-1.png +0 -0
  68. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackPadAngle-2.png +0 -0
  69. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-1.png +0 -0
  70. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-2.png +0 -0
  71. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-and-trackEndAngle-1.png +0 -0
  72. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-track-with-trackStartAngle-and-trackEndAngle-2.png +0 -0
  73. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-both-startAngle-and-endAngle-1.png +0 -0
  74. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-both-startAngle-and-endAngle-2.png +0 -0
  75. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-cornerRadius-1.png +0 -0
  76. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-cornerRadius-2.png +0 -0
  77. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-1.png +0 -0
  78. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-2.png +0 -0
  79. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-and-range-1.png +0 -0
  80. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-domain-and-range-2.png +0 -0
  81. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-range-1.png +0 -0
  82. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-custom-range-2.png +0 -0
  83. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-endAngle-in-radians-1.png +0 -0
  84. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-endAngle-in-radians-2.png +0 -0
  85. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-1.png +0 -0
  86. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-2.png +0 -0
  87. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-and-outerRadius-1.png +0 -0
  88. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-innerRadius-and-outerRadius-2.png +0 -0
  89. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-outerRadius-1.png +0 -0
  90. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-outerRadius-2.png +0 -0
  91. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-padAngle-1.png +0 -0
  92. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-padAngle-2.png +0 -0
  93. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-startAngle-in-radians-1.png +0 -0
  94. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-props-should-render-with-startAngle-in-radians-2.png +0 -0
  95. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-Arc-element-1.png +0 -0
  96. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-Arc-element-2.png +0 -0
  97. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-track-1.png +0 -0
  98. package/dist/components/Arc/__screenshots__/Arc.svelte.test.ts/Arc-should-render-track-2.png +0 -0
  99. package/dist/components/ArcLabel/ArcLabel.shared.svelte.d.ts +1 -0
  100. package/dist/components/{ArcLabel.svelte.test.js → ArcLabel/ArcLabel.svelte.test.js} +3 -3
  101. package/dist/components/ArcLabel/__screenshots__/ArcLabel.svelte.test.ts/ArcLabel-renders-a-text-element-with-the-supplied-value-at-the-centroid-1.png +0 -0
  102. package/dist/components/ArcLabel/__screenshots__/ArcLabel.svelte.test.ts/ArcLabel-renders-a-text-element-with-the-supplied-value-at-the-centroid-2.png +0 -0
  103. package/dist/components/Blur/Blur.canvas.svelte +25 -0
  104. package/dist/components/Blur/Blur.canvas.svelte.d.ts +4 -0
  105. package/dist/components/Blur/Blur.html.svelte +11 -0
  106. package/dist/components/Blur/Blur.html.svelte.d.ts +4 -0
  107. package/dist/components/{Blur.svelte.d.ts → Blur/Blur.shared.svelte.d.ts} +3 -5
  108. package/dist/components/Blur/Blur.svelte +23 -0
  109. package/dist/components/Blur/Blur.svelte.d.ts +4 -0
  110. package/dist/components/Blur/Blur.svg.svelte +24 -0
  111. package/dist/components/Blur/Blur.svg.svelte.d.ts +4 -0
  112. package/dist/components/Chart/Chart.base.svelte +13 -7
  113. package/dist/components/Chart/ChartCore.svelte.test.d.ts +1 -0
  114. package/dist/components/{ChartCore.svelte.test.js → Chart/ChartCore.svelte.test.js} +1 -1
  115. package/dist/components/Circle/Circle.shared.svelte.js +24 -5
  116. package/dist/components/Circle/Circle.svelte.test.js +70 -0
  117. package/dist/components/Dodge/Dodge.shared.svelte.d.ts +132 -0
  118. package/dist/components/Dodge/Dodge.shared.svelte.js +240 -0
  119. package/dist/components/Dodge/Dodge.svelte +88 -0
  120. package/dist/components/Dodge/Dodge.svelte.d.ts +27 -0
  121. package/dist/components/Dodge/Dodge.test.d.ts +1 -0
  122. package/dist/components/Dodge/Dodge.test.js +128 -0
  123. package/dist/components/Image/Image.html.svelte +0 -8
  124. package/dist/components/Image/Image.svg.svelte +1 -9
  125. package/dist/components/Link/Link.base.svelte +15 -9
  126. package/dist/components/Path/Path.canvas.svelte +5 -2
  127. package/dist/components/Path/Path.shared.svelte.d.ts +17 -4
  128. package/dist/components/Path/Path.shared.svelte.js +26 -8
  129. package/dist/components/Path/Path.svg.svelte +75 -60
  130. package/dist/components/Pattern/Pattern.canvas.svelte +4 -1
  131. package/dist/components/Pattern/Pattern.shared.svelte.d.ts +31 -2
  132. package/dist/components/Pattern/Pattern.shared.svelte.js +20 -1
  133. package/dist/components/Pattern/Pattern.svg.svelte +17 -1
  134. package/dist/components/Raster/Raster.base.svelte +2 -8
  135. package/dist/components/Rect/Rect.canvas.svelte +2 -4
  136. package/dist/components/Rect/Rect.canvas.svelte.d.ts +1 -1
  137. package/dist/components/Rect/Rect.html.svelte +3 -9
  138. package/dist/components/Rect/Rect.html.svelte.d.ts +1 -1
  139. package/dist/components/Rect/Rect.shared.svelte.d.ts +5 -2
  140. package/dist/components/Rect/Rect.shared.svelte.js +26 -13
  141. package/dist/components/Rect/Rect.svelte.test.js +45 -0
  142. package/dist/components/Rect/Rect.svg.svelte +36 -21
  143. package/dist/components/Rect/Rect.svg.svelte.d.ts +1 -1
  144. package/dist/components/RectClipPath/RectClipPath.base.svelte +25 -1
  145. package/dist/components/RectClipPath/RectClipPath.shared.svelte.d.ts +8 -0
  146. package/dist/components/Spline/Spline.base.svelte +3 -2
  147. package/dist/components/Text/Text.canvas.svelte +9 -0
  148. package/dist/components/Text/Text.html.svelte +6 -0
  149. package/dist/components/Text/Text.shared.svelte.d.ts +25 -2
  150. package/dist/components/Text/Text.shared.svelte.js +36 -5
  151. package/dist/components/Text/Text.svelte.test.js +40 -0
  152. package/dist/components/Text/Text.svg.svelte +7 -1
  153. package/dist/components/Trail/Trail.base.svelte +10 -7
  154. package/dist/components/Waffle/Waffle.shared.svelte.d.ts +182 -0
  155. package/dist/components/Waffle/Waffle.shared.svelte.js +300 -0
  156. package/dist/components/Waffle/Waffle.svelte +148 -0
  157. package/dist/components/Waffle/Waffle.svelte.d.ts +5 -0
  158. package/dist/components/charts/__screenshots__/ArcChart.svelte.test.ts/ArcChart-uses-the-chart-value-accessor-for-explicit-per-series-tooltip-values-1.png +0 -0
  159. package/dist/components/charts/__screenshots__/ArcChart.svelte.test.ts/ArcChart-uses-the-chart-value-accessor-for-explicit-per-series-tooltip-values-2.png +0 -0
  160. package/dist/components/charts/__screenshots__/BarChart.svelte.test.ts/BarChart-legend-series-toggle-adjusts-group-scale-should-adjust-grouped-bar-widths-when-series-are-toggled-via-legend-1.png +0 -0
  161. package/dist/components/charts/__screenshots__/PieChart.svelte.test.ts/PieChart-uses-hovered-slice-identity-for-implicit-tooltip-series-1.png +0 -0
  162. package/dist/components/charts/__screenshots__/PieChart.svelte.test.ts/PieChart-uses-hovered-slice-identity-for-implicit-tooltip-series-2.png +0 -0
  163. package/dist/components/index.d.ts +6 -2
  164. package/dist/components/index.js +6 -2
  165. package/dist/html.d.ts +6 -2
  166. package/dist/html.js +6 -2
  167. package/dist/states/chart.svelte.d.ts +4 -2
  168. package/dist/states/chart.svelte.js +53 -22
  169. package/dist/states/chart.svelte.test.js +54 -1
  170. package/dist/states/series.svelte.js +9 -13
  171. package/dist/states/series.svelte.test.js +5 -1
  172. package/dist/svg.d.ts +6 -2
  173. package/dist/svg.js +6 -2
  174. package/dist/utils/canvas.js +54 -13
  175. package/dist/utils/canvas.svelte.test.js +44 -0
  176. package/dist/utils/download.d.ts +5 -3
  177. package/dist/utils/download.js +36 -16
  178. package/dist/utils/stack.js +10 -2
  179. package/package.json +1 -1
  180. package/dist/components/Blur.svelte +0 -49
  181. /package/dist/components/{ArcLabel.svelte.test.d.ts → ArcLabel/ArcLabel.svelte.test.d.ts} +0 -0
  182. /package/dist/components/{ChartCore.svelte.test.d.ts → Blur/Blur.shared.svelte.js} +0 -0
@@ -30,10 +30,13 @@
30
30
  rotate,
31
31
  dx,
32
32
  dy,
33
+ // `fontSize` is a typed prop (drives `capHeight` defaults), but on the
34
+ // DOM it must be rendered as the kebab-case `font-size` attribute.
35
+ fontSize,
33
36
  ...rest
34
37
  }: TextProps = $props();
35
38
 
36
- const c = new TextState(() => ({ rotate, dx, dy, ...rest } as TextProps));
39
+ const c = new TextState(() => ({ rotate, dx, dy, fontSize, ...rest } as TextProps));
37
40
 
38
41
  let ref = $state<SVGTextElement>();
39
42
  let svgRef = $state<SVGElement>();
@@ -78,6 +81,7 @@
78
81
  transform={(rest.transform as string | undefined) ?? dataRotateTransform}
79
82
  text-anchor={rest.textAnchor ?? 'start'}
80
83
  dominant-baseline={rest.dominantBaseline ?? 'auto'}
84
+ font-size={fontSize}
81
85
  fill={resolvedFill}
82
86
  fill-opacity={resolvedFillOpacity}
83
87
  stroke={resolvedStroke}
@@ -109,6 +113,7 @@
109
113
  {...rest as any}
110
114
  bind:this={ref}
111
115
  dy={dy ?? 0}
116
+ font-size={fontSize}
112
117
  fill={c.staticFill}
113
118
  fill-opacity={c.staticFillOpacity}
114
119
  stroke={c.staticStroke}
@@ -140,6 +145,7 @@
140
145
  transform={c.transform}
141
146
  text-anchor={rest.textAnchor ?? 'start'}
142
147
  dominant-baseline={rest.dominantBaseline ?? 'auto'}
148
+ font-size={fontSize}
143
149
  fill={c.staticFill}
144
150
  fill-opacity={c.staticFillOpacity}
145
151
  stroke={c.staticStroke}
@@ -122,12 +122,15 @@
122
122
  return '';
123
123
  }
124
124
 
125
- const tweenState = createMotion(defaultPathData(), () => trailPath, {
126
- type: 'tween',
127
- interpolate: interpolatePath,
128
- });
129
-
130
- const isTweened = $derived(extractTweenConfig(motion) != null);
125
+ // Only allocate the tween container when the user opts into a tween via
126
+ // `motion`; otherwise the template reads `trailPath` directly.
127
+ const tweenState =
128
+ extractTweenConfig(motion) != null
129
+ ? createMotion(defaultPathData(), () => trailPath, {
130
+ type: 'tween',
131
+ interpolate: interpolatePath,
132
+ })
133
+ : null;
131
134
 
132
135
  ctx.registerComponent({
133
136
  name: 'Trail',
@@ -137,7 +140,7 @@
137
140
  </script>
138
141
 
139
142
  <Path
140
- pathData={isTweened ? tweenState.current : trailPath}
143
+ pathData={tweenState ? tweenState.current : trailPath}
141
144
  {fill}
142
145
  {fillOpacity}
143
146
  {opacity}
@@ -0,0 +1,182 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SVGAttributes } from 'svelte/elements';
3
+ import type { ChartState } from '../../states/chart.svelte.js';
4
+ import { type Accessor } from '../../utils/common.js';
5
+ import { type Insets } from '../../utils/rect.svelte.js';
6
+ import type { CommonStyleProps, Without } from '../../utils/types.js';
7
+ export type WaffleRound = boolean | ((n: number) => number);
8
+ export type WafflePropsWithoutHTML = {
9
+ /** Override chart context data. */
10
+ data?: any[];
11
+ /** Override `x` from context. @default ctx.x */
12
+ x?: Accessor;
13
+ /** Override `y` from context. @default ctx.y */
14
+ y?: Accessor;
15
+ /** Override `x1` from context. @default ctx.x1 */
16
+ x1?: Accessor;
17
+ /** Override `y1` from context. @default ctx.y1 */
18
+ y1?: Accessor;
19
+ /**
20
+ * Axis the waffle extends along (the value axis).
21
+ *
22
+ * - `'y'` (default): vertical waffle, like Plot's `waffleY`. Cells stack
23
+ * upward from the value=0 baseline.
24
+ * - `'x'`: horizontal waffle, like Plot's `waffleX`. Cells extend rightward.
25
+ *
26
+ * Falls back to the chart's `valueAxis`.
27
+ */
28
+ axis?: 'x' | 'y';
29
+ /**
30
+ * The quantity each cell represents. Larger units produce fewer cells.
31
+ * @default 1
32
+ */
33
+ unit?: number;
34
+ /**
35
+ * The number of cells per row (along the anchor axis). When omitted,
36
+ * computed automatically from the bar width and unit so cells stay
37
+ * approximately square.
38
+ */
39
+ multiple?: number;
40
+ /**
41
+ * Pixel separation between adjacent cells.
42
+ * @default 1
43
+ */
44
+ gap?: number;
45
+ /**
46
+ * How to handle non-integer cell counts.
47
+ *
48
+ * - `false` (default) — keep the partial cell as a fractional cut-off
49
+ * - `true` — `Math.round`
50
+ * - function — custom rounding (e.g. `Math.floor`, `Math.ceil`)
51
+ */
52
+ round?: WaffleRound;
53
+ /** Cell horizontal corner radius (number of pixels, or "100%" for circles). */
54
+ rx?: number | string;
55
+ /** Cell vertical corner radius (number of pixels, or "100%" for circles). */
56
+ ry?: number | string;
57
+ /** Series key for stacked-waffle support. */
58
+ seriesKey?: string;
59
+ /** Insets to shrink each waffle's bounding band. */
60
+ insets?: Insets;
61
+ /** Fixed band-axis size in pixels. Override the band width / height. */
62
+ width?: number;
63
+ /** Fixed band-axis size in pixels. Override the band width / height. */
64
+ height?: number;
65
+ /** Default `(d, i) => i` */
66
+ key?: (d: any, index: number) => any;
67
+ /** Setup pointer events to show tooltip for the hovered datum. */
68
+ tooltip?: boolean;
69
+ /** Click handler invoked with `(event, { data })` for the hovered waffle. */
70
+ onWaffleClick?: (e: MouseEvent, detail: {
71
+ data: any;
72
+ }) => void;
73
+ /**
74
+ * Render a custom symbol per cell instead of the default rect. The snippet
75
+ * receives the cell's `width`/`height` and the resolved `color` for the
76
+ * cell. The CSS `color` is applied to the wrapping element, so any nested
77
+ * SVG using `fill="currentColor"` (or stroke) inherits it automatically.
78
+ *
79
+ * SVG layer only — canvas falls back to the default rect.
80
+ */
81
+ symbol?: Snippet<[
82
+ {
83
+ width: number;
84
+ height: number;
85
+ datum: any;
86
+ color: string;
87
+ }
88
+ ]>;
89
+ } & CommonStyleProps;
90
+ export type WaffleProps = WafflePropsWithoutHTML & Without<Omit<SVGAttributes<SVGElement>, 'width' | 'height' | 'x' | 'y'>, WafflePropsWithoutHTML>;
91
+ /** Per-datum, fully-resolved waffle layout — pixel coords ready to render. */
92
+ export type WaffleItem = {
93
+ data: any;
94
+ index: number;
95
+ /** SVG path data for the waffle outline (relative to translate). */
96
+ pathData: string;
97
+ /** Pixel translate origin — apply to the path/pattern as `translate(tx, ty)`. */
98
+ tx: number;
99
+ ty: number;
100
+ /** Cell box width in pixels (pattern tile width). */
101
+ cx: number;
102
+ /** Cell box height in pixels (pattern tile height). */
103
+ cy: number;
104
+ /** Cell centroid in pixel coords (translated). */
105
+ centroid: {
106
+ x: number;
107
+ y: number;
108
+ };
109
+ /** Resolved fill color. */
110
+ fill: string | null;
111
+ };
112
+ export type WaffleLayoutOptions = {
113
+ axis: 'x' | 'y';
114
+ unit: number;
115
+ multiple?: number;
116
+ round: (n: number) => number;
117
+ /** Anchor-axis size in pixels (the bar's other-axis extent). */
118
+ barSize: number;
119
+ /** Anchor-axis pixel position (the bar's other-axis start). */
120
+ barStart: number;
121
+ /** Pixels per data unit on the value axis (signed; negative = inverted). */
122
+ pixelsPerUnit: number;
123
+ /** Pixel position of the value=0 baseline along the value axis. */
124
+ valueZero: number;
125
+ /** Value range in data units. */
126
+ v1: number;
127
+ v2: number;
128
+ };
129
+ /**
130
+ * Shared reactive state for Waffle. Resolves accessors, computes per-datum
131
+ * dimensions and waffle layouts (pattern tile size, polygon path, centroid),
132
+ * and exposes them via `items`.
133
+ */
134
+ export declare class WaffleState {
135
+ #private;
136
+ ctx: ChartState;
137
+ constructor(getProps: () => WaffleProps);
138
+ axis: "x" | "y";
139
+ unit: number;
140
+ gap: number;
141
+ round: (n: number) => number;
142
+ multipleProp: number | undefined;
143
+ series: import("../index.js").SeriesData<any, any> | undefined;
144
+ /** Opacity multiplier — fades to 0.1 when another series is highlighted. */
145
+ seriesOpacity: number;
146
+ seriesAccessor: string | number | ((d: any) => any) | Accessor<any>[] | undefined;
147
+ stackAccessors: {
148
+ y0: (d: any) => number;
149
+ y1: (d: any) => number;
150
+ value: (d: any) => [number, number] | null;
151
+ } | null;
152
+ data: any[];
153
+ x: Accessor;
154
+ y: Accessor;
155
+ getDimensions: (item: any) => {
156
+ x: any;
157
+ y: any;
158
+ width: number;
159
+ height: number;
160
+ } | undefined;
161
+ /** Pixel slope of the value-axis scale (signed). */
162
+ pixelsPerUnit: number;
163
+ /** Pixel position of value=0 along the value axis. */
164
+ valueZero: number;
165
+ items: WaffleItem[];
166
+ /** Resolved gap. */
167
+ resolvedGap: number;
168
+ }
169
+ /**
170
+ * Generate the polygon outline of a waffle covering the cell interval
171
+ * `[i1, i2)` on a grid of `columns` columns. The shape is approximately
172
+ * rectangular but may have one or two corner cuts when the start or end
173
+ * value is not aligned to a row boundary, plus extra cuts for fractional
174
+ * intervals. The last point is the centroid (popped by callers for tooltips
175
+ * and tip placement).
176
+ *
177
+ * Coordinate space is `(column, row)` in cell units — callers transform to
178
+ * pixel space (and may negate the row axis for screen y).
179
+ *
180
+ * @see https://github.com/observablehq/plot/blob/main/src/marks/waffle.js
181
+ */
182
+ export declare function wafflePoints(i1: number, i2: number, columns: number): [number, number][];
@@ -0,0 +1,300 @@
1
+ import { accessor, chartDataArray } from '../../utils/common.js';
2
+ import { getChartContext } from '../../contexts/chart.js';
3
+ import { createDimensionGetter } from '../../utils/rect.svelte.js';
4
+ /**
5
+ * Shared reactive state for Waffle. Resolves accessors, computes per-datum
6
+ * dimensions and waffle layouts (pattern tile size, polygon path, centroid),
7
+ * and exposes them via `items`.
8
+ */
9
+ export class WaffleState {
10
+ #getProps = () => ({});
11
+ ctx = getChartContext();
12
+ constructor(getProps) {
13
+ this.#getProps = getProps;
14
+ this.ctx.registerComponent({
15
+ name: 'Waffle',
16
+ kind: 'mark',
17
+ markInfo: () => {
18
+ const p = getProps();
19
+ return {
20
+ data: p.data,
21
+ seriesKey: p.seriesKey,
22
+ color: p.fill,
23
+ };
24
+ },
25
+ });
26
+ }
27
+ axis = $derived(this.#getProps().axis ?? this.ctx.valueAxis);
28
+ unit = $derived(Math.max(0, this.#getProps().unit ?? 1));
29
+ gap = $derived(+(this.#getProps().gap ?? 1));
30
+ round = $derived(maybeRound(this.#getProps().round));
31
+ multipleProp = $derived(maybeMultiple(this.#getProps().multiple));
32
+ series = $derived.by(() => {
33
+ const seriesKey = this.#getProps().seriesKey;
34
+ return seriesKey ? this.ctx.series.series.find((s) => s.key === seriesKey) : undefined;
35
+ });
36
+ /** Opacity multiplier — fades to 0.1 when another series is highlighted. */
37
+ seriesOpacity = $derived.by(() => {
38
+ if (this.series?.key == null ||
39
+ this.ctx.series.visibleSeries.length <= 1 ||
40
+ this.ctx.series.isHighlighted(this.series.key, true)) {
41
+ return 1;
42
+ }
43
+ return 0.1;
44
+ });
45
+ seriesAccessor = $derived(this.series
46
+ ? (this.series.value ?? (this.series.data ? undefined : this.series.key))
47
+ : undefined);
48
+ stackAccessors = $derived.by(() => {
49
+ const seriesKey = this.#getProps().seriesKey;
50
+ return seriesKey && this.ctx.series.isStacked
51
+ ? this.ctx.series.getStackAccessors(seriesKey)
52
+ : null;
53
+ });
54
+ data = $derived.by(() => {
55
+ const dataProp = this.#getProps().data;
56
+ if (dataProp)
57
+ return dataProp;
58
+ return this.series?.data ?? chartDataArray(this.ctx.data);
59
+ });
60
+ x = $derived.by(() => {
61
+ const xProp = this.#getProps().x;
62
+ return (xProp ??
63
+ (this.ctx.valueAxis === 'x'
64
+ ? (this.stackAccessors?.value ?? this.seriesAccessor)
65
+ : undefined) ??
66
+ this.ctx.x);
67
+ });
68
+ y = $derived.by(() => {
69
+ const yProp = this.#getProps().y;
70
+ return (yProp ??
71
+ (this.ctx.valueAxis === 'y'
72
+ ? (this.stackAccessors?.value ?? this.seriesAccessor)
73
+ : undefined) ??
74
+ this.ctx.y);
75
+ });
76
+ getDimensions = $derived(createDimensionGetter(this.ctx, () => ({
77
+ x: this.x,
78
+ y: this.y,
79
+ x1: this.#getProps().x1,
80
+ y1: this.#getProps().y1,
81
+ insets: this.#getProps().insets,
82
+ })));
83
+ /** Pixel slope of the value-axis scale (signed). */
84
+ pixelsPerUnit = $derived.by(() => {
85
+ const scale = this.axis === 'y' ? this.ctx.yScale : this.ctx.xScale;
86
+ if (typeof scale !== 'function')
87
+ return 0;
88
+ const a = Number(scale(0));
89
+ const b = Number(scale(1));
90
+ if (!Number.isFinite(a) || !Number.isFinite(b))
91
+ return 0;
92
+ return b - a;
93
+ });
94
+ /** Pixel position of value=0 along the value axis. */
95
+ valueZero = $derived.by(() => {
96
+ const scale = this.axis === 'y' ? this.ctx.yScale : this.ctx.xScale;
97
+ if (typeof scale !== 'function')
98
+ return 0;
99
+ return Number(scale(0)) || 0;
100
+ });
101
+ items = $derived.by(() => {
102
+ const props = this.#getProps();
103
+ const axis = this.axis;
104
+ const unit = this.unit;
105
+ const round = this.round;
106
+ const gap = this.gap;
107
+ const multipleProp = this.multipleProp;
108
+ const data = this.data;
109
+ const pixelsPerUnit = this.pixelsPerUnit;
110
+ const valueZero = this.valueZero;
111
+ if (!data || data.length === 0)
112
+ return [];
113
+ if (!Number.isFinite(pixelsPerUnit) || pixelsPerUnit === 0 || unit <= 0)
114
+ return [];
115
+ const result = [];
116
+ const cellPixels = unit * Math.abs(pixelsPerUnit); // pixels per cell along value axis
117
+ // Determine value range accessor — for stacked series, reads [v1, v2] arrays
118
+ // produced by the chart's stack series; otherwise treats value as [0, v].
119
+ const valueAccessorFn = accessor(axis === 'y'
120
+ ? (this.stackAccessors?.value ?? this.seriesAccessor ?? this.#getProps().y ?? this.ctx.y)
121
+ : (this.stackAccessors?.value ?? this.seriesAccessor ?? this.#getProps().x ?? this.ctx.x));
122
+ for (let i = 0; i < data.length; i++) {
123
+ const d = data[i];
124
+ const dim = this.getDimensions(d);
125
+ if (!dim)
126
+ continue;
127
+ let { x, y, width, height } = dim;
128
+ // Width override
129
+ if (props.width != null && axis === 'y') {
130
+ x = x + (width - props.width) / 2;
131
+ width = props.width;
132
+ }
133
+ if (props.height != null && axis === 'x') {
134
+ y = y + (height - props.height) / 2;
135
+ height = props.height;
136
+ }
137
+ const barSize = axis === 'y' ? width : height;
138
+ const barStart = axis === 'y' ? x : y;
139
+ if (barSize <= 0)
140
+ continue;
141
+ const rawValue = valueAccessorFn(d);
142
+ let v1 = 0;
143
+ let v2;
144
+ if (Array.isArray(rawValue)) {
145
+ v1 = Number(rawValue[0]) || 0;
146
+ v2 = Number(rawValue[1]) || 0;
147
+ }
148
+ else {
149
+ v2 = Number(rawValue) || 0;
150
+ }
151
+ const i1 = round(v1 / unit);
152
+ const i2 = round(v2 / unit);
153
+ if (i1 === i2)
154
+ continue;
155
+ // Default `multiple` from Plot: keep cells approximately square.
156
+ const multiple = multipleProp ?? Math.max(1, Math.floor(Math.sqrt(barSize / cellPixels)));
157
+ // Outer cell tile size (along anchor and dodge axes).
158
+ const cx = Math.min(barSize / multiple, cellPixels * multiple);
159
+ const cy = cellPixels * multiple;
160
+ // Center the cell grid within the bar.
161
+ const tx0 = barStart + (barSize - multiple * cx) / 2;
162
+ // Cells grow away from baseline toward positive values. Sign of
163
+ // `pixelsPerUnit` encodes the screen direction of value growth, so the
164
+ // same transform works for both inverted (typical svg y) and
165
+ // non-inverted scales.
166
+ const valueDir = pixelsPerUnit < 0 ? -1 : 1;
167
+ const polyPoints = wafflePoints(i1, i2, multiple);
168
+ // Pop centroid (last point) before mapping to path string.
169
+ const centroid = polyPoints.pop();
170
+ const transformPoint = axis === 'y'
171
+ ? ([col, row]) => [col * cx, valueDir * row * cy]
172
+ : ([col, row]) => [valueDir * row * cy, col * cx];
173
+ const pts = polyPoints.map(transformPoint);
174
+ const pathData = pts.length === 0 ? '' : 'M' + pts.map((p) => `${p[0]},${p[1]}`).join('L') + 'Z';
175
+ const cPx = transformPoint(centroid);
176
+ const tx = axis === 'y' ? tx0 : valueZero;
177
+ const ty = axis === 'y' ? valueZero : tx0;
178
+ // Resolve fill: explicit `fill` prop > series color > color scale > null
179
+ const fillProp = props.fill;
180
+ let fill = null;
181
+ if (typeof fillProp === 'string')
182
+ fill = fillProp;
183
+ else if (this.series?.color)
184
+ fill = this.series.color;
185
+ else if (this.ctx.config.c)
186
+ fill = String(this.ctx.cGet(d) ?? '') || null;
187
+ result.push({
188
+ data: d,
189
+ index: i,
190
+ pathData,
191
+ tx,
192
+ ty,
193
+ cx,
194
+ cy,
195
+ centroid: { x: tx + cPx[0], y: ty + cPx[1] },
196
+ fill,
197
+ });
198
+ }
199
+ return result;
200
+ });
201
+ /** Resolved gap. */
202
+ resolvedGap = $derived(this.gap);
203
+ }
204
+ function maybeMultiple(multiple) {
205
+ return multiple === undefined ? undefined : Math.max(1, Math.floor(multiple));
206
+ }
207
+ function maybeRound(round) {
208
+ if (round === undefined || round === false)
209
+ return Number;
210
+ if (round === true)
211
+ return Math.round;
212
+ if (typeof round !== 'function') {
213
+ throw new Error(`invalid round: ${round}`);
214
+ }
215
+ return round;
216
+ }
217
+ /**
218
+ * Generate the polygon outline of a waffle covering the cell interval
219
+ * `[i1, i2)` on a grid of `columns` columns. The shape is approximately
220
+ * rectangular but may have one or two corner cuts when the start or end
221
+ * value is not aligned to a row boundary, plus extra cuts for fractional
222
+ * intervals. The last point is the centroid (popped by callers for tooltips
223
+ * and tip placement).
224
+ *
225
+ * Coordinate space is `(column, row)` in cell units — callers transform to
226
+ * pixel space (and may negate the row axis for screen y).
227
+ *
228
+ * @see https://github.com/observablehq/plot/blob/main/src/marks/waffle.js
229
+ */
230
+ export function wafflePoints(i1, i2, columns) {
231
+ if (i2 < i1)
232
+ return wafflePoints(i2, i1, columns);
233
+ if (i1 < 0) {
234
+ return wafflePointsOffset(i1, i2, columns, Math.ceil(-Math.min(i1, i2) / columns));
235
+ }
236
+ const x1f = Math.floor(i1 % columns);
237
+ const x1c = Math.ceil(i1 % columns);
238
+ const x2f = Math.floor(i2 % columns);
239
+ const x2c = Math.ceil(i2 % columns);
240
+ const y1f = Math.floor(i1 / columns);
241
+ const y1c = Math.ceil(i1 / columns);
242
+ const y2f = Math.floor(i2 / columns);
243
+ const y2c = Math.ceil(i2 / columns);
244
+ const points = [];
245
+ if (y2c > y1c)
246
+ points.push([0, y1c]);
247
+ points.push([x1f, y1c], [x1f, y1f + (i1 % 1)], [x1c, y1f + (i1 % 1)]);
248
+ if (!(i1 % columns > columns - 1)) {
249
+ points.push([x1c, y1f]);
250
+ if (y2f > y1f)
251
+ points.push([columns, y1f]);
252
+ }
253
+ if (y2f > y1f)
254
+ points.push([columns, y2f]);
255
+ points.push([x2c, y2f], [x2c, y2f + (i2 % 1)], [x2f, y2f + (i2 % 1)]);
256
+ if (!(i2 % columns < 1)) {
257
+ points.push([x2f, y2c]);
258
+ if (y2c > y1c)
259
+ points.push([0, y2c]);
260
+ }
261
+ points.push(waffleCentroid(i1, i2, columns));
262
+ return points;
263
+ }
264
+ function wafflePointsOffset(i1, i2, columns, k) {
265
+ return wafflePoints(i1 + k * columns, i2 + k * columns, columns).map(([x, y]) => [x, y - k]);
266
+ }
267
+ function waffleCentroid(i1, i2, columns) {
268
+ const r = Math.floor(i2 / columns) - Math.floor(i1 / columns);
269
+ if (r === 0)
270
+ return waffleRowCentroid(i1, i2, columns);
271
+ if (r === 1) {
272
+ if (Math.floor(i2 % columns) > Math.ceil(i1 % columns)) {
273
+ return [(Math.floor(i2 % columns) + Math.ceil(i1 % columns)) / 2, Math.floor(i2 / columns)];
274
+ }
275
+ if (i2 % columns > columns - (i1 % columns)) {
276
+ return waffleRowCentroid(i2 - (i2 % columns), i2, columns);
277
+ }
278
+ return waffleRowCentroid(i1, columns * Math.ceil(i1 / columns), columns);
279
+ }
280
+ return [columns / 2, (Math.round(i1 / columns) + Math.round(i2 / columns)) / 2];
281
+ }
282
+ function waffleRowCentroid(i1, i2, columns) {
283
+ const c = Math.floor(i2) - Math.floor(i1);
284
+ if (c === 0) {
285
+ return [Math.floor(i1 % columns) + 0.5, Math.floor(i1 / columns) + (((i1 + i2) / 2) % 1)];
286
+ }
287
+ if (c === 1) {
288
+ if ((i2 % 1) - (i1 % 1) > 0.5) {
289
+ return [Math.ceil(i1 % columns), Math.floor(i2 / columns) + ((i1 % 1) + (i2 % 1)) / 2];
290
+ }
291
+ if (i2 % 1 > 1 - (i1 % 1)) {
292
+ return [Math.floor(i2 % columns) + 0.5, Math.floor(i2 / columns) + (i2 % 1) / 2];
293
+ }
294
+ return [Math.floor(i1 % columns) + 0.5, Math.floor(i1 / columns) + (1 + (i1 % 1)) / 2];
295
+ }
296
+ return [
297
+ Math.ceil(i1 % columns) + Math.ceil(Math.floor(i2) - Math.ceil(i1)) / 2,
298
+ Math.floor(i1 / columns) + (i2 >= 1 + i1 ? 0.5 : ((i1 + i2) / 2) % 1),
299
+ ];
300
+ }
@@ -0,0 +1,148 @@
1
+ <script lang="ts" module>
2
+ export type { WaffleProps, WafflePropsWithoutHTML } from './Waffle.shared.svelte.js';
3
+ </script>
4
+
5
+ <script lang="ts">
6
+ import { cls } from '@layerstack/tailwind';
7
+
8
+ import Group from '../Group/Group.svelte';
9
+ import Path from '../Path/Path.svelte';
10
+ import Pattern from '../Pattern/Pattern.svelte';
11
+
12
+ import { WaffleState, type WaffleProps } from './Waffle.shared.svelte.js';
13
+
14
+ let {
15
+ data: dataProp,
16
+ x: xProp,
17
+ y: yProp,
18
+ x1: x1Prop,
19
+ y1: y1Prop,
20
+ axis,
21
+ unit,
22
+ multiple,
23
+ gap,
24
+ round,
25
+ rx,
26
+ ry,
27
+ seriesKey,
28
+ insets,
29
+ width,
30
+ height,
31
+ key = (_, i) => i,
32
+ fill,
33
+ fillOpacity,
34
+ stroke,
35
+ strokeWidth,
36
+ opacity,
37
+ class: className,
38
+ tooltip,
39
+ onWaffleClick,
40
+ onpointerenter,
41
+ onpointermove,
42
+ onpointerleave,
43
+ onclick,
44
+ symbol,
45
+ ...rest
46
+ }: WaffleProps = $props();
47
+
48
+ const c = new WaffleState(
49
+ () =>
50
+ ({
51
+ data: dataProp,
52
+ x: xProp,
53
+ y: yProp,
54
+ x1: x1Prop,
55
+ y1: y1Prop,
56
+ axis,
57
+ unit,
58
+ multiple,
59
+ gap,
60
+ round,
61
+ rx,
62
+ ry,
63
+ seriesKey,
64
+ insets,
65
+ width,
66
+ height,
67
+ fill,
68
+ }) as WaffleProps
69
+ );
70
+ </script>
71
+
72
+ {#each c.items as item (key(item.data, item.index))}
73
+ {@const onItemEnter = (e: PointerEvent) => {
74
+ onpointerenter?.(e as any);
75
+ if (tooltip) c.ctx.tooltip.show(e, item.data);
76
+ }}
77
+ {@const onItemMove = (e: PointerEvent) => {
78
+ onpointermove?.(e as any);
79
+ if (tooltip) c.ctx.tooltip.show(e, item.data);
80
+ }}
81
+ {@const onItemLeave = (e: PointerEvent) => {
82
+ onpointerleave?.(e as any);
83
+ if (tooltip) c.ctx.tooltip.hide();
84
+ }}
85
+ {@const onItemClick = (e: MouseEvent) => {
86
+ onclick?.(e as any);
87
+ onWaffleClick?.(e, { data: item.data });
88
+ }}
89
+ {@const cellInset = c.gap / 2}
90
+ {@const innerWidth = Math.max(0, item.cx - 2 * cellInset)}
91
+ {@const innerHeight = Math.max(0, item.cy - 2 * cellInset)}
92
+ {@const color = item.fill ?? (typeof fill === 'string' ? fill : undefined) ?? 'currentColor'}
93
+ {#snippet symbolPatternContent()}
94
+ <g transform={`translate(${cellInset},${cellInset})`} {color}>
95
+ {@render symbol?.({
96
+ width: innerWidth,
97
+ height: innerHeight,
98
+ datum: item.data,
99
+ color,
100
+ })}
101
+ </g>
102
+ {/snippet}
103
+ <Group
104
+ x={item.tx}
105
+ y={item.ty}
106
+ class={cls('lc-waffle', className)}
107
+ opacity={(opacity ?? 1) * c.seriesOpacity}
108
+ >
109
+ <Pattern
110
+ width={item.cx}
111
+ height={item.cy}
112
+ rects={[
113
+ {
114
+ inset: cellInset,
115
+ color: item.fill ?? (typeof fill === 'string' ? fill : undefined),
116
+ opacity: fillOpacity,
117
+ rx,
118
+ ry,
119
+ },
120
+ ]}
121
+ patternContent={symbol ? symbolPatternContent : undefined}
122
+ >
123
+ {#snippet children({ pattern })}
124
+ <Path
125
+ pathData={item.pathData}
126
+ fill={pattern}
127
+ stroke={stroke as string | undefined}
128
+ strokeWidth={strokeWidth as number | undefined}
129
+ class="lc-waffle-cell"
130
+ onpointerenter={onItemEnter}
131
+ onpointermove={onItemMove}
132
+ onpointerleave={onItemLeave}
133
+ onclick={onItemClick}
134
+ {...rest}
135
+ />
136
+ {/snippet}
137
+ </Pattern>
138
+ </Group>
139
+ {/each}
140
+
141
+ <style>
142
+ @layer components {
143
+ :global(:where(.lc-waffle-cell)) {
144
+ --fill-color: var(--color-primary, currentColor);
145
+ --stroke-color: none;
146
+ }
147
+ }
148
+ </style>