svelteplot 0.0.1-alpha.9 → 0.1.3-next.4

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 (251) hide show
  1. package/LICENSE.md +5 -0
  2. package/README.md +3 -36
  3. package/dist/Mark.svelte +290 -0
  4. package/dist/Mark.svelte.d.ts +22 -0
  5. package/dist/Plot.svelte +148 -156
  6. package/dist/Plot.svelte.d.ts +15 -15
  7. package/dist/constants.d.ts +14 -0
  8. package/dist/constants.js +109 -0
  9. package/dist/core/Facet.svelte +59 -0
  10. package/dist/core/Facet.svelte.d.ts +18 -0
  11. package/dist/core/FacetAxes.svelte +66 -0
  12. package/dist/core/FacetAxes.svelte.d.ts +4 -0
  13. package/dist/core/FacetGrid.svelte +86 -0
  14. package/dist/core/FacetGrid.svelte.d.ts +13 -0
  15. package/dist/core/Plot.svelte +567 -0
  16. package/dist/core/Plot.svelte.d.ts +14 -0
  17. package/dist/helpers/arrowPath.d.ts +14 -0
  18. package/dist/helpers/arrowPath.js +129 -0
  19. package/dist/helpers/autoProjection.d.ts +19 -0
  20. package/dist/helpers/autoProjection.js +87 -0
  21. package/dist/helpers/autoScales.d.ts +23 -0
  22. package/dist/helpers/autoScales.js +203 -0
  23. package/dist/helpers/autoTicks.d.ts +3 -0
  24. package/dist/helpers/autoTicks.js +40 -0
  25. package/dist/helpers/autoTimeFormat.d.ts +2 -2
  26. package/dist/helpers/autoTimeFormat.js +34 -5
  27. package/dist/helpers/callWithProps.d.ts +8 -0
  28. package/dist/helpers/callWithProps.js +13 -0
  29. package/dist/helpers/colors.js +17 -2
  30. package/dist/helpers/curves.d.ts +3 -0
  31. package/dist/helpers/curves.js +42 -0
  32. package/dist/helpers/data.d.ts +9 -0
  33. package/dist/helpers/data.js +16 -0
  34. package/dist/helpers/facets.d.ts +12 -0
  35. package/dist/helpers/facets.js +49 -0
  36. package/dist/helpers/formats.d.ts +3 -0
  37. package/dist/helpers/formats.js +3 -0
  38. package/dist/helpers/getBaseStyles.d.ts +7 -2
  39. package/dist/helpers/getBaseStyles.js +34 -10
  40. package/dist/helpers/getLogTicks.js +5 -5
  41. package/dist/helpers/group.d.ts +6 -0
  42. package/dist/helpers/group.js +53 -0
  43. package/dist/helpers/index.d.ts +18 -0
  44. package/dist/helpers/index.js +53 -0
  45. package/dist/helpers/isRawValue.d.ts +2 -0
  46. package/dist/helpers/isRawValue.js +5 -0
  47. package/dist/helpers/isValid.d.ts +6 -0
  48. package/dist/helpers/isValid.js +6 -0
  49. package/dist/helpers/math.d.ts +19 -0
  50. package/dist/helpers/math.js +116 -0
  51. package/dist/helpers/mergeDeep.d.ts +1 -1
  52. package/dist/helpers/noise.d.ts +1 -0
  53. package/dist/helpers/noise.js +72 -0
  54. package/dist/helpers/projection.d.ts +33 -0
  55. package/dist/helpers/projection.js +100 -0
  56. package/dist/helpers/reduce.d.ts +10 -0
  57. package/dist/helpers/reduce.js +85 -0
  58. package/dist/helpers/regressionLoess.d.ts +12 -0
  59. package/dist/helpers/regressionLoess.js +47 -0
  60. package/dist/helpers/removeIdenticalLines.d.ts +8 -1
  61. package/dist/helpers/removeIdenticalLines.js +14 -7
  62. package/dist/helpers/resolve.d.ts +17 -0
  63. package/dist/helpers/resolve.js +152 -0
  64. package/dist/helpers/roundedRect.d.ts +9 -0
  65. package/dist/helpers/roundedRect.js +31 -0
  66. package/dist/helpers/scales.d.ts +42 -0
  67. package/dist/helpers/scales.js +309 -0
  68. package/dist/helpers/time.d.ts +6 -0
  69. package/dist/helpers/time.js +282 -0
  70. package/dist/helpers/typeChecks.d.ts +8 -5
  71. package/dist/helpers/typeChecks.js +27 -6
  72. package/dist/index.d.ts +49 -1
  73. package/dist/index.js +53 -2
  74. package/dist/marks/Area.svelte +146 -0
  75. package/dist/marks/Area.svelte.d.ts +30 -0
  76. package/dist/marks/AreaX.svelte +27 -0
  77. package/dist/marks/AreaX.svelte.d.ts +12 -0
  78. package/dist/marks/AreaY.svelte +38 -0
  79. package/dist/marks/AreaY.svelte.d.ts +19 -0
  80. package/dist/marks/Arrow.svelte +139 -0
  81. package/dist/marks/Arrow.svelte.d.ts +44 -0
  82. package/dist/marks/AxisX.svelte +198 -93
  83. package/dist/marks/AxisX.svelte.d.ts +17 -16
  84. package/dist/marks/AxisY.svelte +176 -62
  85. package/dist/marks/AxisY.svelte.d.ts +17 -14
  86. package/dist/marks/BarX.svelte +81 -0
  87. package/dist/marks/BarX.svelte.d.ts +4 -0
  88. package/dist/marks/BarY.svelte +95 -0
  89. package/dist/marks/BarY.svelte.d.ts +4 -0
  90. package/dist/marks/BollingerX.svelte +44 -0
  91. package/dist/marks/BollingerX.svelte.d.ts +18 -0
  92. package/dist/marks/BollingerY.svelte +39 -0
  93. package/dist/marks/BollingerY.svelte.d.ts +18 -0
  94. package/dist/marks/BoxX.svelte +89 -0
  95. package/dist/marks/BoxX.svelte.d.ts +4 -0
  96. package/dist/marks/BoxY.svelte +110 -0
  97. package/dist/marks/BoxY.svelte.d.ts +29 -0
  98. package/dist/marks/Cell.svelte +110 -0
  99. package/dist/marks/Cell.svelte.d.ts +16 -0
  100. package/dist/marks/CellX.svelte +24 -0
  101. package/dist/marks/CellX.svelte.d.ts +3 -0
  102. package/dist/marks/CellY.svelte +24 -0
  103. package/dist/marks/CellY.svelte.d.ts +3 -0
  104. package/dist/marks/ColorLegend.svelte +148 -27
  105. package/dist/marks/ColorLegend.svelte.d.ts +12 -13
  106. package/dist/marks/CustomMark.svelte +43 -0
  107. package/dist/marks/CustomMark.svelte.d.ts +16 -0
  108. package/dist/marks/CustomMarkHTML.svelte +103 -0
  109. package/dist/marks/CustomMarkHTML.svelte.d.ts +17 -0
  110. package/dist/marks/DifferenceY.svelte +144 -0
  111. package/dist/marks/DifferenceY.svelte.d.ts +30 -0
  112. package/dist/marks/Dot.svelte +128 -73
  113. package/dist/marks/Dot.svelte.d.ts +24 -14
  114. package/dist/marks/DotX.svelte +15 -3
  115. package/dist/marks/DotX.svelte.d.ts +8 -16
  116. package/dist/marks/DotY.svelte +8 -3
  117. package/dist/marks/DotY.svelte.d.ts +5 -17
  118. package/dist/marks/Frame.svelte +32 -31
  119. package/dist/marks/Frame.svelte.d.ts +7 -14
  120. package/dist/marks/Geo.svelte +102 -0
  121. package/dist/marks/Geo.svelte.d.ts +10 -0
  122. package/dist/marks/Graticule.svelte +28 -0
  123. package/dist/marks/Graticule.svelte.d.ts +9 -0
  124. package/dist/marks/GridX.svelte +67 -36
  125. package/dist/marks/GridX.svelte.d.ts +7 -18
  126. package/dist/marks/GridY.svelte +64 -25
  127. package/dist/marks/GridY.svelte.d.ts +7 -14
  128. package/dist/marks/HTMLTooltip.svelte +91 -0
  129. package/dist/marks/HTMLTooltip.svelte.d.ts +11 -0
  130. package/dist/marks/Line.svelte +219 -58
  131. package/dist/marks/Line.svelte.d.ts +30 -14
  132. package/dist/marks/LineX.svelte +8 -8
  133. package/dist/marks/LineX.svelte.d.ts +4 -17
  134. package/dist/marks/LineY.svelte +7 -8
  135. package/dist/marks/LineY.svelte.d.ts +4 -17
  136. package/dist/marks/Link.svelte +173 -0
  137. package/dist/marks/Link.svelte.d.ts +21 -0
  138. package/dist/marks/Pointer.svelte +126 -0
  139. package/dist/marks/Pointer.svelte.d.ts +23 -0
  140. package/dist/marks/Rect.svelte +103 -0
  141. package/dist/marks/Rect.svelte.d.ts +15 -0
  142. package/dist/marks/RectX.svelte +33 -0
  143. package/dist/marks/RectX.svelte.d.ts +15 -0
  144. package/dist/marks/RectY.svelte +33 -0
  145. package/dist/marks/RectY.svelte.d.ts +15 -0
  146. package/dist/marks/RegressionX.svelte +26 -0
  147. package/dist/marks/RegressionX.svelte.d.ts +4 -0
  148. package/dist/marks/RegressionY.svelte +26 -0
  149. package/dist/marks/RegressionY.svelte.d.ts +4 -0
  150. package/dist/marks/RuleX.svelte +52 -28
  151. package/dist/marks/RuleX.svelte.d.ts +14 -14
  152. package/dist/marks/RuleY.svelte +52 -28
  153. package/dist/marks/RuleY.svelte.d.ts +14 -14
  154. package/dist/marks/Sphere.svelte +8 -0
  155. package/dist/marks/Sphere.svelte.d.ts +51 -0
  156. package/dist/marks/Spike.svelte +15 -0
  157. package/dist/marks/Spike.svelte.d.ts +4 -0
  158. package/dist/marks/SymbolLegend.svelte +27 -12
  159. package/dist/marks/SymbolLegend.svelte.d.ts +8 -14
  160. package/dist/marks/Text.svelte +185 -0
  161. package/dist/marks/Text.svelte.d.ts +26 -0
  162. package/dist/marks/TickX.svelte +89 -0
  163. package/dist/marks/TickX.svelte.d.ts +22 -0
  164. package/dist/marks/TickY.svelte +90 -0
  165. package/dist/marks/TickY.svelte.d.ts +22 -0
  166. package/dist/marks/Vector.svelte +213 -0
  167. package/dist/marks/Vector.svelte.d.ts +31 -0
  168. package/dist/marks/helpers/BaseAxisX.svelte +210 -0
  169. package/dist/marks/helpers/BaseAxisX.svelte.d.ts +24 -0
  170. package/dist/marks/helpers/BaseAxisY.svelte +187 -0
  171. package/dist/marks/helpers/BaseAxisY.svelte.d.ts +23 -0
  172. package/dist/marks/helpers/CanvasLayer.svelte +38 -0
  173. package/dist/marks/helpers/CanvasLayer.svelte.d.ts +13 -0
  174. package/dist/marks/helpers/DotCanvas.svelte +184 -0
  175. package/dist/marks/helpers/DotCanvas.svelte.d.ts +11 -0
  176. package/dist/marks/helpers/GeoCanvas.svelte +165 -0
  177. package/dist/marks/helpers/GeoCanvas.svelte.d.ts +13 -0
  178. package/dist/marks/helpers/GroupMultiple.svelte +17 -0
  179. package/dist/marks/helpers/GroupMultiple.svelte.d.ts +9 -0
  180. package/dist/marks/helpers/Marker.svelte +93 -0
  181. package/dist/marks/helpers/Marker.svelte.d.ts +10 -0
  182. package/dist/marks/helpers/MarkerPath.svelte +164 -0
  183. package/dist/marks/helpers/MarkerPath.svelte.d.ts +44 -0
  184. package/dist/marks/helpers/Regression.svelte +174 -0
  185. package/dist/marks/helpers/Regression.svelte.d.ts +26 -0
  186. package/dist/marks/helpers/events.d.ts +8 -0
  187. package/dist/marks/helpers/events.js +64 -0
  188. package/dist/transforms/bin.d.ts +51 -0
  189. package/dist/transforms/bin.js +171 -0
  190. package/dist/transforms/bollinger.d.ts +21 -0
  191. package/dist/transforms/bollinger.js +53 -0
  192. package/dist/transforms/centroid.d.ts +9 -0
  193. package/dist/transforms/centroid.js +13 -0
  194. package/dist/transforms/facet.d.ts +1 -0
  195. package/dist/transforms/facet.js +1 -0
  196. package/dist/transforms/filter.d.ts +2 -0
  197. package/dist/transforms/filter.js +8 -0
  198. package/dist/transforms/group.d.ts +66 -0
  199. package/dist/transforms/group.js +109 -0
  200. package/dist/transforms/interval.d.ts +11 -0
  201. package/dist/transforms/interval.js +34 -0
  202. package/dist/transforms/jitter.d.ts +0 -0
  203. package/dist/transforms/jitter.js +1 -0
  204. package/dist/transforms/map.d.ts +10 -0
  205. package/dist/transforms/map.js +89 -0
  206. package/dist/transforms/normalize.d.ts +9 -0
  207. package/dist/transforms/normalize.js +86 -0
  208. package/dist/transforms/recordize.d.ts +13 -0
  209. package/dist/transforms/recordize.js +75 -0
  210. package/dist/transforms/rename.d.ts +14 -0
  211. package/dist/transforms/rename.js +42 -0
  212. package/dist/transforms/select.d.ts +35 -0
  213. package/dist/transforms/select.js +55 -0
  214. package/dist/transforms/shift.d.ts +13 -0
  215. package/dist/transforms/shift.js +45 -0
  216. package/dist/transforms/sort.d.ts +28 -0
  217. package/dist/transforms/sort.js +61 -0
  218. package/dist/transforms/stack.d.ts +10 -0
  219. package/dist/transforms/stack.js +110 -0
  220. package/dist/transforms/window.d.ts +22 -0
  221. package/dist/transforms/window.js +73 -0
  222. package/dist/types.d.ts +625 -188
  223. package/dist/ui/Checkbox.svelte +6 -0
  224. package/dist/ui/Checkbox.svelte.d.ts +13 -0
  225. package/dist/ui/RadioInput.svelte +27 -0
  226. package/dist/ui/RadioInput.svelte.d.ts +9 -0
  227. package/dist/ui/Select.svelte +27 -0
  228. package/dist/ui/Select.svelte.d.ts +9 -0
  229. package/dist/ui/Slider.svelte +47 -0
  230. package/dist/ui/Slider.svelte.d.ts +11 -0
  231. package/dist/ui/Spiral.svelte +46 -0
  232. package/dist/ui/Spiral.svelte.d.ts +15 -0
  233. package/dist/ui/index.d.ts +4 -0
  234. package/dist/ui/index.js +4 -0
  235. package/package.json +79 -40
  236. package/LICENSE +0 -11
  237. package/dist/classes/Channel.svelte.js +0 -74
  238. package/dist/classes/Mark.svelte.js +0 -17
  239. package/dist/classes/Plot.svelte.js +0 -98
  240. package/dist/contants.d.ts +0 -3
  241. package/dist/contants.js +0 -40
  242. package/dist/helpers/GroupMultiple.svelte +0 -8
  243. package/dist/helpers/GroupMultiple.svelte.d.ts +0 -19
  244. package/dist/helpers/createScale.d.ts +0 -5
  245. package/dist/helpers/createScale.js +0 -57
  246. package/dist/helpers/resolveChannel.d.ts +0 -2
  247. package/dist/helpers/resolveChannel.js +0 -28
  248. package/dist/helpers/wrapArray.d.ts +0 -2
  249. package/dist/helpers/wrapArray.js +0 -4
  250. package/dist/marks/BaseMark.svelte +0 -22
  251. package/dist/marks/BaseMark.svelte.d.ts +0 -19
