layerchart 0.3.5 → 0.4.1

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 (47) hide show
  1. package/components/Arc.svelte +1 -1
  2. package/components/Area.svelte +1 -1
  3. package/components/AreaStack.svelte +1 -1
  4. package/components/AxisX.svelte +2 -2
  5. package/components/AxisY.svelte +2 -2
  6. package/components/Bars.svelte +1 -1
  7. package/components/Baseline.svelte +2 -2
  8. package/components/Chart.svelte +2 -2
  9. package/components/ChartClipPath.svelte +14 -0
  10. package/components/ChartClipPath.svelte.d.ts +18 -0
  11. package/components/Circle.svelte +1 -1
  12. package/components/CircleClipPath.svelte +1 -1
  13. package/components/ClipPath.svelte +1 -1
  14. package/components/ConnectedPoints.svelte +1 -1
  15. package/components/Group.svelte +1 -1
  16. package/components/HighlightLine.svelte +1 -1
  17. package/components/HighlightRect.svelte +1 -1
  18. package/components/Labels.svelte +1 -1
  19. package/components/Line.svelte +1 -1
  20. package/components/LinearGradient.svelte +1 -1
  21. package/components/Link.svelte +7 -2
  22. package/components/Link.svelte.d.ts +4 -0
  23. package/components/Path.svelte +2 -2
  24. package/components/Pattern.svelte +1 -1
  25. package/components/Pie.svelte +1 -1
  26. package/components/Points.svelte +8 -6
  27. package/components/Points.svelte.d.ts +5 -1
  28. package/components/Rect.svelte +1 -1
  29. package/components/RectClipPath.svelte +1 -1
  30. package/components/Sankey.svelte +1 -1
  31. package/components/Text.svelte +1 -1
  32. package/components/Threshold.svelte +1 -1
  33. package/components/Tooltip.svelte +1 -1
  34. package/components/Tree.svelte +30 -0
  35. package/components/Tree.svelte.d.ts +32 -0
  36. package/components/Treemap.svelte +3 -2
  37. package/components/Treemap.svelte.d.ts +1 -0
  38. package/components/Zoom.svelte +108 -0
  39. package/components/Zoom.svelte.d.ts +25 -0
  40. package/components/index.d.ts +2 -0
  41. package/components/index.js +2 -0
  42. package/docs/Preview.svelte +1 -1
  43. package/package.json +24 -21
  44. package/utils/genData.d.ts +19 -0
  45. package/utils/genData.js +16 -0
  46. package/utils/math.d.ts +4 -0
  47. package/utils/math.js +6 -0
@@ -1,4 +1,4 @@
1
- <script >/*
1
+ <script>/*
2
2
  TODO:
3
3
  - [ ] Allow spring/tweened to be reactive (but ignore value)
4
4
  */
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { area as d3Area } from 'd3-shape';
3
3
  import { interpolatePath } from 'd3-interpolate-path';
4
4
  import { createMotionStore } from '../stores/motionStore';
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import Area from './Area.svelte';
3
3
  import Path from './Path.svelte';
4
4
  const { data, yScale, zGet } = getContext('LayerCake');
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { format } from 'svelte-ux/utils/format';
3
3
  import Text from './Text.svelte';
4
4
  import { isScaleBand } from '../utils/scales';
@@ -39,7 +39,7 @@ $: tickVals = Array.isArray(ticks)
39
39
  {/each}
40
40
  </g>
41
41
 
