layerchart 0.4.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,12 +15,12 @@
15
15
  import { getContext } from 'svelte';
16
16
  import { arc as d3arc } from 'd3-shape';
17
17
  import { scaleLinear } from 'd3-scale';
18
- import { createMotionStore } from '../stores/motionStore';
18
+ import { motionStore } from '../stores/motionStore';
19
19
  import { degreesToRadians } from '../utils/math';
20
20
  export let spring = undefined;
21
21
  export let tweened = undefined;
22
22
  export let value = 0;
23
- let tweened_value = createMotionStore(value, { spring, tweened });
23
+ let tweened_value = motionStore(value, { spring, tweened });
24
24
  $: tweened_value.set(value);
25
25
  export let domain = [0, 100];
26
26
  /**
@@ -110,6 +110,6 @@ $: yOffset = -Math.cos(angle) * offset;
110
110
  <path d={trackArc()} class="track" bind:this={trackArcEl} {...track} />
111
111
  {/if}
112
112
 
113
- <path d={arc()} transform="translate({xOffset}, {yOffset})" {...$$restProps} />
113
+ <path d={arc()} transform="translate({xOffset}, {yOffset})" {...$$restProps} on:click />
114
114
 
115
115
  <slot value={$tweened_value} centroid={trackArcCentroid} {boundingBox} />
@@ -18,6 +18,8 @@ declare const __propDef: {
18
18
  offset?: number;
19
19
  };
20
20
  events: {
21
+ click: MouseEvent;
22
+ } & {
21
23
  [evt: string]: CustomEvent<any>;
22
24
  };
23
25
  slots: {
@@ -1,7 +1,7 @@
1
1
  <script>import { getContext } from 'svelte';
2
2
  import { area as d3Area } from 'd3-shape';
3
3
  import { interpolatePath } from 'd3-interpolate-path';
4
- import { createMotionStore } from '../stores/motionStore';
4
+ import { motionStore } from '../stores/motionStore';
5
5
  import Path from './Path.svelte';
6
6
  const { data: contextData, xGet, yGet, yRange } = getContext('LayerCake');
7
7
  // Properties to override what is used from context
@@ -18,7 +18,7 @@ export let color = 'var(--color-blue-500)';
18
18
  export let opacity = 0.3;
19
19
  export let line = false;
20
20
  $: tweenedOptions = tweened ? { interpolate: interpolatePath, ...tweened } : false;
21
- $: tweened_d = createMotionStore('', { tweened: tweenedOptions });
21
+ $: tweened_d = motionStore('', { tweened: tweenedOptions });
22
22
  $: {
23
23
  const path = d3Area()
24
24
  .x(x ?? $xGet)
@@ -0,0 +1,24 @@
1
+ <script>import { getContext } from 'svelte';
2
+ import { scaleLinear } from 'd3-scale';
3
+ import { motionScale } from '../utils/scales';
4
+ const { width, height } = getContext('LayerCake');
5
+ export let domain;
6
+ export let range;
7
+ export let spring = undefined;
8
+ export let tweened = undefined;
9
+ function getExtents(extents, axis, fallback) {
10
+ const resolvedExtents = typeof extents === 'function' ? extents({ width: $width, height: $height }) : extents;
11
+ return [
12
+ resolvedExtents?.[axis + '0'] ?? 0,
13
+ resolvedExtents?.[axis + '1'] ?? fallback // x1 or y1, fallback as $width or $height
14
+ ];
15
+ }
16
+ const xScale = motionScale(scaleLinear, { spring, tweened });
17
+ $: xScale.domain(getExtents(domain, 'x', $width));
18
+ $: xScale.range(getExtents(range, 'x', $width));
19
+ const yScale = motionScale(scaleLinear, { spring, tweened });
20
+ $: yScale.domain(getExtents(domain, 'y', $height));
21
+ $: yScale.range(getExtents(range, 'y', $height));
22
+ </script>
23
+
24
+ <slot xScale={$xScale} yScale={$yScale} />
@@ -0,0 +1,51 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import { motionScale } from '../utils/scales';
3
+ declare const __propDef: {
4
+ props: {
5
+ domain: {
6
+ x0: number;
7
+ y0: number;
8
+ x1: number;
9
+ y1: number;
10
+ } | ((dimensions: {
11
+ width: number;
12
+ height: number;
13
+ }) => {
14
+ x0: number;
15
+ y0: number;
16
+ x1: number;
17
+ y1: number;
18
+ });
19
+ range: {
20
+ x0: number;
21
+ y0: number;
22
+ x1: number;
23
+ y1: number;
24
+ } | ((dimensions: {
25
+ width: number;
26
+ height: number;
27
+ }) => {
28
+ x0: number;
29
+ y0: number;
30
+ x1: number;
31
+ y1: number;
32
+ });
33
+ spring?: boolean | Parameters<typeof motionScale>[1]['spring'];
34
+ tweened?: boolean | Parameters<typeof motionScale>[1]['tweened'];
35
+ };
36
+ events: {
37
+ [evt: string]: CustomEvent<any>;
38
+ };
39
+ slots: {
40
+ default: {
41
+ xScale: any;
42
+ yScale: any;
43
+ };
44
+ };
45
+ };
46
+ export declare type BoundsProps = typeof __propDef.props;
47
+ export declare type BoundsEvents = typeof __propDef.events;
48
+ export declare type BoundsSlots = typeof __propDef.slots;
49
+ export default class Bounds extends SvelteComponentTyped<BoundsProps, BoundsEvents, BoundsSlots> {
50
+ }
51
+ export {};
@@ -1,12 +1,12 @@
1
- <script>import { createMotionStore } from '../stores/motionStore';
1
+ <script>import { motionStore } from '../stores/motionStore';
2
2
  export let cx;
3
3
  export let cy;
4
4
  export let r;
5
5
  export let spring = undefined;
6
6
  export let tweened = undefined;
7
- let tweened_cx = createMotionStore(cx, { spring, tweened });
8
- let tweened_cy = createMotionStore(cy, { spring, tweened });
9
- let tweened_r = createMotionStore(r, { spring, tweened });
7
+ let tweened_cx = motionStore(cx, { spring, tweened });
8
+ let tweened_cy = motionStore(cy, { spring, tweened });
9
+ let tweened_r = motionStore(r, { spring, tweened });
10
10
  $: tweened_cx.set(cx);
11
11
  $: tweened_cy.set(cy);
12
12
  $: tweened_r.set(r);
@@ -1,5 +1,5 @@
1
1
  <script>import { getContext } from 'svelte';
2
- import { createMotionStore } from '../stores/motionStore';
2
+ import { motionStore } from '../stores/motionStore';
3
3
  const { width, height } = getContext('LayerCake');
4
4
  /**
5
5
  * Translate x
@@ -15,8 +15,8 @@ export let y = undefined;
15
15
  export let center = false;
16
16
  export let spring = undefined;
17
17
  export let tweened = undefined;
18
- let tweened_x = createMotionStore(x, { spring, tweened });
19
- let tweened_y = createMotionStore(y, { spring, tweened });
18
+ let tweened_x = motionStore(x, { spring, tweened });
19
+ let tweened_y = motionStore(y, { spring, tweened });
20
20
  $: tweened_x.set(x);
21
21
  $: tweened_y.set(y);
22
22
  let transform = undefined;
@@ -1,14 +1,14 @@
1
- <script>import { createMotionStore } from '../stores/motionStore';
1
+ <script>import { motionStore } from '../stores/motionStore';
2
2
  export let x1;
3
3
  export let y1;
4
4
  export let x2;
5
5
  export let y2;
6
6
  export let spring = undefined;
7
7
  export let tweened = undefined;
8
- let tweened_x1 = createMotionStore(x1, { spring, tweened });
9
- let tweened_y1 = createMotionStore(y1, { spring, tweened });
10
- let tweened_x2 = createMotionStore(x2, { spring, tweened });
11
- let tweened_y2 = createMotionStore(y2, { spring, tweened });
8
+ let tweened_x1 = motionStore(x1, { spring, tweened });
9
+ let tweened_y1 = motionStore(y1, { spring, tweened });
10
+ let tweened_x2 = motionStore(x2, { spring, tweened });
11
+ let tweened_y2 = motionStore(y2, { spring, tweened });
12
12
  $: tweened_x1.set(x1);
13
13
  $: tweened_y1.set(y1);
14
14
  $: tweened_x2.set(x2);
@@ -1,6 +1,6 @@
1
1
  <script>import { link as d3Link, curveBumpX, curveBumpY } from 'd3-shape';
2
2
  import { interpolatePath } from 'd3-interpolate-path';
3
- import { createMotionStore } from '../stores/motionStore';
3
+ import { motionStore } from '../stores/motionStore';
4
4
  // Properties to override what is used from context
5
5
  export let data = undefined; // TODO: Update Type
6
6
  export let orientation = 'horizontal';
@@ -17,7 +17,7 @@ export let tweened = undefined;
17
17
  export let color = 'black';
18
18
  export let width = undefined;
19
19
  $: tweenedOptions = tweened ? { interpolate: interpolatePath, ...tweened } : false;
20
- $: tweened_d = createMotionStore('', { tweened: tweenedOptions });
20
+ $: tweened_d = motionStore('', { tweened: tweenedOptions });
21
21
  $: {
22
22
  orientation; // subscribe to orientation changes to link is update
23
23
  const link = d3Link(curve).source(source).target(target).x(x).y(y);
@@ -0,0 +1,27 @@
1
+ <script>import { getContext } from 'svelte';
2
+ import { partition as d3Partition } from 'd3-hierarchy';
3
+ const { data, width, height } = getContext('LayerCake');
4
+ export let orientation = 'horizontal';
5
+ export let size = undefined;
6
+ /**
7
+ * see: https://github.com/d3/d3-hierarchy#tree_nodeSize
8
+ */
9
+ export let padding = undefined;
10
+ /**
11
+ * see: https://github.com/d3/d3-hierarchy#tree_nodeSize
12
+ */
13
+ export let round = undefined;
14
+ let partition;
15
+ $: {
16
+ partition = d3Partition().size(size ?? (orientation === 'horizontal' ? [$height, $width] : [$width, $height]));
17
+ if (padding) {
18
+ partition.padding(padding);
19
+ }
20
+ if (round) {
21
+ partition.round(round);
22
+ }
23
+ }
24
+ $: partitionData = partition($data);
25
+ </script>
26
+
27
+ <slot nodes={partitionData.descendants()} />
@@ -0,0 +1,27 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ orientation?: 'vertical' | 'horizontal';
5
+ size?: [number, number] | undefined;
6
+ /**
7
+ * see: https://github.com/d3/d3-hierarchy#tree_nodeSize
8
+ */ padding?: number | undefined;
9
+ /**
10
+ * see: https://github.com/d3/d3-hierarchy#tree_nodeSize
11
+ */ round?: boolean | undefined;
12
+ };
13
+ events: {
14
+ [evt: string]: CustomEvent<any>;
15
+ };
16
+ slots: {
17
+ default: {
18
+ nodes: import("d3-hierarchy").HierarchyRectangularNode<unknown>[];
19
+ };
20
+ };
21
+ };
22
+ export declare type PartitionProps = typeof __propDef.props;
23
+ export declare type PartitionEvents = typeof __propDef.events;
24
+ export declare type PartitionSlots = typeof __propDef.slots;
25
+ export default class Partition extends SvelteComponentTyped<PartitionProps, PartitionEvents, PartitionSlots> {
26
+ }
27
+ export {};
@@ -6,7 +6,7 @@ import { getContext } from 'svelte';
6
6
  import { line as d3Line } from 'd3-shape';
