layerchart 0.34.0 → 0.36.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/dist/components/Axis.svelte +17 -14
- package/dist/components/Axis.svelte.d.ts +6 -1
- package/dist/components/ChartClipPath.svelte +6 -4
- package/dist/components/ChartClipPath.svelte.d.ts +1 -0
- package/dist/components/ForceSimulation.svelte +49 -0
- package/dist/components/ForceSimulation.svelte.d.ts +29 -0
- package/dist/components/GeoPath.svelte +29 -6
- package/dist/components/GeoPath.svelte.d.ts +4 -2
- package/dist/components/GeoPoint.svelte +4 -1
- package/dist/components/GeoVisible.svelte +12 -0
- package/dist/components/GeoVisible.svelte.d.ts +19 -0
- package/dist/components/Hull.svelte +53 -0
- package/dist/components/Hull.svelte.d.ts +36 -0
- package/dist/components/Points.svelte +6 -3
- package/dist/components/Points.svelte.d.ts +1 -0
- package/dist/components/Voronoi.svelte +0 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +4 -0
- package/dist/docs/CurveMenuField.svelte +13 -13
- package/dist/docs/CurveMenuField.svelte.d.ts +1 -0
- package/dist/utils/geo.d.ts +13 -0
- package/dist/utils/geo.js +54 -0
- package/package.json +6 -1
|
@@ -166,9 +166,22 @@ function getDefaultLabelProps(tick) {
|
|
|
166
166
|
{/if}
|
|
167
167
|
{/if}
|
|
168
168
|
|
|
169
|
-
{#each tickVals as tick (tick)}
|
|
169
|
+
{#each tickVals as tick, index (tick)}
|
|
170
170
|
{@const tickCoords = getCoords(tick)}
|
|
171
171
|
{@const radialTickCoords = pointRadial(tickCoords.x, tickCoords.y)}
|
|
172
|
+
{@const textLabelProps = {
|
|
173
|
+
x: orientation === 'angle' ? radialTickCoords[0] : tickCoords.x,
|
|
174
|
+
y: orientation === 'angle' ? radialTickCoords[1] : tickCoords.y,
|
|
175
|
+
value: formatValue(tick, format ?? scale.tickFormat?.() ?? ((v) => v)),
|
|
176
|
+
...getDefaultLabelProps(tick),
|
|
177
|
+
tweened,
|
|
178
|
+
spring,
|
|
179
|
+
...labelProps,
|
|
180
|
+
class: cls(
|
|
181
|
+
'label text-[10px] stroke-surface-100 [stroke-width:2px] font-light',
|
|
182
|
+
labelProps?.class
|
|
183
|
+
),
|
|
184
|
+
}}
|
|
172
185
|
|
|
173
186
|
<g in:transitionIn={transitionInParams}>
|
|
174
187
|
{#if grid !== false}
|
|
@@ -241,19 +254,9 @@ function getDefaultLabelProps(tick) {
|
|
|
241
254
|
/>
|
|
242
255
|
{/if}
|
|
243
256
|
|
|
244
|
-
<
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
value={formatValue(tick, format ?? scale.tickFormat?.() ?? ((v) => v))}
|
|
248
|
-
{...getDefaultLabelProps(tick)}
|
|
249
|
-
{tweened}
|
|
250
|
-
{spring}
|
|
251
|
-
{...labelProps}
|
|
252
|
-
class={cls(
|
|
253
|
-
'label text-[10px] stroke-surface-100 [stroke-width:2px] font-light',
|
|
254
|
-
labelProps?.class
|
|
255
|
-
)}
|
|
256
|
-
/>
|
|
257
|
+
<slot name="label" labelProps={textLabelProps} {index}>
|
|
258
|
+
<Text {...textLabelProps} />
|
|
259
|
+
</slot>
|
|
257
260
|
</g>
|
|
258
261
|
{/each}
|
|
259
262
|
</g>
|
|
@@ -22,7 +22,12 @@ declare const __propDef: {
|
|
|
22
22
|
events: {
|
|
23
23
|
[evt: string]: CustomEvent<any>;
|
|
24
24
|
};
|
|
25
|
-
slots: {
|
|
25
|
+
slots: {
|
|
26
|
+
label: {
|
|
27
|
+
labelProps: any;
|
|
28
|
+
index: any;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
26
31
|
};
|
|
27
32
|
export type AxisProps = typeof __propDef.props;
|
|
28
33
|
export type AxisEvents = typeof __propDef.events;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<script>import { getContext } from 'svelte';
|
|
2
2
|
import RectClipPath from './RectClipPath.svelte';
|
|
3
3
|
const { width, height, padding } = getContext('LayerCake');
|
|
4
|
+
/** Whether clipping should include chart padding (ex. axis) */
|
|
5
|
+
export let includePadding = false;
|
|
4
6
|
</script>
|
|
5
7
|
|
|
6
8
|
<RectClipPath
|
|
7
|
-
x={-$padding.left}
|
|
8
|
-
y={-$padding.top}
|
|
9
|
-
width={$width + $padding.left + $padding.right}
|
|
10
|
-
height={$height + $padding.top + $padding.bottom}
|
|
9
|
+
x={includePadding ? -$padding.left : 0}
|
|
10
|
+
y={includePadding ? -$padding.top : 0}
|
|
11
|
+
width={$width + (includePadding ? $padding.left + $padding.right : 0)}
|
|
12
|
+
height={$height + (includePadding ? $padding.top + $padding.bottom : 0)}
|
|
11
13
|
on:click
|
|
12
14
|
{...$$restProps}
|
|
13
15
|
>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script>import { getContext } from 'svelte';
|
|
2
|
+
import { forceSimulation } from 'd3-force';
|
|
3
|
+
const { data } = getContext('LayerCake');
|
|
4
|
+
export let forces;
|
|
5
|
+
export let alpha = 1;
|
|
6
|
+
export let alphaTarget = 0;
|
|
7
|
+
export let alphaDecay = 1 - Math.pow(0.001, 1 / 300);
|
|
8
|
+
export let alphaMin = 0.001;
|
|
9
|
+
export let velocityDecay = 0.4;
|
|
10
|
+
/** Clone data since simulation mutates original */
|
|
11
|
+
export let cloneData = false;
|
|
12
|
+
let _static = false;
|
|
13
|
+
/** If true, will only update nodes after simulation has completed */
|
|
14
|
+
export { _static as static };
|
|
15
|
+
let simulation = forceSimulation(cloneData ? structuredClone($data) : $data);
|
|
16
|
+
$: {
|
|
17
|
+
simulation
|
|
18
|
+
.alpha(alpha)
|
|
19
|
+
.alphaTarget(alphaTarget)
|
|
20
|
+
.alphaMin(alphaMin)
|
|
21
|
+
.alphaDecay(alphaDecay)
|
|
22
|
+
.velocityDecay(velocityDecay)
|
|
23
|
+
.restart();
|
|
24
|
+
if (_static) {
|
|
25
|
+
// TODO: Not sure why it needs to be recreated when static
|
|
26
|
+
simulation = forceSimulation(cloneData ? structuredClone($data) : $data);
|
|
27
|
+
simulation.stop();
|
|
28
|
+
Object.entries(forces).forEach(([name, force]) => {
|
|
29
|
+
simulation.force(name, force);
|
|
30
|
+
});
|
|
31
|
+
for (let i = 0, n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())); i < n; ++i) {
|
|
32
|
+
simulation.tick();
|
|
33
|
+
}
|
|
34
|
+
nodes = simulation.nodes();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// When variables change, set forces and restart the simulation
|
|
38
|
+
Object.entries(forces).forEach(([name, force]) => {
|
|
39
|
+
simulation.force(name, force);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
let nodes = [];
|
|
44
|
+
simulation.on('tick', () => {
|
|
45
|
+
nodes = simulation.nodes();
|
|
46
|
+
});
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<slot {nodes} {simulation} />
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import { type Force } from 'd3-force';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
forces: Record<string, Force<any, any>>;
|
|
6
|
+
alpha?: number | undefined;
|
|
7
|
+
alphaTarget?: number | undefined;
|
|
8
|
+
alphaDecay?: number | undefined;
|
|
9
|
+
alphaMin?: number | undefined;
|
|
10
|
+
velocityDecay?: number | undefined;
|
|
11
|
+
/** Clone data since simulation mutates original */ cloneData?: boolean | undefined;
|
|
12
|
+
/** If true, will only update nodes after simulation has completed */ static?: boolean | undefined;
|
|
13
|
+
};
|
|
14
|
+
events: {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
};
|
|
17
|
+
slots: {
|
|
18
|
+
default: {
|
|
19
|
+
nodes: any[];
|
|
20
|
+
simulation: import("d3-force").Simulation<import("d3-force").SimulationNodeDatum, undefined>;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export type ForceSimulationProps = typeof __propDef.props;
|
|
25
|
+
export type ForceSimulationEvents = typeof __propDef.events;
|
|
26
|
+
export type ForceSimulationSlots = typeof __propDef.slots;
|
|
27
|
+
export default class ForceSimulation extends SvelteComponentTyped<ForceSimulationProps, ForceSimulationEvents, ForceSimulationSlots> {
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script>import { createEventDispatcher, getContext } from 'svelte';
|
|
2
|
-
import {
|
|
2
|
+
import {} from 'd3-geo';
|
|
3
3
|
import { scaleCanvas } from 'layercake';
|
|
4
4
|
import { cls } from 'svelte-ux';
|
|
5
5
|
import { geoContext } from './GeoContext.svelte';
|
|
6
|
+
import { curveLinearClosed } from 'd3-shape';
|
|
7
|
+
import { geoCurvePath } from '../utils/geo.js';
|
|
6
8
|
export let geojson;
|
|
7
9
|
export let fill = undefined;
|
|
8
10
|
export let stroke = undefined;
|
|
@@ -13,29 +15,50 @@ export let render = undefined;
|
|
|
13
15
|
* Tooltip context to setup mouse events to show tooltip for related data
|
|
14
16
|
*/
|
|
15
17
|
export let tooltip = undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Curve of path drawn. Imported via d3-shape.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* import { curveCatmullRom } from 'd3-shape';
|
|
23
|
+
* <GeoPath curve={curveCatmullRom} />
|
|
24
|
+
*
|
|
25
|
+
* @type {CurveFactory | CurveFactoryLineOnly | undefined}
|
|
26
|
+
*/
|
|
27
|
+
export let curve = curveLinearClosed;
|
|
16
28
|
const dispatch = createEventDispatcher();
|
|
17
|
-
const {
|
|
29
|
+
const { width, height } = getContext('LayerCake');
|
|
18
30
|
const canvas = getContext('canvas');
|
|
19
31
|
const geo = geoContext();
|
|
20
|
-
$: geoPath =
|
|
32
|
+
$: geoPath = geoCurvePath($geo, curve);
|
|
33
|
+
const DEFAULT_FILL = 'rgb(0, 0, 0)';
|
|
21
34
|
$: renderContext = canvas ? 'canvas' : 'svg';
|
|
22
35
|
$: ctx = canvas?.ctx;
|
|
23
36
|
$: if (renderContext === 'canvas' && $ctx) {
|
|
37
|
+
let computedStyles = {};
|
|
38
|
+
// Transfer classes defined on <GeoPath> to <canvas> to enable window.getComputedStyle() retrieval (Tailwind classes, etc)
|
|
39
|
+
if ($$props.class) {
|
|
40
|
+
$ctx.canvas.classList.add(...$$props.class.split(' '));
|
|
41
|
+
computedStyles = window.getComputedStyle($ctx.canvas);
|
|
42
|
+
}
|
|
24
43
|
// console.count('render');
|
|
25
44
|
scaleCanvas($ctx, $width, $height);
|
|
26
45
|
$ctx.clearRect(0, 0, $width, $height);
|
|
27
46
|
if (render) {
|
|
47
|
+
geoPath = geoCurvePath($geo, curve, $ctx);
|
|
28
48
|
render($ctx, { geoPath });
|
|
29
49
|
}
|
|
30
50
|
else {
|
|
31
51
|
$ctx.beginPath();
|
|
32
52
|
// Set the context here since setting it in `$: geoPath` is a circular reference
|
|
33
|
-
geoPath
|
|
53
|
+
geoPath = geoCurvePath($geo, curve, $ctx);
|
|
34
54
|
geoPath(geojson);
|
|
35
|
-
$ctx.fillStyle =
|
|
55
|
+
$ctx.fillStyle =
|
|
56
|
+
fill ??
|
|
57
|
+
(computedStyles.fill !== DEFAULT_FILL ? computedStyles.fill : undefined) ??
|
|
58
|
+
'transparent';
|
|
36
59
|
$ctx.fill();
|
|
37
60
|
$ctx.lineWidth = strokeWidth;
|
|
38
|
-
$ctx.strokeStyle = stroke;
|
|
61
|
+
$ctx.strokeStyle = stroke ?? computedStyles.stroke;
|
|
39
62
|
$ctx.stroke();
|
|
40
63
|
}
|
|
41
64
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
import { type
|
|
2
|
+
import { type GeoPermissibleObjects } from 'd3-geo';
|
|
3
3
|
import type { TooltipContextValue } from './TooltipContext.svelte';
|
|
4
|
+
import { type CurveFactory, type CurveFactoryLineOnly } from 'd3-shape';
|
|
4
5
|
declare const __propDef: {
|
|
5
6
|
props: {
|
|
6
7
|
[x: string]: any;
|
|
@@ -12,6 +13,7 @@ declare const __propDef: {
|
|
|
12
13
|
geoPath: any;
|
|
13
14
|
}) => any) | undefined;
|
|
14
15
|
tooltip?: TooltipContextValue | undefined;
|
|
16
|
+
curve?: CurveFactory | CurveFactoryLineOnly | undefined;
|
|
15
17
|
};
|
|
16
18
|
events: {
|
|
17
19
|
mousemove: MouseEvent;
|
|
@@ -22,7 +24,7 @@ declare const __propDef: {
|
|
|
22
24
|
};
|
|
23
25
|
slots: {
|
|
24
26
|
default: {
|
|
25
|
-
geoPath:
|
|
27
|
+
geoPath: (object: GeoPermissibleObjects) => string | undefined;
|
|
26
28
|
};
|
|
27
29
|
};
|
|
28
30
|
};
|
|
@@ -15,9 +15,12 @@ $: [x, y] = $geo([long, lat]) ?? [0, 0];
|
|
|
15
15
|
$: renderContext = canvas ? 'canvas' : 'svg';
|
|
16
16
|
$: ctx = canvas?.ctx;
|
|
17
17
|
$: if (renderContext === 'canvas' && $ctx) {
|
|
18
|
-
// console.count('render');
|
|
19
18
|
scaleCanvas($ctx, $width, $height);
|
|
20
19
|
$ctx.clearRect(0, 0, $width, $height);
|
|
20
|
+
// Transfer classes defined on <GeoPoint> to <canvas> to enable window.getComputedStyle() retrieval (Tailwind classes, etc)
|
|
21
|
+
if ($$props.class) {
|
|
22
|
+
$ctx.canvas.classList.add(...$$props.class.split(' '));
|
|
23
|
+
}
|
|
21
24
|
render($ctx, { x, y });
|
|
22
25
|
}
|
|
23
26
|
</script>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script>import { geoContext } from './GeoContext.svelte';
|
|
2
|
+
import { isVisible } from '../utils/geo.js';
|
|
3
|
+
/** Latitude */
|
|
4
|
+
export let lat;
|
|
5
|
+
/** Longitude */
|
|
6
|
+
export let long;
|
|
7
|
+
const geo = geoContext();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
{#if isVisible($geo)([long, lat])}
|
|
11
|
+
<slot />
|
|
12
|
+
{/if}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
/** Latitude */ lat: number;
|
|
5
|
+
/** Longitude */ long: number;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {
|
|
11
|
+
default: {};
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export type GeoVisibleProps = typeof __propDef.props;
|
|
15
|
+
export type GeoVisibleEvents = typeof __propDef.events;
|
|
16
|
+
export type GeoVisibleSlots = typeof __propDef.slots;
|
|
17
|
+
export default class GeoVisible extends SvelteComponentTyped<GeoVisibleProps, GeoVisibleEvents, GeoVisibleSlots> {
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script>import { createEventDispatcher, getContext } from 'svelte';
|
|
2
|
+
import { cls } from 'svelte-ux';
|
|
3
|
+
import { min } from 'd3-array';
|
|
4
|
+
import { Delaunay } from 'd3-delaunay';
|
|
5
|
+
import { geoVoronoi } from 'd3-geo-voronoi';
|
|
6
|
+
import GeoPath from './GeoPath.svelte';
|
|
7
|
+
import { geoContext } from './GeoContext.svelte';
|
|
8
|
+
import Spline from './Spline.svelte';
|
|
9
|
+
import { curveLinearClosed } from 'd3-shape';
|
|
10
|
+
const { flatData, x: xContext, y: yContext } = getContext('LayerCake');
|
|
11
|
+
const geo = geoContext();
|
|
12
|
+
/** Override data instead of using context */
|
|
13
|
+
export let data = undefined;
|
|
14
|
+
export let curve = curveLinearClosed;
|
|
15
|
+
export let classes = {};
|
|
16
|
+
const dispatch = createEventDispatcher();
|
|
17
|
+
$: points = (data ?? $flatData).map((d) => {
|
|
18
|
+
const xValue = $xContext(d);
|
|
19
|
+
const yValue = $yContext(d);
|
|
20
|
+
const x = Array.isArray(xValue) ? min(xValue) : xValue;
|
|
21
|
+
const y = Array.isArray(yValue) ? min(yValue) : yValue;
|
|
22
|
+
const point = [x, y];
|
|
23
|
+
point.data = d;
|
|
24
|
+
return point;
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<g {...$$restProps} class={cls(classes.root, $$props.class)}>
|
|
29
|
+
{#if $geo}
|
|
30
|
+
{@const polygon = geoVoronoi().hull(points)}
|
|
31
|
+
<GeoPath
|
|
32
|
+
geojson={polygon}
|
|
33
|
+
{curve}
|
|
34
|
+
class={cls('fill-transparent', classes.path)}
|
|
35
|
+
on:mousemove={(e) => dispatch('mousemove', { event: e, points, polygon })}
|
|
36
|
+
on:mouseleave
|
|
37
|
+
on:click={(e) => dispatch('click', { points, polygon })}
|
|
38
|
+
/>
|
|
39
|
+
{:else}
|
|
40
|
+
{@const delaunay = Delaunay.from(points)}
|
|
41
|
+
{@const polygon = delaunay.hullPolygon()}
|
|
42
|
+
<Spline
|
|
43
|
+
data={polygon}
|
|
44
|
+
x={(d) => d[0]}
|
|
45
|
+
y={(d) => d[1]}
|
|
46
|
+
{curve}
|
|
47
|
+
class={cls('fill-transparent', classes.path)}
|
|
48
|
+
on:mousemove={(e) => dispatch('mousemove', { event: e, points, polygon })}
|
|
49
|
+
on:mouseleave
|
|
50
|
+
on:click={(e) => dispatch('click', { points, polygon })}
|
|
51
|
+
/>
|
|
52
|
+
{/if}
|
|
53
|
+
</g>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import { type ComponentProps } from 'svelte';
|
|
3
|
+
import { Delaunay } from 'd3-delaunay';
|
|
4
|
+
import Spline from './Spline.svelte';
|
|
5
|
+
declare const __propDef: {
|
|
6
|
+
props: {
|
|
7
|
+
[x: string]: any;
|
|
8
|
+
data?: any;
|
|
9
|
+
curve?: ComponentProps<Spline>['curve'];
|
|
10
|
+
classes?: {
|
|
11
|
+
root?: string | undefined;
|
|
12
|
+
path?: string | undefined;
|
|
13
|
+
} | undefined;
|
|
14
|
+
};
|
|
15
|
+
events: {
|
|
16
|
+
mouseleave: MouseEvent;
|
|
17
|
+
click: CustomEvent<{
|
|
18
|
+
points: [number, number][];
|
|
19
|
+
polygon: Delaunay.Polygon;
|
|
20
|
+
}>;
|
|
21
|
+
mousemove: CustomEvent<{
|
|
22
|
+
event: MouseEvent;
|
|
23
|
+
points: [number, number][];
|
|
24
|
+
polygon: Delaunay.Polygon;
|
|
25
|
+
}>;
|
|
26
|
+
} & {
|
|
27
|
+
[evt: string]: CustomEvent<any>;
|
|
28
|
+
};
|
|
29
|
+
slots: {};
|
|
30
|
+
};
|
|
31
|
+
export type HullProps = typeof __propDef.props;
|
|
32
|
+
export type HullEvents = typeof __propDef.events;
|
|
33
|
+
export type HullSlots = typeof __propDef.slots;
|
|
34
|
+
export default class Hull extends SvelteComponentTyped<HullProps, HullEvents, HullSlots> {
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -6,7 +6,9 @@ import Link from './Link.svelte';
|
|
|
6
6
|
import { isScaleBand } from '../utils/scales.js';
|
|
7
7
|
import { pointRadial } from 'd3-shape';
|
|
8
8
|
const context = getContext('LayerCake');
|
|
9
|
-
const { data, xGet, y, yGet, xScale, yScale, rGet, config } = context;
|
|
9
|
+
const { data: contextData, xGet, y, yGet, xScale, yScale, rGet, config } = context;
|
|
10
|
+
/** Override data instead of using context */
|
|
11
|
+
export let data = undefined;
|
|
10
12
|
export let r = 5;
|
|
11
13
|
export let offsetX = undefined;
|
|
12
14
|
export let offsetY = undefined;
|
|
@@ -28,7 +30,8 @@ function getOffset(value, offset, scale) {
|
|
|
28
30
|
return 0;
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
$:
|
|
33
|
+
$: pointsData = data ?? $contextData;
|
|
34
|
+
$: points = pointsData.flatMap((d) => {
|
|
32
35
|
if (Array.isArray($config.x)) {
|
|
33
36
|
/*
|
|
34
37
|
x={["prop1" ,"prop2"]}
|
|
@@ -71,7 +74,7 @@ $: points = $data.flatMap((d) => {
|
|
|
71
74
|
};
|
|
72
75
|
}
|
|
73
76
|
});
|
|
74
|
-
$: _links =
|
|
77
|
+
$: _links = pointsData.flatMap((d) => {
|
|
75
78
|
if (Array.isArray($config.x)) {
|
|
76
79
|
/*
|
|
77
80
|
x={["prop1" ,"prop2"]}
|
|
@@ -2,6 +2,7 @@ import { SvelteComponentTyped } from "svelte";
|
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
[x: string]: any;
|
|
5
|
+
data?: any;
|
|
5
6
|
r?: number | undefined;
|
|
6
7
|
offsetX?: number | ((value: number, context: any) => number) | undefined;
|
|
7
8
|
offsetY?: number | ((value: number, context: any) => number) | undefined;
|
|
@@ -2,6 +2,7 @@ export { default as Arc } from './Arc.svelte';
|
|
|
2
2
|
export { default as Area } from './Area.svelte';
|
|
3
3
|
export { default as AreaStack } from './AreaStack.svelte';
|
|
4
4
|
export { default as Axis } from './Axis.svelte';
|
|
5
|
+
export { default as Bar } from './Bar.svelte';
|
|
5
6
|
export { default as Bars } from './Bars.svelte';
|
|
6
7
|
export { default as Blur } from './Blur.svelte';
|
|
7
8
|
export { default as Bounds } from './Bounds.svelte';
|
|
@@ -13,6 +14,7 @@ export { default as CircleClipPath } from './CircleClipPath.svelte';
|
|
|
13
14
|
export { default as ClipPath } from './ClipPath.svelte';
|
|
14
15
|
export { default as ColorRamp } from './ColorRamp.svelte';
|
|
15
16
|
export { default as Frame } from './Frame.svelte';
|
|
17
|
+
export { default as ForceSimulation } from './ForceSimulation.svelte';
|
|
16
18
|
export { default as GeoCircle } from './GeoCircle.svelte';
|
|
17
19
|
export { default as GeoContext, geoContext } from './GeoContext.svelte';
|
|
18
20
|
export { default as GeoEdgeFade } from './GeoEdgeFade.svelte';
|
|
@@ -20,9 +22,11 @@ export { default as GeoPath } from './GeoPath.svelte';
|
|
|
20
22
|
export { default as GeoPoint } from './GeoPoint.svelte';
|
|
21
23
|
export { default as GeoSpline } from './GeoSpline.svelte';
|
|
22
24
|
export { default as GeoTile } from './GeoTile.svelte';
|
|
25
|
+
export { default as GeoVisible } from './GeoVisible.svelte';
|
|
23
26
|
export { default as Graticule } from './Graticule.svelte';
|
|
24
27
|
export { default as Group } from './Group.svelte';
|
|
25
28
|
export { default as Highlight } from './Highlight.svelte';
|
|
29
|
+
export { default as Hull } from './Hull.svelte';
|
|
26
30
|
export { default as Labels } from './Labels.svelte';
|
|
27
31
|
export { default as Legend } from './Legend.svelte';
|
|
28
32
|
export { default as Line } from './Line.svelte';
|
package/dist/components/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { default as Arc } from './Arc.svelte';
|
|
|
2
2
|
export { default as Area } from './Area.svelte';
|
|
3
3
|
export { default as AreaStack } from './AreaStack.svelte';
|
|
4
4
|
export { default as Axis } from './Axis.svelte';
|
|
5
|
+
export { default as Bar } from './Bar.svelte';
|
|
5
6
|
export { default as Bars } from './Bars.svelte';
|
|
6
7
|
export { default as Blur } from './Blur.svelte';
|
|
7
8
|
export { default as Bounds } from './Bounds.svelte';
|
|
@@ -13,6 +14,7 @@ export { default as CircleClipPath } from './CircleClipPath.svelte';
|
|
|
13
14
|
export { default as ClipPath } from './ClipPath.svelte';
|
|
14
15
|
export { default as ColorRamp } from './ColorRamp.svelte';
|
|
15
16
|
export { default as Frame } from './Frame.svelte';
|
|
17
|
+
export { default as ForceSimulation } from './ForceSimulation.svelte';
|
|
16
18
|
export { default as GeoCircle } from './GeoCircle.svelte';
|
|
17
19
|
export { default as GeoContext, geoContext } from './GeoContext.svelte';
|
|
18
20
|
export { default as GeoEdgeFade } from './GeoEdgeFade.svelte';
|
|
@@ -20,9 +22,11 @@ export { default as GeoPath } from './GeoPath.svelte';
|
|
|
20
22
|
export { default as GeoPoint } from './GeoPoint.svelte';
|
|
21
23
|
export { default as GeoSpline } from './GeoSpline.svelte';
|
|
22
24
|
export { default as GeoTile } from './GeoTile.svelte';
|
|
25
|
+
export { default as GeoVisible } from './GeoVisible.svelte';
|
|
23
26
|
export { default as Graticule } from './Graticule.svelte';
|
|
24
27
|
export { default as Group } from './Group.svelte';
|
|
25
28
|
export { default as Highlight } from './Highlight.svelte';
|
|
29
|
+
export { default as Hull } from './Hull.svelte';
|
|
26
30
|
export { default as Labels } from './Labels.svelte';
|
|
27
31
|
export { default as Legend } from './Legend.svelte';
|
|
28
32
|
export { default as Line } from './Line.svelte';
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
<script>import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export let
|
|
5
|
-
const options =
|
|
6
|
-
.filter((key) =>
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
<script>import * as d3shapes from 'd3-shape';
|
|
2
|
+
import { MenuField, entries } from 'svelte-ux';
|
|
3
|
+
export let value = d3shapes['curveLinear'];
|
|
4
|
+
export let showOpenClosed = false;
|
|
5
|
+
const options = entries(d3shapes)
|
|
6
|
+
.filter(([key]) => {
|
|
7
|
+
return (key.startsWith('curve') &&
|
|
8
|
+
(showOpenClosed ? true : !key.endsWith('Open') && !key.endsWith('Closed')) &&
|
|
9
|
+
!key.includes('Bundle') // Not compatibile with area
|
|
10
|
+
);
|
|
11
|
+
})
|
|
12
|
+
.map(([key, value]) => {
|
|
10
13
|
return {
|
|
11
14
|
label: key.replace('curve', ''),
|
|
12
|
-
value:
|
|
15
|
+
value: value,
|
|
13
16
|
};
|
|
14
17
|
});
|
|
15
|
-
onMount(() => {
|
|
16
|
-
value = d3shapes['curveLinear'];
|
|
17
|
-
});
|
|
18
18
|
</script>
|
|
19
19
|
|
|
20
20
|
<MenuField label="Curve" {options} bind:value stepper classes={{ menuIcon: 'hidden' }} />
|
package/dist/utils/geo.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
import { type GeoPermissibleObjects, type GeoProjection, type GeoStreamWrapper } from 'd3-geo';
|
|
2
|
+
import { type Path } from 'd3-path';
|
|
3
|
+
import { type CurveFactory, type CurveFactoryLineOnly } from 'd3-shape';
|
|
4
|
+
/**
|
|
5
|
+
* Render a geoPath() using curve factory
|
|
6
|
+
* @see {@link https://observablehq.com/@d3/context-to-curve}
|
|
7
|
+
*/
|
|
8
|
+
export declare function geoCurvePath(projection: GeoProjection | GeoStreamWrapper | null, curve: CurveFactory | CurveFactoryLineOnly, context?: CanvasRenderingContext2D | Path): (object: GeoPermissibleObjects) => string | undefined;
|
|
1
9
|
/**
|
|
2
10
|
* Return the point on Earth's surface that is diametrically opposite to another point
|
|
3
11
|
* @see: https://en.wikipedia.org/wiki/Antipodes
|
|
4
12
|
*/
|
|
5
13
|
export declare function antipode([longitude, latitude]: [number, number]): [number, number];
|
|
14
|
+
/**
|
|
15
|
+
* Check if point ([x, y]) is visible on projection
|
|
16
|
+
* @see: https://observablehq.com/@d3/testing-projection-visibility
|
|
17
|
+
*/
|
|
18
|
+
export declare function isVisible(projection: GeoProjection | GeoStreamWrapper): ([x, y]: [any, any]) => boolean;
|
package/dist/utils/geo.js
CHANGED
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
import { geoPath as d3geoPath, } from 'd3-geo';
|
|
2
|
+
import { path } from 'd3-path';
|
|
3
|
+
import {} from 'd3-shape';
|
|
4
|
+
/**
|
|
5
|
+
* Render a geoPath() using curve factory
|
|
6
|
+
* @see {@link https://observablehq.com/@d3/context-to-curve}
|
|
7
|
+
*/
|
|
8
|
+
export function geoCurvePath(projection, curve, context) {
|
|
9
|
+
const pathContext = context === undefined ? path() : context;
|
|
10
|
+
const geoPath = d3geoPath(projection, curveContext(curve(pathContext)));
|
|
11
|
+
const fn = (object) => {
|
|
12
|
+
geoPath(object);
|
|
13
|
+
return context === undefined ? pathContext + '' : undefined;
|
|
14
|
+
};
|
|
15
|
+
// Expose geoPath properties such as `.centroid()`
|
|
16
|
+
Object.setPrototypeOf(fn, geoPath);
|
|
17
|
+
return fn;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Translate Curve to GeoContext interface
|
|
21
|
+
*/
|
|
22
|
+
function curveContext(curve) {
|
|
23
|
+
return {
|
|
24
|
+
beginPath() {
|
|
25
|
+
// nothing?
|
|
26
|
+
},
|
|
27
|
+
moveTo(x, y) {
|
|
28
|
+
curve.lineStart();
|
|
29
|
+
curve.point(x, y);
|
|
30
|
+
},
|
|
31
|
+
arc(x, y, radius, startAngle, endAngle, anticlockwise) {
|
|
32
|
+
// nothing?
|
|
33
|
+
},
|
|
34
|
+
lineTo(x, y) {
|
|
35
|
+
curve.point(x, y);
|
|
36
|
+
},
|
|
37
|
+
closePath() {
|
|
38
|
+
curve.lineEnd();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
1
42
|
/**
|
|
2
43
|
* Return the point on Earth's surface that is diametrically opposite to another point
|
|
3
44
|
* @see: https://en.wikipedia.org/wiki/Antipodes
|
|
@@ -5,3 +46,16 @@
|
|
|
5
46
|
export function antipode([longitude, latitude]) {
|
|
6
47
|
return [longitude + 180, -latitude];
|
|
7
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if point ([x, y]) is visible on projection
|
|
51
|
+
* @see: https://observablehq.com/@d3/testing-projection-visibility
|
|
52
|
+
*/
|
|
53
|
+
export function isVisible(projection) {
|
|
54
|
+
let visible;
|
|
55
|
+
const stream = projection.stream({
|
|
56
|
+
point() {
|
|
57
|
+
visible = true;
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
return ([x, y]) => ((visible = false), stream.point(x, y), visible);
|
|
61
|
+
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"author": "Sean Lynch <techniq35@gmail.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "techniq/layerchart",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.36.0",
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@changesets/cli": "^2.27.1",
|
|
10
10
|
"@mdi/js": "^7.4.47",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"@types/d3-array": "^3.2.1",
|
|
18
18
|
"@types/d3-delaunay": "^6.0.4",
|
|
19
19
|
"@types/d3-dsv": "^3.0.7",
|
|
20
|
+
"@types/d3-force": "^3.0.9",
|
|
20
21
|
"@types/d3-geo": "^3.1.0",
|
|
21
22
|
"@types/d3-hierarchy": "^3.1.6",
|
|
22
23
|
"@types/d3-interpolate": "^3.0.4",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"@types/prismjs": "^1.26.3",
|
|
33
34
|
"@types/shapefile": "^0.6.4",
|
|
34
35
|
"@types/topojson-client": "^3.1.4",
|
|
36
|
+
"@types/topojson-simplify": "^3.0.3",
|
|
35
37
|
"autoprefixer": "^10.4.18",
|
|
36
38
|
"execa": "^8.0.1",
|
|
37
39
|
"marked": "^12.0.1",
|
|
@@ -52,6 +54,7 @@
|
|
|
52
54
|
"svelte2tsx": "^0.7.4",
|
|
53
55
|
"tailwindcss": "^3.4.1",
|
|
54
56
|
"topojson-client": "^3.1.0",
|
|
57
|
+
"topojson-simplify": "^3.0.3",
|
|
55
58
|
"tslib": "^2.6.2",
|
|
56
59
|
"typescript": "^5.4.2",
|
|
57
60
|
"unist-util-visit": "^5.0.0",
|
|
@@ -65,11 +68,13 @@
|
|
|
65
68
|
"d3-color": "^3.1.0",
|
|
66
69
|
"d3-delaunay": "^6.0.4",
|
|
67
70
|
"d3-dsv": "^3.0.1",
|
|
71
|
+
"d3-force": "^3.0.0",
|
|
68
72
|
"d3-geo": "^3.1.1",
|
|
69
73
|
"d3-geo-voronoi": "^2.0.1",
|
|
70
74
|
"d3-hierarchy": "^3.1.2",
|
|
71
75
|
"d3-interpolate": "^3.0.1",
|
|
72
76
|
"d3-interpolate-path": "^2.3.0",
|
|
77
|
+
"d3-path": "^3.1.0",
|
|
73
78
|
"d3-quadtree": "^3.0.1",
|
|
74
79
|
"d3-random": "^3.0.1",
|
|
75
80
|
"d3-sankey": "^0.12.3",
|