layerchart 0.23.0 → 0.24.0
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 +2 -0
- package/dist/components/Calendar.svelte +13 -6
- package/dist/components/Calendar.svelte.d.ts +0 -2
- package/dist/components/Chart.svelte +3 -0
- package/dist/components/Chart.svelte.d.ts +11 -0
- package/dist/components/Legend.svelte +7 -6
- package/dist/components/LinearGradient.svelte +14 -14
- package/dist/components/LinearGradient.svelte.d.ts +1 -3
- package/dist/components/Tooltip.svelte +24 -12
- package/dist/components/Tooltip.svelte.d.ts +2 -0
- package/dist/docs/ViewSourceButton.svelte +1 -1
- package/dist/utils/pivot.d.ts +5 -5
- package/package.json +4 -2
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
|
|
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={
|
|
50
|
-
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}
|
|
@@ -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
|
-
|
|
5
|
-
export let
|
|
6
|
-
|
|
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
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
export let
|
|
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
|
|
21
|
+
let topPos = animate ? spring($tooltip.top) : writable($tooltip.top);
|
|
18
22
|
$: if ($tooltip) {
|
|
19
|
-
if (
|
|
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
|
-
$
|
|
29
|
+
$topPos = Math.max($tooltip.top - (topOffset + tooltipHeight), 0);
|
|
22
30
|
}
|
|
23
31
|
else {
|
|
24
|
-
$
|
|
32
|
+
$topPos = $tooltip.top + topOffset;
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
|
-
let
|
|
35
|
+
let leftPos = animate ? spring($tooltip.left) : writable($tooltip.left);
|
|
28
36
|
$: if ($tooltip) {
|
|
29
|
-
if (
|
|
37
|
+
if (left != null) {
|
|
38
|
+
$leftPos = left;
|
|
39
|
+
}
|
|
40
|
+
else if (contained === 'container' &&
|
|
41
|
+
$tooltip.left + leftOffset + tooltipWidth > $containerWidth) {
|
|
30
42
|
// Change side
|
|
31
|
-
$
|
|
43
|
+
$leftPos = Math.max($tooltip.left - (leftOffset + tooltipWidth), 0);
|
|
32
44
|
}
|
|
33
45
|
else {
|
|
34
|
-
$
|
|
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="{$
|
|
43
|
-
style:left="{$
|
|
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-[
|
|
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">
|
package/dist/utils/pivot.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export declare function getAccessor(key:
|
|
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:
|
|
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:
|
|
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.
|
|
7
|
+
"version": "0.24.0",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"dev": "vite dev",
|
|
9
10
|
"build": "vite build",
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
"@types/d3-random": "^3.0.1",
|
|
38
39
|
"@types/d3-sankey": "^0.12.1",
|
|
39
40
|
"@types/d3-scale": "^4.0.4",
|
|
41
|
+
"@types/d3-scale-chromatic": "^3.0.0",
|
|
40
42
|
"@types/d3-shape": "^3.1.2",
|
|
41
43
|
"@types/lodash-es": "^4.17.9",
|
|
42
44
|
"@types/marked": "^5.0.1",
|
|
@@ -86,7 +88,7 @@
|
|
|
86
88
|
"layercake": "^7.6.1",
|
|
87
89
|
"lodash-es": "^4.17.21",
|
|
88
90
|
"shapefile": "^0.6.6",
|
|
89
|
-
"svelte-ux": "^0.49.
|
|
91
|
+
"svelte-ux": "^0.49.1",
|
|
90
92
|
"topojson-client": "^3.1.0"
|
|
91
93
|
},
|
|
92
94
|
"peerDependencies": {
|