7
7
  // import { interpolateString } from 'd3-interpolate';
8
8
  import { interpolatePath } from 'd3-interpolate-path';
9
- import { createMotionStore } from '../stores/motionStore';
9
+ import { motionStore } from '../stores/motionStore';
10
10
  const { data: contextData, xGet, yGet, zGet } = getContext('LayerCake');
11
11
  // Properties to override what is used from context
12
12
  export let data = undefined; // TODO: Update Type
@@ -19,7 +19,7 @@ export let defined = undefined;
19
19
  export let color = 'black';
20
20
  export let width = undefined;
21
21
  $: tweenedOptions = tweened ? { interpolate: interpolatePath, ...tweened } : false;
22
- $: tweened_d = createMotionStore('', { tweened: tweenedOptions });
22
+ $: tweened_d = motionStore('', { tweened: tweenedOptions });
23
23
  $: {
24
24
  const path = d3Line()
25
25
  .x(x ?? $xGet)
@@ -3,7 +3,7 @@ import { pie as d3pie } from 'd3-shape';
3
3
  import Arc from './Arc.svelte';
4
4
  import Group from './Group.svelte';
5
5
  import { degreesToRadians } from '../utils/math';
6
- import { createMotionStore } from '../stores/motionStore';
6
+ import { motionStore } from '../stores/motionStore';
7
7
  /*
8
8
  TODO:
9
9
  - [ ] Offset (always, on hover)
@@ -48,7 +48,7 @@ export let tweened = undefined;
48
48
  export let offset = 0;
49
49
  const { data: contextData, x, y, xRange, rGet, config } = getContext('LayerCake');
50
50
  $: resolved_endAngle = endAngle ?? degreesToRadians($config.xRange ? $xRange[1] : range[1]);
51
- let tweened_endAngle = createMotionStore(0, { spring, tweened });
51
+ let tweened_endAngle = motionStore(0, { spring, tweened });
52
52
  $: tweened_endAngle.set(resolved_endAngle);
53
53
  $: pie = d3pie()
54
54
  .startAngle(startAngle ?? degreesToRadians($config.xRange ? $xRange[0] : range[0]))
@@ -1,14 +1,14 @@
1
- <script>import { createMotionStore } from '../stores/motionStore';
1
+ <script>import { motionStore } from '../stores/motionStore';
2
2
  export let x = 0;
3
3
  export let y = 0;
4
4
  export let width;
5
5
  export let height;
6
6
  export let spring = undefined;
7
7
  export let tweened = undefined;
8
- let tweened_x = createMotionStore(x, { spring, tweened });
9
- let tweened_y = createMotionStore(y, { spring, tweened });
10
- let tweened_width = createMotionStore(width, { spring, tweened });
11
- let tweened_height = createMotionStore(height, { spring, tweened });
8
+ let tweened_x = motionStore(x, { spring, tweened });
9
+ let tweened_y = motionStore(y, { spring, tweened });
10
+ let tweened_width = motionStore(width, { spring, tweened });
11
+ let tweened_height = motionStore(height, { spring, tweened });
12
12
  $: tweened_x.set(x);
13
13
  $: tweened_y.set(y);
14
14
  $: tweened_width.set(width);
@@ -3,12 +3,8 @@
3
3
  * - [ ] Improve zoomable nested (apply extent ratio? const extentRatio = ($extents.y1 - $extents.y0) / $height;
4
4
  */
5
5
  import { getContext } from 'svelte';
6
- import { tweened } from 'svelte/motion';
7
- import { cubicOut } from 'svelte/easing';
8
6
  import * as d3 from 'd3-hierarchy';
9
- import { scaleLinear } from 'd3-scale';
10
7
  import { group } from 'd3-array';
11
- import RectClipPath from './RectClipPath.svelte';
12
8
  import { aspectTile } from '../utils/treemap';
13
9
  const { data, width, height } = getContext('LayerCake');
14
10
  export let tile = d3.treemapSquarify;
@@ -61,43 +57,16 @@ $: {
61
57
  }
62
58
  }
