layerchart 2.0.0-next.1 → 2.0.0-next.3

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 +143 -0
  4. package/dist/components/AnnotationLine.svelte.d.ts +30 -0
  5. package/dist/components/AnnotationPoint.svelte +119 -0
  6. package/dist/components/AnnotationPoint.svelte.d.ts +34 -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 +283 -180
  14. package/dist/components/Axis.svelte.d.ts +117 -0
  15. package/dist/components/Bar.svelte +166 -107
  16. package/dist/components/Bar.svelte.d.ts +51 -0
  17. package/dist/components/Bars.svelte +56 -67
  18. package/dist/components/Bars.svelte.d.ts +27 -0
  19. package/dist/components/Blur.svelte +42 -12
  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 +71 -21
  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 +49 -13
  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 +30 -14
  66. package/dist/components/Graticule.svelte.d.ts +11 -52
  67. package/dist/components/Grid.svelte +230 -117
  68. package/dist/components/Grid.svelte.d.ts +71 -0
  69. package/dist/components/Group.svelte +173 -106
  70. package/dist/components/Group.svelte.d.ts +81 -0
  71. package/dist/components/Highlight.svelte +410 -308
  72. package/dist/components/Highlight.svelte.d.ts +107 -0
  73. package/dist/components/Hull.svelte +97 -46
  74. package/dist/components/Hull.svelte.d.ts +40 -30
  75. package/dist/components/Labels.svelte +127 -47
  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 +107 -63
  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 +108 -76
  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 +21 -19
  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
