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

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 -35
  3. package/dist/Mark.svelte +292 -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 +15 -0
  8. package/dist/constants.js +110 -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 +568 -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 +55 -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 +21 -0
  63. package/dist/helpers/resolve.js +156 -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 +311 -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 +93 -0
  87. package/dist/marks/BarX.svelte.d.ts +4 -0
  88. package/dist/marks/BarY.svelte +103 -0
  89. package/dist/marks/BarY.svelte.d.ts +25 -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 +39 -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 +180 -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 +189 -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 +219 -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 +141 -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 +74 -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 +1 -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 +15 -0
  209. package/dist/transforms/recordize.js +78 -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 +66 -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 +24 -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 +81 -42
  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,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: args,
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;
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import Cell from './Cell.svelte';
3
+ import { recordizeX, recordizeY } from '../index.js';
4
+ import type { BaseMarkProps, DataRow, RectMarkProps } from '../types.js';
5
+ import type { ChannelAccessor } from '../types.js';
6
+
7
+ type CellXProps = BaseMarkProps & {
8
+ data: DataRow[];
9
+ x?: ChannelAccessor;
10
+ fill?: ChannelAccessor;
11
+ stroke?: ChannelAccessor;
12
+ } & RectMarkProps;
13
+
14
+ let { data = [{}], ...options }: CellXProps = $props();
15
+
16
+ const args = $derived(
17
+ recordizeY<CellXProps>({
18
+ data,
19
+ ...options
20
+ })
21
+ );
22
+ </script>
23
+
24
+ <Cell {...args} y="0" fill={options.fill || '__value'} />
@@ -0,0 +1,3 @@
1
+ declare const CellX: import("svelte").Component<any, {}, "">;
2
+ type CellX = ReturnType<typeof CellX>;
3
+ export default CellX;
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import Cell from './Cell.svelte';
3
+ import { recordizeX } from '../index.js';
4
+ import type { BaseMarkProps, DataRow, RectMarkProps } from '../types.js';
5
+ import type { ChannelAccessor } from '../types.js';
6
+
7
+ type CellYProps = BaseMarkProps & {
8
+ data: DataRow[];
9
+ y?: ChannelAccessor;
10
+ fill?: ChannelAccessor;
11
+ stroke?: ChannelAccessor;
12
+ } & RectMarkProps;
13
+
14
+ let { data = [{}], ...options }: CellYProps = $props();
15
+
16
+ const args = $derived(
17
+ recordizeX<CellYProps>({
18
+ data,
19
+ ...options
20
+ })
21
+ );
22
+ </script>
23
+
24
+ <Cell {...args} x="0" fill={options.fill || '__value'} />
@@ -0,0 +1,3 @@
1
+ declare const CellY: import("svelte").Component<any, {}, "">;
2
+ type CellY = ReturnType<typeof CellY>;
3
+ export default CellY;
@@ -1,32 +1,150 @@
1
- <script>import { getContext } from "svelte";
2
- import { symbol as d3Symbol } from "d3-shape";
3
- import { maybeSymbol } from "../helpers/symbols.js";
4
- const plot = getContext("svelteplot");
1
+ <script lang="ts">
2
+ import { getContext } from 'svelte';
3
+ import { Plot, AxisX, Frame } from '../index.js';
4
+ import { symbol as d3Symbol, symbol } from 'd3-shape';
5
+ import { range as d3Range } from 'd3-array';
6
+ import { maybeSymbol } from '../helpers/symbols.js';
7
+
8
+ import type { DefaultOptions, PlotContext } from '../types.js';
9
+
10
+ let {
11
+ width = 250,
12
+ tickSpacing = 30,
13
+ class: className = null
14
+ }: { width?: number; tickSpacing?: number; class?: string } = $props();
15
+
16
+ const { getPlotState } = getContext<PlotContext>('svelteplot');
17
+ const plot = $derived(getPlotState());
18
+
19
+ const DEFAULTS = getContext<Partial<DefaultOptions>>('svelteplot/_defaults');
20
+
21
+ const legendTitle = $derived(plot.options.color.label);
22
+ const scaleType = $derived(plot.scales.color.type);
23
+ const tickFormat = $derived(
24
+ typeof plot.options.color?.tickFormat === 'function'
25
+ ? plot.options.color.tickFormat
26
+ : Intl.NumberFormat(
27
+ plot.options.locale,
28
+ plot.options.color.tickFormat || DEFAULTS.numberFormat
29
+ ).format
30
+ );
31
+ const randId = Math.round(Math.random() * 1e6).toFixed(32);
5
32
  </script>
