layerchart 2.0.0-next.0 → 2.0.0-next.2

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 (266) hide show
  1. package/dist/actions/movable.d.ts +28 -0
  2. package/dist/actions/movable.js +91 -0
  3. package/dist/components/AnnotationLine.svelte +155 -0
  4. package/dist/components/AnnotationLine.svelte.d.ts +28 -0
  5. package/dist/components/AnnotationPoint.svelte +121 -0
  6. package/dist/components/AnnotationPoint.svelte.d.ts +32 -0
  7. package/dist/components/AnnotationRange.svelte +147 -0
  8. package/dist/components/AnnotationRange.svelte.d.ts +40 -0
  9. package/dist/components/Arc.svelte +344 -151
  10. package/dist/components/Arc.svelte.d.ts +138 -0
  11. package/dist/components/Area.svelte +165 -149
  12. package/dist/components/Area.svelte.d.ts +45 -0
  13. package/dist/components/Axis.svelte +287 -174
  14. package/dist/components/Axis.svelte.d.ts +116 -0
  15. package/dist/components/Bar.svelte +163 -107
  16. package/dist/components/Bar.svelte.d.ts +48 -0
  17. package/dist/components/Bars.svelte +54 -68
  18. package/dist/components/Bars.svelte.d.ts +27 -0
  19. package/dist/components/Blur.svelte +31 -7
  20. package/dist/components/Blur.svelte.d.ts +23 -21
  21. package/dist/components/Bounds.svelte +49 -19
  22. package/dist/components/Bounds.svelte.d.ts +24 -50
  23. package/dist/components/BrushContext.svelte +296 -168
  24. package/dist/components/BrushContext.svelte.d.ts +97 -65
  25. package/dist/components/Calendar.svelte +116 -59
  26. package/dist/components/Calendar.svelte.d.ts +50 -31
  27. package/dist/components/Chart.svelte +1289 -398
  28. package/dist/components/Chart.svelte.d.ts +535 -410
  29. package/dist/components/ChartClipPath.svelte +37 -15
  30. package/dist/components/ChartClipPath.svelte.d.ts +21 -19
  31. package/dist/components/Circle.svelte +124 -85
  32. package/dist/components/Circle.svelte.d.ts +52 -0
  33. package/dist/components/CircleClipPath.svelte +76 -16
  34. package/dist/components/CircleClipPath.svelte.d.ts +46 -0
  35. package/dist/components/ClipPath.svelte +60 -15
  36. package/dist/components/ClipPath.svelte.d.ts +40 -27
  37. package/dist/components/ColorRamp.svelte +75 -9
  38. package/dist/components/ColorRamp.svelte.d.ts +37 -19
  39. package/dist/components/ComputedStyles.svelte +17 -5
  40. package/dist/components/ComputedStyles.svelte.d.ts +11 -19
  41. package/dist/components/Connector.svelte +149 -0
  42. package/dist/components/Connector.svelte.d.ts +51 -0
  43. package/dist/components/Dagre.svelte +211 -122
  44. package/dist/components/Dagre.svelte.d.ts +119 -56
  45. package/dist/components/ForceSimulation.svelte +215 -90
  46. package/dist/components/ForceSimulation.svelte.d.ts +82 -35
  47. package/dist/components/Frame.svelte +33 -13
  48. package/dist/components/Frame.svelte.d.ts +13 -17
  49. package/dist/components/GeoCircle.svelte +29 -16
  50. package/dist/components/GeoCircle.svelte.d.ts +22 -24
  51. package/dist/components/GeoContext.svelte +113 -72
  52. package/dist/components/GeoContext.svelte.d.ts +49 -41
  53. package/dist/components/GeoEdgeFade.svelte +47 -12
  54. package/dist/components/GeoEdgeFade.svelte.d.ts +17 -19
  55. package/dist/components/GeoPath.svelte +157 -127
  56. package/dist/components/GeoPath.svelte.d.ts +48 -36
  57. package/dist/components/GeoPoint.svelte +52 -20
  58. package/dist/components/GeoPoint.svelte.d.ts +25 -22
  59. package/dist/components/GeoSpline.svelte +75 -26
  60. package/dist/components/GeoSpline.svelte.d.ts +29 -20
  61. package/dist/components/GeoTile.svelte +100 -49
  62. package/dist/components/GeoTile.svelte.d.ts +38 -23
  63. package/dist/components/GeoVisible.svelte +17 -9
  64. package/dist/components/GeoVisible.svelte.d.ts +10 -18
  65. package/dist/components/Graticule.svelte +28 -13
  66. package/dist/components/Graticule.svelte.d.ts +11 -52
  67. package/dist/components/Grid.svelte +226 -114
  68. package/dist/components/Grid.svelte.d.ts +70 -0
  69. package/dist/components/Group.svelte +132 -105
  70. package/dist/components/Group.svelte.d.ts +53 -0
  71. package/dist/components/Highlight.svelte +409 -307
  72. package/dist/components/Highlight.svelte.d.ts +107 -0
  73. package/dist/components/Hull.svelte +96 -45
  74. package/dist/components/Hull.svelte.d.ts +40 -30
  75. package/dist/components/Labels.svelte +125 -46
  76. package/dist/components/Labels.svelte.d.ts +70 -27
  77. package/dist/components/Legend.svelte +374 -190
  78. package/dist/components/Legend.svelte.d.ts +95 -44
  79. package/dist/components/Line.svelte +163 -125
  80. package/dist/components/Line.svelte.d.ts +75 -0
  81. package/dist/components/LinearGradient.svelte +153 -78
  82. package/dist/components/LinearGradient.svelte.d.ts +66 -31
  83. package/dist/components/Link.svelte +160 -104
  84. package/dist/components/Link.svelte.d.ts +54 -0
  85. package/dist/components/Marker.svelte +100 -39
  86. package/dist/components/Marker.svelte.d.ts +59 -27
  87. package/dist/components/MarkerWrapper.svelte +35 -0
  88. package/dist/components/MarkerWrapper.svelte.d.ts +18 -0
  89. package/dist/components/MonthPath.svelte +65 -20
  90. package/dist/components/MonthPath.svelte.d.ts +23 -17
  91. package/dist/components/MotionPath.svelte +80 -24
  92. package/dist/components/MotionPath.svelte.d.ts +46 -27
  93. package/dist/components/Pack.svelte +53 -17
  94. package/dist/components/Pack.svelte.d.ts +42 -21
  95. package/dist/components/Partition.svelte +64 -22
  96. package/dist/components/Partition.svelte.d.ts +49 -26
  97. package/dist/components/Pattern.svelte +297 -11
  98. package/dist/components/Pattern.svelte.d.ts +103 -19
  99. package/dist/components/Pie.svelte +122 -76
  100. package/dist/components/Pie.svelte.d.ts +65 -51
  101. package/dist/components/Point.svelte +20 -9
  102. package/dist/components/Point.svelte.d.ts +16 -20
  103. package/dist/components/Points.svelte +148 -137
  104. package/dist/components/Points.svelte.d.ts +45 -34
  105. package/dist/components/RadialGradient.svelte +143 -70
  106. package/dist/components/RadialGradient.svelte.d.ts +69 -31
  107. package/dist/components/Rect.svelte +121 -102
  108. package/dist/components/Rect.svelte.d.ts +36 -0
  109. package/dist/components/RectClipPath.svelte +82 -18
  110. package/dist/components/RectClipPath.svelte.d.ts +55 -0
  111. package/dist/components/Rule.svelte +105 -62
  112. package/dist/components/Rule.svelte.d.ts +40 -19
  113. package/dist/components/Sankey.svelte +132 -55
  114. package/dist/components/Sankey.svelte.d.ts +61 -31
  115. package/dist/components/Spline.svelte +281 -218
  116. package/dist/components/Spline.svelte.d.ts +95 -0
  117. package/dist/components/Text.svelte +437 -176
  118. package/dist/components/Text.svelte.d.ts +130 -0
  119. package/dist/components/Threshold.svelte +48 -16
  120. package/dist/components/Threshold.svelte.d.ts +29 -31
  121. package/dist/components/TileImage.svelte +103 -30
  122. package/dist/components/TileImage.svelte.d.ts +48 -23
  123. package/dist/components/TransformContext.svelte +365 -171
  124. package/dist/components/TransformControls.svelte +50 -26
  125. package/dist/components/TransformControls.svelte.d.ts +27 -19
  126. package/dist/components/Tree.svelte +74 -33
  127. package/dist/components/Tree.svelte.d.ts +42 -30
  128. package/dist/components/Treemap.svelte +119 -42
  129. package/dist/components/Treemap.svelte.d.ts +75 -27
  130. package/dist/components/Voronoi.svelte +106 -75
  131. package/dist/components/Voronoi.svelte.d.ts +40 -41
  132. package/dist/components/charts/ArcChart.svelte +464 -0
  133. package/dist/components/charts/ArcChart.svelte.d.ts +90 -0
  134. package/dist/components/charts/AreaChart.svelte +450 -393
  135. package/dist/components/charts/AreaChart.svelte.d.ts +61 -0
  136. package/dist/components/charts/BarChart.svelte +454 -389
  137. package/dist/components/charts/BarChart.svelte.d.ts +76 -0
  138. package/dist/components/charts/ChartAnnotations.svelte +37 -0
  139. package/dist/components/charts/ChartAnnotations.svelte.d.ts +10 -0
  140. package/dist/components/charts/DefaultTooltip.svelte +60 -0
  141. package/dist/components/charts/DefaultTooltip.svelte.d.ts +10 -0
  142. package/dist/components/charts/LineChart.svelte +369 -314
  143. package/dist/components/charts/LineChart.svelte.d.ts +53 -0
  144. package/dist/components/charts/PieChart.svelte +458 -316
  145. package/dist/components/charts/PieChart.svelte.d.ts +137 -353
  146. package/dist/components/charts/ScatterChart.svelte +334 -296
  147. package/dist/components/charts/ScatterChart.svelte.d.ts +39 -0
  148. package/dist/components/charts/index.d.ts +8 -0
  149. package/dist/components/charts/index.js +7 -0
  150. package/dist/components/charts/types.d.ts +253 -0
  151. package/dist/components/charts/utils.svelte.d.ts +30 -0
  152. package/dist/components/charts/utils.svelte.js +55 -0
  153. package/dist/components/index.d.ts +76 -4
  154. package/dist/components/index.js +76 -5
  155. package/dist/components/layout/Canvas.svelte +321 -155
  156. package/dist/components/layout/Canvas.svelte.d.ts +104 -55
  157. package/dist/components/layout/Html.svelte +82 -42
  158. package/dist/components/layout/Html.svelte.d.ts +39 -28
  159. package/dist/components/layout/Layer.svelte +39 -0
  160. package/dist/components/layout/Layer.svelte.d.ts +17 -0
  161. package/dist/components/layout/Svg.svelte +122 -70
  162. package/dist/components/layout/Svg.svelte.d.ts +53 -34
  163. package/dist/components/layout/WebGL.svelte +135 -0
  164. package/dist/components/layout/WebGL.svelte.d.ts +50 -0
  165. package/dist/components/tooltip/Tooltip.svelte +246 -78
  166. package/dist/components/tooltip/Tooltip.svelte.d.ts +149 -31
  167. package/dist/components/tooltip/TooltipContext.svelte +409 -271
  168. package/dist/components/tooltip/TooltipContext.svelte.d.ts +86 -55
  169. package/dist/components/tooltip/TooltipHeader.svelte +100 -11
  170. package/dist/components/tooltip/TooltipHeader.svelte.d.ts +43 -23
  171. package/dist/components/tooltip/TooltipItem.svelte +167 -27
  172. package/dist/components/tooltip/TooltipItem.svelte.d.ts +63 -31
  173. package/dist/components/tooltip/TooltipList.svelte +22 -3
  174. package/dist/components/tooltip/TooltipList.svelte.d.ts +6 -17
  175. package/dist/components/tooltip/TooltipSeparator.svelte +27 -1
  176. package/dist/components/tooltip/TooltipSeparator.svelte.d.ts +6 -15
  177. package/dist/components/tooltip/index.d.ts +6 -0
  178. package/dist/components/tooltip/index.js +6 -0
  179. package/dist/components/tooltip/tooltipMetaContext.d.ts +79 -0
  180. package/dist/components/tooltip/tooltipMetaContext.js +139 -0
  181. package/dist/components/types.d.ts +1 -0
  182. package/dist/components/types.js +1 -0
  183. package/dist/docs/Blockquote.svelte.d.ts +18 -14
  184. package/dist/docs/Code.svelte.d.ts +26 -22
  185. package/dist/docs/ConnectorSweepMenuField.svelte +17 -0
  186. package/dist/docs/ConnectorSweepMenuField.svelte.d.ts +7 -0
  187. package/dist/docs/ConnectorTypeMenuField.svelte +17 -0
  188. package/dist/docs/ConnectorTypeMenuField.svelte.d.ts +7 -0
  189. package/dist/docs/CurveMenuField.svelte +14 -3
  190. package/dist/docs/CurveMenuField.svelte.d.ts +9 -18
  191. package/dist/docs/GeoDebug.svelte +47 -42
  192. package/dist/docs/GeoDebug.svelte.d.ts +4 -16
  193. package/dist/docs/Header1.svelte.d.ts +27 -16
  194. package/dist/docs/Json.svelte.d.ts +20 -16
  195. package/dist/docs/Layout.svelte.d.ts +18 -13
  196. package/dist/docs/Link.svelte.d.ts +33 -21
  197. package/dist/docs/PathDataMenuField.svelte +14 -10
  198. package/dist/docs/PathDataMenuField.svelte.d.ts +8 -18
  199. package/dist/docs/Preview.svelte +20 -7
  200. package/dist/docs/Preview.svelte.d.ts +12 -22
  201. package/dist/docs/TilesetField.svelte.d.ts +21 -17
  202. package/dist/docs/TransformDebug.svelte +5 -6
  203. package/dist/docs/TransformDebug.svelte.d.ts +18 -14
  204. package/dist/docs/ViewSourceButton.svelte.d.ts +21 -17
  205. package/dist/types/d3-shape-extentions.d.ts +7 -0
  206. package/dist/utils/afterTick.d.ts +5 -0
  207. package/dist/utils/afterTick.js +8 -0
  208. package/dist/utils/arcText.svelte.d.ts +57 -0
  209. package/dist/utils/arcText.svelte.js +262 -0
  210. package/dist/utils/array.d.ts +9 -1
  211. package/dist/utils/array.js +13 -0
  212. package/dist/utils/attributes.d.ts +29 -0
  213. package/dist/utils/attributes.js +40 -0
  214. package/dist/utils/canvas.js +47 -10
  215. package/dist/utils/chart.d.ts +78 -0
  216. package/dist/utils/chart.js +512 -0
  217. package/dist/utils/color.d.ts +1 -0
  218. package/dist/utils/color.js +8 -0
  219. package/dist/utils/common.d.ts +3 -5
  220. package/dist/utils/common.js +3 -2
  221. package/dist/utils/connectorUtils.d.ts +21 -0
  222. package/dist/utils/connectorUtils.js +111 -0
  223. package/dist/utils/createId.d.ts +7 -0
  224. package/dist/utils/createId.js +9 -0
  225. package/dist/utils/debug.d.ts +1 -0
  226. package/dist/utils/debug.js +84 -0
  227. package/dist/utils/filterObject.d.ts +9 -0
  228. package/dist/utils/filterObject.js +12 -0
  229. package/dist/utils/graph/dagre.d.ts +34 -0
  230. package/dist/utils/graph/dagre.js +78 -0
  231. package/dist/utils/graph/dagre.test.d.ts +1 -0
  232. package/dist/utils/{graph.test.js → graph/dagre.test.js} +19 -33
  233. package/dist/utils/graph/sankey.d.ts +28 -0
  234. package/dist/utils/{graph.js → graph/sankey.js} +13 -41
  235. package/dist/utils/index.d.ts +3 -1
  236. package/dist/utils/index.js +3 -1
  237. package/dist/utils/key.svelte.d.ts +3 -0
  238. package/dist/utils/key.svelte.js +11 -0
  239. package/dist/utils/legendPayload.d.ts +7 -0
  240. package/dist/utils/legendPayload.js +8 -0
  241. package/dist/utils/motion.svelte.d.ts +140 -0
  242. package/dist/utils/motion.svelte.js +180 -0
  243. package/dist/utils/motion.test.d.ts +1 -0
  244. package/dist/utils/motion.test.js +213 -0
  245. package/dist/utils/{rect.d.ts → rect.svelte.d.ts} +7 -4
  246. package/dist/utils/rect.svelte.js +105 -0
  247. package/dist/utils/scales.svelte.d.ts +90 -0
  248. package/dist/utils/{scales.js → scales.svelte.js} +100 -39
  249. package/dist/utils/stack.d.ts +2 -3
  250. package/dist/utils/stack.js +1 -1
  251. package/dist/utils/string.js +87 -0
  252. package/dist/utils/ticks.d.ts +8 -2
  253. package/dist/utils/ticks.js +28 -0
  254. package/dist/utils/ticks.test.d.ts +1 -0
  255. package/dist/utils/ticks.test.js +67 -0
  256. package/dist/utils/types.d.ts +81 -0
  257. package/package.json +25 -24
  258. package/dist/components/ChartContext.svelte +0 -295
  259. package/dist/components/ChartContext.svelte.d.ts +0 -139
  260. package/dist/components/TransformContext.svelte.d.ts +0 -158
  261. package/dist/stores/motionStore.d.ts +0 -30
  262. package/dist/stores/motionStore.js +0 -62
  263. package/dist/utils/graph.d.ts +0 -37
  264. package/dist/utils/rect.js +0 -107
  265. package/dist/utils/scales.d.ts +0 -66
  266. /package/dist/{utils/graph.test.d.ts → components/charts/types.js} +0 -0