@@ -0,0 +1,90 @@
1
+ import { type ScaleBand } from 'd3-scale';
2
+ import { type MotionProp, type MotionOptions, type SpringOptions, type TweenOptions } from './motion.svelte.js';
3
+ import type { Accessor } from './common.js';
4
+ import type { OnlyObjects } from './types.js';
5
+ export type AnyScale<TInput extends SingleDomainType = any, TOutput extends SingleDomainType = any, TScaleArgs extends any[] | readonly any[] = any[]> = {
6
+ (value: TInput): TOutput;
7
+ domain(domain: TInput[] | readonly TInput[]): AnyScale<TInput, TOutput, TScaleArgs>;
8
+ domain(): TInput[];
9
+ range(range: TOutput[] | readonly TOutput[]): AnyScale<TInput, TOutput, TScaleArgs>;
10
+ range(): TOutput[];
11
+ rangeRound?: (range: TOutput[] | readonly TOutput[]) => AnyScale<TInput, TOutput, TScaleArgs>;
12
+ copy: () => AnyScale<TInput, TOutput, TScaleArgs>;
13
+ invert?: (value: TOutput) => TInput;
14
+ invertExtent?: (value: TOutput) => [TInput, TInput];
15
+ bandwidth?: () => number;
16
+ ticks?: (count?: number) => TInput[];
17
+ tickFormat?: (count?: number) => (value: TInput) => string;
18
+ clamp?: (clamp: boolean) => AnyScale<TInput, TOutput, TScaleArgs>;
19
+ interpolate?: (interpolate: (a: TOutput, b: TOutput) => (t: number) => TOutput) => AnyScale<TInput, TOutput, TScaleArgs>;
20
+ nice?: (count?: number) => AnyScale<TInput, TOutput, TScaleArgs>;
21
+ interpolator?(interpolator: (t: number) => TOutput): AnyScale<TInput, TOutput, TScaleArgs>;
22
+ interpolator?(): (t: number) => TOutput;
23
+ thresholds?: () => TInput[];
24
+ quantiles?: () => TInput[];
25
+ };
26
+ export declare function getRange(scale: any): any[];
27
+ export type SingleDomainType = number | string | Date | null | undefined;
28
+ export type DomainType = (number | string | Date | null | undefined)[] | null | undefined;
29
+ export declare function createMotionScale<Domain, Range>(scale: AnyScale, motion: MotionProp | undefined, options: {
30
+ defaultDomain?: Domain;
31
+ defaultRange?: Range;
32
+ }): {
33
+ readonly current: any;
34
+ domain: (values: Domain) => Promise<void>;
35
+ range: (values: Range) => Promise<void>;
36
+ };
37
+ /**
38
+ * Implementation for missing `scaleBand().invert()`
39
+ *
40
+ * See: https://stackoverflow.com/questions/38633082/d3-getting-invert-value-of-band-scales
41
+ * https://github.com/d3/d3-scale/pull/64
42
+ * https://github.com/vega/vega-scale/blob/master/src/scaleBand.js#L118
43
+ * https://observablehq.com/@d3/ordinal-brushing
44
+ * https://github.com/d3/d3-scale/blob/11777dac7d4b0b3e229d658aee3257ea67bd5ffa/src/band.js#L32
45
+ * https://gist.github.com/LuisSevillano/d53a1dc529eef518780c6df99613e2fd
46
+ */
47
+ export declare function scaleBandInvert(scale: ScaleBand<any>): (value: number) => any;
48
+ export declare function isScaleBand(scale: AnyScale<any, any>): scale is ScaleBand<any>;
49
+ /**
50
+ * Generic way to invert a scale value, handling scaleBand and continuous scales (linear, time, etc).
51
+ * Useful to map mouse event location (x,y) to domain value
52
+ */
53
+ export declare function scaleInvert(scale: AnyScale<any, any>, value: number): any;
54
+ /** Create new copy of scale with domain and range */
55
+ export declare function createScale(scale: AnyScale, domain: DomainType, range: any[] | readonly any[] | Function, context?: Record<any, any>): AnyScale<any, any, any[]>;
56
+ /**
57
+ * Create a `scaleBand()` within another scaleBand()'s bandwidth
58
+ * (typically a x1 of an x0 scale, used for grouping)
59
+ */
60
+ export declare function groupScaleBand<Domain extends {
61
+ toString(): string;
62
+ }>(scale: ScaleBand<Domain>, flatData: any[], groupBy: string, padding?: {
63
+ inner?: number;
64
+ outer?: number;
65
+ }): ScaleBand<string>;
66
+ /**
67
+ * Animate d3-scale as domain and/or range are updated using tweened store
68
+ */
69
+ export declare function tweenedScale<Domain, Range>(scale: any, tweenedOptions?: TweenOptions): {
70
+ readonly current: any;
71
+ domain: (values: Domain) => Promise<void>;
72
+ range: (values: Range) => Promise<void>;
73
+ };
74
+ /**
75
+ * Animate d3-scale as domain and/or range are updated using spring store
76
+ */
77
+ export declare function springScale<Domain, Range>(scale: AnyScale, springOptions?: SpringOptions): {
78
+ readonly current: any;
79
+ domain: (values: Domain) => Promise<void>;
80
+ range: (values: Range) => Promise<void>;
81
+ };
82
+ /**
83
+ * Create a store wrapper around a d3-scale which interpolates the domain and/or range using `tweened()` or `spring()` stores. Fallbacks to `writable()` store if not interpolating
84
+ */
85
+ export declare function motionScale<Domain, Range>(scale: AnyScale, options: OnlyObjects<MotionOptions>): {
86
+ readonly current: any;
87
+ domain: (values: Domain) => Promise<void>;
88
+ range: (values: Range) => Promise<void>;
89
+ };
90
+ export declare function makeAccessor<TData>(acc: Accessor<TData>): (d: TData) => any;
@@ -1,10 +1,42 @@
1
- import { derived } from 'svelte/store';
2
- import { tweened, spring } from 'svelte/motion';
3
- import { motionStore } from '../stores/motionStore.js';
4
- import { scaleBand } from 'd3-scale';
5
1
  import { unique } from '@layerstack/utils';
