@fjader/svelte 0.2.3 → 0.2.5
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 +3 -1
- package/dist/animation/EntranceGate.d.ts +52 -0
- package/dist/animation/EntranceGate.js +93 -0
- package/dist/animation/TransitionClock.d.ts +61 -30
- package/dist/animation/TransitionClock.js +67 -29
- package/dist/animation/transition-log.d.ts +41 -0
- package/dist/animation/transition-log.js +57 -0
- package/dist/components/axes/AxisBottom.svelte +27 -8
- package/dist/components/axes/AxisBottom.svelte.d.ts +10 -0
- package/dist/components/axes/AxisCenter.svelte +4 -2
- package/dist/components/axes/AxisLeft.svelte +81 -10
- package/dist/components/axes/AxisLeft.svelte.d.ts +17 -0
- package/dist/components/axes/BandAxisTicks.svelte +4 -3
- package/dist/components/axes/axis-title.d.ts +30 -0
- package/dist/components/axes/axis-title.js +77 -0
- package/dist/components/charts/ChartCell.svelte +33 -6
- package/dist/components/charts/ChartCell.svelte.d.ts +9 -0
- package/dist/components/charts/ChartContainer.svelte +55 -5
- package/dist/components/charts/ChartContainer.svelte.d.ts +14 -1
- package/dist/components/charts/ChartHover.svelte.d.ts +14 -0
- package/dist/components/charts/ChartHover.svelte.js +22 -0
- package/dist/components/charts/ChartVisibility.svelte.d.ts +43 -0
- package/dist/components/charts/ChartVisibility.svelte.js +67 -0
- package/dist/components/guides/Grid.svelte +12 -1
- package/dist/components/guides/legend/ContinuousColorLegend.svelte +7 -1
- package/dist/components/guides/legend/OrdinalColorLegend.svelte +8 -5
- package/dist/components/marks/AreaMarkX.svelte +18 -4
- package/dist/components/marks/AreaMarkY.svelte +18 -4
- package/dist/components/marks/BarMarkX.svelte +20 -4
- package/dist/components/marks/BarMarkY.svelte +20 -4
- package/dist/components/marks/DotsMark.svelte +8 -3
- package/dist/components/marks/LineMark.svelte +13 -6
- package/dist/components/marks/ParallelCoordinatesMark.svelte +11 -2
- package/dist/components/marks/ParallelCoordinatesMark.svelte.d.ts +4 -0
- package/dist/components/marks/RectMark.svelte +8 -3
- package/dist/components/marks/RectXMark.svelte +9 -3
- package/dist/components/marks/RectYMark.svelte +9 -3
- package/dist/components/marks/RuleMarkX.svelte +31 -25
- package/dist/components/marks/RuleMarkY.svelte +31 -25
- package/dist/components/marks/TextMark.svelte +52 -14
- package/dist/components/marks/lifecycle/MarkLifecycleV2.svelte.d.ts +22 -1
- package/dist/components/marks/lifecycle/MarkLifecycleV2.svelte.js +579 -66
- package/dist/components/marks/lifecycle/domain-queries.d.ts +13 -2
- package/dist/components/marks/lifecycle/domain-queries.js +43 -11
- package/dist/components/marks/lifecycle/domain-registration.d.ts +6 -1
- package/dist/components/marks/lifecycle/domain-registration.js +17 -20
- package/dist/components/marks/lifecycle/other-rows.svelte.d.ts +112 -0
- package/dist/components/marks/lifecycle/other-rows.svelte.js +193 -0
- package/dist/components/marks/lifecycle/other-split.d.ts +80 -0
- package/dist/components/marks/lifecycle/other-split.js +112 -0
- package/dist/components/marks/lifecycle/query-builder.d.ts +53 -3
- package/dist/components/marks/lifecycle/query-builder.js +46 -23
- package/dist/components/marks/utils/MarkColor.svelte.d.ts +3 -1
- package/dist/components/marks/utils/MarkColor.svelte.js +33 -3
- package/dist/components/marks/utils/MarkSeries.svelte.d.ts +14 -1
- package/dist/components/marks/utils/MarkSeries.svelte.js +25 -1
- package/dist/components/marks/utils/MarkSize.svelte.js +4 -0
- package/dist/components/marks/utils/reactive-config.d.ts +1 -1
- package/dist/components/marks/utils/reactive-config.js +9 -0
- package/dist/components/marks/utils/tooltip-helpers.d.ts +4 -1
- package/dist/components/marks/utils/tooltip-helpers.js +2 -1
- package/dist/components/rendering/Areas.svelte +57 -19
- package/dist/components/rendering/Areas.svelte.d.ts +12 -0
- package/dist/components/rendering/BaseGPURenderer.svelte.d.ts +3 -1
- package/dist/components/rendering/BaseGPURenderer.svelte.js +4 -2
- package/dist/components/rendering/Dots.svelte +23 -3
- package/dist/components/rendering/Dots.svelte.d.ts +6 -0
- package/dist/components/rendering/GridLine.svelte +13 -1
- package/dist/components/rendering/GridLine.svelte.d.ts +5 -0
- package/dist/components/rendering/Lines.svelte +48 -13
- package/dist/components/rendering/Lines.svelte.d.ts +12 -0
- package/dist/components/rendering/ParallelLines.svelte +5 -5
- package/dist/components/rendering/Rects.svelte +164 -30
- package/dist/components/rendering/Rects.svelte.d.ts +23 -2
- package/dist/components/rendering/RuleX.svelte +1 -1
- package/dist/components/rendering/RuleY.svelte +1 -1
- package/dist/components/rendering/WebGPUCanvas.svelte +4 -2
- package/dist/components/rendering/activity-reads.d.ts +47 -12
- package/dist/components/rendering/activity-reads.js +61 -19
- package/dist/components/rendering/uniform-sizes.d.ts +1 -1
- package/dist/components/rendering/uniform-sizes.js +1 -1
- package/dist/config/ChartConfig.svelte.d.ts +10 -1
- package/dist/config/ChartConfig.svelte.js +17 -0
- package/dist/gpu/GPUCoordinator.svelte.d.ts +31 -1
- package/dist/gpu/GPUCoordinator.svelte.js +164 -7
- package/dist/gpu/MorphedChannels.d.ts +11 -28
- package/dist/gpu/MorphedChannels.js +72 -8
- package/dist/gpu/ScaleTemplateSystem.d.ts +20 -2
- package/dist/gpu/ScaleTemplateSystem.js +83 -6
- package/dist/index.d.ts +19 -4
- package/dist/index.js +22 -4
- package/dist/interactors/Interval1D.svelte +6 -1
- package/dist/interactors/Interval2D.svelte +6 -1
- package/dist/interactors/ParallelAxisSource.svelte +10 -1
- package/dist/interactors/Toggle.svelte +32 -3
- package/dist/interactors/Tooltip.svelte +138 -41
- package/dist/interactors/TooltipManager.svelte.d.ts +20 -5
- package/dist/interactors/TooltipManager.svelte.js +46 -12
- package/dist/interactors/other-tooltip.d.ts +16 -0
- package/dist/interactors/other-tooltip.js +22 -0
- package/dist/query-engine/CrossfilterSelection.svelte.d.ts +4 -2
- package/dist/query-engine/CrossfilterSelection.svelte.js +2 -0
- package/dist/query-engine/FieldActivity.svelte.d.ts +49 -1
- package/dist/query-engine/FieldActivity.svelte.js +175 -5
- package/dist/query-engine/FilterGroup.svelte.d.ts +23 -1
- package/dist/query-engine/FilterGroup.svelte.js +43 -3
- package/dist/query-engine/FilterGroupRegistry.svelte.d.ts +31 -3
- package/dist/query-engine/FilterGroupRegistry.svelte.js +62 -15
- package/dist/query-engine/MarkHandle.svelte.d.ts +28 -1
- package/dist/query-engine/MarkHandle.svelte.js +33 -1
- package/dist/query-engine/QueryEngine.d.ts +225 -5
- package/dist/query-engine/QueryEngine.js +697 -47
- package/dist/query-engine/categorical-identity.d.ts +41 -0
- package/dist/query-engine/categorical-identity.js +145 -65
- package/dist/query-engine/debug/query-log.d.ts +39 -0
- package/dist/query-engine/debug/query-log.js +90 -0
- package/dist/query-engine/duckdb.d.ts +55 -8
- package/dist/query-engine/duckdb.js +82 -30
- package/dist/query-engine/index.d.ts +7 -4
- package/dist/query-engine/index.js +3 -3
- package/dist/query-engine/preagg/BuildQueue.d.ts +33 -13
- package/dist/query-engine/preagg/BuildQueue.js +51 -15
- package/dist/query-engine/preagg/Preagg.d.ts +46 -3
- package/dist/query-engine/preagg/Preagg.js +159 -31
- package/dist/query-engine/preagg/plan.d.ts +33 -1
- package/dist/query-engine/preagg/plan.js +158 -14
- package/dist/query-engine/sliced-lane.d.ts +108 -0
- package/dist/query-engine/sliced-lane.js +299 -0
- package/dist/query-engine/source-routing.d.ts +106 -0
- package/dist/query-engine/source-routing.js +189 -0
- package/dist/query-engine/toggle-predicate.d.ts +21 -0
- package/dist/query-engine/toggle-predicate.js +29 -1
- package/dist/scales/ActivityTable.d.ts +5 -1
- package/dist/scales/ActivityTable.js +12 -3
- package/dist/scales/BandScaleState.svelte.d.ts +22 -9
- package/dist/scales/BandScaleState.svelte.js +39 -21
- package/dist/scales/ChartScales.svelte.d.ts +3 -0
- package/dist/scales/ChartScales.svelte.js +26 -8
- package/dist/scales/ColorScaleState.svelte.d.ts +18 -2
- package/dist/scales/ColorScaleState.svelte.js +138 -26
- package/dist/scales/LinearScaleState.svelte.d.ts +7 -10
- package/dist/scales/LinearScaleState.svelte.js +21 -39
- package/dist/scales/ScaleGeneration.svelte.d.ts +48 -0
- package/dist/scales/ScaleGeneration.svelte.js +42 -0
- package/dist/scales/ScaleRegistry.svelte.js +3 -1
- package/dist/scales/SlotTransition.d.ts +15 -1
- package/dist/scales/SlotTransition.js +33 -4
- package/dist/scales/TimeScaleState.svelte.d.ts +7 -3
- package/dist/scales/TimeScaleState.svelte.js +7 -7
- package/dist/scales/color-utils.d.ts +0 -3
- package/dist/scales/color-utils.js +0 -3
- package/dist/scales/entered.d.ts +8 -0
- package/dist/scales/entered.js +10 -0
- package/dist/spec/LazyQueryEngine.js +2 -19
- package/dist/spec/MarkRegistry.d.ts +3 -1
- package/dist/spec/MarkRegistry.js +13 -1
- package/dist/spec/PlotFromSpec.svelte +1 -0
- package/dist/spec/export.js +11 -2
- package/dist/spec/types.d.ts +43 -13
- package/dist/sql/bin.d.ts +25 -0
- package/dist/sql/bin.js +108 -5
- package/dist/theme.css +5 -4
- package/dist/transforms/TransformCompiler.d.ts +47 -2
- package/dist/transforms/TransformCompiler.js +70 -1
- package/dist/transforms/index.js +176 -42
- package/dist/types.d.ts +177 -2
- package/package.json +4 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { activityReads,
|
|
2
|
+
import { activityReads, connectedActivityWGSL } from './activity-reads';
|
|
3
3
|
import { UNIFORM_BYTES } from './uniform-sizes';
|
|
4
4
|
import { getContext, onMount, onDestroy } from 'svelte';
|
|
5
5
|
import { RendererHost } from './RendererHost.svelte';
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
DOT_RADIUS: 36, // f32
|
|
39
39
|
SHOW_BOTTOM_DOTS: 40, // u32 (0 or 1)
|
|
40
40
|
FULL_DOMAIN_SPAN: 44, // f32
|
|
41
|
-
GROUP_INDEX: 48 // u32
|
|
41
|
+
GROUP_INDEX: 48, // u32
|
|
42
|
+
ACTIVITY_SERIES_MODE: 52, // u32
|
|
43
|
+
ACTIVITY_SERIES_SCALE_INDEX: 56, // u32
|
|
44
|
+
ENTRANCE_AXIS: 60 // u32 (0 fades, 1 grows along x, 2 along y)
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
interface Props {
|
|
@@ -60,8 +63,20 @@
|
|
|
60
63
|
colorScaleIndex?: number;
|
|
61
64
|
/** The page-wide index of this mark's filter group: which run of a field's activity block it reads. */
|
|
62
65
|
groupIndex?: number;
|
|
66
|
+
/**
|
|
67
|
+
* The series scale selection activity is also read through, from
|
|
68
|
+
* `seriesData`: mode 1 and its index when the mark groups by a `z` of
|
|
69
|
+
* its own, mode 0 (no read) otherwise. MarkSeries decides.
|
|
70
|
+
*/
|
|
71
|
+
activitySeriesMode?: number;
|
|
72
|
+
activitySeriesScaleIndex?: number;
|
|
63
73
|
constantColor?: [number, number, number, number];
|
|
64
74
|
markId?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Whether the area grows from 0 along its measure axis when its chart
|
|
77
|
+
* enters. False fades it in, for a band with bounds of its own.
|
|
78
|
+
*/
|
|
79
|
+
grow?: boolean;
|
|
65
80
|
}
|
|
66
81
|
|
|
67
82
|
let {
|
|
@@ -82,8 +97,11 @@
|
|
|
82
97
|
colorMode = 0,
|
|
83
98
|
colorScaleIndex = 0,
|
|
84
99
|
groupIndex = 0,
|
|
100
|
+
activitySeriesMode = 0,
|
|
101
|
+
activitySeriesScaleIndex = 0,
|
|
85
102
|
constantColor = DEFAULT_FILL_COLOR,
|
|
86
|
-
markId = ''
|
|
103
|
+
markId = '',
|
|
104
|
+
grow = false
|
|
87
105
|
}: Props = $props();
|
|
88
106
|
|
|
89
107
|
const chartContext = getContext<ChartContext>('chart');
|
|
@@ -152,9 +170,11 @@
|
|
|
152
170
|
showBottomDots: u32,
|
|
153
171
|
fullDomainSpan: f32,
|
|
154
172
|
groupIndex: u32, // Page-wide filter group index, for activity reads
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
173
|
+
// The series scale selection activity is also read through, for a z of
|
|
174
|
+
// its own; mode 0 reads nothing.
|
|
175
|
+
activitySeriesMode: u32,
|
|
176
|
+
activitySeriesScaleIndex: u32,
|
|
177
|
+
entranceAxis: u32 // 0 fades in, 1 grows along x, 2 along y
|
|
158
178
|
};
|
|
159
179
|
@group(1) @binding(5) var<uniform> markConstants: MarkConstants;
|
|
160
180
|
|
|
@@ -186,6 +206,12 @@
|
|
|
186
206
|
}
|
|
187
207
|
}
|
|
188
208
|
|
|
209
|
+
// A point projected to pixels as it is during the chart's entrance: pulled
|
|
210
|
+
// toward 0 on the measure axis while the area grows.
|
|
211
|
+
fn enterPx(p: vec2<f32>) -> vec2<f32> {
|
|
212
|
+
return entrancePosition(projectToPixels(p), markConstants.entranceAxis);
|
|
213
|
+
}
|
|
214
|
+
|
|
189
215
|
const DISCARD_POS = vec4<f32>(2.0, 2.0, 2.0, 1.0);
|
|
190
216
|
|
|
191
217
|
@vertex
|
|
@@ -220,7 +246,7 @@
|
|
|
220
246
|
output.position = DISCARD_POS;
|
|
221
247
|
return output;
|
|
222
248
|
}
|
|
223
|
-
let center =
|
|
249
|
+
let center = enterPx(makePoint(dim, boundary));
|
|
224
250
|
|
|
225
251
|
var circleR: f32;
|
|
226
252
|
if (markConstants.dotRadius < 0.0) {
|
|
@@ -254,9 +280,11 @@
|
|
|
254
280
|
var output: VertexOutput;
|
|
255
281
|
output.position = pixelsToClip(pos);
|
|
256
282
|
output.colorValue = colorValues[instanceIdx];
|
|
257
|
-
output.alpha = selectionDim(
|
|
258
|
-
${
|
|
283
|
+
output.alpha = entranceAlpha(markConstants.entranceAxis) * selectionDim(
|
|
284
|
+
${connectedActivityWGSL(ACTIVITY_READS, {
|
|
259
285
|
color: 'markConstants.colorMode, markConstants.colorScaleIndex, colorValues[instanceIdx]',
|
|
286
|
+
series:
|
|
287
|
+
'markConstants.activitySeriesMode, markConstants.activitySeriesScaleIndex, seriesValues[instanceIdx]',
|
|
260
288
|
group: 'markConstants.groupIndex'
|
|
261
289
|
})}
|
|
262
290
|
);
|
|
@@ -304,10 +332,10 @@
|
|
|
304
332
|
}
|
|
305
333
|
|
|
306
334
|
// Project segment endpoints for adaptive resolution
|
|
307
|
-
let topPxCurr =
|
|
308
|
-
let topPxNext =
|
|
309
|
-
let botPxCurr =
|
|
310
|
-
let botPxNext =
|
|
335
|
+
let topPxCurr = enterPx(makePoint(dimCurr, topCurr));
|
|
336
|
+
let topPxNext = enterPx(makePoint(dimNext, topNext));
|
|
337
|
+
let botPxCurr = enterPx(makePoint(dimCurr, botCurr));
|
|
338
|
+
let botPxNext = enterPx(makePoint(dimNext, botNext));
|
|
311
339
|
|
|
312
340
|
// Adaptive sub-segment resolution: more segments for longer pixel spans.
|
|
313
341
|
// Use the longer of top/bottom chord for resolution calculation.
|
|
@@ -336,10 +364,10 @@
|
|
|
336
364
|
let dimPrev = dimValues[prevIdx];
|
|
337
365
|
let dimAfter = dimValues[afterIdx];
|
|
338
366
|
|
|
339
|
-
let topPxPrev =
|
|
340
|
-
let topPxAfter =
|
|
341
|
-
let botPxPrev =
|
|
342
|
-
let botPxAfter =
|
|
367
|
+
let topPxPrev = enterPx(makePoint(dimPrev, topValues[prevIdx]));
|
|
368
|
+
let topPxAfter = enterPx(makePoint(dimAfter, topValues[afterIdx]));
|
|
369
|
+
let botPxPrev = enterPx(makePoint(dimPrev, bottomValues[prevIdx]));
|
|
370
|
+
let botPxAfter = enterPx(makePoint(dimAfter, bottomValues[afterIdx]));
|
|
343
371
|
|
|
344
372
|
// Compute t for this vertex from effective resolution (not geometry buffer)
|
|
345
373
|
let subSegSize = 1.0 / f32(effectiveRes);
|
|
@@ -359,9 +387,11 @@
|
|
|
359
387
|
var output: VertexOutput;
|
|
360
388
|
output.position = pixelsToClip(finalPos);
|
|
361
389
|
output.colorValue = colorValues[currIdx];
|
|
362
|
-
output.alpha = markConstants.fillOpacity * selectionDim(
|
|
363
|
-
${
|
|
390
|
+
output.alpha = markConstants.fillOpacity * entranceAlpha(markConstants.entranceAxis) * selectionDim(
|
|
391
|
+
${connectedActivityWGSL(ACTIVITY_READS, {
|
|
364
392
|
color: 'markConstants.colorMode, markConstants.colorScaleIndex, colorValues[currIdx]',
|
|
393
|
+
series:
|
|
394
|
+
'markConstants.activitySeriesMode, markConstants.activitySeriesScaleIndex, seriesValues[currIdx]',
|
|
365
395
|
group: 'markConstants.groupIndex'
|
|
366
396
|
})}
|
|
367
397
|
);
|
|
@@ -471,7 +501,15 @@
|
|
|
471
501
|
view.setUint32(UNIFORM_OFFSETS.COLOR_MODE, colorMode, LE);
|
|
472
502
|
view.setUint32(UNIFORM_OFFSETS.COLOR_SCALE_INDEX, colorScaleIndex, LE);
|
|
473
503
|
view.setUint32(UNIFORM_OFFSETS.GROUP_INDEX, groupIndex, LE);
|
|
504
|
+
view.setUint32(UNIFORM_OFFSETS.ACTIVITY_SERIES_MODE, activitySeriesMode, LE);
|
|
505
|
+
view.setUint32(UNIFORM_OFFSETS.ACTIVITY_SERIES_SCALE_INDEX, activitySeriesScaleIndex, LE);
|
|
474
506
|
view.setUint32(UNIFORM_OFFSETS.ORIENTATION, orientation === 'horizontal' ? 1 : 0, LE);
|
|
507
|
+
// Grows along the boundary axis: y for a vertical area, x for a horizontal one.
|
|
508
|
+
view.setUint32(
|
|
509
|
+
UNIFORM_OFFSETS.ENTRANCE_AXIS,
|
|
510
|
+
grow ? (orientation === 'horizontal' ? 1 : 2) : 0,
|
|
511
|
+
LE
|
|
512
|
+
);
|
|
475
513
|
view.setFloat32(UNIFORM_OFFSETS.CONSTANT_COLOR + 0, constantColor[0], LE);
|
|
476
514
|
view.setFloat32(UNIFORM_OFFSETS.CONSTANT_COLOR + 4, constantColor[1], LE);
|
|
477
515
|
view.setFloat32(UNIFORM_OFFSETS.CONSTANT_COLOR + 8, constantColor[2], LE);
|
|
@@ -18,8 +18,20 @@ interface Props {
|
|
|
18
18
|
colorScaleIndex?: number;
|
|
19
19
|
/** The page-wide index of this mark's filter group: which run of a field's activity block it reads. */
|
|
20
20
|
groupIndex?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The series scale selection activity is also read through, from
|
|
23
|
+
* `seriesData`: mode 1 and its index when the mark groups by a `z` of
|
|
24
|
+
* its own, mode 0 (no read) otherwise. MarkSeries decides.
|
|
25
|
+
*/
|
|
26
|
+
activitySeriesMode?: number;
|
|
27
|
+
activitySeriesScaleIndex?: number;
|
|
21
28
|
constantColor?: [number, number, number, number];
|
|
22
29
|
markId?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Whether the area grows from 0 along its measure axis when its chart
|
|
32
|
+
* enters. False fades it in, for a band with bounds of its own.
|
|
33
|
+
*/
|
|
34
|
+
grow?: boolean;
|
|
23
35
|
}
|
|
24
36
|
declare const Areas: import("svelte").Component<Props, {}, "">;
|
|
25
37
|
type Areas = ReturnType<typeof Areas>;
|
|
@@ -57,7 +57,9 @@ export declare class BaseGPURenderer {
|
|
|
57
57
|
* the band axis's scale is whose clock these channels adopt. See
|
|
58
58
|
* MorphedChannels for the fold, the snap and the clock.
|
|
59
59
|
*/
|
|
60
|
-
writeMorphed(bandAxis: 'x' | 'y', bandIds: ArrayLike<number>, channels: readonly (readonly [number, AllowSharedBufferSource])[]
|
|
60
|
+
writeMorphed(bandAxis: 'x' | 'y', bandIds: ArrayLike<number>, channels: readonly (readonly [number, AllowSharedBufferSource])[],
|
|
61
|
+
/** Bindings that land at once rather than travel (see MorphedChannels.write). */
|
|
62
|
+
land?: readonly number[] | 'all'): void;
|
|
61
63
|
/**
|
|
62
64
|
* Write data to a uniform binding.
|
|
63
65
|
*/
|
|
@@ -242,7 +242,9 @@ export class BaseGPURenderer {
|
|
|
242
242
|
* the band axis's scale is whose clock these channels adopt. See
|
|
243
243
|
* MorphedChannels for the fold, the snap and the clock.
|
|
244
244
|
*/
|
|
245
|
-
writeMorphed(bandAxis, bandIds, channels
|
|
245
|
+
writeMorphed(bandAxis, bandIds, channels,
|
|
246
|
+
/** Bindings that land at once rather than travel (see MorphedChannels.write). */
|
|
247
|
+
land) {
|
|
246
248
|
if (!this.#device)
|
|
247
249
|
return;
|
|
248
250
|
if (!MorphedChannels.supported) {
|
|
@@ -283,7 +285,7 @@ export class BaseGPURenderer {
|
|
|
283
285
|
}
|
|
284
286
|
}
|
|
285
287
|
this.#morphAxis = bandAxis;
|
|
286
|
-
if (this.#morphed.write(bandIds, channels) || rebind) {
|
|
288
|
+
if (this.#morphed.write(bandIds, channels, land) || rebind) {
|
|
287
289
|
this.#scheduleBindGroupUpdate();
|
|
288
290
|
}
|
|
289
291
|
else if (!this.#bindGroupUpdateScheduled) {
|
|
@@ -43,6 +43,12 @@
|
|
|
43
43
|
alphaData: Float32Array | null;
|
|
44
44
|
facetData?: Float32Array | null;
|
|
45
45
|
dataVersion: number;
|
|
46
|
+
/**
|
|
47
|
+
* The data version whose first write lands without morphing, or 0: a
|
|
48
|
+
* catch-up result (MarkLifecycleV2.landsFor). Later writes of that version
|
|
49
|
+
* animate as usual.
|
|
50
|
+
*/
|
|
51
|
+
landsFor?: number;
|
|
46
52
|
zIndex?: number;
|
|
47
53
|
colorMode?: number;
|
|
48
54
|
colorScaleIndex?: number;
|
|
@@ -74,6 +80,7 @@
|
|
|
74
80
|
alphaData,
|
|
75
81
|
facetData = null,
|
|
76
82
|
dataVersion,
|
|
83
|
+
landsFor = 0,
|
|
77
84
|
zIndex = 0,
|
|
78
85
|
colorMode = 0,
|
|
79
86
|
colorScaleIndex = 0,
|
|
@@ -188,7 +195,7 @@
|
|
|
188
195
|
output.colorValue = colorValue;
|
|
189
196
|
output.uv = quadPosition;
|
|
190
197
|
output.radius = displayRadius;
|
|
191
|
-
output.alpha = alpha * selectionDim(
|
|
198
|
+
output.alpha = alpha * entranceAlpha(0u) * selectionDim(
|
|
192
199
|
${markActivityWGSL(ACTIVITY_READS, {
|
|
193
200
|
color: 'markConstants.colorMode, markConstants.colorScaleIndex, colorValue',
|
|
194
201
|
x: 'x',
|
|
@@ -260,6 +267,18 @@
|
|
|
260
267
|
|
|
261
268
|
// --- WRITING EFFECTS ---
|
|
262
269
|
|
|
270
|
+
// Whether this write lands: the first of the catch-up's data version
|
|
271
|
+
// (landsFor). Plain, not $state: only the write effect reads and sets it.
|
|
272
|
+
// Assumes a catch-up result is ONE morph write: should it ever take two
|
|
273
|
+
// (values, then band ids after the instant layout), the second springs.
|
|
274
|
+
// A morph SPRING right after a morph snap on a return points here.
|
|
275
|
+
let lastMorphedVersion = -1;
|
|
276
|
+
function landsNow(): boolean {
|
|
277
|
+
const first = dataVersion !== lastMorphedVersion;
|
|
278
|
+
lastMorphedVersion = dataVersion;
|
|
279
|
+
return first && landsFor !== 0 && landsFor === dataVersion;
|
|
280
|
+
}
|
|
281
|
+
|
|
263
282
|
// The measure axis's single channel morphs, as ONE write per data update,
|
|
264
283
|
// so one update starts one transition. The band's ids go with it: they are
|
|
265
284
|
// how a row set that is not the one being animated gets noticed and snapped.
|
|
@@ -269,8 +288,9 @@
|
|
|
269
288
|
// design question rather than a consequence of this one.
|
|
270
289
|
$effect(() => {
|
|
271
290
|
if (!renderer?.resourcesCreated || !bandAxis) return;
|
|
272
|
-
|
|
273
|
-
|
|
291
|
+
const land = landsNow() ? 'all' : undefined;
|
|
292
|
+
if (bandAxis === 'x') renderer.writeMorphed('x', xData, [[BINDINGS.Y, yData]], land);
|
|
293
|
+
else renderer.writeMorphed('y', yData, [[BINDINGS.X, xData]], land);
|
|
274
294
|
});
|
|
275
295
|
$effect(() => {
|
|
276
296
|
if (renderer?.resourcesCreated && !morphX) renderer.writeAttribute(BINDINGS.X, xData);
|
|
@@ -6,6 +6,12 @@ interface Props {
|
|
|
6
6
|
alphaData: Float32Array | null;
|
|
7
7
|
facetData?: Float32Array | null;
|
|
8
8
|
dataVersion: number;
|
|
9
|
+
/**
|
|
10
|
+
* The data version whose first write lands without morphing, or 0: a
|
|
11
|
+
* catch-up result (MarkLifecycleV2.landsFor). Later writes of that version
|
|
12
|
+
* animate as usual.
|
|
13
|
+
*/
|
|
14
|
+
landsFor?: number;
|
|
9
15
|
zIndex?: number;
|
|
10
16
|
colorMode?: number;
|
|
11
17
|
colorScaleIndex?: number;
|
|
@@ -44,6 +44,11 @@
|
|
|
44
44
|
* way a bar's height is. Omitted, every line is fully drawn.
|
|
45
45
|
*/
|
|
46
46
|
alpha?: Float32Array | null;
|
|
47
|
+
/**
|
|
48
|
+
* The band layout whose first opacity write lands without morphing, or 0
|
|
49
|
+
* (a layout that landed at once; see BandScaleState.slotsLandedLayout).
|
|
50
|
+
*/
|
|
51
|
+
landsFor?: number;
|
|
47
52
|
/** The band axis these lines belong to, when `alpha` should morph. */
|
|
48
53
|
bandAxis?: 'x' | 'y' | null;
|
|
49
54
|
color?: [number, number, number, number];
|
|
@@ -55,6 +60,7 @@
|
|
|
55
60
|
axis,
|
|
56
61
|
positions,
|
|
57
62
|
alpha = null,
|
|
63
|
+
landsFor = 0,
|
|
58
64
|
bandAxis = null,
|
|
59
65
|
color = [0.8, 0.8, 0.8, 0.3],
|
|
60
66
|
lineWidth = 1,
|
|
@@ -175,9 +181,15 @@ ${placement}
|
|
|
175
181
|
// the positions are that id list — which is what writeMorphed checks rows
|
|
176
182
|
// against.
|
|
177
183
|
const morphs = $derived(!!bandAxis && !!alpha && alpha.length === positions?.length);
|
|
184
|
+
// The landed layout last written; plain, read and set by the write alone.
|
|
185
|
+
let lastLandedLayout = 0;
|
|
178
186
|
$effect(() => {
|
|
179
187
|
if (!renderer?.resourcesCreated || !morphs) return;
|
|
180
|
-
|
|
188
|
+
// Only the first write after that layout lands: the opacity it changed.
|
|
189
|
+
const first = landsFor !== lastLandedLayout;
|
|
190
|
+
lastLandedLayout = landsFor;
|
|
191
|
+
const land = first && landsFor !== 0 ? 'all' : undefined;
|
|
192
|
+
renderer.writeMorphed(bandAxis!, positions, [[BINDINGS.ALPHA, alpha!]], land);
|
|
181
193
|
});
|
|
182
194
|
|
|
183
195
|
// Otherwise every line is fully drawn. Keyed on the line COUNT alone, because
|
|
@@ -9,6 +9,11 @@ interface Props {
|
|
|
9
9
|
* way a bar's height is. Omitted, every line is fully drawn.
|
|
10
10
|
*/
|
|
11
11
|
alpha?: Float32Array | null;
|
|
12
|
+
/**
|
|
13
|
+
* The band layout whose first opacity write lands without morphing, or 0
|
|
14
|
+
* (a layout that landed at once; see BandScaleState.slotsLandedLayout).
|
|
15
|
+
*/
|
|
16
|
+
landsFor?: number;
|
|
12
17
|
/** The band axis these lines belong to, when `alpha` should morph. */
|
|
13
18
|
bandAxis?: 'x' | 'y' | null;
|
|
14
19
|
color?: [number, number, number, number];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { activityReads,
|
|
2
|
+
import { activityReads, connectedActivityWGSL } from './activity-reads';
|
|
3
3
|
import { UNIFORM_BYTES } from './uniform-sizes';
|
|
4
4
|
import { getContext, onMount, onDestroy } from 'svelte';
|
|
5
5
|
import { RendererHost } from './RendererHost.svelte';
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
GLOBAL_ALPHA: 36, // f32
|
|
39
39
|
GROUP_INDEX: 40, // u32
|
|
40
40
|
ACTIVITY_COLOR_MODE: 44, // u32
|
|
41
|
-
ACTIVITY_COLOR_SCALE_INDEX: 48 // u32
|
|
41
|
+
ACTIVITY_COLOR_SCALE_INDEX: 48, // u32
|
|
42
|
+
ACTIVITY_SERIES_MODE: 52, // u32
|
|
43
|
+
ACTIVITY_SERIES_SCALE_INDEX: 56, // u32
|
|
44
|
+
ENTRANCE_AXIS: 60 // u32 (0 fades, 1 grows along x, 2 along y)
|
|
42
45
|
};
|
|
43
46
|
|
|
44
47
|
interface Props {
|
|
@@ -63,11 +66,23 @@
|
|
|
63
66
|
*/
|
|
64
67
|
activityColorMode?: number | null;
|
|
65
68
|
activityColorScaleIndex?: number | null;
|
|
69
|
+
/**
|
|
70
|
+
* The series scale selection activity is also read through, from
|
|
71
|
+
* `seriesData`: mode 1 and its index when the mark groups by a `z` of
|
|
72
|
+
* its own, mode 0 (no read) otherwise. MarkSeries decides.
|
|
73
|
+
*/
|
|
74
|
+
activitySeriesMode?: number;
|
|
75
|
+
activitySeriesScaleIndex?: number;
|
|
66
76
|
constantColor?: [number, number, number, number];
|
|
67
77
|
m4Decimator?: M4Decimator | null;
|
|
68
78
|
dotsRung?: import('../../lod/DotsRung.svelte').DotsRung | null;
|
|
69
79
|
globalAlpha?: number;
|
|
70
80
|
markId?: string;
|
|
81
|
+
/**
|
|
82
|
+
* The axis this line grows along when its chart enters, or null to fade
|
|
83
|
+
* in. A line mark fades; an area's outline grows with its fill.
|
|
84
|
+
*/
|
|
85
|
+
grow?: 'x' | 'y' | null;
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
let {
|
|
@@ -86,11 +101,14 @@
|
|
|
86
101
|
groupIndex = 0,
|
|
87
102
|
activityColorMode = null,
|
|
88
103
|
activityColorScaleIndex = null,
|
|
104
|
+
activitySeriesMode = 0,
|
|
105
|
+
activitySeriesScaleIndex = 0,
|
|
89
106
|
constantColor = DEFAULT_STROKE_COLOR,
|
|
90
107
|
m4Decimator = null,
|
|
91
108
|
dotsRung = null,
|
|
92
109
|
globalAlpha = 1.0,
|
|
93
|
-
markId = ''
|
|
110
|
+
markId = '',
|
|
111
|
+
grow = null
|
|
94
112
|
}: Props = $props();
|
|
95
113
|
|
|
96
114
|
const chartContext = getContext<ChartContext>('chart');
|
|
@@ -164,10 +182,20 @@
|
|
|
164
182
|
// own colour by default; an area's outline, drawn in a constant stroke,
|
|
165
183
|
// reads its fill's so it dims with the fill.
|
|
166
184
|
activityColorMode: u32,
|
|
167
|
-
activityColorScaleIndex: u32
|
|
185
|
+
activityColorScaleIndex: u32,
|
|
186
|
+
// The series scale it is also read through, for a z of its own; mode 0
|
|
187
|
+
// reads nothing.
|
|
188
|
+
activitySeriesMode: u32,
|
|
189
|
+
activitySeriesScaleIndex: u32,
|
|
190
|
+
entranceAxis: u32 // 0 fades in, 1 grows along x, 2 along y
|
|
168
191
|
};
|
|
169
192
|
@group(1) @binding(4) var<uniform> markConstants: MarkConstants;
|
|
170
193
|
|
|
194
|
+
// A point projected to pixels as it is during the chart's entrance.
|
|
195
|
+
fn enterPx(p: vec2<f32>) -> vec2<f32> {
|
|
196
|
+
return entrancePosition(projectToPixels(p), markConstants.entranceAxis);
|
|
197
|
+
}
|
|
198
|
+
|
|
171
199
|
struct VertexOutput {
|
|
172
200
|
@builtin(position) position: vec4<f32>,
|
|
173
201
|
@location(0) colorValue: f32,
|
|
@@ -211,7 +239,7 @@
|
|
|
211
239
|
output.position = DISCARD_POS;
|
|
212
240
|
return output;
|
|
213
241
|
}
|
|
214
|
-
let center =
|
|
242
|
+
let center = enterPx(vec2<f32>(x, y));
|
|
215
243
|
|
|
216
244
|
// JS computes dotRadius via DotsRung. 0 = no dots. >0 = show at this size.
|
|
217
245
|
let circleR = select(halfWidth, markConstants.dotRadius * frameUniforms.devicePixelRatio,
|
|
@@ -221,10 +249,12 @@
|
|
|
221
249
|
var output: VertexOutput;
|
|
222
250
|
output.position = pixelsToClip(pos);
|
|
223
251
|
output.colorValue = colorValues[instanceIdx];
|
|
224
|
-
output.alpha = markConstants.globalAlpha * selectionDim(
|
|
225
|
-
${
|
|
252
|
+
output.alpha = markConstants.globalAlpha * entranceAlpha(markConstants.entranceAxis) * selectionDim(
|
|
253
|
+
${connectedActivityWGSL(ACTIVITY_READS, {
|
|
226
254
|
color:
|
|
227
255
|
'markConstants.activityColorMode, markConstants.activityColorScaleIndex, colorValues[instanceIdx]',
|
|
256
|
+
series:
|
|
257
|
+
'markConstants.activitySeriesMode, markConstants.activitySeriesScaleIndex, seriesValues[instanceIdx]',
|
|
228
258
|
group: 'markConstants.groupIndex'
|
|
229
259
|
})}
|
|
230
260
|
);
|
|
@@ -258,8 +288,8 @@
|
|
|
258
288
|
}
|
|
259
289
|
|
|
260
290
|
// Project segment endpoints to pixel space
|
|
261
|
-
let pCurr =
|
|
262
|
-
let pNext =
|
|
291
|
+
let pCurr = enterPx(vec2<f32>(xCurr, yCurr));
|
|
292
|
+
let pNext = enterPx(vec2<f32>(xNext, yNext));
|
|
263
293
|
|
|
264
294
|
// Adaptive sub-segment resolution: more segments for longer pixel spans.
|
|
265
295
|
// Fixed-resolution curves (linear, step) have CURVE_RESOLUTION <= 3;
|
|
@@ -286,8 +316,8 @@
|
|
|
286
316
|
nextIdx + 1u >= pointCount || seriesValues[nextIdx + 1u] != seriesNext);
|
|
287
317
|
|
|
288
318
|
// Project neighbor control points
|
|
289
|
-
let pPrev =
|
|
290
|
-
let pAfter =
|
|
319
|
+
let pPrev = enterPx(vec2<f32>(xValues[prevIdx], yValues[prevIdx]));
|
|
320
|
+
let pAfter = enterPx(vec2<f32>(xValues[afterIdx], yValues[afterIdx]));
|
|
291
321
|
|
|
292
322
|
// Compute t values from effective resolution (not geometry buffer)
|
|
293
323
|
let subSegSize = 1.0 / f32(effectiveRes);
|
|
@@ -322,10 +352,12 @@
|
|
|
322
352
|
var output: VertexOutput;
|
|
323
353
|
output.position = pixelsToClip(finalPos);
|
|
324
354
|
output.colorValue = colorValues[currIdx];
|
|
325
|
-
output.alpha = markConstants.globalAlpha * selectionDim(
|
|
326
|
-
${
|
|
355
|
+
output.alpha = markConstants.globalAlpha * entranceAlpha(markConstants.entranceAxis) * selectionDim(
|
|
356
|
+
${connectedActivityWGSL(ACTIVITY_READS, {
|
|
327
357
|
color:
|
|
328
358
|
'markConstants.activityColorMode, markConstants.activityColorScaleIndex, colorValues[currIdx]',
|
|
359
|
+
series:
|
|
360
|
+
'markConstants.activitySeriesMode, markConstants.activitySeriesScaleIndex, seriesValues[currIdx]',
|
|
329
361
|
group: 'markConstants.groupIndex'
|
|
330
362
|
})}
|
|
331
363
|
);
|
|
@@ -443,6 +475,9 @@
|
|
|
443
475
|
view.setUint32(UNIFORM_OFFSETS.GROUP_INDEX, groupIndex, LE);
|
|
444
476
|
view.setUint32(UNIFORM_OFFSETS.ACTIVITY_COLOR_MODE, activityMode, LE);
|
|
445
477
|
view.setUint32(UNIFORM_OFFSETS.ACTIVITY_COLOR_SCALE_INDEX, activityScale, LE);
|
|
478
|
+
view.setUint32(UNIFORM_OFFSETS.ACTIVITY_SERIES_MODE, activitySeriesMode, LE);
|
|
479
|
+
view.setUint32(UNIFORM_OFFSETS.ACTIVITY_SERIES_SCALE_INDEX, activitySeriesScaleIndex, LE);
|
|
480
|
+
view.setUint32(UNIFORM_OFFSETS.ENTRANCE_AXIS, grow === 'x' ? 1 : grow === 'y' ? 2 : 0, LE);
|
|
446
481
|
view.setFloat32(UNIFORM_OFFSETS.CONSTANT_COLOR + 0, constantColor[0], LE);
|
|
447
482
|
view.setFloat32(UNIFORM_OFFSETS.CONSTANT_COLOR + 4, constantColor[1], LE);
|
|
448
483
|
view.setFloat32(UNIFORM_OFFSETS.CONSTANT_COLOR + 8, constantColor[2], LE);
|
|
@@ -22,11 +22,23 @@ interface Props {
|
|
|
22
22
|
*/
|
|
23
23
|
activityColorMode?: number | null;
|
|
24
24
|
activityColorScaleIndex?: number | null;
|
|
25
|
+
/**
|
|
26
|
+
* The series scale selection activity is also read through, from
|
|
27
|
+
* `seriesData`: mode 1 and its index when the mark groups by a `z` of
|
|
28
|
+
* its own, mode 0 (no read) otherwise. MarkSeries decides.
|
|
29
|
+
*/
|
|
30
|
+
activitySeriesMode?: number;
|
|
31
|
+
activitySeriesScaleIndex?: number;
|
|
25
32
|
constantColor?: [number, number, number, number];
|
|
26
33
|
m4Decimator?: M4Decimator | null;
|
|
27
34
|
dotsRung?: import('../../lod/DotsRung.svelte').DotsRung | null;
|
|
28
35
|
globalAlpha?: number;
|
|
29
36
|
markId?: string;
|
|
37
|
+
/**
|
|
38
|
+
* The axis this line grows along when its chart enters, or null to fade
|
|
39
|
+
* in. A line mark fades; an area's outline grows with its fill.
|
|
40
|
+
*/
|
|
41
|
+
grow?: 'x' | 'y' | null;
|
|
30
42
|
}
|
|
31
43
|
declare const Lines: import("svelte").Component<Props, {}, "">;
|
|
32
44
|
type Lines = ReturnType<typeof Lines>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { activityReads,
|
|
2
|
+
import { activityReads, connectedActivityWGSL } from './activity-reads';
|
|
3
3
|
import { PARALLEL_MAX_AXES, UNIFORM_BYTES } from './uniform-sizes';
|
|
4
4
|
import { getContext, onMount, onDestroy } from 'svelte';
|
|
5
5
|
import { RendererHost } from './RendererHost.svelte';
|
|
@@ -199,8 +199,8 @@
|
|
|
199
199
|
var output: VertexOutput;
|
|
200
200
|
output.position = pixelsToClip(pos);
|
|
201
201
|
output.colorValue = colorValues[rowIdx];
|
|
202
|
-
output.alpha = config.opacity * selectionDim(
|
|
203
|
-
${
|
|
202
|
+
output.alpha = config.opacity * entranceAlpha(0u) * selectionDim(
|
|
203
|
+
${connectedActivityWGSL(ACTIVITY_READS, {
|
|
204
204
|
color: 'config.colorMode, config.colorScaleIndex, colorValues[rowIdx]',
|
|
205
205
|
group: 'config.groupIndex'
|
|
206
206
|
})}
|
|
@@ -283,8 +283,8 @@
|
|
|
283
283
|
var output: VertexOutput;
|
|
284
284
|
output.position = pixelsToClip(finalPos);
|
|
285
285
|
output.colorValue = colorValues[rowIdx];
|
|
286
|
-
output.alpha = config.opacity * selectionDim(
|
|
287
|
-
${
|
|
286
|
+
output.alpha = config.opacity * entranceAlpha(0u) * selectionDim(
|
|
287
|
+
${connectedActivityWGSL(ACTIVITY_READS, {
|
|
288
288
|
color: 'config.colorMode, config.colorScaleIndex, colorValues[rowIdx]',
|
|
289
289
|
group: 'config.groupIndex'
|
|
290
290
|
})}
|