@@ -0,0 +1,81 @@
1
+ <!--
2
+ @component
3
+ For horizontal bar charts using a band scale as y axis
4
+ -->
5
+ <script lang="ts">
6
+ import Mark from '../Mark.svelte';
7
+ import { getContext } from 'svelte';
8
+ import { stackX, recordizeX, intervalX, sort } from '../index.js';
9
+ import { resolveProp, resolveStyles } from '../helpers/resolve.js';
10
+ import { roundedRect } from '../helpers/roundedRect.js';
11
+ import type { PlotContext, BaseMarkProps, RectMarkProps, ChannelAccessor } from '../types.js';
12
+ import type { StackOptions } from '../transforms/stack.js';
13
+ import type { DataRow } from '../types.js';
14
+ import { addEventHandlers } from './helpers/events.js';
15
+ import GroupMultiple from './helpers/GroupMultiple.svelte';
16
+
17
+ type BarXProps = BaseMarkProps & {
18
+ data: DataRow[];
19
+ x?: ChannelAccessor;
20
+ x1?: ChannelAccessor;
21
+ x2?: ChannelAccessor;
22
+ y?: ChannelAccessor;
23
+ stack?: StackOptions;
24
+ borderRadius?:
25
+ | number
26
+ | {
27
+ topLeft?: number;
28
+ topRight?: number;
29
+ bottomRight?: number;
30
+ bottomLeft?: number;
31
+ };
32
+ } & RectMarkProps;
33
+
34
+ let { data = [{}], class: className = null, stack, ...options }: BarXProps = $props();
35
+
36
+ const { getPlotState } = getContext<PlotContext>('svelteplot');
37
+ const plot = $derived(getPlotState());
38
+
39
+ const args = $derived(
40
+ stackX(
41
+ intervalX(
42
+ // by default, sort by y channel (the ordinal labels)
43
+ sort(recordizeX({ data, sort: { channel: 'y' }, ...options })),
44
+ { plot }
45
+ ),
46
+ stack
47
+ )
48
+ );
49
+ </script>
50
+
51
+ <Mark
52
+ type="barX"
53
+ requiredScales={{ y: ['band'] }}
54
+ channels={['x1', 'x2', 'y', 'fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity']}
55
+ {...args}>
56
+ {#snippet children({ mark, usedScales, scaledData })}
57
+ <GroupMultiple class="bar-x" length={scaledData.length}>
58
+ {#each scaledData as d}
59
+ {@const bw = plot.scales.y.fn.bandwidth()}
60
+ {@const minx = Math.min(d.x1, d.x2)}
61
+ {@const maxx = Math.max(d.x1, d.x2)}
62
+ {@const inset = resolveProp(args.inset, d.datum, 0)}
63
+ {@const dx = resolveProp(args.dx, d.datum, 0)}
64
+ {@const dy = resolveProp(args.dy, d.datum, 0)}
65
+ {#if d.valid}
66
+ {@const [style, styleClass] = resolveStyles(plot, d, args, 'fill', usedScales)}
67
+ <path
68
+ d={roundedRect(0, 0, maxx - minx, bw - inset * 2, options.borderRadius)}
69
+ class={[styleClass, className]}
70
+ {style}
71
+ transform="translate({[minx + dx, d.y + inset + dy - bw * 0.5]})"
72
+ use:addEventHandlers={{
73
+ getPlotState,
74
+ options: mark.options,
75
+ datum: d.datum
76
+ }} />
77
+ {/if}
78
+ {/each}
79
+ </GroupMultiple>
80
+ {/snippet}
81
+ </Mark>
@@ -0,0 +1,4 @@
1
+ /** For horizontal bar charts using a band scale as y axis */
2
+ declare const BarX: import("svelte").Component<any, {}, "">;
3
+ type BarX = ReturnType<typeof BarX>;
4
+ export default BarX;
@@ -0,0 +1,95 @@
1
+ <!--
2
+ @component
3
+ For vertical column charts using a band scale as x axis
4
+ -->
5
+ <script lang="ts">
6
+ import Mark from '../Mark.svelte';
7
+ import { getContext } from 'svelte';
8
+ import { intervalY, stackY, recordizeY, sort } from '../index.js';
9
+ import { resolveProp, resolveStyles } from '../helpers/resolve.js';
10
+ import { roundedRect } from '../helpers/roundedRect.js';
11
+ import {
12
+ type PlotContext,
13
+ type BaseMarkProps,
14
+ type RectMarkProps,
15
+ type ChannelAccessor,
16
+ type DataRow,
17
+ type FacetContext
18
+ } from '../types.js';
19
+ import type { StackOptions } from '../transforms/stack.js';
20
+ import { maybeData } from '../helpers/index.js';
21
+ import { addEventHandlers } from './helpers/events.js';
22
+ import GroupMultiple from './helpers/GroupMultiple.svelte';
23
+
24
+ type BarYProps = BaseMarkProps & {
25
+ data: DataRow[];
26
+ x?: ChannelAccessor;
27
+ y?: ChannelAccessor;
28
+ y1?: ChannelAccessor;
29
+ y2?: ChannelAccessor;
30
+ stack?: StackOptions;
31
+ /**
32
+ * Converts y into y1/y2 ranges based on the provided interval. Disables the
33
+ * implicit stacking
34
+ */
35
+ interval?: number | string;
36
+ borderRadius?:
37
+ | number
38
+ | {
39
+ topLeft?: number;
40
+ topRight?: number;
41
+ bottomRight?: number;
42
+ bottomLeft?: number;
43
+ };
44
+ } & RectMarkProps;
45
+
46
+ let { data = [{}], class: className = null, stack, ...options }: BarYProps = $props();
47
+
48
+ const { getPlotState } = getContext<PlotContext>('svelteplot');
49
+ let plot = $derived(getPlotState());
50
+
51
+ let args = $derived(
52
+ stackY(
53
+ intervalY(
54
+ // by default, sort by x channel (the ordinal labels)
55
+ sort(recordizeY({ data: maybeData(data), sort: { channel: 'x' }, ...options })),
56
+ { plot }
57
+ ),
58
+ stack
59
+ )
60
+ );
61
+
62
+ const { getTestFacet } = getContext<FacetContext>('svelteplot/facet');
63
+ </script>
64
+
65
+ <Mark
66
+ type="barY"
67
+ requiredScales={{ x: ['band'] }}
68
+ channels={['x', 'y1', 'y2', 'fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity']}
69
+ {...args}>
70
+ {#snippet children({ mark, scaledData, usedScales })}
71
+ <GroupMultiple class="bar-y" length={scaledData.length}>
72
+ {#each scaledData as d}
73
+ {@const bw = plot.scales.x.fn.bandwidth()}
74
+ {@const miny = Math.min(d.y1, d.y2)}
75
+ {@const maxy = Math.max(d.y1, d.y2)}
76
+ {@const inset = resolveProp(args.inset, d.datum, 0)}
77
+ {@const dx = resolveProp(args.dx, d.datum, 0)}
78
+ {@const dy = resolveProp(args.dy, d.datum, 0)}
79
+ {#if d.valid}
80
+ {@const [style, styleClass] = resolveStyles(plot, d, args, 'fill', usedScales)}
81
+ <path
82
+ d={roundedRect(0, 0, bw - inset * 2, maxy - miny, options.borderRadius)}
83
+ class={[styleClass, className]}
84
+ {style}
85
+ transform="translate({[d.x + inset + dx - bw * 0.5, miny + dy]})"
86
+ use:addEventHandlers={{
87
+ getPlotState,
88
+ options: mark.options,
89
+ datum: d.datum
90
+ }} />
91
+ {/if}
92
+ {/each}
93
+ </GroupMultiple>
94
+ {/snippet}
95
+ </Mark>
@@ -0,0 +1,4 @@
1
+ /** For vertical column charts using a band scale as x axis */
2
+ declare const BarY: import("svelte").Component<any, {}, "">;
3
+ type BarY = ReturnType<typeof BarY>;
4
+ export default BarY;
@@ -0,0 +1,44 @@
1
+ <!--
2
+ @component
3
+ line representing a moving average and an area representing volatility as a band
4
+ -->
5
+ <script lang="ts">
6
+ import { Area, Line, bollingerX, recordizeX } from '../index.js';
7
+ import type { BaseMarkProps, ChannelAccessor, DataRow } from '../types.js';
8
+ import { pick } from 'es-toolkit';
9
+
10
+ type BollingerXProps = BaseMarkProps & {
11
+ data: DataRow[];
12
+ x?: ChannelAccessor;
13
+ y?: ChannelAccessor;
14
+ /**
15
+ * the window size (the window transform’s k option), an integer; defaults to 20
16
+ */
17
+ n?: number;
18
+ /**
19
+ * the band radius, a number representing a multiple of standard deviations; defaults to 2
20
+ */
21
+ k?: number;
22
+ };
23
+
24
+ let { data, class: className = null, n = 20, k = 2, ...options }: BollingerXProps = $props();
25
+
26
+ let args = $derived(bollingerX(recordizeX({ data, ...options }), { n, k }));
27
+ </script>
28
+
29
+ <g class="bollinger {className || ''}">
30
+ <Line
31
+ {...{
32
+ x: '__avg',
33
+ y: '__x',
34
+ ...pick(args, ['data', 'stroke', 'strokeOpacity', 'opacity'])
35
+ }} />
36
+ <Area
37
+ {...{
38
+ y1: '__x',
39
+ x1: '__lo',
40
+ x2: '__hi',
41
+ fillOpacity: 0.2,
42
+ ...pick(args, ['data', 'fill', 'fillOpacity', 'opacity'])
43
+ }} />
44
+ </g>
@@ -0,0 +1,18 @@
1
+ import type { BaseMarkProps, ChannelAccessor, DataRow } from '../types.js';
2
+ type BollingerXProps = BaseMarkProps & {
3
+ data: DataRow[];
4
+ x?: ChannelAccessor;
5
+ y?: ChannelAccessor;
6
+ /**
7
+ * the window size (the window transform’s k option), an integer; defaults to 20
8
+ */
9
+ n?: number;
10
+ /**
11
+ * the band radius, a number representing a multiple of standard deviations; defaults to 2
12
+ */
13
+ k?: number;
14
+ };
15
+ /** line representing a moving average and an area representing volatility as a band */
16
+ declare const BollingerX: import("svelte").Component<BollingerXProps, {}, "">;
17
+ type BollingerX = ReturnType<typeof BollingerX>;
18
+ export default BollingerX;
@@ -0,0 +1,39 @@
1
+ <!--
2
+ @component
3
+ line representing a moving average and an area representing volatility as a band
4
+ -->
5
+ <script lang="ts">
6
+ import { Area, Line, bollingerY, recordizeY } from '../index.js';
7
+ import type { BaseMarkProps, ChannelAccessor, DataRow } from '../types.js';
8
+ import { pick } from 'es-toolkit';
9
+
10
+ type BollingerYProps = BaseMarkProps & {
11
+ data: DataRow[];
12
+ x?: ChannelAccessor;
13
+ y?: ChannelAccessor;
14
+ /**
15
+ * the window size (the window transform’s k option), an integer; defaults to 20
16
+ */
17
+ n?: number;
18
+ /**
19
+ * the band radius, a number representing a multiple of standard deviations; defaults to 2
20
+ */
21
+ k?: number;
22
+ };
23
+
24
+ let { data, n = 20, k = 2, class: className, ...options }: BollingerYProps = $props();
25
+
26
+ const args = $derived(bollingerY(recordizeY({ data, ...options }), { n, k }));
27
+ </script>
28
+
29
+ <g class="bollinger {className || ''}">
30
+ <Line {...pick(args, ['x', 'y', 'data', 'stroke', 'strokeOpacity', 'opacity'])} />
31
+ <Area
32
+ {...{
33
+ x1: '__x',
34
+ y1: '__lo',
35
+ y2: '__hi',
36
+ fillOpacity: 0.2,
37
+ ...pick(args, ['data', 'fill', 'fillOpacity', 'opacity'])
38
+ }} />
39
+ </g>
@@ -0,0 +1,18 @@
1
+ import type { BaseMarkProps, ChannelAccessor, DataRow } from '../types.js';
2
+ type BollingerYProps = BaseMarkProps & {
3
+ data: DataRow[];
4
+ x?: ChannelAccessor;
5
+ y?: ChannelAccessor;
6
+ /**
7
+ * the window size (the window transform’s k option), an integer; defaults to 20
8
+ */
9
+ n?: number;
10
+ /**
11
+ * the band radius, a number representing a multiple of standard deviations; defaults to 2
12
+ */
13
+ k?: number;
14
+ };
15
+ /** line representing a moving average and an area representing volatility as a band */
16
+ declare const BollingerY: import("svelte").Component<BollingerYProps, {}, "">;
17
+ type BollingerY = ReturnType<typeof BollingerY>;
18
+ export default BollingerY;
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import GroupMultiple from './helpers/GroupMultiple.svelte';
3
+ import type { BoxProps } from './BoxY.svelte';
4
+ import { BarX, TickX, RuleY, Dot, groupY } from '../index.js';
5
+ import { resolveChannel } from '../helpers/resolve.js';
6
+
7
+ let {
8
+ data = [{}],
9
+ x,
10
+ y,
11
+ rule,
12
+ bar,
13
+ tickMedian = true,
14
+ tickMinMax = false,
15
+ dot,
16
+ class: className = null
17
+ }: BoxProps = $props();
18
+
19
+ const { data: grouped } = $derived(
20
+ groupY(
21
+ {
22
+ data: data.filter((d) => resolveChannel('x', d, { x, y }) != null),
23
+ x,
24
+ y,
25
+ x1: x,
26
+ x2: x
27
+ },
28
+ { x: 'median', x1: 'p25', x2: 'p75', fill: (rows) => rows }
29
+ )
30
+ );
31
+
32
+ const boxData = $derived(
33
+ grouped
34
+ .map((row) => {
35
+ const iqr = row.__x2 - row.__x1;
36
+ const whisker = iqr * 1.5;
37
+ const lower = row.__x1 - whisker;
38
+ const upper = row.__x2 + whisker;
39
+ const data = row.__fill.map((d) => ({
40
+ ...d,
41
+ __x: resolveChannel('x', d, { x, y })
42
+ }));
43
+ const outliers = data.filter((d) => d.__x < lower || d.__x > upper);
44
+ const inside = data
45
+ .filter((d) => d.__x >= lower && d.__x <= upper)
46
+ .sort((a, b) => a.__x - b.__x);
47
+ // if (inside.length === 0) console.log('No data inside boxplot', data, row, lower, upper);
48
+ return {
49
+ [y]: row[y],
50
+ __y: row[y],
51
+ p25: row.__x1,
52
+ p75: row.__x2,
53
+ median: row.__x,
54
+ min: inside[0].__x,
55
+ max: inside.at(-1).__x,
56
+ outliers
57
+ };
58
+ })
59
+ .sort((a, b) => b.median - a.median)
60
+ );
61
+ </script>
62
+
63
+ <GroupMultiple class="box-x {className || ''}" length={className ? 2 : grouped.length}>
64
+ <RuleY data={boxData} y="__y" x1="min" x2="max" {...rule || {}} />
65
+ <BarX data={boxData} y="__y" x1="p25" x2="p75" fill="#ddd" {...bar || {}} />
66
+ {#if tickMedian}
67
+ <TickX
68
+ data={boxData}
69
+ y="__y"
70
+ x="median"
71
+ strokeWidth={2}
72
+ {...typeof tickMedian === 'object' ? tickMedian : {}} />
73
+ {/if}
74
+ {#if tickMinMax}
75
+ <TickX
76
+ data={boxData}
77
+ x="min"
78
+ y="__y"
79
+ inset="20%"
80
+ {...typeof tickMinMax === 'object' ? tickMinMax : {}} />
81
+ <TickX
82
+ data={boxData}
83
+ x="max"
84
+ y="__y"
85
+ inset="20%"
86
+ {...typeof tickMinMax === 'object' ? tickMinMax : {}} />
87
+ {/if}
88
+ <Dot data={boxData.map((d) => d.outliers).flat()} {x} {y} {...dot || {}} />
89
+ </GroupMultiple>
@@ -0,0 +1,4 @@
1
+ import type { BoxProps } from './BoxY.svelte';
2
+ declare const BoxX: import("svelte").Component<BoxProps, {}, "">;
3
+ type BoxX = ReturnType<typeof BoxX>;
4
+ export default BoxX;
@@ -0,0 +1,110 @@
1
+ <script lang="ts" module>
2
+ export type BoxProps = {
3
+ data: DataRecord[];
4
+ x: ChannelAccessor;
5
+ y: ChannelAccessor;
6
+ /**
7
+ * Options for the rule marks that represent the min/max range
8
+ */
9
+ rule: Record<string, ChannelAccessor>;
10
+ /**
11
+ * Options for the bar marks that represent the IQR range
12
+ */
13
+ bar: Record<string, ChannelAccessor>;
14
+ /**
15
+ * Options for the tick marks that represent the median
16
+ */
17
+ tickMedian: Record<string, ChannelAccessor> | boolean;
18
+ /**
19
+ * Options for the tick marks that represent the min/max range
20
+ */
21
+ tickMinMax: Record<string, ChannelAccessor> | boolean;
22
+ /**
23
+ * Options for the dot marks that represent the outliers
24
+ */
25
+ dot: Record<string, ChannelAccessor>;
26
+ };
27
+ </script>
28
+
29
+ <script lang="ts">
30
+ import GroupMultiple from './helpers/GroupMultiple.svelte';
31
+ import type { ChannelAccessor, DataRecord } from '../types.js';
32
+ import { groupX, BarY, TickY, RuleX, Dot } from '../index.js';
33
+ import { resolveChannel } from '../helpers/resolve.js';
34
+
35
+ let {
36
+ data = [{}],
37
+ x,
38
+ y,
39
+ rule,
40
+ bar,
41
+ tickMedian = true,
42
+ tickMinMax = false,
43
+ dot,
44
+ class: className = null
45
+ }: BoxProps = $props();
46
+
47
+ let { data: grouped } = $derived(
48
+ groupX(
49
+ {
50
+ data: data.filter((d) => resolveChannel('x', d, { x, y }) != null),
51
+ x,
52
+ y,
53
+ y1: y,
54
+ y2: y
55
+ },
56
+ { y: 'median', y1: 'p25', y2: 'p75', fill: (rows) => rows }
57
+ )
58
+ );
59
+
60
+ let boxData = $derived(
61
+ grouped.map((row) => {
62
+ const iqr = row.__y2 - row.__y1;
63
+ const whisker = iqr * 1.5;
64
+ const lower = row.__y1 - whisker;
65
+ const upper = row.__y2 + whisker;
66
+ const data = row.__fill.map((d) => ({ ...d, __y: resolveChannel('y', d, { x, y }) }));
67
+ const outliers = data.filter((d) => d.__y < lower || d.__y > upper);
68
+ const inside = data
69
+ .filter((d) => d.__y >= lower && d.__y <= upper)
70
+ .sort((a, b) => a.__y - b.__y);
71
+ return {
72
+ __x: row[x],
73
+ p25: row.__y1,
74
+ p75: row.__y2,
75
+ median: row.__y,
76
+ min: inside[0].__y,
77
+ max: inside.at(-1).__y,
78
+ outliers
79
+ };
80
+ })
81
+ );
82
+ </script>
83
+
84
+ <GroupMultiple class="box-y {className || ''}" length={className ? 2 : grouped.length}>
85
+ <RuleX data={boxData} x="__x" y1="min" y2="max" {...rule || {}} />
86
+ <BarY data={boxData} x="__x" y1="p25" y2="p75" fill="#ddd" {...bar || {}} />
87
+ {#if tickMedian}
88
+ <TickY
89
+ data={boxData}
90
+ x="__x"
91
+ y="median"
92
+ strokeWidth={2}
93
+ {...typeof tickMedian === 'object' ? tickMedian : {}} />
94
+ {/if}
95
+ {#if tickMinMax}
96
+ <TickY
97
+ data={boxData}
98
+ x="__x"
99
+ y="min"
100
+ inset="20%"
101
+ {...typeof tickMinMax === 'object' ? tickMinMax : {}} />
102
+ <TickY
103
+ data={boxData}
104
+ x="__x"
105
+ y="max"
106
+ inset="20%"
107
+ {...typeof tickMinMax === 'object' ? tickMinMax : {}} />
108
+ {/if}
109
+ <Dot data={boxData.map((d) => d.outliers).flat()} {x} {y} {...dot || {}} />
110
+ </GroupMultiple>
@@ -0,0 +1,29 @@
1
+ export type BoxProps = {
2
+ data: DataRecord[];
3
+ x: ChannelAccessor;
4
+ y: ChannelAccessor;
5
+ /**
6
+ * Options for the rule marks that represent the min/max range
7
+ */
8
+ rule: Record<string, ChannelAccessor>;
9
+ /**
10
+ * Options for the bar marks that represent the IQR range
11
+ */
12
+ bar: Record<string, ChannelAccessor>;
13
+ /**
14
+ * Options for the tick marks that represent the median
15
+ */
16
+ tickMedian: Record<string, ChannelAccessor> | boolean;
17
+ /**
18
+ * Options for the tick marks that represent the min/max range
19
+ */
20
+ tickMinMax: Record<string, ChannelAccessor> | boolean;
21
+ /**
22
+ * Options for the dot marks that represent the outliers
23
+ */
24
+ dot: Record<string, ChannelAccessor>;
25
+ };
26
+ import type { ChannelAccessor, DataRecord } from '../types.js';
27
+ declare const BoxY: import("svelte").Component<BoxProps, {}, "">;
28
+ type BoxY = ReturnType<typeof BoxY>;
29
+ export default BoxY;
@@ -0,0 +1,110 @@
1
+ <!--
2
+ @component
3
+ For arbitrary rectangles, requires band x and y scales
4
+ -->
5
+ <script lang="ts">
6
+ import Mark from '../Mark.svelte';
7
+ import { getContext } from 'svelte';
8
+ import { recordizeY, sort } from '../index.js';
9
+ import { roundedRect } from '../helpers/roundedRect.js';
10
+ import { resolveChannel, resolveProp, resolveStyles } from '../helpers/resolve.js';
11
+ import { coalesce, maybeNumber } from '../helpers/index.js';
12
+ import type {
13
+ PlotContext,
14
+ DataRecord,
15
+ BaseMarkProps,
16
+ BaseRectMarkProps,
17
+ ChannelAccessor
18
+ } from '../types.js';
19
+ import { isValid } from '../helpers/isValid.js';
20
+ import { addEventHandlers } from './helpers/events.js';
21
+
22
+ type CellProps = BaseMarkProps & {
23
+ data: DataRecord[];
24
+ x?: ChannelAccessor;
25
+ y?: ChannelAccessor;
26
+ borderRadius?:
27
+ | number
28
+ | {
29
+ topLeft?: number;
30
+ topRight?: number;
31
+ bottomRight?: number;
32
+ bottomLeft?: number;
33
+ };
34
+ } & BaseRectMarkProps;
35
+
36
+ let { data = [{}], class: className = null, ...options }: CellProps = $props();
37
+
38
+ const { getPlotState } = getContext<PlotContext>('svelteplot');
39
+ const plot = $derived(getPlotState());
40
+
41
+ const args = $derived(
42
+ options.sort !== undefined
43
+ ? // user has defined a custom sorting
44
+ sort(recordizeY({ data, ...options }))
45
+ : // sort by x and y
46
+ (sort({
47
+ ...sort({
48
+ ...recordizeY({ data, ...options }),
49
+ sort: { channel: 'x' }
50
+ }),
51
+ sort: { channel: 'y' }
52
+ }) as Props)
53
+ );
54
+ </script>
55
+
56
+ <Mark
57
+ type="cell"
58
+ required={['x', 'y']}
59
+ requiredScales={{ x: ['band'], y: ['band'] }}
60
+ channels={['x', 'y', 'fill', 'stroke', 'opacity', 'fillOpacity', 'strokeOpacity']}
61
+ {...args}>
62
+ {#snippet children({ mark, scaledData, usedScales })}
63
+ {@const bwx = plot.scales.x.fn.bandwidth()}
64
+ {@const bwy = plot.scales.y.fn.bandwidth()}
65
+ <g class="cell {className || ''}" data-fill={usedScales.fillOpacity}>
66
+ {#each scaledData as d}
67
+ {@const inset = resolveProp(args.inset, d.datum, 0)}
68
+ {@const insetLeft = resolveProp(args.insetLeft, d.datum)}
69
+ {@const insetRight = resolveProp(args.insetRight, d.datum)}
70
+ {@const insetTop = resolveProp(args.insetTop, d.datum)}
71
+ {@const insetBottom = resolveProp(args.insetBottom, d.datum)}
72
+ {@const dx = resolveProp(args.dx, d.datum, 0)}
73
+ {@const dy = resolveProp(args.dy, d.datum, 0)}
74
+ {@const insetL = maybeNumber(coalesce(insetLeft, inset, 0))}
75
+ {@const insetT = maybeNumber(coalesce(insetTop, inset, 0))}
76
+ {@const insetR = maybeNumber(coalesce(insetRight, inset, 0))}
77
+ {@const insetB = maybeNumber(coalesce(insetBottom, inset, 0))}
78
+ {#if d.valid && (args.fill == null || isValid(resolveChannel('fill', d.datum, args)))}
79
+ {@const [style, styleClass] = resolveStyles(plot, d, args, 'fill', usedScales)}
80
+ <path
81
+ d={roundedRect(
82
+ 0,
83
+ 0,
84
+ bwx - insetL - insetR,
85
+ bwy - insetT - insetB,
86
+ options.borderRadius
87
+ )}
88
+ class={[styleClass]}
89
+ {style}
90
+ transform="translate({[
91
+ d.x + insetL + dx - bwx * 0.5,
92
+ d.y + insetT + dy - bwy * 0.5
93
+ ]})"
94
+ use:addEventHandlers={{
95
+ getPlotState,
96
+ options: mark.options,
97
+ datum: d.datum
98
+ }} />
99
+ {/if}
100
+ {/each}
101
+ </g>
102
+ {/snippet}
103
+ </Mark>
104
+
105
+ <style>
106
+ rect {
107
+ stroke: none;
108
+ /* fill: none; */
109
+ }
110
+ </style>
@@ -0,0 +1,16 @@
1
+ import type { DataRecord, BaseMarkProps, BaseRectMarkProps, ChannelAccessor } from '../types.js';
2
+ type CellProps = BaseMarkProps & {
3
+ data: DataRecord[];
4
+ x?: ChannelAccessor;
5
+ y?: ChannelAccessor;
6
+ borderRadius?: number | {
7
+ topLeft?: number;
8
+ topRight?: number;
9
+ bottomRight?: number;
10
+ bottomLeft?: number;
11
+ };
12
+ } & BaseRectMarkProps;
13
+ /** For arbitrary rectangles, requires band x and y scales */
14
+ declare const Cell: import("svelte").Component<CellProps, {}, "">;
15
+ type Cell = ReturnType<typeof Cell>;
16
+ export default Cell;