svelteplot 0.8.1 → 0.9.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 +1 -1
- package/dist/Mark.svelte +1 -1
- package/dist/Mark.svelte.d.ts +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/core/Plot.svelte +4 -4
- package/dist/helpers/projection.js +7 -2
- package/dist/hooks/usePlot.svelte.d.ts +51 -0
- package/dist/hooks/usePlot.svelte.js +90 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/marks/Area.svelte +3 -5
- package/dist/marks/Area.svelte.d.ts +1 -0
- package/dist/marks/AreaX.svelte.d.ts +1 -0
- package/dist/marks/Arrow.svelte +3 -5
- package/dist/marks/Arrow.svelte.d.ts +1 -0
- package/dist/marks/AxisX.svelte +2 -3
- package/dist/marks/AxisX.svelte.d.ts +1 -0
- package/dist/marks/AxisY.svelte +3 -4
- package/dist/marks/AxisY.svelte.d.ts +1 -0
- package/dist/marks/BarX.svelte +2 -4
- package/dist/marks/BarX.svelte.d.ts +1 -0
- package/dist/marks/BarY.svelte +2 -4
- package/dist/marks/BarY.svelte.d.ts +1 -0
- package/dist/marks/BollingerX.svelte.d.ts +1 -0
- package/dist/marks/BollingerY.svelte.d.ts +1 -0
- package/dist/marks/BoxX.svelte +4 -138
- package/dist/marks/BoxY.svelte +20 -137
- package/dist/marks/BoxY.svelte.d.ts +8 -3
- package/dist/marks/Brush.svelte +3 -3
- package/dist/marks/Brush.svelte.d.ts +1 -0
- package/dist/marks/Cell.svelte +2 -4
- package/dist/marks/Cell.svelte.d.ts +1 -0
- package/dist/marks/ColorLegend.svelte +2 -4
- package/dist/marks/CustomMark.svelte.d.ts +1 -0
- package/dist/marks/CustomMarkHTML.svelte +5 -10
- package/dist/marks/DifferenceY.svelte +3 -5
- package/dist/marks/DifferenceY.svelte.d.ts +1 -0
- package/dist/marks/Dot.svelte +4 -5
- package/dist/marks/Dot.svelte.d.ts +1 -0
- package/dist/marks/DotX.svelte.d.ts +1 -0
- package/dist/marks/DotY.svelte.d.ts +1 -0
- package/dist/marks/Frame.svelte +3 -9
- package/dist/marks/Frame.svelte.d.ts +1 -0
- package/dist/marks/Geo.svelte +5 -5
- package/dist/marks/Geo.svelte.d.ts +2 -0
- package/dist/marks/GridX.svelte +3 -10
- package/dist/marks/GridX.svelte.d.ts +1 -0
- package/dist/marks/GridY.svelte +3 -4
- package/dist/marks/GridY.svelte.d.ts +1 -0
- package/dist/marks/HTMLTooltip.svelte +5 -5
- package/dist/marks/Image.svelte.d.ts +1 -0
- package/dist/marks/Line.svelte +7 -6
- package/dist/marks/Line.svelte.d.ts +1 -0
- package/dist/marks/LineX.svelte.d.ts +1 -0
- package/dist/marks/LineY.svelte.d.ts +1 -0
- package/dist/marks/Link.svelte +2 -4
- package/dist/marks/Link.svelte.d.ts +1 -0
- package/dist/marks/Pointer.svelte +4 -4
- package/dist/marks/Rect.svelte +2 -4
- package/dist/marks/Rect.svelte.d.ts +1 -0
- package/dist/marks/RectX.svelte +4 -4
- package/dist/marks/RectY.svelte +4 -4
- package/dist/marks/RuleX.svelte +2 -4
- package/dist/marks/RuleX.svelte.d.ts +1 -0
- package/dist/marks/RuleY.svelte +2 -4
- package/dist/marks/RuleY.svelte.d.ts +1 -0
- package/dist/marks/Spike.svelte.d.ts +1 -0
- package/dist/marks/SymbolLegend.svelte +2 -4
- package/dist/marks/SymbolLegend.svelte.d.ts +17 -2
- package/dist/marks/Text.svelte.d.ts +1 -0
- package/dist/marks/TickX.svelte +2 -3
- package/dist/marks/TickX.svelte.d.ts +1 -0
- package/dist/marks/TickY.svelte +2 -3
- package/dist/marks/TickY.svelte.d.ts +1 -0
- package/dist/marks/Trail.svelte +161 -0
- package/dist/marks/Trail.svelte.d.ts +107 -0
- package/dist/marks/Vector.svelte +3 -4
- package/dist/marks/Vector.svelte.d.ts +1 -0
- package/dist/marks/WaffleX.svelte +2 -3
- package/dist/marks/WaffleX.svelte.d.ts +1 -0
- package/dist/marks/WaffleY.svelte +2 -4
- package/dist/marks/WaffleY.svelte.d.ts +1 -0
- package/dist/marks/helpers/AreaCanvas.svelte +2 -4
- package/dist/marks/helpers/Box.svelte +271 -0
- package/dist/marks/helpers/Box.svelte.d.ts +118 -0
- package/dist/marks/helpers/CanvasLayer.svelte +2 -4
- package/dist/marks/helpers/DotCanvas.svelte +3 -5
- package/dist/marks/helpers/GeoCanvas.svelte +2 -4
- package/dist/marks/helpers/LineCanvas.svelte +2 -4
- package/dist/marks/helpers/LinearGradientX.svelte +3 -4
- package/dist/marks/helpers/LinearGradientY.svelte +3 -4
- package/dist/marks/helpers/MarkerPath.svelte +4 -5
- package/dist/marks/helpers/MarkerPath.svelte.d.ts +1 -0
- package/dist/marks/helpers/MultilineText.svelte +4 -4
- package/dist/marks/helpers/RectPath.svelte +5 -6
- package/dist/marks/helpers/Regression.svelte +4 -8
- package/dist/marks/helpers/TrailCanvas.svelte +138 -0
- package/dist/marks/helpers/TrailCanvas.svelte.d.ts +40 -0
- package/dist/marks/helpers/events.d.ts +2 -2
- package/dist/marks/helpers/events.js +4 -4
- package/dist/marks/helpers/trail.d.ts +23 -0
- package/dist/marks/helpers/trail.js +372 -0
- package/dist/marks/index.d.ts +1 -0
- package/dist/marks/index.js +1 -0
- package/dist/transforms/bollinger.d.ts +1 -0
- package/dist/transforms/interval.d.ts +2 -0
- package/dist/transforms/select.d.ts +7 -0
- package/dist/transforms/sort.d.ts +4 -0
- package/dist/transforms/window.d.ts +2 -0
- package/dist/types/mark.d.ts +2 -1
- package/dist/types/plot.d.ts +6 -1
- package/dist/ui/Spiral.svelte +4 -0
- package/package.json +24 -23
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { TAU } from '../../constants.js';
|
|
2
|
+
import { maybeCurve } from '../../helpers/curves.js';
|
|
3
|
+
/**
|
|
4
|
+
* Draw a stroked capsule trail along successive points with varying widths.
|
|
5
|
+
* Adapted from Vega's trail mark implementation.
|
|
6
|
+
*/
|
|
7
|
+
export function trailPath(samples, defined, context, options = {}) {
|
|
8
|
+
const { curve = 'linear', cap = 'round', tension = 0.5 } = options;
|
|
9
|
+
const samplesPerSegment = options.samplesPerSegment ?? estimateSamplesPerSegment(samples, defined);
|
|
10
|
+
const curveFactory = maybeCurve(curve, tension);
|
|
11
|
+
let drawSamples = samples;
|
|
12
|
+
let drawDefined = defined;
|
|
13
|
+
if (curve !== 'linear' || tension !== 0) {
|
|
14
|
+
const smoothedSamples = [];
|
|
15
|
+
const smoothedDefined = [];
|
|
16
|
+
const len = Math.min(samples.length, defined.length);
|
|
17
|
+
let i = 0;
|
|
18
|
+
while (i < len) {
|
|
19
|
+
if (!defined[i]) {
|
|
20
|
+
smoothedSamples.push(samples[i]);
|
|
21
|
+
smoothedDefined.push(false);
|
|
22
|
+
i += 1;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const segment = [];
|
|
26
|
+
while (i < len && defined[i]) {
|
|
27
|
+
segment.push(samples[i]);
|
|
28
|
+
i += 1;
|
|
29
|
+
}
|
|
30
|
+
const resampled = resampleCurve(segment, curveFactory, Math.max(1, samplesPerSegment));
|
|
31
|
+
smoothedSamples.push(...resampled);
|
|
32
|
+
smoothedDefined.push(...new Array(resampled.length).fill(true));
|
|
33
|
+
// preserve a gap between defined segments
|
|
34
|
+
if (i < len) {
|
|
35
|
+
smoothedSamples.push(samples[i]);
|
|
36
|
+
smoothedDefined.push(false);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
drawSamples = smoothedSamples;
|
|
40
|
+
drawDefined = smoothedDefined;
|
|
41
|
+
}
|
|
42
|
+
const len = Math.min(drawSamples.length, drawDefined.length);
|
|
43
|
+
if (len === 0)
|
|
44
|
+
return;
|
|
45
|
+
// Butt caps: build joined polygon offsets using angle bisectors to avoid gaps.
|
|
46
|
+
if (cap === 'butt') {
|
|
47
|
+
const normalizeVec = (x, y) => {
|
|
48
|
+
const lenVec = Math.hypot(x, y);
|
|
49
|
+
return lenVec === 0 ? [0, 0] : [x / lenVec, y / lenVec];
|
|
50
|
+
};
|
|
51
|
+
let i = 0;
|
|
52
|
+
while (i < len) {
|
|
53
|
+
if (!drawDefined[i]) {
|
|
54
|
+
i += 1;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const runStart = i;
|
|
58
|
+
while (i < len && drawDefined[i])
|
|
59
|
+
i += 1;
|
|
60
|
+
const runEnd = i - 1;
|
|
61
|
+
const left = [];
|
|
62
|
+
const right = [];
|
|
63
|
+
for (let j = runStart; j <= runEnd; j += 1) {
|
|
64
|
+
const curr = drawSamples[j];
|
|
65
|
+
const r = curr.r;
|
|
66
|
+
const hasPrev = j > runStart;
|
|
67
|
+
const hasNext = j < runEnd;
|
|
68
|
+
const prev = hasPrev ? drawSamples[j - 1] : curr;
|
|
69
|
+
const next = hasNext ? drawSamples[j + 1] : curr;
|
|
70
|
+
const dirPrev = hasPrev
|
|
71
|
+
? normalizeVec(curr.x - prev.x, curr.y - prev.y)
|
|
72
|
+
: normalizeVec(next.x - curr.x, next.y - curr.y);
|
|
73
|
+
const dirNext = hasNext ? normalizeVec(next.x - curr.x, next.y - curr.y) : dirPrev;
|
|
74
|
+
const normPrev = [-dirPrev[1], dirPrev[0]];
|
|
75
|
+
const normNext = [-dirNext[1], dirNext[0]];
|
|
76
|
+
let nx = normPrev[0] + normNext[0];
|
|
77
|
+
let ny = normPrev[1] + normNext[1];
|
|
78
|
+
const nLen = Math.hypot(nx, ny);
|
|
79
|
+
if (nLen < 1e-6) {
|
|
80
|
+
// Straight/180-deg turn: fall back to current normal.
|
|
81
|
+
nx = normPrev[0];
|
|
82
|
+
ny = normPrev[1];
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
nx /= nLen;
|
|
86
|
+
ny /= nLen;
|
|
87
|
+
}
|
|
88
|
+
// Scale to preserve half-width along the miter direction.
|
|
89
|
+
const dot = nx * normPrev[0] + ny * normPrev[1];
|
|
90
|
+
const safeDot = Math.abs(dot) < 1e-6 ? 1 : dot;
|
|
91
|
+
const scale = r / safeDot;
|
|
92
|
+
const ox = nx * scale;
|
|
93
|
+
const oy = ny * scale;
|
|
94
|
+
left.push([curr.x + ox, curr.y + oy]);
|
|
95
|
+
right.push([curr.x - ox, curr.y - oy]);
|
|
96
|
+
}
|
|
97
|
+
if (left.length > 0) {
|
|
98
|
+
context.moveTo(left[0][0], left[0][1]);
|
|
99
|
+
for (let j = 1; j < left.length; j += 1) {
|
|
100
|
+
context.lineTo(left[j][0], left[j][1]);
|
|
101
|
+
}
|
|
102
|
+
for (let j = right.length - 1; j >= 0; j -= 1) {
|
|
103
|
+
context.lineTo(right[j][0], right[j][1]);
|
|
104
|
+
}
|
|
105
|
+
context.closePath();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return typeof context.toString === 'function' ? context.toString() : undefined;
|
|
109
|
+
}
|
|
110
|
+
// Round caps: original capsule behavior.
|
|
111
|
+
let ready = false;
|
|
112
|
+
let x1 = 0;
|
|
113
|
+
let y1 = 0;
|
|
114
|
+
let r1 = 0;
|
|
115
|
+
function point(x2, y2, r2, isStartOfRun, isEndOfRun) {
|
|
116
|
+
if (ready) {
|
|
117
|
+
let ux = y1 - y2;
|
|
118
|
+
let uy = x2 - x1;
|
|
119
|
+
if (ux || uy) {
|
|
120
|
+
// compute normal vector scaled by radius
|
|
121
|
+
const ud = Math.hypot(ux, uy);
|
|
122
|
+
const rx = (ux /= ud) * r1;
|
|
123
|
+
const ry = (uy /= ud) * r1;
|
|
124
|
+
const t = Math.atan2(uy, ux);
|
|
125
|
+
// keep rounded joins for interior segments even when using butt caps
|
|
126
|
+
const drawStartCap = !isStartOfRun || cap === 'round';
|
|
127
|
+
const drawEndCap = !isEndOfRun || cap === 'round';
|
|
128
|
+
context.moveTo(x1 - rx, y1 - ry);
|
|
129
|
+
context.lineTo(x2 - ux * r2, y2 - uy * r2);
|
|
130
|
+
if (drawEndCap) {
|
|
131
|
+
context.arc(x2, y2, r2, t - Math.PI, t);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
context.lineTo(x2 + ux * r2, y2 + uy * r2);
|
|
135
|
+
}
|
|
136
|
+
context.lineTo(x1 + rx, y1 + ry);
|
|
137
|
+
if (drawStartCap) {
|
|
138
|
+
context.arc(x1, y1, r1, t, t + Math.PI);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
if (cap === 'round' || (!isStartOfRun && !isEndOfRun)) {
|
|
143
|
+
context.arc(x2, y2, r2, 0, TAU);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
context.closePath();
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
ready = true;
|
|
150
|
+
}
|
|
151
|
+
x1 = x2;
|
|
152
|
+
y1 = y2;
|
|
153
|
+
r1 = r2;
|
|
154
|
+
}
|
|
155
|
+
let i = 0;
|
|
156
|
+
while (i < len) {
|
|
157
|
+
// Skip gaps
|
|
158
|
+
if (!drawDefined[i]) {
|
|
159
|
+
i += 1;
|
|
160
|
+
ready = false;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const runStart = i;
|
|
164
|
+
while (i < len && drawDefined[i])
|
|
165
|
+
i += 1;
|
|
166
|
+
const runEnd = i - 1;
|
|
167
|
+
// Prime the first point of the run
|
|
168
|
+
const first = drawSamples[runStart];
|
|
169
|
+
ready = false;
|
|
170
|
+
x1 = first.x;
|
|
171
|
+
y1 = first.y;
|
|
172
|
+
r1 = first.r;
|
|
173
|
+
ready = true;
|
|
174
|
+
for (let j = runStart + 1; j <= runEnd; j += 1) {
|
|
175
|
+
const { x: x2, y: y2, r } = drawSamples[j];
|
|
176
|
+
const isStart = j - 1 === runStart;
|
|
177
|
+
const isEnd = j === runEnd;
|
|
178
|
+
point(Number(x2), Number(y2), Number(r), isStart, isEnd);
|
|
179
|
+
}
|
|
180
|
+
ready = false;
|
|
181
|
+
}
|
|
182
|
+
return typeof context.toString === 'function' ? context.toString() : undefined;
|
|
183
|
+
}
|
|
184
|
+
function resampleCurve(points, curveFactory, samplesPerSegment) {
|
|
185
|
+
if (points.length === 0)
|
|
186
|
+
return [];
|
|
187
|
+
const commands = [];
|
|
188
|
+
let pendingRadius = points[0].r;
|
|
189
|
+
let currentRadius = points[0].r;
|
|
190
|
+
let currentPoint = null;
|
|
191
|
+
const ctx = {
|
|
192
|
+
beginPath() { },
|
|
193
|
+
closePath() { },
|
|
194
|
+
moveTo(x, y) {
|
|
195
|
+
currentPoint = [x, y];
|
|
196
|
+
currentRadius = pendingRadius;
|
|
197
|
+
commands.push({ type: 'move', to: [x, y], r: currentRadius });
|
|
198
|
+
},
|
|
199
|
+
lineTo(x, y) {
|
|
200
|
+
const from = currentPoint ?? [x, y];
|
|
201
|
+
commands.push({
|
|
202
|
+
type: 'line',
|
|
203
|
+
from: [from[0], from[1], currentRadius],
|
|
204
|
+
to: [x, y, pendingRadius]
|
|
205
|
+
});
|
|
206
|
+
currentPoint = [x, y];
|
|
207
|
+
currentRadius = pendingRadius;
|
|
208
|
+
},
|
|
209
|
+
bezierCurveTo(x1, y1, x2, y2, x, y) {
|
|
210
|
+
const from = currentPoint ?? [x, y];
|
|
211
|
+
commands.push({
|
|
212
|
+
type: 'cubic',
|
|
213
|
+
from: [from[0], from[1], currentRadius],
|
|
214
|
+
cp1: [x1, y1],
|
|
215
|
+
cp2: [x2, y2],
|
|
216
|
+
to: [x, y, pendingRadius]
|
|
217
|
+
});
|
|
218
|
+
currentPoint = [x, y];
|
|
219
|
+
currentRadius = pendingRadius;
|
|
220
|
+
},
|
|
221
|
+
quadraticCurveTo(x1, y1, x, y) {
|
|
222
|
+
const from = currentPoint ?? [x, y];
|
|
223
|
+
commands.push({
|
|
224
|
+
type: 'quad',
|
|
225
|
+
from: [from[0], from[1], currentRadius],
|
|
226
|
+
cp: [x1, y1],
|
|
227
|
+
to: [x, y, pendingRadius]
|
|
228
|
+
});
|
|
229
|
+
currentPoint = [x, y];
|
|
230
|
+
currentRadius = pendingRadius;
|
|
231
|
+
},
|
|
232
|
+
arc() { },
|
|
233
|
+
rect() { }
|
|
234
|
+
};
|
|
235
|
+
const curve = curveFactory(ctx);
|
|
236
|
+
curve.lineStart();
|
|
237
|
+
for (let idx = 0; idx < points.length; idx += 1) {
|
|
238
|
+
const pt = points[idx];
|
|
239
|
+
pendingRadius = pt.r;
|
|
240
|
+
curve.point(pt.x, pt.y);
|
|
241
|
+
}
|
|
242
|
+
curve.lineEnd();
|
|
243
|
+
const geom = flattenCommands(commands, samplesPerSegment);
|
|
244
|
+
if (geom.length === 0)
|
|
245
|
+
return geom;
|
|
246
|
+
// Re-map radii along the resampled path using the original cumulative
|
|
247
|
+
// length as the parameter to avoid curve-specific radius drift.
|
|
248
|
+
const origCum = [0];
|
|
249
|
+
for (let i = 1; i < points.length; i += 1) {
|
|
250
|
+
const dx = points[i].x - points[i - 1].x;
|
|
251
|
+
const dy = points[i].y - points[i - 1].y;
|
|
252
|
+
origCum.push(origCum[i - 1] + Math.hypot(dx, dy));
|
|
253
|
+
}
|
|
254
|
+
const origTotal = origCum[origCum.length - 1] || 1;
|
|
255
|
+
const resCum = [0];
|
|
256
|
+
for (let i = 1; i < geom.length; i += 1) {
|
|
257
|
+
const dx = geom[i].x - geom[i - 1].x;
|
|
258
|
+
const dy = geom[i].y - geom[i - 1].y;
|
|
259
|
+
resCum.push(resCum[i - 1] + Math.hypot(dx, dy));
|
|
260
|
+
}
|
|
261
|
+
const resTotal = resCum[resCum.length - 1] || 1;
|
|
262
|
+
const radiusAt = (target) => {
|
|
263
|
+
let idx = 1;
|
|
264
|
+
while (idx < origCum.length && origCum[idx] < target)
|
|
265
|
+
idx += 1;
|
|
266
|
+
if (idx === origCum.length)
|
|
267
|
+
return points[points.length - 1].r;
|
|
268
|
+
const t0 = origCum[idx - 1];
|
|
269
|
+
const t1 = origCum[idx];
|
|
270
|
+
const r0 = points[idx - 1].r;
|
|
271
|
+
const r1 = points[idx].r;
|
|
272
|
+
const t = t1 === t0 ? 0 : (target - t0) / (t1 - t0);
|
|
273
|
+
return lerp(r0, r1, t);
|
|
274
|
+
};
|
|
275
|
+
for (let i = 0; i < geom.length; i += 1) {
|
|
276
|
+
const frac = resCum[i] / resTotal;
|
|
277
|
+
geom[i].r = Number(radiusAt(frac * origTotal).toFixed(2));
|
|
278
|
+
}
|
|
279
|
+
return geom;
|
|
280
|
+
}
|
|
281
|
+
function flattenCommands(commands, samplesPerSegment, precision = 2) {
|
|
282
|
+
const result = [];
|
|
283
|
+
let last = null;
|
|
284
|
+
const round = (v) => {
|
|
285
|
+
const m = 10 ** precision;
|
|
286
|
+
return Math.round(v * m) / m;
|
|
287
|
+
};
|
|
288
|
+
const pushPoint = (x, y, r) => {
|
|
289
|
+
x = round(x);
|
|
290
|
+
y = round(y);
|
|
291
|
+
r = round(r);
|
|
292
|
+
if (!last || last[0] !== x || last[1] !== y || last[2] !== r) {
|
|
293
|
+
result.push({ x, y, r });
|
|
294
|
+
last = [x, y, r];
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
for (const cmd of commands) {
|
|
298
|
+
if (cmd.type === 'move') {
|
|
299
|
+
pushPoint(cmd.to[0], cmd.to[1], cmd.r);
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
if (cmd.type === 'line') {
|
|
303
|
+
const [x1, y1, r1] = cmd.from;
|
|
304
|
+
const [x2, y2, r2] = cmd.to;
|
|
305
|
+
for (let step = 1; step <= samplesPerSegment; step += 1) {
|
|
306
|
+
const t = step / samplesPerSegment;
|
|
307
|
+
pushPoint(lerp(x1, x2, t), lerp(y1, y2, t), lerp(r1, r2, t));
|
|
308
|
+
}
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (cmd.type === 'cubic') {
|
|
312
|
+
const [x0, y0, r0] = cmd.from;
|
|
313
|
+
const [x1, y1] = cmd.cp1;
|
|
314
|
+
const [x2, y2] = cmd.cp2;
|
|
315
|
+
const [x3, y3, r3] = cmd.to;
|
|
316
|
+
for (let step = 1; step <= samplesPerSegment; step += 1) {
|
|
317
|
+
const t = step / samplesPerSegment;
|
|
318
|
+
pushPoint(cubic(x0, x1, x2, x3, t), cubic(y0, y1, y2, y3, t), lerp(r0, r3, t));
|
|
319
|
+
}
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (cmd.type === 'quad') {
|
|
323
|
+
const [x0, y0, r0] = cmd.from;
|
|
324
|
+
const [cx, cy] = cmd.cp;
|
|
325
|
+
const [x1, y1, r1] = cmd.to;
|
|
326
|
+
for (let step = 1; step <= samplesPerSegment; step += 1) {
|
|
327
|
+
const t = step / samplesPerSegment;
|
|
328
|
+
pushPoint(quad(x0, cx, x1, t), quad(y0, cy, y1, t), lerp(r0, r1, t));
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
function cubic(p0, p1, p2, p3, t) {
|
|
335
|
+
const it = 1 - t;
|
|
336
|
+
return it * it * it * p0 + 3 * it * it * t * p1 + 3 * it * t * t * p2 + t * t * t * p3;
|
|
337
|
+
}
|
|
338
|
+
function quad(p0, p1, p2, t) {
|
|
339
|
+
const it = 1 - t;
|
|
340
|
+
return it * it * p0 + 2 * it * t * p1 + t * t * p2;
|
|
341
|
+
}
|
|
342
|
+
function lerp(a, b, t) {
|
|
343
|
+
return a + (b - a) * t;
|
|
344
|
+
}
|
|
345
|
+
function estimateSamplesPerSegment(samples, defined) {
|
|
346
|
+
const n = Math.min(samples.length, defined.length);
|
|
347
|
+
let distSum = 0;
|
|
348
|
+
let distCount = 0;
|
|
349
|
+
let rSum = 0;
|
|
350
|
+
let rCount = 0;
|
|
351
|
+
for (let i = 0; i < n; i++) {
|
|
352
|
+
if (defined[i]) {
|
|
353
|
+
rSum += samples[i].r;
|
|
354
|
+
rCount += 1;
|
|
355
|
+
}
|
|
356
|
+
if (i === 0 || !defined[i] || !defined[i - 1])
|
|
357
|
+
continue;
|
|
358
|
+
const dx = samples[i].x - samples[i - 1].x;
|
|
359
|
+
const dy = samples[i].y - samples[i - 1].y;
|
|
360
|
+
const d = Math.hypot(dx, dy);
|
|
361
|
+
if (isFinite(d) && d > 0) {
|
|
362
|
+
distSum += d;
|
|
363
|
+
distCount += 1;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
const meanDist = distCount ? distSum / distCount : 0;
|
|
367
|
+
const meanRadius = rCount ? rSum / rCount : 0;
|
|
368
|
+
const base = meanRadius > 0 ? meanDist / meanRadius : meanDist;
|
|
369
|
+
// Keep within a reasonable range to avoid excessive subdivision.
|
|
370
|
+
return Math.max(1, Math.min(32, Math.round(base || 1)));
|
|
371
|
+
}
|
|
372
|
+
export default trailPath;
|
package/dist/marks/index.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export { default as Spike } from './Spike.svelte';
|
|
|
45
45
|
export { default as Text } from './Text.svelte';
|
|
46
46
|
export { default as TickX } from './TickX.svelte';
|
|
47
47
|
export { default as TickY } from './TickY.svelte';
|
|
48
|
+
export { default as Trail } from './Trail.svelte';
|
|
48
49
|
export { default as Vector } from './Vector.svelte';
|
|
49
50
|
export { default as WaffleX } from './WaffleX.svelte';
|
|
50
51
|
export { default as WaffleY } from './WaffleY.svelte';
|
package/dist/marks/index.js
CHANGED
|
@@ -45,6 +45,7 @@ export { default as Spike } from './Spike.svelte';
|
|
|
45
45
|
export { default as Text } from './Text.svelte';
|
|
46
46
|
export { default as TickX } from './TickX.svelte';
|
|
47
47
|
export { default as TickY } from './TickY.svelte';
|
|
48
|
+
export { default as Trail } from './Trail.svelte';
|
|
48
49
|
export { default as Vector } from './Vector.svelte';
|
|
49
50
|
export { default as WaffleX } from './WaffleX.svelte';
|
|
50
51
|
export { default as WaffleY } from './WaffleY.svelte';
|
|
@@ -37,6 +37,7 @@ export declare function bollingerDim(dim: 'x' | 'y', { data, ...channels }: Tran
|
|
|
37
37
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
38
38
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
39
39
|
clipPath?: string | undefined;
|
|
40
|
+
mask?: string | undefined;
|
|
40
41
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
41
42
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
42
43
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -27,6 +27,7 @@ export declare function intervalX<T>(args: TransformArg<T>, { plot }: {
|
|
|
27
27
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, T>;
|
|
28
28
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, T>;
|
|
29
29
|
clipPath?: string | undefined;
|
|
30
|
+
mask?: string | undefined;
|
|
30
31
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
31
32
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, T>;
|
|
32
33
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
@@ -93,6 +94,7 @@ export declare function intervalY<T>(args: TransformArg<T>, { plot }: {
|
|
|
93
94
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, T>;
|
|
94
95
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, T>;
|
|
95
96
|
clipPath?: string | undefined;
|
|
97
|
+
mask?: string | undefined;
|
|
96
98
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
97
99
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, T>;
|
|
98
100
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
@@ -31,6 +31,7 @@ export declare function select({ data, ...channels }: TransformArg<DataRecord>,
|
|
|
31
31
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
32
32
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
33
33
|
clipPath?: string | undefined;
|
|
34
|
+
mask?: string | undefined;
|
|
34
35
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
35
36
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
36
37
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -98,6 +99,7 @@ export declare function selectFirst(args: TransformArg<DataRecord>): {
|
|
|
98
99
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
99
100
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
100
101
|
clipPath?: string | undefined;
|
|
102
|
+
mask?: string | undefined;
|
|
101
103
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
102
104
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
103
105
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -165,6 +167,7 @@ export declare function selectLast(args: TransformArg<DataRecord>): {
|
|
|
165
167
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
166
168
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
167
169
|
clipPath?: string | undefined;
|
|
170
|
+
mask?: string | undefined;
|
|
168
171
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
169
172
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
170
173
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -229,6 +232,7 @@ export declare function selectMinX(args: TransformArg<DataRecord>): {
|
|
|
229
232
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
230
233
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
231
234
|
clipPath?: string | undefined;
|
|
235
|
+
mask?: string | undefined;
|
|
232
236
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
233
237
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
234
238
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -293,6 +297,7 @@ export declare function selectMaxX(args: TransformArg<DataRecord>): {
|
|
|
293
297
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
294
298
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
295
299
|
clipPath?: string | undefined;
|
|
300
|
+
mask?: string | undefined;
|
|
296
301
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
297
302
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
298
303
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -357,6 +362,7 @@ export declare function selectMinY(args: TransformArg<DataRecord>): {
|
|
|
357
362
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
358
363
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
359
364
|
clipPath?: string | undefined;
|
|
365
|
+
mask?: string | undefined;
|
|
360
366
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
361
367
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
362
368
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -421,6 +427,7 @@ export declare function selectMaxY(args: TransformArg<DataRecord>): {
|
|
|
421
427
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
422
428
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
423
429
|
clipPath?: string | undefined;
|
|
430
|
+
mask?: string | undefined;
|
|
424
431
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
425
432
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
426
433
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -27,6 +27,7 @@ export declare function sort<T>({ data, ...channels }: TransformArg<T>, options?
|
|
|
27
27
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, T>;
|
|
28
28
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, T>;
|
|
29
29
|
clipPath?: string | undefined;
|
|
30
|
+
mask?: string | undefined;
|
|
30
31
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
31
32
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, T>;
|
|
32
33
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
@@ -92,6 +93,7 @@ export declare function sort<T>({ data, ...channels }: TransformArg<T>, options?
|
|
|
92
93
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, T>;
|
|
93
94
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, T>;
|
|
94
95
|
clipPath?: string | undefined;
|
|
96
|
+
mask?: string | undefined;
|
|
95
97
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
96
98
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, T>;
|
|
97
99
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, T>;
|
|
@@ -159,6 +161,7 @@ export declare function shuffle({ data, ...channels }: TransformArg<DataRow[]>,
|
|
|
159
161
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, DataRow[]>;
|
|
160
162
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, DataRow[]>;
|
|
161
163
|
clipPath?: string | undefined;
|
|
164
|
+
mask?: string | undefined;
|
|
162
165
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, DataRow[]>;
|
|
163
166
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, DataRow[]>;
|
|
164
167
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, DataRow[]>;
|
|
@@ -224,6 +227,7 @@ export declare function reverse({ data, ...channels }: TransformArg<DataRow[]>):
|
|
|
224
227
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, DataRow[]>;
|
|
225
228
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, DataRow[]>;
|
|
226
229
|
clipPath?: string | undefined;
|
|
230
|
+
mask?: string | undefined;
|
|
227
231
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, DataRow[]>;
|
|
228
232
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, DataRow[]>;
|
|
229
233
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, DataRow[]>;
|
|
@@ -33,6 +33,7 @@ export declare function windowX(args: TransformArg<DataRecord>, options: WindowO
|
|
|
33
33
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
34
34
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
35
35
|
clipPath?: string | undefined;
|
|
36
|
+
mask?: string | undefined;
|
|
36
37
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
37
38
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
38
39
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
@@ -100,6 +101,7 @@ export declare function windowY(args: TransformArg<DataRecord>, options: WindowO
|
|
|
100
101
|
strokeDashoffset?: import("../types/index.js").ConstantAccessor<number, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
101
102
|
mixBlendMode?: import("../types/index.js").ConstantAccessor<import("csstype").Property.MixBlendMode, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
102
103
|
clipPath?: string | undefined;
|
|
104
|
+
mask?: string | undefined;
|
|
103
105
|
imageFilter?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
104
106
|
shapeRendering?: import("../types/index.js").ConstantAccessor<import("csstype").Property.ShapeRendering, Record<string | symbol, import("../types/index.js").RawValue>>;
|
|
105
107
|
paintOrder?: import("../types/index.js").ConstantAccessor<string, Record<string | symbol, import("../types/index.js").RawValue>>;
|
package/dist/types/mark.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type Mark<T> = {
|
|
|
6
6
|
data: DataRecord<T>[];
|
|
7
7
|
options: T;
|
|
8
8
|
};
|
|
9
|
-
export type MarkType = 'area' | 'arrow' | 'barX' | 'barY' | 'cell' | 'custom' | 'dot' | 'vector' | 'frame' | 'geo' | 'gridX' | 'gridY' | 'line' | 'rect' | 'regression' | 'ruleX' | 'ruleY' | 'swoopyArrow' | 'text' | 'tickX' | 'tickY' | 'waffleX' | 'waffleY';
|
|
9
|
+
export type MarkType = 'area' | 'arrow' | 'barX' | 'barY' | 'cell' | 'custom' | 'dot' | 'vector' | 'frame' | 'geo' | 'gridX' | 'gridY' | 'line' | 'rect' | 'regression' | 'ruleX' | 'ruleY' | 'swoopyArrow' | 'text' | 'tickX' | 'tickY' | 'trail' | 'waffleX' | 'waffleY';
|
|
10
10
|
export type MarkStyleProps = 'strokeDasharray' | 'strokeLinejoin' | 'strokeLinecap' | 'opacity' | 'cursor' | 'pointerEvents' | 'blend' | 'fill' | 'fillOpacity' | 'fontFamily' | 'fontWeight' | 'fontVariant' | 'fontSize' | 'fontStyle' | 'letterSpacing' | 'wordSpacing' | 'stroke' | 'strokeWidth' | 'strokeOpacity' | 'x' | 'y' | 'clipPath' | 'mask' | 'filter' | 'angle' | 'radius' | 'symbol' | 'textAnchor' | 'textTransform' | 'textDecoration' | 'width';
|
|
11
11
|
import type { MouseEventHandler } from 'svelte/elements';
|
|
12
12
|
import type { ChannelAccessor, ConstantAccessor, DataRecord, RawValue } from './index.js';
|
|
@@ -44,6 +44,7 @@ export type BaseMarkProps<T> = Partial<{
|
|
|
44
44
|
strokeDashoffset: ConstantAccessor<number, T>;
|
|
45
45
|
mixBlendMode: ConstantAccessor<CSS.Property.MixBlendMode, T>;
|
|
46
46
|
clipPath: string;
|
|
47
|
+
mask: string;
|
|
47
48
|
imageFilter: ConstantAccessor<string, T>;
|
|
48
49
|
shapeRendering: ConstantAccessor<CSS.Property.ShapeRendering, T>;
|
|
49
50
|
paintOrder: ConstantAccessor<string, T>;
|
package/dist/types/plot.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ColorScheme } from './colorScheme.js';
|
|
|
3
3
|
import type { GeoProjection } from 'd3-geo';
|
|
4
4
|
import type { ChannelAccessor, ChannelName, ColorScaleOptions, DataRecord, LegendScaleOptions, PlotScales, RawValue, ScaleOptions, XScaleOptions, YScaleOptions } from './index.js';
|
|
5
5
|
import type { Snippet } from 'svelte';
|
|
6
|
-
import type { Area, AreaX, AreaY, Arrow, AxisX, AxisY, BarX, BarY, BoxX, BoxY, Brush, BrushX, BrushY, Cell, DifferenceY, Dot, Frame, Geo, Graticule, GridX, GridY, Image, Line, Link, Pointer, Rect, RectX, RectY, RuleX, RuleY, Sphere, Spike, Text, TickX, TickY, Vector } from '../marks/index.js';
|
|
6
|
+
import type { Area, AreaX, AreaY, Arrow, AxisX, AxisY, BarX, BarY, BoxX, BoxY, Brush, BrushX, BrushY, Cell, DifferenceY, Dot, Frame, Geo, Graticule, GridX, GridY, Image, Line, Link, Pointer, Rect, RectX, RectY, RuleX, RuleY, Sphere, Spike, Text, TickX, TickY, Trail, Vector } from '../marks/index.js';
|
|
7
7
|
import type WaffleX from '../marks/WaffleX.svelte';
|
|
8
8
|
import type WaffleY from '../marks/WaffleY.svelte';
|
|
9
9
|
export type PlotState = {
|
|
@@ -26,6 +26,7 @@ export type PlotState = {
|
|
|
26
26
|
*/
|
|
27
27
|
hasFilledDotMarks: boolean;
|
|
28
28
|
css: ((d: string) => string) | null;
|
|
29
|
+
publicState: Readonly<PlotState>;
|
|
29
30
|
};
|
|
30
31
|
export type PlotContext = {
|
|
31
32
|
/**
|
|
@@ -296,6 +297,10 @@ export type PlotDefaults = {
|
|
|
296
297
|
* default props for tickY marks
|
|
297
298
|
*/
|
|
298
299
|
tickY: Partial<Omit<ComponentProps<typeof TickY>, IgnoreDefaults>>;
|
|
300
|
+
/**
|
|
301
|
+
* default props for tickY marks
|
|
302
|
+
*/
|
|
303
|
+
trail: Partial<Omit<ComponentProps<typeof Trail>, IgnoreDefaults>>;
|
|
299
304
|
/**
|
|
300
305
|
* default props for vector marks
|
|
301
306
|
*/
|
package/dist/ui/Spiral.svelte
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { usePlot } from '../hooks/usePlot.svelte';
|
|
3
|
+
|
|
2
4
|
let { numTurns = 4, finalRadius = 10, duration = 2, ...restProps } = $props();
|
|
3
5
|
|
|
6
|
+
const plot = usePlot();
|
|
7
|
+
|
|
4
8
|
const pathD = $derived.by(() => {
|
|
5
9
|
const numPoints = 100;
|
|
6
10
|
const k = finalRadius / (2 * Math.PI * numTurns);
|