@@ -1,25 +1,24 @@
1
- <script lang="ts" context="module">
2
- import { getContext, setContext } from 'svelte';
3
- import { writable, type Readable } from 'svelte/store';
1
+ <script lang="ts" module>
2
+ import { Context } from 'runed';
4
3
 
5
- export const brushContextKey = Symbol();
4
+ const _BrushContext = new Context<BrushContextValue>('BrushContext');
5
+
6
+ export type BrushRange = {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ };
6
12
 
7
13
  export type BrushContextValue = {
8
14
  xDomain: DomainType;
9
15
  yDomain: DomainType;
10
16
  isActive: boolean;
11
- range: {
12
- x: number;
13
- y: number;
14
- width: number;
15
- height: number;
16
- };
17
+ range: BrushRange;
17
18
  handleSize: number;
18
19
  };
19
20
 
20
- export type BrushContext = Readable<BrushContextValue>;
21
-
22
- const defaultContext: BrushContext = writable({
21
+ const defaultContext: BrushContextValue = {
23
22
  xDomain: null,
24
23
  yDomain: null,
25
24
  isActive: false,
@@ -30,14 +29,112 @@
30
29
  height: 0,
31
30
  },
32
31
  handleSize: 0,
33
- });
34
- export function brushContext() {
35
- return getContext<BrushContext>(brushContextKey) ?? defaultContext;
32
+ };
33
+ export function getBrushContext() {
34
+ const defaults = $state(defaultContext);
35
+ return _BrushContext.getOr(defaults);
36
36
  }