42
- <style >
42
+ <style>
43
43
  .tick {
44
44
  font-size: 0.725em;
45
45
  font-weight: 200;
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { format } from 'svelte-ux/utils/format';
3
3
  import Text from './Text.svelte';
4
4
  import { isScaleBand } from '../utils/scales';
@@ -53,7 +53,7 @@ $: tickVals = Array.isArray(ticks)
53
53
  {/each}
54
54
  </g>
55
55
 
56
- <style >
56
+ <style>
57
57
  .tick {
58
58
  font-size: 0.725em;
59
59
  font-weight: 200;
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { scaleBand } from 'd3-scale';
3
3
  import { max, min } from 'd3-array';
4
4
  import { unique } from 'svelte-ux/utils/array';
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  const { xRange, yScale, yRange } = getContext('LayerCake');
3
3
  export let x = false;
4
4
  export let y = false;
@@ -14,7 +14,7 @@ export let y = false;
14
14
  {/if}
15
15
  </g>
16
16
 
17
- <style >
17
+ <style>
18
18
  .baseline {
19
19
  stroke: #777;
20
20
  }
@@ -1,8 +1,8 @@
1
- <script context="module" >import { LayerCake, Svg, Html } from 'layercake';
1
+ <script context="module">import { LayerCake, Svg, Html } from 'layercake';
2
2
  export { Svg, Html };
3
3
  </script>
4
4
 
5
- <script >import { max, min } from 'd3-array';
5
+ <script>import { max, min } from 'd3-array';
6
6
  import { get } from 'lodash-es';
7
7
  /**
8
8
  * Resolve a value from data based on the accessor type
@@ -0,0 +1,14 @@
1
+ <script>import { getContext } from 'svelte';
2
+ import RectClipPath from './RectClipPath.svelte';
3
+ const { width, height, padding } = getContext('LayerCake');
4
+ </script>
5
+
6
+ <RectClipPath
7
+ x={-$padding.left}
8
+ y={-$padding.top}
9
+ width={$width + $padding.left + $padding.right}
10
+ height={$height + $padding.top + $padding.bottom}
11
+ {...$$restProps}
12
+ >
13
+ <slot />
14
+ </RectClipPath>
@@ -0,0 +1,18 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ [x: string]: any;
5
+ };
6
+ events: {
7
+ [evt: string]: CustomEvent<any>;
8
+ };
9
+ slots: {
10
+ default: {};
11
+ };
12
+ };
13
+ export declare type ChartClipPathProps = typeof __propDef.props;
14
+ export declare type ChartClipPathEvents = typeof __propDef.events;
15
+ export declare type ChartClipPathSlots = typeof __propDef.slots;
16
+ export default class ChartClipPath extends SvelteComponentTyped<ChartClipPathProps, ChartClipPathEvents, ChartClipPathSlots> {
17
+ }
18
+ export {};
@@ -1,4 +1,4 @@
1
- <script >import { createMotionStore } from '../stores/motionStore';
1
+ <script>import { createMotionStore } from '../stores/motionStore';
2
2
  export let cx;
3
3
  export let cy;
4
4
  export let r;
@@ -1,4 +1,4 @@
1
- <script >import { uniqueId } from 'svelte-ux/utils/string';
1
+ <script>import { uniqueId } from 'svelte-ux/utils/string';
2
2
  import ClipPath from './ClipPath.svelte';
3
3
  import Circle from './Circle.svelte';
4
4
  /** Unique id for clipPath */
@@ -1,4 +1,4 @@
1
- <script >import { uniqueId } from 'svelte-ux/utils/string';
1
+ <script>import { uniqueId } from 'svelte-ux/utils/string';
2
2
  /** Unique id for clipPath */
3
3
  export let id = uniqueId('clipPath-');
4
4
  </script>
@@ -1,4 +1,4 @@
1
- <script >/*
1
+ <script>/*
2
2
  TODO:
3
3
  - [ ] Consider becoming LinkLine using d3-path buider https://github.com/d3/d3-path
4
4
  - https://github.com/airbnb/visx/blob/master/packages/visx-shape/src/shapes/link/line/LinkHorizontalLine.tsx
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { createMotionStore } from '../stores/motionStore';
3
3
  const { width, height } = getContext('LayerCake');
4
4
  /**
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { get } from 'svelte/store';
3
3
  import Circle from './Circle.svelte';
4
4
  import Line from './Line.svelte';
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { isScaleBand } from '../utils/scales';
3
3
  import Rect from './Rect.svelte';
4
4
  export let data;
@@ -1,4 +1,4 @@
1
- <script >/*
1
+ <script>/*
2
2
  * TODO
3
3
  * - [ ] Support step curves (center like scaleBand())
4
4
  * - [ ] Support multiple values (threshold, stacks, etc)
@@ -1,4 +1,4 @@
1
- <script >import { createMotionStore } from '../stores/motionStore';
1
+ <script>import { createMotionStore } from '../stores/motionStore';
2
2
  export let x1;
3
3
  export let y1;
4
4
  export let x2;
@@ -1,4 +1,4 @@
1
- <script >export let id;
1
+ <script>export let id;
2
2
  export let from;
3
3
  export let via; // TODO: Currently --tw-gradient-via is not the color but the full stops
4
4
  export let to;
@@ -1,21 +1,26 @@
1
- <script >import { linkHorizontal } from 'd3-shape';
1
+ <script>import { link as d3Link, curveBumpX, curveBumpY } from 'd3-shape';
2
2
  import { interpolatePath } from 'd3-interpolate-path';
3
3
  import { createMotionStore } from '../stores/motionStore';
4
4
  // Properties to override what is used from context
5
5
  export let data = undefined; // TODO: Update Type
6
+ export let orientation = 'horizontal';
6
7
  /**
7
8
  * Update source and target accessors to be compatibke with d3-sankey. see: https://github.com/d3/d3-sankey#sankeyLinkHorizontal
8
9
  */
9
10
  export let sankey = false;
10
11
  export let source = sankey ? (d) => [d.source.x1, d.y0] : (d) => d.source;
11
12
  export let target = sankey ? (d) => [d.target.x0, d.y1] : (d) => d.target;
13
+ export let x = sankey ? (d) => d[0] : (d) => (orientation === 'horizontal' ? d.y : d.x);
14
+ export let y = sankey ? (d) => d[1] : (d) => (orientation === 'horizontal' ? d.x : d.y);
15
+ export let curve = orientation === 'horizontal' ? curveBumpX : curveBumpY;
12
16
  export let tweened = undefined;
13
17
  export let color = 'black';
14
18
  export let width = undefined;
15
19
  $: tweenedOptions = tweened ? { interpolate: interpolatePath, ...tweened } : false;
16
20
  $: tweened_d = createMotionStore('', { tweened: tweenedOptions });
17
21
  $: {
18
- const link = linkHorizontal().source(source).target(target);
22
+ orientation; // subscribe to orientation changes to link is update
23
+ const link = d3Link(curve).source(source).target(target).x(x).y(y);
19
24
  const d = link(data);
20
25
  tweened_d.set(d);
21
26
  }
@@ -4,9 +4,13 @@ declare const __propDef: {
4
4
  props: {
5
5
  [x: string]: any;
6
6
  data?: any;
7
+ orientation?: 'vertical' | 'horizontal';
7
8
  sankey?: boolean;
8
9
  source?: (d: any) => any;
9
10
  target?: (d: any) => any;
11
+ x?: (d: any) => any;
12
+ y?: (d: any) => any;
13
+ curve?: import("d3-shape").CurveFactory;
10
14
  tweened?: boolean | Parameters<typeof tweenedStore>[1];
11
15
  color?: string;
12
16
  width?: any;
@@ -1,4 +1,4 @@
1
- <script >/*
1
+ <script>/*
2
2
  TODO:
3
3
  - [ ] Show path progressively show / animated in on load. Also fix sliding in from left side (at last in from bottom)
4
4
  */
@@ -35,7 +35,7 @@ $: {
35
35
 
36
36
  <path class="path-line" d={$tweened_d} stroke={color} stroke-width={width} {...$$restProps} />
37
37
 
38
- <style >
38
+ <style>
39
39
  .path-line {
40
40
  fill: none;
41
41
  stroke-linejoin: round;
@@ -1,4 +1,4 @@
1
- <script >// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/pattern
1
+ <script>// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/pattern
2
2
  // https://airbnb.io/visx/patterns
3
3
  // https://github.com/airbnb/visx/tree/master/packages/visx-pattern/src/patterns
4
4
  export let id;
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import { pie as d3pie } from 'd3-shape';
3
3
  import Arc from './Arc.svelte';
4
4
  import Group from './Group.svelte';
@@ -1,4 +1,4 @@
1
- <script >import { getContext } from 'svelte';
1
+ <script>import { getContext } from 'svelte';
2
2
  import Circle from './Circle.svelte';
3
3
  import { isScaleBand } from '../utils/scales';
4
4
  const context = getContext('LayerCake');
@@ -58,8 +58,10 @@ $: points = $data.flatMap((d) => {
58
58
  });
59
59
  </script>
60
60
 
61
- <g class="point-group">
62
- {#each points as p}
63
- <Circle cx={p.x} cy={p.y} {r} {...$$restProps} />
64
- {/each}
65
- </g>
61
+ <slot {points}>
62
+ <g class="point-group">
63
+ {#each points as point}
64
+ <Circle cx={point.x} cy={point.y} {r} {...$$restProps} />
65
+ {/each}
66
+ </g>
67
+ </slot>
@@ -9,7 +9,11 @@ declare const __propDef: {
9
9
  events: {
10
10
  [evt: string]: CustomEvent<any>;
11
11
  };
12
- slots: {};
12
+ slots: {
13
+ default: {
14
+ points: any;
15
+ };
16
+ };
13
17
  };
14
18
  export declare type PointsProps = typeof __propDef.props;
15
19
  export declare type PointsEvents = typeof __propDef.events;
@@ -1,4 +1,4 @@
1
- <script >import { createMotionStore } from '../stores/motionStore';
1
+ <script>import { createMotionStore } from '../stores/motionStore';
2
2
  export let x = 0;
3
3
  export let y = 0;
4
4
  export let width;
@@ -1,4 +1,4 @@
1
- <script >import { uniqueId } from 'svelte-ux/utils/string';
1
+ <script>import { uniqueId } from 'svelte-ux/utils/string';
2
2
  import ClipPath from './ClipPath.svelte';
3
3
  import Rect from './Rect.svelte';
4
4
  /** Unique id for clipPath */
@@ -1,4 +1,4 @@
1
- <script >// https://github.com/d3/d3-sankey
1
+ <script>// https://github.com/d3/d3-sankey
2
2
  import { createEventDispatcher, getContext } from 'svelte';
3
3
  import { sankey as d3Sankey, sankeyLeft, sankeyCenter, sankeyRight, sankeyJustify } from 'd3-sankey';
4
4
  const dispatch = createEventDispatcher();
@@ -1,4 +1,4 @@
1
- <script >import { getStringWidth } from '../utils/string';
1
+ <script>import { getStringWidth } from '../utils/string';
2
2
  /*
3
3
  TODO:
4
4
  - [ ] Handle styled text (use <slot /> to measure?)
@@ -1,4 +1,4 @@
1
- <script >/*
1
+ <script>/*
2
2
  See also:
3
3
  - https://observablehq.com/@d3/difference-chart
4
4
  - https://github.com/airbnb/visx/issues/245
@@ -1,4 +1,4 @@
1
- <script >import { getContext, createEventDispatcher } from 'svelte';
1
+ <script>import { getContext, createEventDispatcher } from 'svelte';
2
2
  import { spring } from 'svelte/motion';
3
3
  import { fade } from 'svelte/transition';
4
4
  import { writable } from 'svelte/store';
@@ -0,0 +1,30 @@
1
+ <script>import { getContext } from 'svelte';
2
+ import { tree as d3Tree } from 'd3-hierarchy';
3
+ const { data, width, height, padding } = getContext('LayerCake');
4
+ /**
5
+ * Sets this tree layout’s node size to the specified two-element array of numbers `[width, height]`.
6
+ * If unset, layout size is used instead. When a node size is specified, the root node is always
7
+ * positioned at `⟨0, 0⟩`.
8
+ *
9
+ * see: https://github.com/d3/d3-hierarchy#tree_nodeSize
10
+ */
11
+ export let nodeSize = undefined;
12
+ /**
13
+ * see: https://github.com/d3/d3-hierarchy#tree_separation
14
+ */
15
+ export let separation = undefined;
16
+ export let orientation = 'horizontal';
17
+ let tree;
18
+ $: {
19
+ tree = d3Tree().size(orientation === 'horizontal' ? [$height, $width] : [$width, $height]);
20
+ if (nodeSize) {
21
+ tree.nodeSize(nodeSize);
22
+ }
23
+ if (separation) {
24
+ tree.separation(separation);
25
+ }
26
+ }
27
+ $: treeData = tree($data);
28
+ </script>
29
+
30
+ <slot nodes={treeData.descendants()} links={treeData.links()} />
@@ -0,0 +1,32 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import { HierarchyPointNode } from 'd3-hierarchy';
3
+ declare const __propDef: {
4
+ props: {
5
+ /**
6
+ * Sets this tree layout’s node size to the specified two-element array of numbers `[width, height]`.
7
+ * If unset, layout size is used instead. When a node size is specified, the root node is always
8
+ * positioned at `⟨0, 0⟩`.
9
+ *
10
+ * see: https://github.com/d3/d3-hierarchy#tree_nodeSize
11
+ */ nodeSize?: [number, number] | undefined;
12
+ /**
13
+ * see: https://github.com/d3/d3-hierarchy#tree_separation
14
+ */ separation?: (a: HierarchyPointNode<any>, b: HierarchyPointNode<any>) => number;
15
+ orientation?: 'vertical' | 'horizontal';
16
+ };
17
+ events: {
18
+ [evt: string]: CustomEvent<any>;
19
+ };
20
+ slots: {
21
+ default: {
22
+ nodes: any;
23
+ links: any;
24
+ };
25
+ };
26
+ };
27
+ export declare type TreeProps = typeof __propDef.props;
28
+ export declare type TreeEvents = typeof __propDef.events;
29
+ export declare type TreeSlots = typeof __propDef.slots;
30
+ export default class Tree extends SvelteComponentTyped<TreeProps, TreeEvents, TreeSlots> {
31
+ }
32
+ export {};
@@ -1,4 +1,4 @@
1
- <script >/**
1
+ <script>/**
2
2
  * TODO:
3
3
  * - [ ] Improve zoomable nested (apply extent ratio? const extentRatio = ($extents.y1 - $extents.y0) / $height;
4
4
  */
@@ -19,6 +19,7 @@ export let paddingTop = 0;
19
19
  export let paddingBottom = 0;
20
20
  export let paddingLeft = undefined;
21
21
  export let paddingRight = undefined;
22
+ export let nodeKey = (node, i) => i;
22
23
  export let selected = null;
23
24
  $: tileFunc =
24
25
  tile === 'squarify'
@@ -85,7 +86,7 @@ $: yScale = scaleLinear().domain([$extents.y0, $extents.y1]).rangeRound([0, $hei
85
86
  <RectClipPath width={$width} height={$height}>
86
87
  {#each Array.from(nodesByDepth) as [depth, nodes]}
87
88
  <g>
88
- {#each nodes as node}
89
+ {#each nodes as node, i (nodeKey(node, i))}
89
90
  <slot
90
91
  name="node"
91
92
  {node}
@@ -10,6 +10,7 @@ declare const __propDef: {
10
10
  paddingBottom?: number;
11
11
  paddingLeft?: any;
12
12
  paddingRight?: any;
13
+ nodeKey?: (node: d3.HierarchyNode<any>, i: number) => any;
13
14
  selected?: any;
14
15
  };
15
16
  events: {
@@ -0,0 +1,108 @@
1
+ <script>import { getContext } from 'svelte';
2
+ import { spring } from 'svelte/motion';
3
+ const { width, height, padding } = getContext('LayerCake');
4
+ let dragging = false;
5
+ let translate = spring({ x: 0, y: 0 });
6
+ let scale = spring({ x: 1, y: 1 });
7
+ let startPoint;
8
+ let startTranslate;
9
+ let svgEl = null;
10
+ export function reset() {
11
+ $translate = { x: 0, y: 0 };
12
+ $scale = { x: 1, y: 1 };
13
+ }
14
+ export function increase() {
15
+ $scale = {
16
+ x: $scale.x * 1.25,
17
+ y: $scale.y * 1.25
18
+ };
19
+ }
20
+ export function decrease() {
21
+ $scale = {
22
+ x: $scale.x * 0.8,
23
+ y: $scale.y * 0.8
24
+ };
25
+ }
26
+ export function translateCenter() {
27
+ $translate = {
28
+ x: 0,
29
+ y: 0
30
+ };
31
+ }
32
+ function handleMouseDown(e) {
33
+ dragging = true;
34
+ svgEl = e.target.ownerSVGElement;
35
+ startPoint = localPoint(svgEl, e);
36
+ startTranslate = $translate;
37
+ window.addEventListener('mousemove', handleMouseMove);
38
+ window.addEventListener('mouseup', handleMouseUp);
39
+ }
40
+ function handleMouseUp(e) {
41
+ dragging = false;
42
+ window.removeEventListener('mousemove', handleMouseMove);
43
+ window.removeEventListener('mouseup', handleMouseUp);
44
+ }
45
+ function handleMouseMove(e) {
46
+ if (!dragging)
47
+ return;
48
+ const endPoint = localPoint(svgEl, e);
49
+ const deltaX = endPoint.x - startPoint.x;
50
+ const deltaY = endPoint.y - startPoint.y;
51
+ translate.set({
52
+ x: startTranslate.x + deltaX / $scale.x,
53
+ y: startTranslate.y + deltaY / $scale.y
54
+ }, { hard: true });
55
+ }
56
+ function handleDoubleClick() {
57
+ increase();
58
+ }
59
+ function handleWheel(e) {
60
+ e.preventDefault();
61
+ const scaleBy = -e.deltaY > 0 ? 1.1 : 0.9;
62
+ // TODO: Update to match d3-zoom delta
63
+ // https://github.com/d3/d3-zoom#zoom_wheelDelta
64
+ // const scaleBy = -e.deltaY * (e.deltaMode === 1 ? 0.05 : e.deltaMode ? 1 : 0.002);
65
+ scale.set({
66
+ x: $scale.x * scaleBy,
67
+ y: $scale.y * scaleBy
68
+ }, { hard: true });
69
+ }
70
+ function localPoint(svgEl, e) {
71
+ const screenCTM = svgEl.getScreenCTM();
72
+ const coords = {
73
+ x: e.clientX,
74
+ y: e.clientY
75
+ };
76
+ let point = svgEl.createSVGPoint();
77
+ point.x = coords.x;
78
+ point.y = coords.y;
79
+ point = point.matrixTransform(screenCTM.inverse());
80
+ return {
81
+ x: point.x,
82
+ y: point.y
83
+ };
84
+ }
85
+ $: center = { x: $width / 2, y: $height / 2 };
86
+ $: viewportCenter = {
87
+ x: center.x - $translate.x,
88
+ y: center.y - $translate.y
89
+ };
90
+ $: newTranslate = {
91
+ x: $translate.x * $scale.x + center.x - center.x * $scale.x,
92
+ y: $translate.y * $scale.y + center.y - center.y * $scale.y
93
+ };
94
+ </script>
95
+
96
+ <rect
97
+ x={-$padding.left}
98
+ y={-$padding.top}
99
+ width={$width + $padding.left + $padding.right}
100
+ height={$height + $padding.top + $padding.bottom}
101
+ on:mousewheel={handleWheel}
102
+ on:mousedown={handleMouseDown}
103
+ on:dblclick={handleDoubleClick}
104
+ fill="transparent"
105
+ />
106
+ <g transform="translate({newTranslate.x},{newTranslate.y}) scale({$scale.x},{$scale.y})">
107
+ <slot />
108
+ </g>
@@ -0,0 +1,25 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ reset?: () => void;
5
+ increase?: () => void;
6
+ decrease?: () => void;
7
+ translateCenter?: () => void;
8
+ };
9
+ events: {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots: {
13
+ default: {};
14
+ };
15
+ };
16
+ export declare type ZoomProps = typeof __propDef.props;
17
+ export declare type ZoomEvents = typeof __propDef.events;
18
+ export declare type ZoomSlots = typeof __propDef.slots;
19
+ export default class Zoom extends SvelteComponentTyped<ZoomProps, ZoomEvents, ZoomSlots> {
20
+ get reset(): () => void;
21
+ get increase(): () => void;
22
+ get decrease(): () => void;
23
+ get translateCenter(): () => void;
24
+ }
25
+ export {};
@@ -6,6 +6,7 @@ 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
8
  export { default as Chart } from './Chart.svelte';
9
+ export { default as ChartClipPath } from './ChartClipPath.svelte';
9
10
  export { default as Circle } from './Circle.svelte';
10
11
  export { default as CircleClipPath } from './CircleClipPath.svelte';
11
12
  export { default as ClipPath } from './ClipPath.svelte';
@@ -28,3 +29,4 @@ export { default as Text } from './Text.svelte';
28
29
  export { default as Threshold } from './Threshold.svelte';
29
30
  export { default as Tooltip } from './Tooltip.svelte';
30
31
  export { default as Treemap } from './Treemap.svelte';
32
+ export { default as Zoom } from './Zoom.svelte';
@@ -6,6 +6,7 @@ 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
8
  export { default as Chart } from './Chart.svelte';
9
+ export { default as ChartClipPath } from './ChartClipPath.svelte';
9
10
  export { default as Circle } from './Circle.svelte';
10
11
  export { default as CircleClipPath } from './CircleClipPath.svelte';
11
12
  export { default as ClipPath } from './ClipPath.svelte';
@@ -28,3 +29,4 @@ export { default as Text } from './Text.svelte';
28
29
  export { default as Threshold } from './Threshold.svelte';
29
30
  export { default as Tooltip } from './Tooltip.svelte';
30
31
  export { default as Treemap } from './Treemap.svelte';
32
+ export { default as Zoom } from './Zoom.svelte';
@@ -1,4 +1,4 @@
1
- <script >import Prism from 'prismjs';
1
+ <script>import Prism from 'prismjs';
2
2
  import 'prism-svelte';
3
3
  export let code = null;
4
4
  export let language = 'svelte';
package/package.json CHANGED
@@ -3,38 +3,38 @@
3
3
  "author": "Sean Lynch <techniq35@gmail.com>",
4
4
  "license": "MIT",
5
5
  "repository": "techniq/layerchart",
6
- "version": "0.3.5",
6
+ "version": "0.4.1",
7
7
  "devDependencies": {
8
- "@sveltejs/adapter-vercel": "^1.0.0-next.47",
9
- "@sveltejs/kit": "^1.0.0-next.303",
8
+ "@rollup/plugin-dsv": "^2.0.3",
9
+ "@sveltejs/adapter-vercel": "^1.0.0-next.58",
10
+ "@sveltejs/kit": "^1.0.0-next.350",
10
11
  "@tailwindcss/typography": "^0.5.2",
11
- "@types/d3-array": "^3.0.2",
12
+ "@types/d3-array": "^3.0.3",
12
13
  "@types/d3-dsv": "^3.0.0",
13
- "@types/d3-hierarchy": "^3.0.2",
14
+ "@types/d3-hierarchy": "^3.1.0",
14
15
  "@types/d3-sankey": "^0.11.2",
15
16
  "@types/d3-scale": "^4.0.2",
16
- "@types/d3-shape": "^3.0.2",
17
+ "@types/d3-shape": "^3.1.0",
17
18
  "@types/lodash-es": "^4.17.6",
18
- "autoprefixer": "^10.4.4",
19
- "mdsvex": "^0.10.5",
20
- "prettier": "^2.6.1",
21
- "prettier-plugin-svelte": "^2.6.0",
19
+ "autoprefixer": "^10.4.7",
20
+ "mdsvex": "^0.10.6",
21
+ "prettier": "^2.6.2",
22
+ "prettier-plugin-svelte": "^2.7.0",
22
23
  "prism-themes": "^1.9.0",
23
- "svelte": "^3.46.6",
24
- "svelte-check": "^2.4.6",
25
- "svelte-preprocess": "^4.10.4",
26
- "svelte2tsx": "^0.5.6",
27
- "tailwindcss": "^3.0.23",
28
- "tailwindcss-elevation": "^1.0.1",
29
- "tslib": "^2.3.1",
30
- "typescript": "^4.6.3",
24
+ "svelte": "^3.48.0",
25
+ "svelte-check": "^2.7.2",
26
+ "svelte-preprocess": "^4.10.7",
27
+ "svelte2tsx": "^0.5.10",
28
+ "tailwindcss": "^3.1.0",
29
+ "tslib": "^2.4.0",
30
+ "typescript": "^4.7.3",
31
31
  "unist-util-visit": "^4.1.0",
32
32
  "vite-plugin-sveld": "^1.0.3"
33
33
  },
34
34
  "type": "module",
35
35
  "dependencies": {
36
- "@mdi/js": "^6.6.96",
37
- "d3-array": "^3.1.1",
36
+ "@mdi/js": "^6.7.96",
37
+ "d3-array": "^3.1.6",
38
38
  "d3-dsv": "^3.0.1",
39
39
  "d3-hierarchy": "^3.1.2",
40
40
  "d3-interpolate-path": "^2.2.3",
@@ -45,7 +45,7 @@
45
45
  "date-fns": "^2.28.0",
46
46
  "layercake": "^6.1.0",
47
47
  "lodash-es": "^4.17.21",
48
- "svelte-ux": "^0.4.7"
48
+ "svelte-ux": "^0.5.1"
49
49
  },
50
50
  "exports": {
51
51
  "./package.json": "./package.json",
@@ -57,6 +57,7 @@
57
57
  "./components/Bars.svelte": "./components/Bars.svelte",
58
58
  "./components/Baseline.svelte": "./components/Baseline.svelte",
59
59
  "./components/Chart.svelte": "./components/Chart.svelte",
60
+ "./components/ChartClipPath.svelte": "./components/ChartClipPath.svelte",
60
61
  "./components/Circle.svelte": "./components/Circle.svelte",
61
62
  "./components/CircleClipPath.svelte": "./components/CircleClipPath.svelte",
62
63
  "./components/ClipPath.svelte": "./components/ClipPath.svelte",
@@ -78,7 +79,9 @@
78
79
  "./components/Text.svelte": "./components/Text.svelte",
79
80
  "./components/Threshold.svelte": "./components/Threshold.svelte",
80
81
  "./components/Tooltip.svelte": "./components/Tooltip.svelte",
82
+ "./components/Tree.svelte": "./components/Tree.svelte",
81
83
  "./components/Treemap.svelte": "./components/Treemap.svelte",
84
+ "./components/Zoom.svelte": "./components/Zoom.svelte",
82
85
  "./components": "./components/index.js",
83
86
  "./docs/Blockquote.svelte": "./docs/Blockquote.svelte",
84
87
  "./docs/Code.svelte": "./docs/Code.svelte",
@@ -30,3 +30,22 @@ export declare const longData: {
30
30
  fruit: string;
31
31
  value: number;
32
32
  }[];
33
+ export declare function getPhyllotaxis({ radius, count, width, height }: {
34
+ radius: any;
35
+ count: any;
36
+ width: any;
37
+ height: any;
38
+ }): {
39
+ x: number;
40
+ y: number;
41
+ }[];
42
+ export declare function getSpiral({ angle, radius, count, width, height }: {
43
+ angle: any;
44
+ radius: any;
45
+ count: any;
46
+ width: any;
47
+ height: any;
48
+ }): {
49
+ x: number;
50
+ y: number;
51
+ }[];
package/utils/genData.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { subDays } from 'date-fns';
2
+ import { degreesToRadians, radiansToDegrees } from './math';
2
3
  /**
3
4
  * Get random number between min (inclusive) and max (exclusive)
4
5
  * see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_0_inclusive_and_1_exclusive
@@ -57,3 +58,18 @@ export const longData = [
57
58
  { year: '2016', basket: 2, fruit: 'cherries', value: 720 },
58
59
  { year: '2016', basket: 2, fruit: 'dates', value: 400 }
59
60
  ];
61
+ export function getPhyllotaxis({ radius, count, width, height }) {
62
+ // Phyllotaxis: https://www.youtube.com/watch?v=KWoJgHFYWxY
63
+ const rads = Math.PI * (3 - Math.sqrt(5)); // ~2.4 rads or ~137.5 degrees
64
+ return getSpiral({ angle: radiansToDegrees(rads), radius, count, width, height });
65
+ }
66
+ export function getSpiral({ angle, radius, count, width, height }) {
67
+ return Array.from({ length: count }, (_, i) => {
68
+ const r = radius * Math.sqrt(i);
69
+ const a = degreesToRadians(angle * i);
70
+ return {
71
+ x: width / 2 + r * Math.cos(a),
72
+ y: height / 2 + r * Math.sin(a)
73
+ };
74
+ });
75
+ }
package/utils/math.d.ts CHANGED
@@ -2,3 +2,7 @@
2
2
  * Convert degrees to radians
3
3
  */
4
4
  export declare function degreesToRadians(degrees: number): number;
5
+ /**
6
+ * Convert radians to degrees
7
+ */
8
+ export declare function radiansToDegrees(radians: number): number;
package/utils/math.js CHANGED
@@ -4,3 +4,9 @@
4
4
  export function degreesToRadians(degrees) {
5
5
  return (degrees * Math.PI) / 180;
6
6
  }
7
+ /**
8
+ * Convert radians to degrees
9
+ */
10
+ export function radiansToDegrees(radians) {
11
+ return radians * (180 / Math.PI);
12
+ }