63
59
  $: root = treemap($data);
60
+ // TODO: Remove selected
64
61
  $: selected = root; // set initial selection
65
- // group nodes by depth so can be rendered lowest to highest
62
+ // group nodes by depth so can be rendered lowest to highest, to stack properly
66
63
  $: nodesByDepth = group(root, (d) => d.depth);
67
- const duration = 800;
68
- const extents = tweened(undefined, { easing: cubicOut, duration });
69
- $: $extents = selected
70
- ? {
71
- x0: selected.x0,
72
- y0: selected.y0,
73
- x1: selected.x1,
74
- y1: selected.y1
75
- }
76
- : {
77
- x0: 0,
78
- y0: 0,
79
- x1: $width,
80
- y1: $height
81
- };
82
- $: xScale = scaleLinear().domain([$extents.x0, $extents.x1]).rangeRound([0, $width]);
83
- $: yScale = scaleLinear().domain([$extents.y0, $extents.y1]).rangeRound([0, $height]);
84
64
  </script>
85
65
 
86
- <RectClipPath width={$width} height={$height}>
87
- {#each Array.from(nodesByDepth) as [depth, nodes]}
88
- <g>
89
- {#each nodes as node, i (nodeKey(node, i))}
90
- <slot
91
- name="node"
92
- {node}
93
- rect={{
94
- x: xScale(node.x0),
95
- y: yScale(node.y0),
96
- width: xScale(node.x1) - xScale(node.x0),
97
- height: yScale(node.y1) - yScale(node.y0)
98
- }}
99
- />
100
- {/each}
101
- </g>
102
- {/each}
103
- </RectClipPath>
66
+ {#each Array.from(nodesByDepth) as [depth, nodes]}
67
+ <g>
68
+ {#each nodes as node, i (nodeKey(node, i))}
69
+ <slot name="node" {node} />
70
+ {/each}
71
+ </g>
72
+ {/each}
@@ -19,12 +19,6 @@ declare const __propDef: {
19
19
  slots: {
20
20
  node: {
21
21
  node: unknown;
22
- rect: {
23
- x: number;
24
- y: number;
25
- width: number;
26
- height: number;
27
- };
28
22
  };
29
23
  };
30
24
  };
@@ -5,6 +5,7 @@ export { default as AxisX } from './AxisX.svelte';
5
5
  export { default as AxisY } from './AxisY.svelte';
6
6
  export { default as Bars } from './Bars.svelte';
7
7
  export { default as Baseline } from './Baseline.svelte';
8
+ export { default as Bounds } from './Bounds.svelte';
8
9
  export { default as Chart } from './Chart.svelte';
9
10
  export { default as ChartClipPath } from './ChartClipPath.svelte';
10
11
  export { default as Circle } from './Circle.svelte';
@@ -18,6 +19,7 @@ export { default as Labels } from './Labels.svelte';
18
19
  export { default as Line } from './Line.svelte';
19
20
  export { default as LinearGradient } from './LinearGradient.svelte';
20
21
  export { default as Link } from './Link.svelte';
22
+ export { default as Partition } from './Partition.svelte';
21
23
  export { default as Path } from './Path.svelte';
22
24
  export { default as Pattern } from './Pattern.svelte';
23
25
  export { default as Pie } from './Pie.svelte';
@@ -28,5 +30,6 @@ export { default as Sankey } from './Sankey.svelte';
28
30
  export { default as Text } from './Text.svelte';
29
31
  export { default as Threshold } from './Threshold.svelte';
30
32
  export { default as Tooltip } from './Tooltip.svelte';
33
+ export { default as Tree } from './Tree.svelte';
31
34
  export { default as Treemap } from './Treemap.svelte';
32
35
  export { default as Zoom } from './Zoom.svelte';
@@ -5,6 +5,7 @@ export { default as AxisX } from './AxisX.svelte';
5
5
  export { default as AxisY } from './AxisY.svelte';
6
6
  export { default as Bars } from './Bars.svelte';
7
7
  export { default as Baseline } from './Baseline.svelte';
8
+ export { default as Bounds } from './Bounds.svelte';
8
9
  export { default as Chart } from './Chart.svelte';
9
10
  export { default as ChartClipPath } from './ChartClipPath.svelte';
10
11
  export { default as Circle } from './Circle.svelte';
@@ -18,6 +19,7 @@ export { default as Labels } from './Labels.svelte';
18
19
  export { default as Line } from './Line.svelte';
19
20
  export { default as LinearGradient } from './LinearGradient.svelte';
20
21
  export { default as Link } from './Link.svelte';
22
+ export { default as Partition } from './Partition.svelte';
21
23
  export { default as Path } from './Path.svelte';
22
24
  export { default as Pattern } from './Pattern.svelte';
23
25
  export { default as Pie } from './Pie.svelte';
@@ -28,5 +30,6 @@ export { default as Sankey } from './Sankey.svelte';
28
30
  export { default as Text } from './Text.svelte';
29
31
  export { default as Threshold } from './Threshold.svelte';
30
32
  export { default as Tooltip } from './Tooltip.svelte';
33
+ export { default as Tree } from './Tree.svelte';
31
34
  export { default as Treemap } from './Treemap.svelte';
32
35
  export { default as Zoom } from './Zoom.svelte';
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Sean Lynch <techniq35@gmail.com>",
4
4
  "license": "MIT",
5
5
  "repository": "techniq/layerchart",
6
- "version": "0.4.1",
6
+ "version": "0.5.2",
7
7
  "devDependencies": {
8
8
  "@rollup/plugin-dsv": "^2.0.3",
9
9
  "@sveltejs/adapter-vercel": "^1.0.0-next.58",
@@ -56,6 +56,7 @@
56
56
  "./components/AxisY.svelte": "./components/AxisY.svelte",
57
57
  "./components/Bars.svelte": "./components/Bars.svelte",
58
58
  "./components/Baseline.svelte": "./components/Baseline.svelte",
59
+ "./components/Bounds.svelte": "./components/Bounds.svelte",
59
60
  "./components/Chart.svelte": "./components/Chart.svelte",
60
61
  "./components/ChartClipPath.svelte": "./components/ChartClipPath.svelte",
61
62
  "./components/Circle.svelte": "./components/Circle.svelte",
@@ -69,6 +70,7 @@
69
70
  "./components/Line.svelte": "./components/Line.svelte",
70
71
  "./components/LinearGradient.svelte": "./components/LinearGradient.svelte",
71
72
  "./components/Link.svelte": "./components/Link.svelte",
73
+ "./components/Partition.svelte": "./components/Partition.svelte",
72
74
  "./components/Path.svelte": "./components/Path.svelte",
73
75
  "./components/Pattern.svelte": "./components/Pattern.svelte",
74
76
  "./components/Pie.svelte": "./components/Pie.svelte",
@@ -1,8 +1,9 @@
1
1
  import { spring, tweened } from 'svelte/motion';
2
+ export declare type MotionOptions = {
3
+ spring?: boolean | Parameters<typeof spring>[1];
4
+ tweened?: boolean | Parameters<typeof tweened>[1];
5
+ };
2
6
  /**
3
7
  * Convenient wrapper to create a motion store (spring(), tweened()) based on properties, or fall back to basic writable() store
4
8
  */
5
- export declare function createMotionStore(value: any, options: {
6
- spring?: boolean | Parameters<typeof spring>[1];
7
- tweened?: boolean | Parameters<typeof tweened>[1];
8
- }): import("svelte/motion").Tweened<unknown> | import("svelte/motion").Spring<any> | import("svelte/store").Writable<any>;
9
+ export declare function motionStore(value: any, options: MotionOptions): import("svelte/motion").Tweened<unknown> | import("svelte/motion").Spring<any> | import("svelte/store").Writable<any>;
@@ -3,7 +3,7 @@ import { spring, tweened } from 'svelte/motion';
3
3
  /**
4
4
  * Convenient wrapper to create a motion store (spring(), tweened()) based on properties, or fall back to basic writable() store
5
5
  */
6
- export function createMotionStore(value, options) {
6
+ export function motionStore(value, options) {
7
7
  if (options.spring) {
8
8
  return spring(value, options.spring === true ? undefined : options.spring);
9
9
  }
package/utils/scales.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { tweened } from 'svelte/motion';
2
+ import { MotionOptions } from '../stores/motionStore';
1
3
  /**
2
4
  * Implemenation for missing `scaleBand().invert()`
3
5
  *
@@ -8,3 +10,19 @@
8
10
  */
9
11
  export declare function scaleBandInvert(scale: any): (value: any) => any;
10
12
  export declare function isScaleBand(scale: any): boolean;
13
+ /**
14
+ * Animate d3-scale as domain and/or range are updated using tweened store
15
+ */
16
+ export declare function tweenedScale(scale: any, tweenedOptions?: Parameters<typeof tweened>[1]): {
17
+ subscribe: (this: void, run: import("svelte/store").Subscriber<any>, invalidate?: (value?: any) => void) => import("svelte/store").Unsubscriber;
18
+ domain: (values: any) => Promise<void>;
19
+ range: (values: any) => Promise<void>;
20
+ };
21
+ /**
22
+ * Create a store wrapper around a d3-scale which interpolates the domain and/or range using `tweened()` or `spring()` stores. Fallbacks to `writable()` if not interpolating
23
+ */
24
+ export declare function motionScale(scale: any, options: MotionOptions): {
25
+ subscribe: (this: void, run: import("svelte/store").Subscriber<any>, invalidate?: (value?: any) => void) => import("svelte/store").Unsubscriber;
26
+ domain: (values: any) => void | Promise<void>;
27
+ range: (values: any) => void | Promise<void>;
28
+ };
package/utils/scales.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { derived } from 'svelte/store';
2
+ import { tweened } from 'svelte/motion';
3
+ import { motionStore } from '../stores/motionStore';
1
4
  /**
2
5
  * Implemenation for missing `scaleBand().invert()`
3
6
  *
@@ -19,3 +22,47 @@ export function scaleBandInvert(scale) {
19
22
  export function isScaleBand(scale) {
20
23
  return typeof scale.bandwidth === 'function';
21
24
  }
25
+ /**
26
+ * Animate d3-scale as domain and/or range are updated using tweened store
27
+ */
28
+ export function tweenedScale(scale, tweenedOptions = {}) {
29
+ const tweenedDomain = tweened(undefined, tweenedOptions);
30
+ const tweenedRange = tweened(undefined, tweenedOptions);
31
+ const tweenedScale = derived([tweenedDomain, tweenedRange], ([domain, range]) => {
32
+ const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
33
+ if (domain) {
34
+ scaleInstance.domain(domain);
35
+ }
36
+ if (range) {
37
+ scaleInstance.range(range);
38
+ }
39
+ return scaleInstance;
40
+ });
41
+ return {
42
+ subscribe: tweenedScale.subscribe,
43
+ domain: (values) => tweenedDomain.set(values),
44
+ range: (values) => tweenedRange.set(values)
45
+ };
46
+ }
47
+ /**
48
+ * Create a store wrapper around a d3-scale which interpolates the domain and/or range using `tweened()` or `spring()` stores. Fallbacks to `writable()` if not interpolating
49
+ */
50
+ export function motionScale(scale, options) {
51
+ const domainStore = motionStore(undefined, options);
52
+ const rangeStore = motionStore(undefined, options);
53
+ const tweenedScale = derived([domainStore, rangeStore], ([domain, range]) => {
54
+ const scaleInstance = scale.domain ? scale : scale(); // support `scaleLinear` or `scaleLinear()` (which could have `.interpolate()` and others set)
55
+ if (domain) {
56
+ scaleInstance.domain(domain);
57
+ }
58
+ if (range) {
59
+ scaleInstance.range(range);
60
+ }
61
+ return scaleInstance;
62
+ });
63
+ return {
64
+ subscribe: tweenedScale.subscribe,
65
+ domain: (values) => domainStore.set(values),
66
+ range: (values) => rangeStore.set(values)
67
+ };
68
+ }