2
+ import { scaleBand } from 'd3-scale';
3
+ import { createControlledMotion, } from './motion.svelte.js';
4
+ import { Spring, Tween } from 'svelte/motion';
5
+ function isAnyScale(scale) {
6
+ return typeof scale === 'function' && typeof scale.range === 'function';
7
+ }
8
+ export function getRange(scale) {
9
+ if (isAnyScale(scale)) {
10
+ return scale.range();
11
+ }
12
+ console.error("[LayerChart] Your scale doesn't have a `.range` method?");
13
+ return [];
14
+ }
15
+ // this may need to become a getter for options so we can reactively update after mount
16
+ export function createMotionScale(scale, motion, options) {
17
+ const domain = createControlledMotion(options.defaultDomain, motion);
18
+ const range = createControlledMotion(options.defaultRange, motion);
19
+ const motionScale = $derived.by(() => {
20
+ // @ts-expect-error
21
+ const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
22
+ if (domain.current) {
23
+ scaleInstance.domain(domain.current);
24
+ }
25
+ if (range.current) {
26
+ scaleInstance.range(range.current);
27
+ }
28
+ return scaleInstance;
29
+ });
30
+ return {
31
+ get current() {
32
+ return motionScale;
33
+ },
34
+ domain: (values) => domain.set(values),
35
+ range: (values) => range.set(values),
36
+ };
37
+ }
6
38
  /**
7
- * Implemenation for missing `scaleBand().invert()`
39
+ * Implementation for missing `scaleBand().invert()`
8
40
  *
9
41
  * See: https://stackoverflow.com/questions/38633082/d3-getting-invert-value-of-band-scales
10
42
  * https://github.com/d3/d3-scale/pull/64
@@ -51,7 +83,10 @@ export function createScale(scale, domain, range, context) {
51
83
  }
52
84
  return scaleCopy;
53
85
  }
54
- /** Create a `scaleBand()` within another scaleBand()'s bandwidth (typically a x1 of an x0 scale, used for grouping) */
86
+ /**
87
+ * Create a `scaleBand()` within another scaleBand()'s bandwidth
88
+ * (typically a x1 of an x0 scale, used for grouping)
89
+ */
55
90
  export function groupScaleBand(scale, flatData, groupBy, padding) {
56
91
  //
57
92
  const groupKeys = unique(flatData.map((d) => d[groupBy]));
@@ -70,20 +105,22 @@ export function groupScaleBand(scale, flatData, groupBy, padding) {
70
105
  * Animate d3-scale as domain and/or range are updated using tweened store
71
106
  */
72
107
  export function tweenedScale(scale, tweenedOptions = {}) {
73
- const tweenedDomain = tweened(undefined, tweenedOptions);
74
- const tweenedRange = tweened(undefined, tweenedOptions);
75
- const tweenedScale = derived([tweenedDomain, tweenedRange], ([domain, range]) => {
76
- const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
77
- if (domain) {
78
- scaleInstance.domain(domain);
108
+ const tweenedDomain = new Tween(undefined, tweenedOptions);
109
+ const tweenedRange = new Tween(undefined, tweenedOptions);
110
+ const tweenedScale = $derived.by(() => {
111
+ const scaledInstance = scale.domain ? scale : scale();
112
+ if (tweenedDomain.current) {
113
+ scaledInstance.domain(tweenedDomain.current);
79
114
  }
80
- if (range) {
81
- scaleInstance.range(range);
115
+ if (tweenedRange.current) {
116
+ scaledInstance.range(tweenedRange.current);
82
117
  }
83
- return scaleInstance;
118
+ return scaledInstance;
84
119
  });
85
120
  return {
86
- subscribe: tweenedScale.subscribe,
121
+ get current() {
122
+ return tweenedScale;
123
+ },
87
124
  domain: (values) => tweenedDomain.set(values),
88
125
  range: (values) => tweenedRange.set(values),
89
126
  };
@@ -92,45 +129,69 @@ export function tweenedScale(scale, tweenedOptions = {}) {
92
129
  * Animate d3-scale as domain and/or range are updated using spring store
93
130
  */
94
131
  export function springScale(scale, springOptions = {}) {
95
- const domainStore = spring(undefined, springOptions);
96
- const rangeStore = spring(undefined, springOptions);
97
- const tweenedScale = derived([domainStore, rangeStore], ([domain, range]) => {
98
- // @ts-expect-error
99
- const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
100
- if (domain) {
101
- scaleInstance.domain(domain);
132
+ const domainState = new Spring(undefined, springOptions);
133
+ const rangeState = new Spring(undefined, springOptions);
134
+ const sprungScale = $derived.by(() => {
135
+ // @ts-expect-error - TODO: investigate/fix
136
+ const scaledInstance = scale.domain ? scale : scale();
137
+ if (domainState.current) {
138
+ scaledInstance.domain(domainState.current);
102
139
  }
103
- if (range) {
104
- scaleInstance.range(range);
140
+ if (rangeState.current) {
141
+ scaledInstance.range(rangeState.current);
105
142
  }
106
- return scaleInstance;
143
+ return scaledInstance;
107
144
  });
108
145
  return {
109
- subscribe: tweenedScale.subscribe,
110
- domain: (values) => domainStore.set(values),
111
- range: (values) => rangeStore.set(values),
146
+ get current() {
147
+ return sprungScale;
148
+ },
149
+ domain: (values) => domainState.set(values),
150
+ range: (values) => rangeState.set(values),
112
151
  };
113
152
  }
114
153
  /**
115
154
  * Create a store wrapper around a d3-scale which interpolates the domain and/or range using `tweened()` or `spring()` stores. Fallbacks to `writable()` store if not interpolating
116
155
  */
117
156
  export function motionScale(scale, options) {
118
- const domainStore = motionStore(undefined, options);
119
- const rangeStore = motionStore(undefined, options);
120
- const tweenedScale = derived([domainStore, rangeStore], ([domain, range]) => {
157
+ const domainState = createControlledMotion(undefined, options);
158
+ const rangeState = createControlledMotion(undefined, options);
159
+ const tweenedScale = $derived.by(() => {
121
160
  // @ts-expect-error
122
161
  const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
123
- if (domain) {
124
- scaleInstance.domain(domain);
162
+ if (domainState.current) {
163
+ scaleInstance.domain(domainState.current);
125
164
  }
126
- if (range) {
127
- scaleInstance.range(range);
165
+ if (rangeState.current) {
166
+ scaleInstance.range(rangeState.current);
128
167
  }
129
168
  return scaleInstance;
130
169
  });
131
170
  return {
132
- subscribe: tweenedScale.subscribe,
133
- domain: (values) => domainStore.set(values),
134
- range: (values) => rangeStore.set(values),
171
+ get current() {
172
+ return tweenedScale;
173
+ },
174
+ domain: (values) => domainState.set(values),
175
+ range: (values) => rangeState.set(values),
135
176
  };
136
177
  }
178
+ function canBeZero(val) {
179
+ if (val === 0)
180
+ return true;
181
+ return val;
182
+ }
183
+ export function makeAccessor(acc) {
184
+ if (!canBeZero(acc))
185
+ return null;
186
+ if (Array.isArray(acc)) {
187
+ return (d) => acc.map((k) => {
188
+ // @ts-expect-error - TODO: Fix these types
189
+ return typeof k !== 'function' ? d[k] : k(d);
190
+ });
191
+ }
192
+ else if (typeof acc !== 'function') {
193
+ // @ts-expect-error - TODO: Fix these types
194
+ return (d) => d[acc];
195
+ }
196
+ return acc;
197
+ }
@@ -1,6 +1,5 @@
1
- import { stackOffsetNone, stackOrderNone } from 'd3-shape';
2
- type OrderType = typeof stackOrderNone;
3
- type OffsetType = typeof stackOffsetNone;
1
+ type OrderType = typeof import('d3-shape').stackOrderNone;
2
+ type OffsetType = typeof import('d3-shape').stackOffsetNone;
4
3
  export declare function groupStackData<TData>(data: TData[], options: {
5
4
  xKey: string;
6
5
  groupBy?: string;
@@ -1,5 +1,5 @@
1
1
  import { flatGroup, group, max, rollup, sum } from 'd3-array';
2
- import { stack, stackOffsetNone, stackOrderNone } from 'd3-shape';
2
+ import { stack } from 'd3-shape';
3
3
  import { pivotWider } from './pivot.js';
4
4
  export function groupStackData(data, options) {
5
5
  const dataByKey = group(data, (d) => d[options.xKey]);
@@ -66,3 +66,90 @@ function getPixel(imageData, x, y) {
66
66
  var d = imageData.data;
67
67
  return [d[i], d[i + 1], d[i + 2], d[i + 3]];
68
68
  }
69
+ export function toTitleCase(str) {
70
+ return str.replace(/^\w/, (d) => d.toUpperCase());
71
+ }
72
+ const DEFAULT_ELLIPSIS = '…';
73
+ /**
74
+ * Truncates a string to fit within a specified pixel width or character count.
75
+ * If the string's width exceeds the maxWidth, it will be truncated. If the character
76
+ * count exceeds maxChars, it will also be truncated.
77
+ *
78
+ * The ellipsis can be placed at the start, middle, or end of the string.
79
+ */
80
+ export function truncateText(text, { position = 'end', ellipsis = DEFAULT_ELLIPSIS, maxWidth, style, maxChars }) {
81
+ if (!text)
82
+ return '';
83
+ // no constraints, return original text
84
+ if (maxWidth === undefined && maxChars === undefined)
85
+ return text;
86
+ // apply maxChars constraint first (if provided)
87
+ let workingText = text;
88
+ if (maxChars !== undefined && text.length > maxChars) {
89
+ if (position === 'start') {
90
+ workingText = ellipsis + text.slice(-maxChars);
91
+ }
92
+ else if (position === 'middle') {
93
+ const half = Math.floor(maxChars / 2);
94
+ workingText = text.slice(0, half) + ellipsis + text.slice(-half);
95
+ }
96
+ else {
97
+ workingText = text.slice(0, maxChars) + ellipsis;
98
+ }
99
+ }
100
+ // apply maxWidth constraint (if provided)
101
+ if (maxWidth !== undefined) {
102
+ const fullWidth = getStringWidth(workingText, style);
103
+ // if width measurement fails or text fits, return current text
104
+ if (fullWidth === null || fullWidth <= maxWidth)
105
+ return workingText;
106
+ const ellipsisWidth = getStringWidth(ellipsis, style) ?? 0;
107
+ let availableWidth = maxWidth - ellipsisWidth;
108
+ if (position === 'start') {
109
+ let truncated = workingText.slice(ellipsis.length); // remove initial ellipsis if present
110
+ let truncatedWidth = getStringWidth(truncated, style);
111
+ while (truncatedWidth !== null && truncatedWidth > availableWidth && truncated.length > 0) {
112
+ truncated = truncated.slice(1);
113
+ truncatedWidth = getStringWidth(truncated, style);
114
+ }
115
+ return ellipsis + truncated;
116
+ }
117
+ else if (position === 'middle') {
118
+ const halfWidth = availableWidth / 2;
119
+ let left = '';
120
+ let right = '';
121
+ let bestLeft = '';
122
+ let bestRight = '';
123
+ for (let i = 0, j = workingText.length - 1; i < workingText.length && j >= 0; i++, j--) {
124
+ const leftTest = workingText.slice(0, i + 1);
125
+ const rightTest = workingText.slice(j);
126
+ const leftWidth = getStringWidth(leftTest, style);
127
+ const rightWidth = getStringWidth(rightTest, style);
128
+ if (leftWidth !== null && leftWidth <= halfWidth)
129
+ left = leftTest;
130
+ if (rightWidth !== null && rightWidth <= halfWidth)
131
+ right = rightTest;
132
+ const combinedWidth = getStringWidth(left + ellipsis + right, style);
133
+ if (combinedWidth !== null && combinedWidth <= maxWidth) {
134
+ bestLeft = left; // longest valid left
135
+ bestRight = right; // longest valid right
136
+ }
137
+ else {
138
+ // we've exceed maxWidth, so break out
139
+ break;
140
+ }
141
+ }
142
+ return bestLeft + ellipsis + bestRight;
143
+ }
144
+ else {
145
+ let truncated = workingText.slice(0, -ellipsis.length);
146
+ let truncatedWidth = getStringWidth(truncated + ellipsis, style);
147
+ while (truncatedWidth !== null && truncatedWidth > maxWidth && truncated.length > 0) {
148
+ truncated = truncated.slice(0, -1);
149
+ truncatedWidth = getStringWidth(truncated + ellipsis, style);
150
+ }
151
+ return truncated + ellipsis;
152
+ }
153
+ }
154
+ return workingText;
155
+ }
@@ -1,3 +1,9 @@
1
- export declare function getMajorTicks(start: Date, end: Date): import("d3-time").TimeInterval | null;
1
+ import { type TimeInterval } from 'd3-time';
2
+ import { type AnyScale } from './scales.svelte.js';
3
+ export declare function getMajorTicks(start: Date, end: Date): TimeInterval | null;
2
4
  export declare function formatMajorTick(date: Date, rangeStart: Date, rangeEnd: Date): string;
3
- export declare function getMinorTicks(start: Date, end: Date): import("d3-time").TimeInterval | null;
5
+ export declare function getMinorTicks(start: Date, end: Date): TimeInterval | null;
6
+ export type TicksConfig = number | any[] | ((scale: AnyScale) => any[] | undefined) | {
7
+ interval: TimeInterval | null;
8
+ } | null;
9
+ export declare function resolveTickVals(scale: AnyScale, ticks?: TicksConfig, placement?: 'radius' | 'top' | 'bottom' | 'left' | 'right' | 'angle'): any[];
@@ -1,6 +1,7 @@
1
1
  import { timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeMillisecond, } from 'd3-time';
2
2
  import { format } from 'date-fns';
3
3
  import { formatDate, PeriodType, getDuration, fail } from '@layerstack/utils';
4
+ import { isScaleBand } from './scales.svelte.js';
4
5
  // TODO: Use PeriodType along with Duration to format (and possibly select intervals)
5
6
  const majorTicks = [
6
7
  {
@@ -153,3 +154,30 @@ export function getMinorTicks(start, end) {
153
154
  }
154
155
  fail(`Unable to locate minor ticks for duration: ${duration}`);
155
156
  }
157
+ export function resolveTickVals(scale, ticks, placement) {
158
+ if (Array.isArray(ticks))
159
+ return ticks;
160
+ if (typeof ticks === 'function')
161
+ return ticks(scale) ?? [];
162
+ if (isLiteralObject(ticks) && 'interval' in ticks) {
163
+ if (ticks.interval === null || !('ticks' in scale) || typeof scale.ticks !== 'function') {
164
+ return []; // Explicitly return empty array for null interval or invalid scale
165
+ }
166
+ return scale.ticks(ticks.interval);
167
+ }
168
+ if (isScaleBand(scale)) {
169
+ return ticks && typeof ticks === 'number'
170
+ ? scale.domain().filter((_, i) => i % ticks === 0)
171
+ : scale.domain();
172
+ }
173
+ if (scale.ticks && typeof scale.ticks === 'function') {
174
+ if (placement) {
175
+ return scale.ticks(ticks ?? (placement === 'left' || placement === 'right' ? 4 : undefined));
176
+ }
177
+ return scale.ticks(ticks);
178
+ }
179
+ return [];
180
+ }
181
+ function isLiteralObject(val) {
182
+ return val !== null && typeof val === 'object' && !Array.isArray(val);
183
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,67 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { resolveTickVals } from './ticks.js';
3
+ // Mock helpers
4
+ const mockTicksFn = vi.fn();
5
+ const mockDomain = vi.fn(() => ['a', 'b', 'c', 'd', 'e']);
6
+ describe('resolveTickVals', () => {
7
+ it('returns array ticks directly', () => {
8
+ const ticks = [1, 2, 3];
9
+ const scale = { ticks: mockTicksFn };
10
+ expect(resolveTickVals(scale, ticks)).toEqual([1, 2, 3]);
11
+ });
12
+ it('calls function ticks with scale', () => {
13
+ const fnTicks = vi.fn(() => [4, 5, 6]);
14
+ const scale = { ticks: mockTicksFn };
15
+ expect(resolveTickVals(scale, fnTicks)).toEqual([4, 5, 6]);
16
+ expect(fnTicks).toHaveBeenCalledWith(scale);
17
+ });
18
+ it('uses interval when provided', () => {
19
+ const interval = { every: vi.fn() };
20
+ const ticksConfig = { interval };
21
+ const scale = { ticks: vi.fn(() => [7, 8, 9]) };
22
+ expect(resolveTickVals(scale, ticksConfig)).toEqual([7, 8, 9]);
23
+ expect(scale.ticks).toHaveBeenCalledWith(interval);
24
+ });
25
+ it('returns empty array if interval is null', () => {
26
+ const ticksConfig = { interval: null };
27
+ const scale = { ticks: mockTicksFn };
28
+ expect(resolveTickVals(scale, ticksConfig)).toEqual([]);
29
+ });
30
+ it('filters band scale domain with number ticks', () => {
31
+ const scale = { domain: mockDomain, bandwidth: vi.fn() };
32
+ expect(resolveTickVals(scale, 2)).toEqual(['a', 'c', 'e']);
33
+ });
34
+ it('returns full domain for band scale without ticks', () => {
35
+ const scale = { domain: mockDomain, bandwidth: vi.fn() };
36
+ expect(resolveTickVals(scale)).toEqual(['a', 'b', 'c', 'd', 'e']);
37
+ });
38
+ it('uses default 4 ticks for left placement', () => {
39
+ const scale = { ticks: vi.fn(() => [1, 2, 3, 4]) };
40
+ expect(resolveTickVals(scale, undefined, 'left')).toEqual([1, 2, 3, 4]);
41
+ expect(scale.ticks).toHaveBeenCalledWith(4);
42
+ });
43
+ it('uses default 4 ticks for right placement', () => {
44
+ const scale = { ticks: vi.fn(() => [1, 2, 3, 4]) };
45
+ expect(resolveTickVals(scale, undefined, 'right')).toEqual([1, 2, 3, 4]);
46
+ expect(scale.ticks).toHaveBeenCalledWith(4);
47
+ });
48
+ it('uses undefined for non-left/right placement', () => {
49
+ const scale = { ticks: vi.fn(() => [1, 2]) };
50
+ expect(resolveTickVals(scale, undefined, 'top')).toEqual([1, 2]);
51
+ expect(scale.ticks).toHaveBeenCalledWith(undefined);
52
+ });
53
+ it('passes number ticks to scale.ticks', () => {
54
+ const scale = { ticks: vi.fn(() => [10, 20]) };
55
+ expect(resolveTickVals(scale, 5)).toEqual([10, 20]);
56
+ expect(scale.ticks).toHaveBeenCalledWith(5);
57
+ });
58
+ it('returns empty array for scale without ticks', () => {
59
+ const scale = {};
60
+ expect(resolveTickVals(scale, 5)).toEqual([]);
61
+ });
62
+ it('handles null ticks with placement', () => {
63
+ const scale = { ticks: vi.fn(() => [1, 2, 3]) };
64
+ expect(resolveTickVals(scale, null, 'bottom')).toEqual([1, 2, 3]);
65
+ expect(scale.ticks).toHaveBeenCalledWith(undefined);
66
+ });
67
+ });
@@ -1,5 +1,86 @@
1
+ import type { HierarchyNode } from 'd3-hierarchy';
2
+ import type { AnyScale } from './scales.svelte.js';
3
+ import type { SankeyGraph } from 'd3-sankey';
4
+ import type { TransitionConfig } from 'svelte/transition';
1
5
  /**
2
6
  * Useful to workaround Svelte 3/4 markup type issues
3
7
  * TODO: Remove usage after migrating to Svelte 5
4
8
  */
5
9
  export declare function asAny(x: any): any;
10
+ /**
11
+ * Constructs a new type by omitting properties from type
12
+ * 'T' that exist in type 'U'.
13
+ *
14
+ * @template T - The base object type from which properties will be omitted.
15
+ * @template U - The object type whose properties will be omitted from 'T'.
16
+ * @example
17
+ * type Result = Without<{ a: number; b: string; }, { b: string; }>;
18
+ * // Result type will be { a: number; }
19
+ */
20
+ export type Without<T extends object, U extends object> = Omit<T, keyof U>;
21
+ export type AxisKey = 'x' | 'y' | 'z' | 'r';
22
+ export type Extents = {
23
+ [K in AxisKey]?: Array<number | string>;
24
+ };
25
+ export type Padding = {
26
+ top: number;
27
+ right: number;
28
+ bottom: number;
29
+ left: number;
30
+ };
31
+ export type Nice = boolean | number;
32
+ export type BaseRange = number[] | string[] | ((args: {
33
+ width: number;
34
+ height: number;
35
+ }) => number[] | string[]);
36
+ export type YRangeWithScale<Scale extends AnyScale = AnyScale> = number[] | string[] | ((args: {
37
+ yScale: Scale;
38
+ width: number;
39
+ height: number;
40
+ }) => number[] | string[]);
41
+ export type XRangeWithScale<Scale extends AnyScale = AnyScale> = number[] | string[] | ((args: {
42
+ xScale: Scale;
43
+ width: number;
44
+ height: number;
45
+ }) => number[] | string[]);
46
+ export type FieldAccessors<T> = {
47
+ x?: (d: T) => number | string | (number | string)[];
48
+ y?: (d: T) => number | string | (number | string)[];
49
+ z?: (d: T) => number | string | (number | string)[];
50
+ r?: (d: T) => number | string | (number | string)[];
51
+ };
52
+ export type PaddingArray = [number, number] | number[] | undefined;
53
+ export type DataType<T> = T[] | HierarchyNode<T> | SankeyGraph<any, any> | readonly T[];
54
+ export type Transition = (node: Element, params?: any) => TransitionConfig;
55
+ export type TransitionParams<T extends Transition> = Parameters<T>[1];
56
+ /**
57
+ * Common style properties that apply to many components.
58
+ * Includes `fill`, `fillOpacity`, `stroke`, `strokeWidth`, and `opacity`.
59
+ */
60
+ export type CommonStyleProps = {
61
+ /**
62
+ * The fill color of the element.
63
+ */
64
+ fill?: string;
65
+ /**
66
+ * The fill opacity of the element.
67
+ */
68
+ fillOpacity?: number;
69
+ /**
70
+ * The stroke color of the element.
71
+ */
72
+ stroke?: string;
73
+ /**
74
+ * The stroke width of the element.
75
+ */
76
+ strokeWidth?: number;
77
+ /**
78
+ * The opacity of the element. (0 to 1)
79
+ */
80
+ opacity?: number;
81
+ };
82
+ export type OnlyObjects<T> = T extends object ? T : never;
83
+ export type Getter<T> = () => T;
84
+ export type GetterValues<T> = {
85
+ [K in keyof T]: Getter<T[K]>;
86
+ };