layerchart 2.0.0-next.13 → 2.0.0-next.15
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/ForceSimulation.svelte +57 -23
- package/dist/components/ForceSimulation.svelte.d.ts +34 -10
- package/dist/components/charts/AreaChart.svelte +8 -1
- package/dist/components/charts/BarChart.svelte +8 -0
- package/dist/components/charts/LineChart.svelte +8 -1
- package/dist/utils/genData.d.ts +14 -0
- package/dist/utils/genData.js +18 -0
- package/package.json +1 -1
|
@@ -1,26 +1,48 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
forceSimulation,
|
|
4
|
+
type Force,
|
|
5
|
+
type Simulation,
|
|
6
|
+
type SimulationLinkDatum,
|
|
7
|
+
type SimulationNodeDatum,
|
|
8
|
+
} from 'd3-force';
|
|
3
9
|
import type { Snippet } from 'svelte';
|
|
4
10
|
|
|
5
11
|
type Forces = Record<string, Force<any, any>>;
|
|
6
12
|
|
|
7
|
-
export type
|
|
13
|
+
export type Data<TNode = any, TLink = any> = {
|
|
14
|
+
nodes: TNode[];
|
|
15
|
+
links?: TLink[];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type LinkPosition = Prettify<{
|
|
8
19
|
x1: number;
|
|
9
20
|
y1: number;
|
|
10
21
|
x2: number;
|
|
11
22
|
y2: number;
|
|
12
|
-
}
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
type NodeDatumFor<NodeDatum> = Prettify<NodeDatum & SimulationNodeDatum>;
|
|
26
|
+
type LinkDatumFor<NodeDatum, LinkDatum> = Prettify<
|
|
27
|
+
LinkDatum & SimulationLinkDatum<NodeDatumFor<NodeDatum>>
|
|
28
|
+
>;
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
type SimulationFor<NodeDatum, LinkDatum> = Simulation<
|
|
31
|
+
NodeDatumFor<NodeDatum>,
|
|
32
|
+
LinkDatumFor<NodeDatum, LinkDatum>
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
export type ForceSimulationProps<NodeDatum, LinkDatum> = {
|
|
15
36
|
/**
|
|
16
37
|
* Force simulation parameters
|
|
17
38
|
*/
|
|
18
39
|
forces: Forces;
|
|
19
40
|
|
|
20
41
|
/**
|
|
21
|
-
* An
|
|
42
|
+
* An object with arrays of nodes and links,
|
|
43
|
+
* to be used for position calculation.
|
|
22
44
|
*/
|
|
23
|
-
|
|
45
|
+
data: Data<NodeDatum, LinkDatum>;
|
|
24
46
|
|
|
25
47
|
/**
|
|
26
48
|
* Current alpha value of the simulation
|
|
@@ -88,22 +110,23 @@
|
|
|
88
110
|
children?: Snippet<
|
|
89
111
|
[
|
|
90
112
|
{
|
|
91
|
-
nodes:
|
|
92
|
-
|
|
113
|
+
nodes: NodeDatumFor<NodeDatum>[];
|
|
114
|
+
links: LinkDatumFor<NodeDatum, LinkDatum>[];
|
|
93
115
|
linkPositions: LinkPosition[];
|
|
116
|
+
simulation: SimulationFor<NodeDatum, LinkDatum>;
|
|
94
117
|
},
|
|
95
118
|
]
|
|
96
119
|
>;
|
|
97
120
|
};
|
|
98
121
|
</script>
|
|
99
122
|
|
|
100
|
-
<script lang="ts">
|
|
101
|
-
import { getChartContext } from './Chart.svelte';
|
|
123
|
+
<script lang="ts" generics="NodeDatum, LinkDatum = undefined">
|
|
102
124
|
import { watch } from 'runed';
|
|
125
|
+
import type { Prettify } from '@layerstack/utils';
|
|
103
126
|
|
|
104
127
|
let {
|
|
105
128
|
forces,
|
|
106
|
-
|
|
129
|
+
data,
|
|
107
130
|
alpha = $bindable(1),
|
|
108
131
|
alphaTarget = 0,
|
|
109
132
|
alphaDecay = 1 - Math.pow(0.001, 1 / 300),
|
|
@@ -116,18 +139,23 @@
|
|
|
116
139
|
onEnd: onEndProp = () => {},
|
|
117
140
|
children,
|
|
118
141
|
cloneNodes = false,
|
|
119
|
-
}: ForceSimulationProps = $props();
|
|
120
|
-
|
|
121
|
-
const ctx = getChartContext();
|
|
142
|
+
}: ForceSimulationProps<NodeDatum, LinkDatum> = $props();
|
|
122
143
|
|
|
123
144
|
// MARK: Public Props
|
|
124
145
|
|
|
125
146
|
// MARK: Private Props
|
|
126
147
|
|
|
127
|
-
let nodes: SimulationNodeDatum[] = $state([]);
|
|
128
148
|
let linkPositions: LinkPosition[] = $state([]);
|
|
149
|
+
let simulatedNodes: NodeDatumFor<NodeDatum>[] = $state([]);
|
|
150
|
+
let simulatedLinks: LinkDatumFor<NodeDatum, LinkDatum>[] = $derived(
|
|
151
|
+
(data.links ?? []) as LinkDatumFor<NodeDatum, LinkDatum>[]
|
|
152
|
+
);
|
|
129
153
|
|
|
130
|
-
|
|
154
|
+
// This casting is unfortunately necessary, due to unfortunate
|
|
155
|
+
// overloading choices made, over at `@typed/d3-force`:
|
|
156
|
+
const simulation: SimulationFor<NodeDatum, LinkDatum> = (
|
|
157
|
+
forceSimulation() as SimulationFor<NodeDatum, LinkDatum>
|
|
158
|
+
).stop();
|
|
131
159
|
|
|
132
160
|
// d3.Simulation does not provide a `.forces()` getter, so we need to
|
|
133
161
|
// keep track of previous forces ourselves, for diffing against `forces`.
|
|
@@ -166,11 +194,11 @@
|
|
|
166
194
|
);
|
|
167
195
|
|
|
168
196
|
watch.pre(
|
|
169
|
-
() =>
|
|
197
|
+
() => data,
|
|
170
198
|
() => {
|
|
171
|
-
// Any time the `data` store gets changed
|
|
172
|
-
// pass them to the internal d3 simulation object:
|
|
173
|
-
pushNodesToSimulation(
|
|
199
|
+
// Any time the `nodes` prop, or the `data` store gets changed
|
|
200
|
+
// we pass them to the internal d3 simulation object:
|
|
201
|
+
pushNodesToSimulation(data.nodes);
|
|
174
202
|
runOrResumeSimulation();
|
|
175
203
|
}
|
|
176
204
|
);
|
|
@@ -259,7 +287,7 @@
|
|
|
259
287
|
// Keeping the link positions in sync with the simulation
|
|
260
288
|
// so we don't need to recalculate _all_ link positions on each tick
|
|
261
289
|
// which bogs down the simulation
|
|
262
|
-
linkPositions =
|
|
290
|
+
linkPositions = simulatedLinks.map((link: any) => ({
|
|
263
291
|
x1: link.source.x ?? 0,
|
|
264
292
|
y1: link.source.y ?? 0,
|
|
265
293
|
x2: link.target.x ?? 0,
|
|
@@ -270,7 +298,8 @@
|
|
|
270
298
|
// MARK: Pull State
|
|
271
299
|
|
|
272
300
|
function pullNodesFromSimulation() {
|
|
273
|
-
|
|
301
|
+
const simulationNodes = simulation.nodes();
|
|
302
|
+
simulatedNodes = cloneNodes ? structuredClone(simulationNodes) : simulationNodes;
|
|
274
303
|
}
|
|
275
304
|
|
|
276
305
|
function pullAlphaFromSimulation() {
|
|
@@ -393,4 +422,9 @@
|
|
|
393
422
|
});
|
|
394
423
|
</script>
|
|
395
424
|
|
|
396
|
-
{@render children?.({
|
|
425
|
+
{@render children?.({
|
|
426
|
+
nodes: simulatedNodes,
|
|
427
|
+
links: simulatedLinks,
|
|
428
|
+
simulation,
|
|
429
|
+
linkPositions,
|
|
430
|
+
})}
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
import { type Force, type Simulation, type SimulationNodeDatum } from 'd3-force';
|
|
1
|
+
import { type Force, type Simulation, type SimulationLinkDatum, type SimulationNodeDatum } from 'd3-force';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
type Forces = Record<string, Force<any, any>>;
|
|
4
|
-
export type
|
|
4
|
+
export type Data<TNode = any, TLink = any> = {
|
|
5
|
+
nodes: TNode[];
|
|
6
|
+
links?: TLink[];
|
|
7
|
+
};
|
|
8
|
+
export type LinkPosition = Prettify<{
|
|
5
9
|
x1: number;
|
|
6
10
|
y1: number;
|
|
7
11
|
x2: number;
|
|
8
12
|
y2: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
13
|
+
}>;
|
|
14
|
+
type NodeDatumFor<NodeDatum> = Prettify<NodeDatum & SimulationNodeDatum>;
|
|
15
|
+
type LinkDatumFor<NodeDatum, LinkDatum> = Prettify<LinkDatum & SimulationLinkDatum<NodeDatumFor<NodeDatum>>>;
|
|
16
|
+
type SimulationFor<NodeDatum, LinkDatum> = Simulation<NodeDatumFor<NodeDatum>, LinkDatumFor<NodeDatum, LinkDatum>>;
|
|
17
|
+
export type ForceSimulationProps<NodeDatum, LinkDatum> = {
|
|
11
18
|
/**
|
|
12
19
|
* Force simulation parameters
|
|
13
20
|
*/
|
|
14
21
|
forces: Forces;
|
|
15
22
|
/**
|
|
16
|
-
* An
|
|
23
|
+
* An object with arrays of nodes and links,
|
|
24
|
+
* to be used for position calculation.
|
|
17
25
|
*/
|
|
18
|
-
|
|
26
|
+
data: Data<NodeDatum, LinkDatum>;
|
|
19
27
|
/**
|
|
20
28
|
* Current alpha value of the simulation
|
|
21
29
|
* @default 1
|
|
@@ -73,12 +81,28 @@ export type ForceSimulationProps = {
|
|
|
73
81
|
onEnd?: () => void;
|
|
74
82
|
children?: Snippet<[
|
|
75
83
|
{
|
|
76
|
-
nodes:
|
|
77
|
-
|
|
84
|
+
nodes: NodeDatumFor<NodeDatum>[];
|
|
85
|
+
links: LinkDatumFor<NodeDatum, LinkDatum>[];
|
|
78
86
|
linkPositions: LinkPosition[];
|
|
87
|
+
simulation: SimulationFor<NodeDatum, LinkDatum>;
|
|
79
88
|
}
|
|
80
89
|
]>;
|
|
81
90
|
};
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
import type { Prettify } from '@layerstack/utils';
|
|
92
|
+
declare class __sveltets_Render<NodeDatum, LinkDatum = undefined> {
|
|
93
|
+
props(): ForceSimulationProps<NodeDatum, LinkDatum>;
|
|
94
|
+
events(): {};
|
|
95
|
+
slots(): {};
|
|
96
|
+
bindings(): "alpha";
|
|
97
|
+
exports(): {};
|
|
98
|
+
}
|
|
99
|
+
interface $$IsomorphicComponent {
|
|
100
|
+
new <NodeDatum, LinkDatum = undefined>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['props']>, ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['events']>, ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['slots']>> & {
|
|
101
|
+
$$bindings?: ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['bindings']>;
|
|
102
|
+
} & ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['exports']>;
|
|
103
|
+
<NodeDatum, LinkDatum = undefined>(internal: unknown, props: ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['props']> & {}): ReturnType<__sveltets_Render<NodeDatum, LinkDatum>['exports']>;
|
|
104
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
105
|
+
}
|
|
106
|
+
declare const ForceSimulation: $$IsomorphicComponent;
|
|
107
|
+
type ForceSimulation<NodeDatum, LinkDatum = undefined> = InstanceType<typeof ForceSimulation<NodeDatum, LinkDatum>>;
|
|
84
108
|
export default ForceSimulation;
|
|
@@ -135,7 +135,14 @@
|
|
|
135
135
|
|
|
136
136
|
const series = $derived(
|
|
137
137
|
seriesProp === undefined
|
|
138
|
-
? [
|
|
138
|
+
? [
|
|
139
|
+
{
|
|
140
|
+
key: 'default',
|
|
141
|
+
label: typeof y === 'string' ? y : 'value',
|
|
142
|
+
value: y,
|
|
143
|
+
color: 'var(--color-primary)',
|
|
144
|
+
},
|
|
145
|
+
]
|
|
139
146
|
: seriesProp
|
|
140
147
|
);
|
|
141
148
|
|
|
@@ -159,6 +159,14 @@
|
|
|
159
159
|
? [
|
|
160
160
|
{
|
|
161
161
|
key: 'default',
|
|
162
|
+
label:
|
|
163
|
+
orientation === 'vertical'
|
|
164
|
+
? typeof yProp === 'string'
|
|
165
|
+
? yProp
|
|
166
|
+
: 'value'
|
|
167
|
+
: typeof xProp === 'string'
|
|
168
|
+
? xProp
|
|
169
|
+
: 'value',
|
|
162
170
|
value: orientation === 'vertical' ? yProp : xProp,
|
|
163
171
|
},
|
|
164
172
|
]
|
|
@@ -141,7 +141,14 @@
|
|
|
141
141
|
|
|
142
142
|
const series = $derived(
|
|
143
143
|
seriesProp === undefined
|
|
144
|
-
? [
|
|
144
|
+
? [
|
|
145
|
+
{
|
|
146
|
+
key: 'default',
|
|
147
|
+
label: typeof yProp === 'string' ? yProp : 'value',
|
|
148
|
+
value: yProp,
|
|
149
|
+
color: 'var(--color-primary)',
|
|
150
|
+
},
|
|
151
|
+
]
|
|
145
152
|
: seriesProp
|
|
146
153
|
);
|
|
147
154
|
const seriesState = new SeriesState(() => series);
|
package/dist/utils/genData.d.ts
CHANGED
|
@@ -75,3 +75,17 @@ export declare function getSpiral({ angle, radius, count, width, height, }: {
|
|
|
75
75
|
x: number;
|
|
76
76
|
y: number;
|
|
77
77
|
}[];
|
|
78
|
+
interface SineWaveOptions {
|
|
79
|
+
numPoints: number;
|
|
80
|
+
frequency?: number;
|
|
81
|
+
amplitude?: number;
|
|
82
|
+
noiseLevel?: number;
|
|
83
|
+
phase?: number;
|
|
84
|
+
xMin?: number;
|
|
85
|
+
xMax?: number;
|
|
86
|
+
}
|
|
87
|
+
export declare function generateSineWave(options: SineWaveOptions): {
|
|
88
|
+
x: number;
|
|
89
|
+
y: number;
|
|
90
|
+
}[];
|
|
91
|
+
export {};
|
package/dist/utils/genData.js
CHANGED
|
@@ -124,3 +124,21 @@ export function getSpiral({ angle, radius, count, width, height, }) {
|
|
|
124
124
|
};
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
|
+
export function generateSineWave(options) {
|
|
128
|
+
const { numPoints, frequency = 1, amplitude = 1, noiseLevel = 0, phase = 0, xMin = 0, xMax = 2 * Math.PI, } = options;
|
|
129
|
+
if (numPoints <= 0) {
|
|
130
|
+
throw new Error('Number of points must be greater than 0');
|
|
131
|
+
}
|
|
132
|
+
const points = [];
|
|
133
|
+
const xStep = (xMax - xMin) / (numPoints - 1);
|
|
134
|
+
for (let i = 0; i < numPoints; i++) {
|
|
135
|
+
const x = xMin + i * xStep;
|
|
136
|
+
// Generate base sine wave
|
|
137
|
+
const sineValue = amplitude * Math.sin(frequency * x + phase);
|
|
138
|
+
// Add random noise if specified
|
|
139
|
+
const noise = noiseLevel > 0 ? (Math.random() - 0.5) * 2 * noiseLevel : 0;
|
|
140
|
+
const y = sineValue + noise;
|
|
141
|
+
points.push({ x, y });
|
|
142
|
+
}
|
|
143
|
+
return points;
|
|
144
|
+
}
|
package/package.json
CHANGED