37
37
 
38
- function setBrushContext(brush: BrushContext) {
39
- setContext(brushContextKey, brush);
38
+ export function setBrushContext(brush: BrushContextValue) {
39
+ return _BrushContext.set(brush);
40
40
  }
41
+
42
+ type BrushEventPayload = {
43
+ xDomain: DomainType | null;
44
+ yDomain: DomainType | null;
45
+ };
46
+
47
+ type BrushContextPropsWithoutHTML = {
48
+ /**
49
+ * The axis to apply brushing
50
+ *
51
+ * @default 'x'
52
+ */
53
+ axis?: 'x' | 'y' | 'both';
54
+
55
+ /**
56
+ * Size of the draggable handles (width/height)
57
+ *
58
+ * @default 5
59
+ */
60
+ handleSize?: number;
61
+
62
+ /**
63
+ * Only show range while actively brushing.
64
+ * Useful with `brushEnd` event
65
+ *
66
+ * @default false
67
+ */
68
+ resetOnEnd?: boolean;
69
+
70
+ /**
71
+ * Ignore click to reset.
72
+ * Useful to add click handlers to marks. Requires external resetting (button, another chart, etc)
73
+ *
74
+ * @default false
75
+ */
76
+ ignoreResetClick?: boolean;
77
+
78
+ xDomain?: DomainType;
79
+
80
+ yDomain?: DomainType;
81
+
82
+ /**
83
+ * Mode of operation
84
+ * - `integrated`: use with single chart
85
+ * - `separated`: use with separate (typically smaller) chart and state can be managed
86
+ * externally (sync with other charts, etc). Show active selection when domain does not equal
87
+ * original
88
+ *
89
+ * @default 'integrated'
90
+ */
91
+ mode?: 'integrated' | 'separated';
92
+
93
+ /**
94
+ * Disable brush
95
+ *
96
+ * @default false
97
+ */
98
+ disabled?: boolean;
99
+
100
+ /**
101
+ * Attributes passed to the range <div> element
102
+ */
103
+ range?: Partial<HTMLAttributes<HTMLElement>>;
104
+
105
+ /**
106
+ * Attributes passed to the handle <div> elements
107
+ */
108
+ handle?: Partial<HTMLAttributes<HTMLElement>>;
109
+
110
+ /**
111
+ * Classes to apply to the various elements rendered
112
+ *
113
+ * @default {}
114
+ */
115
+ classes?: {
116
+ root?: string;
117
+ frame?: string;
118
+ range?: string;
119
+ handle?: string;
120
+ labels?: string;
121
+ };
122
+
123
+ onChange?: (detail: BrushEventPayload) => void;
124
+ onBrushStart?: (detail: BrushEventPayload) => void;
125
+ onBrushEnd?: (detail: BrushEventPayload) => void;
126
+ onReset?: (detail: BrushEventPayload) => void;
127
+
128
+ /**
129
+ * A reference to this brush's context for use in parent
130
+ * components.
131
+ *
132
+ * @bindable
133
+ */
134
+ brushContext?: BrushContextValue;
135
+
136
+ children?: Snippet<[{ brushContext: BrushContextValue }]>;
137
+ };
41
138
  </script>
42
139
 
43
140
  <script lang="ts">
@@ -46,84 +143,111 @@
46
143
  import { cls } from '@layerstack/tailwind';
47
144
  import { Logger } from '@layerstack/utils';
48
145
 
49
- import { chartContext } from './ChartContext.svelte';
50
-
51
- import type { DomainType } from '../utils/scales.js';
146
+ import { scaleInvert, type DomainType } from '../utils/scales.svelte.js';
52
147
  import { add } from '../utils/math.js';
53
148
  import type { HTMLAttributes } from 'svelte/elements';
149
+ import { getChartContext } from './Chart.svelte';
150
+ import type { Snippet } from 'svelte';
151
+ import { layerClass } from '../utils/attributes.js';
152
+
153
+ const ctx = getChartContext();
154
+
155
+ let {
156
+ brushContext: brushContextProp = $bindable(),
157
+ axis = 'x',
158
+ handleSize = 5,
159
+ resetOnEnd = false,
160
+ ignoreResetClick = false,
161
+ xDomain: xDomain,
162
+ yDomain: yDomain,
163
+ mode = 'integrated',
164
+ disabled = false,
165
+ range = {},
166
+ handle = {},
167
+ classes = {},
168
+ onBrushEnd = () => {},
169
+ onBrushStart = () => {},
170
+ onChange = () => {},
171
+ onReset = () => {},
172
+ children,
173
+ }: BrushContextPropsWithoutHTML = $props();
174
+
175
+ let rootEl = $state<HTMLElement>();
176
+
177
+ if (xDomain === undefined) {
178
+ xDomain = ctx.xScale.domain();
179
+ }
180
+ if (yDomain === undefined) {
181
+ yDomain = ctx.yScale.domain();
182
+ }
54
183
 
55
- const { xScale, yScale, width, height, padding, containerWidth, containerHeight, config } =
56
- chartContext();
57
-
58
- /** Axis to apply brushing */
59
- export let axis: 'x' | 'y' | 'both' = 'x';
60
-
61
- /** Size of draggable handles (width/height) */
62
- export let handleSize = 5;
63
-
64
- /** Only show range while actively brushing. Useful with `brushEnd` event */
65
- export let resetOnEnd = false;
66
-
67
- export let xDomain: DomainType = $xScale.domain() as [number, number];
68
- export let yDomain: DomainType = $yScale.domain() as [number, number];
69
-
70
- /** Mode of operation
71
- * `integrated`: use with single chart
72
- * `separated`: use with separate (typically smaller) chart and state can be managed externally (sync with other charts, etc). Show active selection when domain does not equal original
73
- */
74
- export let mode: 'integrated' | 'separated' = 'integrated';
184
+ $effect.pre(() => {
185
+ if (xDomain !== undefined) return;
186
+ xDomain = ctx.xScale.domain();
187
+ });
75
188
 
76
- /** Disable brush */
77
- export let disabled = false;
189
+ $effect.pre(() => {
190
+ if (yDomain !== undefined) return;
191
+ yDomain = ctx.yScale.domain();
192
+ });
78
193
 
79
- // Capture original domains for reset()
80
- const originalXDomain = $config.xDomain;
81
- const originalYDomain = $config.yDomain;
194
+ const ogXDomain = xDomain;
195
+ const ogYDomain = yDomain;
196
+ const originalXDomain = ctx.config.xDomain;
197
+ const originalYDomain = ctx.config.yDomain;
82
198
 
83
- $: [xDomainMin, xDomainMax] = extent<number>($xScale.domain()) as [number, number];
84
- $: [yDomainMin, yDomainMax] = extent<number>($yScale.domain()) as [number, number];
199
+ const xDomainMinMax = $derived(extent<number>(ctx.xScale.domain()) as [number, number]);
200
+ const xDomainMin = $derived(xDomainMinMax[0]);
201
+ const xDomainMax = $derived(xDomainMinMax[1]);
85
202
 
86
- /** Attributes passed to range <div> element */
87
- export let range: Partial<HTMLAttributes<HTMLDivElement>> | undefined = undefined;
203
+ const yDomainMinMax = $derived(extent<number>(ctx.yScale.domain()) as [number, number]);
204
+ const yDomainMin = $derived(yDomainMinMax[0]);
205
+ const yDomainMax = $derived(yDomainMinMax[1]);
88
206
 
89
- /** Attributes passed to handle <div> elements */
90
- export let handle: Partial<HTMLAttributes<HTMLDivElement>> | undefined = undefined;
207
+ const top = $derived(ctx.yScale(yDomain?.[1]));
208
+ const bottom = $derived(ctx.yScale(yDomain?.[0]));
209
+ const left = $derived(ctx.xScale(xDomain?.[0]));
210
+ const right = $derived(ctx.xScale(xDomain?.[1]));
91
211
 
92
- export let classes: {
93
- root?: string;
94
- frame?: string;
95
- range?: string;
96
- handle?: string;
97
- labels?: string;
98
- } = {};
212
+ const _range = $derived({
213
+ x: axis === 'both' || axis === 'x' ? left : 0,
214
+ y: axis === 'both' || axis === 'y' ? top : 0,
215
+ width: axis === 'both' || axis === 'x' ? right - left : ctx.width,
216
+ height: axis === 'both' || axis === 'y' ? bottom - top : ctx.height,
217
+ });
99
218
 
100
- export let onchange: (detail: { xDomain?: DomainType; yDomain?: DomainType }) => void = () => {};
101
- export let onbrushstart: (detail: {
102
- xDomain?: DomainType;
103
- yDomain?: DomainType;
104
- }) => void = () => {};
105
- export let onbrushend: (detail: {
106
- xDomain?: DomainType;
107
- yDomain?: DomainType;
108
- }) => void = () => {};
109
- export let onreset: (detail: { xDomain?: DomainType; yDomain?: DomainType }) => void = () => {};
219
+ let isActive = $state(false);
110
220
 
111
- /** Exposed to allow binding in Chart */
112
- export let brush = writable<BrushContextValue>({
113
- xDomain: null,
114
- yDomain: null,
115
- isActive: false,
116
- range: {
117
- x: 0,
118
- y: 0,
119
- width: 0,
120
- height: 0,
221
+ const brushContext = {
222
+ get xDomain() {
223
+ return xDomain!;
121
224
  },
122
- handleSize: 0,
123
- });
124
- setBrushContext(brush);
225
+ set xDomain(v: DomainType) {
226
+ xDomain = v;
227
+ },
228
+ get yDomain() {
229
+ return yDomain!;
230
+ },
231
+ set yDomain(v: DomainType) {
232
+ yDomain = v;
233
+ },
234
+ get isActive() {
235
+ return isActive;
236
+ },
237
+ set isActive(v: boolean) {
238
+ isActive = v;
239
+ },
240
+ get range() {
241
+ return _range;
242
+ },
243
+ get handleSize() {
244
+ return handleSize;
245
+ },
246
+ };
247
+
248
+ brushContextProp = brushContext;
125
249
 
126
- let rootEl: HTMLDivElement;
250
+ setBrushContext(brushContext);
127
251
 
128
252
  const logger = new Logger('BrushContext');
129
253
  const RESET_THRESHOLD = 1; // size of pointer delta to ignore
@@ -146,9 +270,16 @@
146
270
 
147
271
  if (
148
272
  startPoint &&
149
- (startPoint.x < 0 || startPoint.x > $width || startPoint.y < 0 || startPoint.y > $height)
273
+ (startPoint.x < 0 ||
274
+ startPoint.x > ctx.width ||
275
+ startPoint.y < 0 ||
276
+ startPoint.y > ctx.height)
150
277
  ) {
151
- logger.debug('ignoring click as outside of chart bounds', { startPoint, $width, $height });
278
+ logger.debug('ignoring click as outside of chart bounds', {
279
+ startPoint,
280
+ width: ctx.width,
281
+ height: ctx.height,
282
+ });
152
283
  return;
153
284
  }
154
285
 
@@ -156,21 +287,21 @@
156
287
  xDomain: [xDomain?.[0] ?? xDomainMin, xDomain?.[1] ?? xDomainMax] as [number, number],
157
288
  yDomain: [yDomain?.[0] ?? yDomainMin, yDomain?.[1] ?? yDomainMax] as [number, number],
158
289
  value: {
159
- x: $xScale.invert?.(startPoint?.x ?? 0),
160
- y: $yScale.invert?.(startPoint?.y ?? 0),
290
+ x: scaleInvert(ctx.xScale, startPoint?.x ?? 0),
291
+ y: scaleInvert(ctx.yScale, startPoint?.y ?? 0),
161
292
  },
162
293
  };
163
294
 
164
- onbrushstart({ xDomain, yDomain });
295
+ onBrushStart({ xDomain, yDomain });
165
296
 
166
297
  const onPointerMove = (e: PointerEvent) => {
167
298
  const currentPoint = localPoint(e, rootEl);
168
299
  fn(start, {
169
- x: $xScale.invert?.(currentPoint?.x ?? 0),
170
- y: $yScale.invert?.(currentPoint?.y ?? 0),
300
+ x: scaleInvert(ctx.xScale, currentPoint?.x ?? 0),
301
+ y: scaleInvert(ctx.yScale, currentPoint?.y ?? 0),
171
302
  });
172
303
 
173
- onchange({ xDomain, yDomain });
304
+ onChange({ xDomain, yDomain });
174
305
  };
175
306
 
176
307
  const onPointerUp = (e: PointerEvent) => {
@@ -189,9 +320,13 @@
189
320
  _range.height < RESET_THRESHOLD
190
321
  ) {
191
322
  // Clicked on frame, or pointer delta was <1
192
- logger.debug('resetting due to frame click');
193
- reset();
194
- onchange({ xDomain, yDomain });
323
+ if (ignoreResetClick) {
324
+ logger.debug('ignoring frame click reset');
325
+ } else {
326
+ logger.debug('resetting due to frame click');
327
+ reset();
328
+ onChange({ xDomain, yDomain });
329
+ }
195
330
  } else {
196
331
  logger.debug('drag end', {
197
332
  target: e.target,
@@ -202,10 +337,15 @@
202
337
  });
203
338
  }
204
339
 
205
- onbrushend({ xDomain, yDomain });
340
+ onBrushEnd({ xDomain, yDomain });
206
341
 
207
342
  if (resetOnEnd) {
208
- reset();
343
+ if (ignoreResetClick) {
344
+ // Still hide brush, but do not reset domain
345
+ brushContext.isActive = false;
346
+ } else {
347
+ reset();
348
+ }
209
349
  }
210
350
 
211
351
  window.removeEventListener('pointermove', onPointerMove);
@@ -219,7 +359,7 @@
219
359
 
220
360
  const createRange = handler((start, value) => {
221
361
  logger.debug('createRange');
222
- isActive = true;
362
+ brushContext.isActive = true;
223
363
 
224
364
  xDomain = [
225
365
  // @ts-expect-error
@@ -288,12 +428,12 @@
288
428
 
289
429
  function reset() {
290
430
  logger.debug('reset');
291
- isActive = false;
431
+ brushContext.isActive = false;
292
432
 
293
- xDomain = originalXDomain;
294
- yDomain = originalYDomain;
433
+ onReset({ xDomain, yDomain });
295
434
 
296
- onreset({ xDomain, yDomain });
435
+ xDomain = ogXDomain;
436
+ yDomain = ogYDomain;
297
437
  }
298
438
 
299
439
  function selectAll() {
@@ -302,67 +442,50 @@
302
442
  yDomain = [yDomainMin, yDomainMax];
303
443
  }
304
444
 
305
- $: top = $yScale(yDomain?.[1]);
306
- $: bottom = $yScale(yDomain?.[0]);
307
- $: left = $xScale(xDomain?.[0]);
308
- $: right = $xScale(xDomain?.[1]);
309
-
310
- $: _range = {
311
- x: axis === 'both' || axis === 'x' ? left : 0,
312
- y: axis === 'both' || axis === 'y' ? top : 0,
313
- width: axis === 'both' || axis === 'x' ? right - left : $width,
314
- height: axis === 'both' || axis === 'y' ? bottom - top : $height,
315
- };
316
-
317
- let isActive = false;
318
- $: if (mode === 'separated') {
319
- // Set reactively to handle cases where xDomain/yDomain are set externally (ex. `bind:xDomain`)
320
- const isXAxisActive =
321
- xDomain?.[0]?.valueOf() !== originalXDomain?.[0]?.valueOf() ||
322
- xDomain?.[1]?.valueOf() !== originalXDomain?.[1]?.valueOf();
323
-
324
- const isYAxisActive =
325
- yDomain?.[0]?.valueOf() !== originalYDomain?.[0]?.valueOf() ||
326
- yDomain?.[1]?.valueOf() !== originalYDomain?.[1]?.valueOf();
327
-
328
- isActive =
329
- axis === 'x' ? isXAxisActive : axis == 'y' ? isYAxisActive : isXAxisActive || isYAxisActive;
330
- }
331
-
332
- $: $brush = {
333
- xDomain,
334
- yDomain,
335
- isActive,
336
- range: _range,
337
- handleSize,
338
- };
445
+ $effect.pre(() => {
446
+ if (mode === 'separated') {
447
+ // Set reactively to handle cases where xDomain/yDomain are set externally (ex. `bind:xDomain`)
448
+ const isXAxisActive =
449
+ xDomain?.[0]?.valueOf() !== originalXDomain?.[0]?.valueOf() ||
450
+ xDomain?.[1]?.valueOf() !== originalXDomain?.[1]?.valueOf();
451
+
452
+ const isYAxisActive =
453
+ yDomain?.[0]?.valueOf() !== originalYDomain?.[0]?.valueOf() ||
454
+ yDomain?.[1]?.valueOf() !== originalYDomain?.[1]?.valueOf();
455
+
456
+ const result =
457
+ axis === 'x' ? isXAxisActive : axis == 'y' ? isYAxisActive : isXAxisActive || isYAxisActive;
458
+ brushContext.isActive = result;
459
+ }
460
+ });
339
461
  </script>
340
462
 
341
463
  {#if disabled}
342
- <slot />
464
+ {@render children?.({ brushContext })}
343
465
  {:else}
466
+ {@const handleClass = layerClass('brush-handle')}
344
467
  <!-- svelte-ignore a11y_no_static_element_interactions -->
345
468
  <div
346
- style:top="{$padding.top}px"
347
- style:left="{$padding.left}px"
348
- style:width="{$width}px"
349
- style:height="{$height}px"
350
- class={cls('BrushContext absolute touch-none')}
351
- on:pointerdown={createRange}
352
- on:dblclick={() => selectAll()}
353
469
  bind:this={rootEl}
470
+ style:top="{ctx.padding.top}px"
471
+ style:left="{ctx.padding.left}px"
472
+ style:width="{ctx.width}px"
473
+ style:height="{ctx.height}px"
474
+ class={cls(layerClass('brush-context'), 'absolute touch-none')}
475
+ onpointerdown={createRange}
476
+ ondblclick={() => selectAll()}
354
477
  >
355
478
  <div
356
- class="absolute"
357
- style:top="-{$padding.top ?? 0}px"
358
- style:left="-{$padding.left ?? 0}px"
359
- style:width="{$containerWidth}px"
360
- style:height="{$containerHeight}px"
479
+ class={cls(layerClass('brush-container'), 'absolute')}
480
+ style:top="-{ctx.padding.top ?? 0}px"
481
+ style:left="-{ctx.padding.left ?? 0}px"
482
+ style:width="{ctx.containerWidth}px"
483
+ style:height="{ctx.containerHeight}px"
361
484
  >
362
- <slot brush={$brush} />
485
+ {@render children?.({ brushContext })}
363
486
  </div>
364
487
 
365
- {#if isActive}
488
+ {#if brushContext.isActive}
366
489
  <div
367
490
  {...range}
368
491
  style:left="{_range.x}px"
@@ -370,14 +493,14 @@
370
493
  style:width="{_range.width}px"
371
494
  style:height="{_range.height}px"
372
495
  class={cls(
373
- 'range',
496
+ layerClass('brush-range'),
374
497
  'absolute bg-surface-content/10 cursor-move select-none',
375
498
  'z-10',
376
499
  classes.range,
377
500
  range?.class
378
501
  )}
379
- on:pointerdown={adjustRange}
380
- on:dblclick={() => reset()}
502
+ onpointerdown={adjustRange}
503
+ ondblclick={() => reset()}
381
504
  ></div>
382
505
 
383
506
  {#if axis === 'both' || axis === 'y'}
@@ -387,20 +510,21 @@
387
510
  style:top="{_range.y}px"
388
511
  style:width="{_range.width}px"
389
512
  style:height="{handleSize}px"
513
+ data-position="top"
390
514
  class={cls(
391
- 'handle top',
515
+ handleClass,
392
516
  'cursor-ns-resize select-none',
393
517
  'range absolute',
394
518
  'z-10',
395
519
  classes.handle,
396
520
  handle?.class
397
521
  )}
398
- on:pointerdown={adjustTop}
399
- on:dblclick={(e) => {
522
+ onpointerdown={adjustTop}
523
+ ondblclick={(e) => {
400
524
  e.stopPropagation();
401
525
  if (yDomain) {
402
526
  yDomain[0] = yDomainMin;
403
- onchange({ xDomain, yDomain });
527
+ onChange({ xDomain, yDomain });
404
528
  }
405
529
  }}
406
530
  ></div>
@@ -411,7 +535,9 @@
411
535
  style:top="{bottom - handleSize}px"
412
536
  style:width="{_range.width}px"
413
537
  style:height="{handleSize}px"
538
+ data-position="bottom"
414
539
  class={cls(
540
+ handleClass,
415
541
  'handle bottom',
416
542
  'cursor-ns-resize select-none',
417
543
  'range absolute',
@@ -419,12 +545,12 @@
419
545
  classes.handle,
420
546
  handle?.class
421
547
  )}
422
- on:pointerdown={adjustBottom}
423
- on:dblclick={(e) => {
548
+ onpointerdown={adjustBottom}
549
+ ondblclick={(e) => {
424
550
  e.stopPropagation();
425
551
  if (yDomain) {
426
552
  yDomain[1] = yDomainMax;
427
- onchange({ xDomain, yDomain });
553
+ onChange({ xDomain, yDomain });
428
554
  }
429
555
  }}
430
556
  ></div>
@@ -437,20 +563,21 @@
437
563
  style:top="{_range.y}px"
438
564
  style:width="{handleSize}px"
439
565
  style:height="{_range.height}px"
566
+ data-position="left"
440
567
  class={cls(
441
- 'handle left',
568
+ handleClass,
442
569
  'cursor-ew-resize select-none',
443
570
  'range absolute',
444
571
  'z-10',
445
572
  classes.handle,
446
573
  handle?.class
447
574
  )}
448
- on:pointerdown={adjustLeft}
449
- on:dblclick={(e) => {
575
+ onpointerdown={adjustLeft}
576
+ ondblclick={(e) => {
450
577
  e.stopPropagation();
451
578
  if (xDomain) {
452
579
  xDomain[0] = xDomainMin;
453
- onchange({ xDomain, yDomain });
580
+ onChange({ xDomain, yDomain });
454
581
  }
455
582
  }}
456
583
  ></div>
@@ -461,20 +588,21 @@
461
588
  style:top="{_range.y}px"
462
589
  style:width="{handleSize}px"
463
590
  style:height="{_range.height}px"
591
+ data-position="right"
464
592
  class={cls(
465
- 'handle right',
593
+ handleClass,
466
594
  'cursor-ew-resize select-none',
467
595
  'range absolute',
468
596
  'z-10',
469
597
  classes.handle,
470
598
  handle?.class
471
599
  )}
472
- on:pointerdown={adjustRight}
473
- on:dblclick={(e) => {
600
+ onpointerdown={adjustRight}
601
+ ondblclick={(e) => {
474
602
  e.stopPropagation();
475
603
  if (xDomain) {
476
604
  xDomain[1] = xDomainMax;
477
- onchange({ xDomain, yDomain });
605
+ onChange({ xDomain: xDomain, yDomain: yDomain });
478
606
  }
479
607
  }}
480
608
  ></div>