layerchart 0.23.0 → 0.24.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.
package/README.md CHANGED
@@ -23,6 +23,8 @@ Others
23
23
 
24
24
  - Legends including ColorRamps
25
25
 
26
+ See also [Svelte UX](http://svelte-ux.techniq.dev) for a large collection of components, actions, stores, and utilities to build highly interactive applications.
27
+
26
28
  ## Publishing
27
29
 
28
30
  - `npm run changeset` for each changelog worthy change
@@ -1,8 +1,10 @@
1
1
  <script>import { getContext } from 'svelte';
2
- import { timeDays, timeMonths, timeWeek, timeYear } from 'd3-time';
2
+ import { timeDays, timeMonths, timeWeek, timeYear, utcYear } from 'd3-time';
3
+ import { index } from 'd3-array';
4
+ import { format } from 'date-fns';
3
5
  import Rect from './Rect.svelte';
4
6
  import MonthPath from './MonthPath.svelte';
5
- import { index } from 'd3-array';
7
+ import Text from './Text.svelte';
6
8
  export let start;
7
9
  export let end;
8
10
  /**
@@ -33,8 +35,6 @@ $: cells = yearDays.map((date) => {
33
35
  return {
34
36
  x: timeWeek.count(timeYear(date), date) * cellWidth,
35
37
  y: date.getDay() * cellHeight,
36
- width: cellWidth,
37
- height: cellHeight,
38
38
  color: $config.r ? $rGet(cellData) : 'transparent',
39
39
  data: cellData,
40
40
  };
@@ -46,8 +46,8 @@ $: cells = yearDays.map((date) => {
46
46
  <Rect
47
47
  x={cell.x}
48
48
  y={cell.y}
49
- width={cell.width}
50
- height={cell.height}
49
+ width={cellWidth}
50
+ height={cellHeight}
51
51
  fill={cell.color}
52
52
  on:mousemove={(e) => tooltip?.show(e, cell.data)}
53
53
  on:mouseleave={(e) => tooltip?.hide()}
@@ -64,5 +64,12 @@ $: cells = yearDays.map((date) => {
64
64
  cellSize={[cellWidth, cellHeight]}
65
65
  {...typeof monthPath === 'object' ? monthPath : null}
66
66
  />
67
+
68
+ <Text
69
+ x={timeWeek.count(timeYear.floor(date), timeWeek.ceil(date)) * cellWidth}
70
+ y={-4}
71
+ value={format(date, 'MMM')}
72
+ class="text-xs"
73
+ />
67
74
  {/each}
68
75
  {/if}
@@ -21,8 +21,6 @@ declare const __propDef: {
21
21
  cells: {
22
22
  x: number;
23
23
  y: number;
24
- width: number;
25
- height: number;
26
24
  color: any;
27
25
  data: any;
28
26
  }[];
@@ -82,6 +82,7 @@ export let geo = undefined;
82
82
  let:yScale
83
83
  let:zScale
84
84
  let:rScale
85
+ let:padding
85
86
  >
86
87
  <GeoContext {...geo} let:projection>
87
88
  {#if tooltip}
@@ -99,6 +100,7 @@ export let geo = undefined;
99
100
  {yScale}
100
101
  {zScale}
101
102
  {rScale}
103
+ {padding}
102
104
  />
103
105
  </TooltipContext>
104
106
  {:else}
@@ -114,6 +116,7 @@ export let geo = undefined;
114
116
  {yScale}
115
117
  {zScale}
116
118
  {rScale}
119
+ {padding}
117
120
  />
118
121
  {/if}
119
122
  </GeoContext>
@@ -35,6 +35,17 @@ declare const __propDef: {
35
35
  yScale: any;
36
36
  zScale: any;
37
37
  rScale: any;
38
+ padding: {
39
+ top: number;
40
+ right: number;
41
+ bottom: number;
42
+ left: number;
43
+ } & {
44
+ top?: number | undefined;
45
+ right?: number | undefined;
46
+ bottom?: number | undefined;
47
+ left?: number | undefined;
48
+ };
38
49
  };
39
50
  };
40
51
  };
@@ -41,7 +41,7 @@ else if (scale.interpolator) {
41
41
  xScale = Object.assign(scale.copy().interpolator(interpolateRound(0, width)), {
42
42
  range() {
43
43
  return [0, width];
44
- }
44
+ },
45
45
  });
46
46
  interpolator = scale.interpolator();
47
47
  // scaleSequentialQuantile doesn’t implement ticks or tickFormat.
@@ -72,7 +72,7 @@ else if (scale.invertExtent) {
72
72
  y: 0,
73
73
  width: xScale(i) - xScale(i - 1),
74
74
  height,
75
- fill: d
75
+ fill: d,
76
76
  };
77
77
  });
78
78
  tickValues = range(thresholds.length);
@@ -90,7 +90,7 @@ else {
90
90
  y: 0,
91
91
  width: Math.max(0, xScale.bandwidth() - 1),
92
92
  height,
93
- fill: scale(d)
93
+ fill: scale(d),
94
94
  };
95
95
  });
96
96
  tickValues = scale.domain();
@@ -101,6 +101,7 @@ else {
101
101
  </script>
102
102
 
103
103
  <div
104
+ {...$$restProps}
104
105
  class={cls(
105
106
  'inline-block',
106
107
  placement && [
@@ -114,12 +115,12 @@ else {
114
115
  right: 'top-1/2 right-0 -translate-y-1/2',
115
116
  'bottom-left': 'bottom-0 left-0',
116
117
  bottom: 'bottom-0 left-1/2 -translate-x-1/2',
117
- 'bottom-right': 'bottom-0 right-0'
118
- }[placement]
118
+ 'bottom-right': 'bottom-0 right-0',
119
+ }[placement],
119
120
  ],
121
+ $$restProps.class,
120
122
  classes.root
121
123
  )}
122
- {...$$restProps}
123
124
  >
124
125
  <div class={cls('text-[10px] font-semibold', classes.title)}>{title}</div>
125
126
  <slot values={tickValues} {scale}>
@@ -1,9 +1,12 @@
1
1
  <script>import { uniqueId } from 'svelte-ux';
2
2
  /** Unique id for linearGradient */
3
3
  export let id = uniqueId('linearGradient-');
4
- export let from;
5
- export let via = undefined; // TODO: Currently --tw-gradient-via is not the color but the full stops
6
- export let to;
4
+ /** Array array of strings (colors), will equally distributed from 0-100%. If array of tuples, will use first value as the offset, and second as color */
5
+ export let stops = [
6
+ 'var(--tw-gradient-from)',
7
+ 'var(--tw-gradient-to)',
8
+ ];
9
+ /** Apply color stops top-to-bottom (true) or left-to-right (false) */
7
10
  export let vertical = false;
8
11
  export let x1 = '0%';
9
12
  export let y1 = '0%';
@@ -26,17 +29,14 @@ export let units = 'objectBoundingBox';
26
29
  {...$$restProps}
27
30
  >
28
31
  <slot name="stops">
29
- {#if from}
30
- <stop offset="0%" stop-color={from === true ? 'var(--tw-gradient-from)' : from} />
31
- {/if}
32
-
33
- {#if via}
34
- <!-- <stop offset="50%" stop-color={via === true ? 'var(--tw-gradient-via)' : via} /> -->
35
- <stop offset="50%" stop-color={via} />
36
- {/if}
37
-
38
- {#if to}
39
- <stop offset="100%" stop-color={to === true ? 'var(--tw-gradient-to)' : to} />
32
+ {#if stops}
33
+ {#each stops as stop, i}
34
+ {#if Array.isArray(stop)}
35
+ <stop offset={stop[0]} stop-color={stop[1]} />
36
+ {:else}
37
+ <stop offset="{i * (100 / (stops.length - 1))}%" stop-color={stop} />
38
+ {/if}
39
+ {/each}
40
40
  {/if}
41
41
  </slot>
42
42
  </linearGradient>
@@ -3,9 +3,7 @@ declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
5
  id?: string | undefined;
6
- from: string | boolean;
7
- via?: string | boolean | undefined;
8
- to: string | boolean;
6
+ stops?: string[] | [string | number, string][] | undefined;
9
7
  vertical?: boolean | undefined;
10
8
  x1?: string | undefined;
11
9
  y1?: string | undefined;
@@ -4,8 +4,12 @@ import { fade } from 'svelte/transition';
4
4
  import { writable } from 'svelte/store';
5
5
  import { cls } from 'svelte-ux';
6
6
  import { tooltipContext } from './TooltipContext.svelte';
7
- export let topOffset = 10;
8
- export let leftOffset = 10;
7
+ /** Use fixed `top` position instead of calculating based on data and mouse position */
8
+ export let top = undefined;
9
+ /** Use fixed `left` position instead of calculating based on data and mouse position */
10
+ export let left = undefined;
11
+ export let topOffset = top ? 0 : 10;
12
+ export let leftOffset = left ? 0 : 10;
9
13
  export let contained = 'container'; // TODO: Support 'window' using getBoundingClientRect()
10
14
  export let animate = true;
11
15
  export let header = undefined;
@@ -14,24 +18,32 @@ const { containerWidth, containerHeight } = getContext('LayerCake');
14
18
  const tooltip = tooltipContext();
15
19
  let tooltipWidth = 0;
16
20
  let tooltipHeight = 0;
17
- let top = animate ? spring($tooltip.top) : writable($tooltip.top);
21
+ let topPos = animate ? spring($tooltip.top) : writable($tooltip.top);
18
22
  $: if ($tooltip) {
19
- if (contained === 'container' && $tooltip.top + topOffset + tooltipHeight > $containerHeight) {
23
+ if (top != null) {
24
+ $topPos = top;
25
+ }
26
+ else if (contained === 'container' &&
27
+ $tooltip.top + topOffset + tooltipHeight > $containerHeight) {
20
28
  // Change side. Do not allow tooltip to go above the top
21
- $top = Math.max($tooltip.top - (topOffset + tooltipHeight), 0);
29
+ $topPos = Math.max($tooltip.top - (topOffset + tooltipHeight), 0);
22
30
  }
23
31
  else {
24
- $top = $tooltip.top + topOffset;
32
+ $topPos = $tooltip.top + topOffset;
25
33
  }
26
34
  }
27
- let left = animate ? spring($tooltip.left) : writable($tooltip.left);
35
+ let leftPos = animate ? spring($tooltip.left) : writable($tooltip.left);
28
36
  $: if ($tooltip) {
29
- if (contained === 'container' && $tooltip.left + leftOffset + tooltipWidth > $containerWidth) {
37
+ if (left != null) {
38
+ $leftPos = left;
39
+ }
40
+ else if (contained === 'container' &&
41
+ $tooltip.left + leftOffset + tooltipWidth > $containerWidth) {
30
42
  // Change side
31
- $left = Math.max($tooltip.left - (leftOffset + tooltipWidth), 0);
43
+ $leftPos = Math.max($tooltip.left - (leftOffset + tooltipWidth), 0);
32
44
  }
33
45
  else {
34
- $left = $tooltip.left + leftOffset;
46
+ $leftPos = $tooltip.left + leftOffset;
35
47
  }
36
48
  }
37
49
  </script>
@@ -39,8 +51,8 @@ $: if ($tooltip) {
39
51
  {#if $tooltip.data}
40
52
  <div
41
53
  class={cls('absolute pointer-events-none z-50', classes.root)}
42
- style:top="{$top}px"
43
- style:left="{$left}px"
54
+ style:top="{$topPos}px"
55
+ style:left="{$leftPos}px"
44
56
  transition:fade={{ duration: 100 }}
45
57
  bind:clientWidth={tooltipWidth}
46
58
  bind:clientHeight={tooltipHeight}
@@ -2,6 +2,8 @@ import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
+ top?: number | undefined;
6
+ left?: number | undefined;
5
7
  topOffset?: number | undefined;
6
8
  leftOffset?: number | undefined;
7
9
  contained?: false | "container" | undefined;
@@ -13,7 +13,7 @@ export let icon;
13
13
  <Dialog
14
14
  {open}
15
15
  on:close={toggle}
16
- class="max-h-[98vh] md:max-h-[90vh] max-w-[98vw] md:max-w-[90vw] grid grid-rows-[auto,1fr,auto]"
16
+ class="max-h-[98dvh] md:max-h-[90dvh] max-w-[98vw] md:max-w-[90vw] grid grid-rows-[auto,1fr,auto]"
17
17
  >
18
18
  <div class="grid grid-cols-[1fr,auto] gap-3 items-center p-4">
19
19
  <div class="overflow-auto">
@@ -1,14 +1,14 @@
1
- export declare function getAccessor(key: any): any;
1
+ export declare function getAccessor(key: string): (d: any) => any;
2
2
  /**
3
3
  * Pivot longer (columns to rows)
4
4
  * - see: https://observablehq.com/d/3ea8d446f5ba96fe
5
5
  * - see also: https://observablehq.com/d/ac2a320cf2b0adc4 as generator
6
6
  */
7
- export declare function pivotLonger(data: any, columns: any, name: any, value: any): any;
7
+ export declare function pivotLonger(data: any[], columns: string[], name: string, value: string): any[];
8
8
  /**
9
9
  * Pivot wider (rows to columns)
10
10
  * - see: https://github.com/d3/d3-array/issues/142#issuecomment-761861983
11
11
  */
12
- export declare function pivotWider(data: any, column: any, name: any, value: any): unknown[];
13
- export declare function first(items: any): any;
14
- export declare function last(items: any): any;
12
+ export declare function pivotWider(data: any[], column: string, name: string, value: string): any[];
13
+ export declare function first(items: any[]): any;
14
+ export declare function last(items: any[]): any;
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "layerchart",
3
+ "description": "Composable Svelte chart components to build a wide range of visualizations",
3
4
  "author": "Sean Lynch <techniq35@gmail.com>",
4
5
  "license": "MIT",
5
6
  "repository": "techniq/layerchart",
6
- "version": "0.23.0",
7
+ "version": "0.24.1",
7
8
  "scripts": {
8
9
  "dev": "vite dev",
9
10
  "build": "vite build",
@@ -20,53 +21,54 @@
20
21
  "publish": "changeset publish"
21
22
  },
22
23
  "devDependencies": {
23
- "@rollup/plugin-dsv": "^3.0.2",
24
+ "@rollup/plugin-dsv": "^3.0.4",
24
25
  "@sveltejs/adapter-vercel": "^3.0.3",
25
- "@sveltejs/kit": "^1.25.0",
26
+ "@sveltejs/kit": "^1.25.2",
26
27
  "@sveltejs/package": "^2.2.2",
27
28
  "@svitejs/changesets-changelog-github-compact": "^1.1.0",
28
29
  "@tailwindcss/typography": "^0.5.10",
29
- "@types/d3-array": "^3.0.7",
30
- "@types/d3-delaunay": "^6.0.1",
31
- "@types/d3-dsv": "^3.0.2",
32
- "@types/d3-geo": "^3.0.4",
33
- "@types/d3-hierarchy": "^3.1.3",
34
- "@types/d3-interpolate": "^3.0.1",
35
- "@types/d3-interpolate-path": "^2.0.0",
36
- "@types/d3-quadtree": "^3.0.2",
30
+ "@types/d3-array": "^3.0.8",
31
+ "@types/d3-delaunay": "^6.0.2",
32
+ "@types/d3-dsv": "^3.0.4",
33
+ "@types/d3-geo": "^3.0.5",
34
+ "@types/d3-hierarchy": "^3.1.4",
35
+ "@types/d3-interpolate": "^3.0.2",
36
+ "@types/d3-interpolate-path": "^2.0.1",
37
+ "@types/d3-quadtree": "^3.0.3",
37
38
  "@types/d3-random": "^3.0.1",
38
- "@types/d3-sankey": "^0.12.1",
39
- "@types/d3-scale": "^4.0.4",
40
- "@types/d3-shape": "^3.1.2",
39
+ "@types/d3-sankey": "^0.12.2",
40
+ "@types/d3-scale": "^4.0.5",
41
+ "@types/d3-scale-chromatic": "^3.0.0",
42
+ "@types/d3-shape": "^3.1.3",
41
43
  "@types/lodash-es": "^4.17.9",
42
- "@types/marked": "^5.0.1",
43
- "@types/shapefile": "^0.6.1",
44
+ "@types/marked": "^6.0.0",
45
+ "@types/shapefile": "^0.6.2",
44
46
  "@types/topojson-client": "^3.1.2",
45
- "autoprefixer": "^10.4.15",
47
+ "autoprefixer": "^10.4.16",
46
48
  "execa": "^8.0.1",
47
- "marked": "^9.0.0",
49
+ "marked": "^9.1.1",
48
50
  "mdsvex": "^0.11.0",
49
51
  "prettier": "^3.0.3",
50
52
  "prettier-plugin-svelte": "^3.0.3",
51
53
  "prism-themes": "^1.9.0",
52
54
  "rehype-slug": "^6.0.0",
53
- "svelte": "^4.2.0",
54
- "svelte-check": "^3.5.1",
55
+ "svelte": "^4.2.1",
56
+ "svelte-check": "^3.5.2",
55
57
  "svelte-preprocess": "^5.0.4",
56
- "svelte2tsx": "^0.6.21",
58
+ "svelte2tsx": "^0.6.23",
57
59
  "tailwindcss": "^3.3.3",
58
60
  "tslib": "^2.6.2",
59
61
  "typescript": "^5.2.2",
60
62
  "unist-util-visit": "^5.0.0",
61
63
  "us-atlas": "^3.0.1",
62
- "vite": "^4.4.9"
64
+ "vite": "^4.4.11"
63
65
  },
64
66
  "type": "module",
65
67
  "dependencies": {
66
68
  "@changesets/cli": "^2.26.2",
67
- "@mdi/js": "^7.2.96",
68
- "@types/d3-time": "^3.0.0",
69
- "@vercel/analytics": "^1.0.2",
69
+ "@mdi/js": "^7.3.67",
70
+ "@types/d3-time": "^3.0.1",
71
+ "@vercel/analytics": "^1.1.1",
70
72
  "d3-array": "^3.2.4",
71
73
  "d3-delaunay": "^6.0.4",
72
74
  "d3-dsv": "^3.0.1",
@@ -83,10 +85,10 @@
83
85
  "d3-tile": "^1.0.0",
84
86
  "d3-time": "^3.1.0",
85
87
  "date-fns": "^2.30.0",
86
- "layercake": "^7.6.1",
88
+ "layercake": "^8.0.0",
87
89
  "lodash-es": "^4.17.21",
88
90
  "shapefile": "^0.6.6",
89
- "svelte-ux": "^0.49.0",
91
+ "svelte-ux": "^0.52.1",
90
92
  "topojson-client": "^3.1.0"
91
93
  },
92
94
  "peerDependencies": {