6
33
 
7
- {#if plot.color.manualActiveMarks.length > 0}
8
- <div class="color-legend">
9
- {#each plot.colorScale.domain() as value}
10
- {@const symbolV = plot.symbolScale(value)}
11
- {@const symbolType = maybeSymbol(symbolV)}
12
- <div class="item">
13
- <div class="swatch">
14
- <svg width="15" height="15"
15
- >{#if plot.colorSymbolRedundant}
16
- <path
17
- transform="translate(7.5,7.5)"
18
- fill={plot.hasFilledDotMarks ? plot.colorScale(value) : 'none'}
19
- stroke={plot.hasFilledDotMarks ? null : plot.colorScale(value)}
20
- d={d3Symbol(symbolType, 40)()}
21
- />
22
- {:else}
23
- <rect fill={plot.colorScale(value)} width="15" height="15" />
24
- {/if}</svg
25
- >
34
+ <!--
35
+ @component
36
+ The ColorLegend is an HTML mark that can be placed in the header, footer and overlay
37
+ snippets. You can activate an implicit ColorLegend above the chart using the global
38
+ color.legend scale option.
39
+ -->
40
+
41
+ {#if plot.scales.color.manualActiveMarks > 0}
42
+ <div class="color-legend {className || ''}">
43
+ {#if legendTitle}
44
+ <!-- eslint-disable-next-line svelte/no-at-html-tags -->
45
+ <div class="title">{@html legendTitle}</div>
46
+ {/if}
47
+ {#if scaleType === 'ordinal' || scaleType === 'categorical'}
48
+ {#each plot.scales.color.domain as value}
49
+ {@const symbolV = plot.scales.symbol.fn(value)}
50
+ {@const symbolType = maybeSymbol(symbolV)}
51
+ <div class="item">
52
+ <div class="swatch">
53
+ <svg width="15" height="15"
54
+ >{#if plot.colorSymbolRedundant}
55
+ <path
56
+ transform="translate(7.5,7.5)"
57
+ style:fill={plot.hasFilledDotMarks
58
+ ? plot.scales.color.fn(value)
59
+ : 'none'}
60
+ style:stroke={plot.hasFilledDotMarks
61
+ ? null
62
+ : plot.scales.color.fn(value)}
63
+ d={d3Symbol(symbolType, 40)()} />
64
+ {:else}
65
+ <rect
66
+ style:fill={plot.scales.color.fn(value)}
67
+ width="15"
68
+ height="15" />
69
+ {/if}</svg>
70
+ </div>
71
+ <span class="item-label">{value}</span>
26
72
  </div>
27
- <span class="item-label">{value}</span>
28
- </div>
29
- {/each}
73
+ {/each}
74
+ {:else if scaleType === 'quantile' || scaleType === 'quantize' || scaleType === 'threshold'}
75
+ {@const domain = plot.scales.color.domain}
76
+ {@const range = plot.scales.color.range}
77
+ {@const tickLabels =
78
+ scaleType === 'quantile'
79
+ ? plot.scales.color.fn.quantiles()
80
+ : scaleType === 'quantize'
81
+ ? plot.scales.color.fn.thresholds()
82
+ : plot.scales.color.fn.domain()}
83
+ {@const ticks = d3Range(
84
+ domain[0],
85
+ domain[1],
86
+ (domain[1] - domain[0]) / range.length
87
+ ).slice(1)}
88
+
89
+ <Plot
90
+ maxWidth="240px"
91
+ margins={1}
92
+ marginLeft={1}
93
+ marginRight={1}
94
+ marginTop={6}
95
+ marginBottom={20}
96
+ height={38}
97
+ inset={0}
98
+ x={{ domain, ticks }}>
99
+ <defs>
100
+ <linearGradient id="gradient-{randId}" x2="1">
101
+ <stop offset="0%" stop-color={range[0]} />
102
+ {#each ticks as t, i}
103
+ {@const offset = (100 * (t - domain[0])) / (domain[1] - domain[0])}
104
+ <stop
105
+ offset="{offset - 0.001}%"
106
+ stop-color={plot.scales.color.fn(tickLabels[i] - 0.1)} />
107
+ <stop
108
+ offset="{offset}%"
109
+ stop-color={plot.scales.color.fn(tickLabels[i])} />
110
+ {/each}
111
+ <stop offset="100%" stop-color={range.at(-1)} />
112
+ </linearGradient>
113
+ </defs>
114
+ <Frame dy={-5} stroke={null} fill="url(#gradient-{randId})" />
115
+ <AxisX tickSize={18} dy={-17} />
116
+ </Plot>
117
+ {:else}
118
+ <!--- continuous -->
119
+ {@const domain = plot.scales.color.domain}
120
+ {@const ticks = new Set([
121
+ domain[0],
122
+ ...(plot.scales.color?.fn?.ticks?.(Math.ceil(width / 5)) ?? []),
123
+ domain[1]
124
+ ])}
125
+ <Plot
126
+ maxWidth="240px"
127
+ margins={1}
128
+ marginLeft={10}
129
+ marginRight={10}
130
+ marginTop={6}
131
+ marginBottom={20}
132
+ height={38}
133
+ inset={0}
134
+ x={{ domain, tickSpacing, tickFormat }}>
135
+ <defs>
136
+ <linearGradient id="gradient-{randId}" x2="1">
137
+ {#each ticks as t}
138
+ <stop
139
+ offset="{(100 * (t - domain[0])) / (domain[1] - domain[0])}%"
140
+ stop-color={plot.scales.color.fn(t)} />
141
+ {/each}
142
+ </linearGradient>
143
+ </defs>
144
+ <Frame dy={-5} stroke={null} fill="url(#gradient-{randId})" />
145
+ <AxisX tickSize={18} dy={-17} />
146
+ </Plot>
147
+ {/if}
30
148
  </div>
31
149
  {/if}
32
150
 
@@ -37,6 +155,9 @@ const plot = getContext("svelteplot");
37
155
  display: inline-block;
38
156
  margin-right: 2em;
39
157
  }
158
+ .title {
159
+ font-weight: 500;
160
+ }
40
161
  .item {
41
162
  margin: 0 1em 0.5ex 0;
42
163
  }
@@ -49,6 +170,6 @@ const plot = getContext("svelteplot");
49
170
  display: inline-block;
50
171
  }
51
172
  .item-label {
52
- vertical-align: text-bottom;
173
+ vertical-align: super;
53
174
  }
54
175
  </style>
@@ -1,14 +1,13 @@
1
- import { SvelteComponent } from "svelte";
2
- declare const __propDef: {
3
- props: Record<string, never>;
4
- events: {
5
- [evt: string]: CustomEvent<any>;
6
- };
7
- slots: {};
1
+ type $$ComponentProps = {
2
+ width?: number;
3
+ tickSpacing?: number;
4
+ class?: string;
8
5
  };
9
- export type ColorLegendProps = typeof __propDef.props;
10
- export type ColorLegendEvents = typeof __propDef.events;
11
- export type ColorLegendSlots = typeof __propDef.slots;
12
- export default class ColorLegend extends SvelteComponent<ColorLegendProps, ColorLegendEvents, ColorLegendSlots> {
13
- }
14
- export {};
6
+ /**
7
+ * The ColorLegend is an HTML mark that can be placed in the header, footer and overlay
8
+ * snippets. You can activate an implicit ColorLegend above the chart using the global
9
+ * color.legend scale option.
10
+ */
11
+ declare const ColorLegend: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type ColorLegend = ReturnType<typeof ColorLegend>;
13
+ export default ColorLegend;
@@ -0,0 +1,43 @@
1
+ <!--
2
+ @component
3
+ For showing custom SVG marks positioned at x/y coordinates
4
+ -->
5
+ <script module lang="ts">
6
+ import type { ChannelAccessor, DataRow } from '../types.js';
7
+ import type { Snippet } from 'svelte';
8
+
9
+ export type HTMLMarkProps = {
10
+ data: DataRow[];
11
+ x?: ChannelAccessor;
12
+ y?: ChannelAccessor;
13
+ children: Snippet<{ datum: DataRow; x: number; y: number }>;
14
+ };
15
+ </script>
16
+
17
+ <script lang="ts">
18
+ import { getContext } from 'svelte';
19
+ import type { PlotContext } from '../types.js';
20
+
21
+ const { getPlotState } = getContext<PlotContext>('svelteplot');
22
+ let plot = $derived(getPlotState());
23
+
24
+ import { resolveChannel } from '../helpers/resolve.js';
25
+ import { projectXY } from '../helpers/scales.js';
26
+ import { isValid } from '../helpers/index.js';
27
+ import GroupMultiple from './helpers/GroupMultiple.svelte';
28
+
29
+ let { data = [{}], x, y, children, class: className = null }: HTMLMarkProps = $props();
30
+ </script>
31
+
32
+ <GroupMultiple class="g-custom-mark {className || ''}" length={className ? 2 : data.length}>
33
+ {#each data as datum}
34
+ {@const x_ = resolveChannel('x', datum, { x, y })}
35
+ {@const y_ = resolveChannel('y', datum, { x, y })}
36
+ {#if isValid(x_) && isValid(y_)}
37
+ {@const [px, py] = projectXY(plot.scales, x_, y_)}
38
+ <g transform="translate({px}, {py})">
39
+ {@render children({ datum, x: px, y: py })}
40
+ </g>
41
+ {/if}
42
+ {/each}
43
+ </GroupMultiple>
@@ -0,0 +1,16 @@
1
+ import type { ChannelAccessor, DataRow } from '../types.js';
2
+ import type { Snippet } from 'svelte';
3
+ export type HTMLMarkProps = {
4
+ data: DataRow[];
5
+ x?: ChannelAccessor;
6
+ y?: ChannelAccessor;
7
+ children: Snippet<{
8
+ datum: DataRow;
9
+ x: number;
10
+ y: number;
11
+ }>;
12
+ };
13
+ /** For showing custom SVG marks positioned at x/y coordinates */
14
+ declare const CustomMark: import("svelte").Component<HTMLMarkProps, {}, "">;
15
+ type CustomMark = ReturnType<typeof CustomMark>;
16
+ export default CustomMark;
@@ -0,0 +1,103 @@
1
+ <!--
2
+ @component
3
+ For showing custom HTML tooltips positioned at x/y coordinates
4
+ -->
5
+ <script module lang="ts">
6
+ import type { ChannelAccessor, ConstantAccessor, DataRow } from '../types.js';
7
+ import type { Snippet } from 'svelte';
8
+
9
+ export type HTMLMarkProps = {
10
+ data: DataRow[];
11
+ x?: ChannelAccessor;
12
+ y?: ChannelAccessor;
13
+ frameAnchor?: ConstantAccessor<
14
+ | 'bottom'
15
+ | 'top'
16
+ | 'left'
17
+ | 'right'
18
+ | 'top-left'
19
+ | 'bottom-left'
20
+ | 'top-right'
21
+ | 'bottom-right'
22
+ | 'center'
23
+ >;
24
+ children: Snippet<{ datum: DataRow; x: number; y: number }>;
25
+ };
26
+ </script>
27
+
28
+ <script lang="ts">
29
+ import { getContext } from 'svelte';
30
+ import type { PlotContext } from '../types.js';
31
+
32
+ const { getPlotState } = getContext<PlotContext>('svelteplot');
33
+ const plot = $derived(getPlotState());
34
+
35
+ import { resolveChannel } from '../helpers/resolve.js';
36
+ import { projectX, projectY, projectXY } from '../helpers/scales.js';
37
+ import { isValid } from '../helpers/index.js';
38
+
39
+ let {
40
+ data = [{}],
41
+ x,
42
+ y,
43
+ frameAnchor,
44
+ children,
45
+ class: className = null
46
+ }: HTMLMarkProps = $props();
47
+
48
+ function getXY(datum) {
49
+ const fa = frameAnchor || 'center';
50
+ const isLeft = fa.endsWith('left');
51
+ const isRight = fa.endsWith('right');
52
+ const isTop = fa.startsWith('top');
53
+ const isBottom = fa.startsWith('bottom');
54
+
55
+ if (x == null || y == null) {
56
+ // project x and y individually
57
+ const px =
58
+ x != null
59
+ ? projectX('x', plot.scales, resolveChannel('x', datum, { x, y }))
60
+ : plot.options.marginLeft +
61
+ (isLeft ? 0 : isRight ? plot.width : plot.width / 2);
62
+ const py =
63
+ y != null
64
+ ? projectY('y', plot.scales, resolveChannel('y', datum, { x, y }))
65
+ : plot.options.marginTop +
66
+ (isTop ? 0 : isBottom ? plot.height : plot.height / 2);
67
+ return [px, py];
68
+ } else {
69
+ // use projectXY
70
+ const x_ = resolveChannel('x', datum, { x, y });
71
+ const y_ = resolveChannel('y', datum, { x, y });
72
+ return projectXY(plot.scales, x_, y_);
73
+ }
74
+ }
75
+ </script>
76
+
77
+ {#snippet customMarks()}
78
+ {#each data as datum}
79
+ {@const [px, py] = getXY(datum)}
80
+ {#if isValid(px) && isValid(py)}
81
+ <div
82
+ class="custom-mark-html"
83
+ style:left="{px.toFixed(0)}px"
84
+ style:top="{py.toFixed(0)}px">
85
+ {@render children({ datum, x: px, y: py })}
86
+ </div>
87
+ {/if}
88
+ {/each}
89
+ {/snippet}
90
+
91
+ {#if data.length > 1 || className}
92
+ <div class="g-custom-mark-html {className || ''}">
93
+ {@render customMarks()}
94
+ </div>
95
+ {:else}
96
+ {@render customMarks()}
97
+ {/if}
98
+
99
+ <style>
100
+ .custom-mark-html {
101
+ position: absolute;
102
+ }
103
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { ChannelAccessor, ConstantAccessor, DataRow } from '../types.js';
2
+ import type { Snippet } from 'svelte';
3
+ export type HTMLMarkProps = {
4
+ data: DataRow[];
5
+ x?: ChannelAccessor;
6
+ y?: ChannelAccessor;
7
+ frameAnchor?: ConstantAccessor<'bottom' | 'top' | 'left' | 'right' | 'top-left' | 'bottom-left' | 'top-right' | 'bottom-right' | 'center'>;
8
+ children: Snippet<{
9
+ datum: DataRow;
10
+ x: number;
11
+ y: number;
12
+ }>;
13
+ };
14
+ /** For showing custom HTML tooltips positioned at x/y coordinates */
15
+ declare const CustomMarkHtml: import("svelte").Component<HTMLMarkProps, {}, "">;
16
+ type CustomMarkHtml = ReturnType<typeof CustomMarkHtml>;
17
+ export default CustomMarkHtml;