@fjader/svelte 0.2.4 → 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 +1 -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 +4 -2
- package/dist/components/axes/AxisCenter.svelte +4 -2
- package/dist/components/axes/AxisLeft.svelte +4 -2
- package/dist/components/axes/BandAxisTicks.svelte +3 -2
- package/dist/components/charts/ChartCell.svelte +32 -5
- package/dist/components/charts/ChartCell.svelte.d.ts +9 -0
- package/dist/components/charts/ChartContainer.svelte +45 -3
- package/dist/components/charts/ChartContainer.svelte.d.ts +7 -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/marks/AreaMarkX.svelte +16 -4
- package/dist/components/marks/AreaMarkY.svelte +16 -4
- package/dist/components/marks/BarMarkX.svelte +7 -3
- package/dist/components/marks/BarMarkY.svelte +7 -3
- package/dist/components/marks/DotsMark.svelte +6 -3
- package/dist/components/marks/LineMark.svelte +11 -8
- package/dist/components/marks/ParallelCoordinatesMark.svelte +7 -2
- package/dist/components/marks/ParallelCoordinatesMark.svelte.d.ts +2 -0
- package/dist/components/marks/RectMark.svelte +6 -3
- package/dist/components/marks/RectXMark.svelte +7 -3
- package/dist/components/marks/RectYMark.svelte +7 -3
- package/dist/components/marks/RuleMarkX.svelte +30 -26
- package/dist/components/marks/RuleMarkY.svelte +30 -26
- package/dist/components/marks/TextMark.svelte +44 -5
- package/dist/components/marks/lifecycle/MarkLifecycleV2.svelte.d.ts +16 -0
- package/dist/components/marks/lifecycle/MarkLifecycleV2.svelte.js +398 -54
- package/dist/components/marks/lifecycle/domain-queries.d.ts +11 -2
- package/dist/components/marks/lifecycle/domain-queries.js +33 -6
- package/dist/components/marks/lifecycle/domain-registration.d.ts +6 -1
- package/dist/components/marks/lifecycle/domain-registration.js +15 -14
- package/dist/components/marks/lifecycle/other-rows.svelte.d.ts +9 -1
- package/dist/components/marks/lifecycle/other-rows.svelte.js +2 -2
- package/dist/components/marks/lifecycle/query-builder.d.ts +27 -2
- package/dist/components/marks/lifecycle/query-builder.js +23 -20
- 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 +3 -0
- 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 +1 -1
- 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 +51 -11
- package/dist/components/rendering/Rects.svelte.d.ts +16 -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 +41 -24
- package/dist/components/rendering/activity-reads.js +54 -31
- 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 +7 -0
- 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 -2
- package/dist/gpu/MorphedChannels.js +33 -11
- package/dist/gpu/ScaleTemplateSystem.d.ts +20 -2
- package/dist/gpu/ScaleTemplateSystem.js +58 -2
- package/dist/index.d.ts +17 -4
- package/dist/index.js +19 -4
- package/dist/interactors/TooltipManager.svelte.js +14 -5
- 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 +2 -3
- package/dist/query-engine/FieldActivity.svelte.js +1 -2
- 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 +671 -41
- package/dist/query-engine/categorical-identity.d.ts +34 -8
- package/dist/query-engine/categorical-identity.js +138 -73
- 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 +28 -1
- package/dist/query-engine/preagg/plan.js +128 -8
- 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/scales/BandScaleState.svelte.d.ts +9 -1
- package/dist/scales/BandScaleState.svelte.js +16 -5
- 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 +41 -13
- package/dist/sql/bin.d.ts +25 -0
- package/dist/sql/bin.js +108 -5
- package/dist/transforms/TransformCompiler.d.ts +10 -0
- package/dist/transforms/TransformCompiler.js +26 -0
- package/dist/transforms/index.js +144 -24
- package/dist/types.d.ts +136 -2
- package/package.json +2 -2
|
@@ -14,6 +14,12 @@ interface Props {
|
|
|
14
14
|
share?: SplitProp | null;
|
|
15
15
|
facetData?: Float32Array | null;
|
|
16
16
|
dataVersion: number;
|
|
17
|
+
/**
|
|
18
|
+
* The data version whose first write lands without morphing, or 0: a
|
|
19
|
+
* catch-up result (MarkLifecycleV2.landsFor). Later writes of that version
|
|
20
|
+
* animate as usual.
|
|
21
|
+
*/
|
|
22
|
+
landsFor?: number;
|
|
17
23
|
zIndex?: number;
|
|
18
24
|
colorMode?: number;
|
|
19
25
|
colorScaleIndex?: number;
|
|
@@ -26,14 +32,22 @@ interface Props {
|
|
|
26
32
|
markId?: string;
|
|
27
33
|
/**
|
|
28
34
|
* The band axis, when this mark's rows are one per category in category
|
|
29
|
-
* order and may therefore morph
|
|
35
|
+
* order and may therefore morph; or a histogram's binned axis, one row per
|
|
36
|
+
* bin in bin order. null to morph nothing.
|
|
30
37
|
*
|
|
31
38
|
* The OTHER axis's channels morph. The band's never do: they carry a
|
|
32
39
|
* category id that the shader resolves through the slot table, and
|
|
33
40
|
* interpolating an identity produces a fraction that resolves to some
|
|
34
|
-
* other category. Position already animates, through the slot table.
|
|
41
|
+
* other category. Position already animates, through the slot table. A
|
|
42
|
+
* bin's edges do not change under a filter, and a re-bin snaps.
|
|
35
43
|
*/
|
|
36
44
|
bandAxis?: 'x' | 'y' | null;
|
|
45
|
+
/**
|
|
46
|
+
* The axis this mark grows along when its chart enters: its measure axis,
|
|
47
|
+
* for bars and histograms anchored at 0. null fades it in instead, for
|
|
48
|
+
* rects with bounds of their own (a Gantt bar has no 0 to grow from).
|
|
49
|
+
*/
|
|
50
|
+
grow?: 'x' | 'y' | null;
|
|
37
51
|
}
|
|
38
52
|
declare const Rects: import("svelte").Component<Props, {}, "">;
|
|
39
53
|
type Rects = ReturnType<typeof Rects>;
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
var output: VertexOutput;
|
|
182
182
|
output.position = vec4<f32>(normalizedPos.x, -normalizedPos.y, 0.0, 1.0);
|
|
183
183
|
output.colorValue = colorValue;
|
|
184
|
-
output.alpha = alpha * selectionDim(
|
|
184
|
+
output.alpha = alpha * entranceAlpha(0u) * selectionDim(
|
|
185
185
|
${markActivityWGSL(ACTIVITY_READS, {
|
|
186
186
|
color: 'markConstants.colorMode, markConstants.colorScaleIndex, colorValue',
|
|
187
187
|
x: 'x',
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
var output: VertexOutput;
|
|
181
181
|
output.position = vec4<f32>(normalizedPos.x, -normalizedPos.y, 0.0, 1.0);
|
|
182
182
|
output.colorValue = colorValue;
|
|
183
|
-
output.alpha = alpha * selectionDim(
|
|
183
|
+
output.alpha = alpha * entranceAlpha(0u) * selectionDim(
|
|
184
184
|
${markActivityWGSL(ACTIVITY_READS, {
|
|
185
185
|
color: 'markConstants.colorMode, markConstants.colorScaleIndex, colorValue',
|
|
186
186
|
x: 'x0',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { onMount, onDestroy, setContext, getContext } from 'svelte';
|
|
3
3
|
import { getGPUContext } from '../../gpu';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
|
-
import type { ChartContext, WebGPUCanvasContext } from '../../types';
|
|
5
|
+
import type { ChartContext, EntranceMode, WebGPUCanvasContext } from '../../types';
|
|
6
6
|
import type { GPUCoordinator, ChartRegistrationResult } from '../../gpu/GPUCoordinator.svelte';
|
|
7
7
|
import type { FacetScaleRef } from '../../gpu/GPUCoordinator.svelte';
|
|
8
8
|
|
|
@@ -120,7 +120,9 @@
|
|
|
120
120
|
chartControl = gpuCoordinator.registerChart(chartId, canvas, {
|
|
121
121
|
zIndex: 0,
|
|
122
122
|
facetIndex: facetIndex ?? 0,
|
|
123
|
-
facetScale
|
|
123
|
+
facetScale,
|
|
124
|
+
entrance: c.config?.chartProps?.entrance as EntranceMode | undefined,
|
|
125
|
+
entranceGate: c.config?.entrance ?? null
|
|
124
126
|
});
|
|
125
127
|
|
|
126
128
|
// Notify coordinator that context is ready
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Which selection activities a mark reads: its ordinal colour, its band x,
|
|
3
|
-
* its band y. One answer per renderer, used
|
|
3
|
+
* its band y, and a line's or area's series. One answer per renderer, used
|
|
4
|
+
* twice:
|
|
4
5
|
*
|
|
5
6
|
* - The renderer builds its shader's `markActivity` call from it, so a read
|
|
6
7
|
* the table does not list is passed as 1.0 and cannot happen.
|
|
@@ -26,17 +27,14 @@ export interface ActivityReads {
|
|
|
26
27
|
readonly color: boolean;
|
|
27
28
|
readonly x: boolean;
|
|
28
29
|
readonly y: boolean;
|
|
30
|
+
/** A line's or area's `z`: the series field when it is not the colour field. */
|
|
31
|
+
readonly series: boolean;
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
34
|
* What a renderer reads. `hasExtent` is a rule's: RuleX with y1/y2, RuleY with
|
|
32
|
-
* x1/x2. Lines
|
|
33
|
-
* a band axis spans its categories.
|
|
34
|
-
*
|
|
35
|
-
* Not yet supported: a line or area grouped by `z` that is not its colour
|
|
36
|
-
* field. Its series ids reach the shader, but only to break the line between
|
|
37
|
-
* series; no activity is read through them, and the series field is not among
|
|
38
|
-
* the mark's reads. So a selection on that field filters the mark in other
|
|
39
|
-
* charts and does nothing in its own, instead of dimming the other series.
|
|
35
|
+
* x1/x2. Lines and areas dim by colour and by series (`z`), never by a band
|
|
36
|
+
* axis: a line over a band axis spans its categories. Parallel coordinates
|
|
37
|
+
* have no `z` and dim by colour only.
|
|
40
38
|
*/
|
|
41
39
|
export declare function activityReads(renderer: ActivityRenderer, hasExtent?: boolean): ActivityReads;
|
|
42
40
|
/**
|
|
@@ -53,12 +51,14 @@ export declare function rendererForMark(markType: string): ActivityRenderer | nu
|
|
|
53
51
|
* sorted, from what its renderer reads and the identity key of each of its
|
|
54
52
|
* categorical scales (null for a channel with no such scale, or a scale with
|
|
55
53
|
* no identity: a field with no identity has no activity to dim by, so a
|
|
56
|
-
* selection on it filters the mark).
|
|
54
|
+
* selection on it filters the mark). `series` is null unless the mark has a
|
|
55
|
+
* `z` of its own; a series that is the colour field is already in `color`.
|
|
57
56
|
*/
|
|
58
57
|
export declare function readsFor(reads: ActivityReads, keys: {
|
|
59
58
|
color: string | null;
|
|
60
59
|
x: string | null;
|
|
61
60
|
y: string | null;
|
|
61
|
+
series?: string | null;
|
|
62
62
|
}): readonly string[];
|
|
63
63
|
/** A mark that reads no activity. Shared, so its reads never look changed. */
|
|
64
64
|
export declare const NO_READS: readonly string[];
|
|
@@ -68,29 +68,40 @@ export declare const NO_READS: readonly string[];
|
|
|
68
68
|
* by (its band axes, its ordinal colour) dims it, and any other selection
|
|
69
69
|
* filters it. 'filter': every selection filters it, even on a field it draws
|
|
70
70
|
* by, so its aggregates are recomputed for the subset (top N within a region).
|
|
71
|
+
* 'ignore': no selection filters or dims it; context, such as the whole
|
|
72
|
+
* drawn behind a filtered part.
|
|
71
73
|
*/
|
|
72
|
-
export type SelectionResponse = 'auto' | 'filter';
|
|
74
|
+
export type SelectionResponse = 'auto' | 'filter' | 'ignore';
|
|
73
75
|
export { NO_GROUP };
|
|
74
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Whether a selection can dim the mark: only under 'auto'. A 'filter' mark is
|
|
78
|
+
* filtered instead, and an 'ignore' mark neither.
|
|
79
|
+
*/
|
|
80
|
+
export declare function dimsBySelection(response: SelectionResponse | undefined): boolean;
|
|
81
|
+
/** A mark's reads under its selection response: none for a mark that never dims. */
|
|
75
82
|
export declare function readsForResponse(response: SelectionResponse | undefined, reads: readonly string[]): readonly string[];
|
|
76
|
-
/** The group index a mark's shader reads activity with: NO_GROUP for
|
|
83
|
+
/** The group index a mark's shader reads activity with: NO_GROUP for a mark that never dims. */
|
|
77
84
|
export declare function groupIndexForResponse(response: SelectionResponse | undefined, groupIndex: number): number;
|
|
78
85
|
/**
|
|
79
|
-
* The WGSL activity of a renderer that reads
|
|
80
|
-
* parallel coordinates):
|
|
81
|
-
*
|
|
82
|
-
*
|
|
86
|
+
* The WGSL activity of a renderer that reads no band axis (lines, areas,
|
|
87
|
+
* parallel coordinates): its colour activity and, for lines and areas, its
|
|
88
|
+
* series activity, 1.0 for each the table says it does not read.
|
|
89
|
+
*
|
|
90
|
+
* `series` is markColorActivity's first three arguments for the series scale,
|
|
91
|
+
* the same lookup as colour on another scale and buffer. The mark passes mode
|
|
92
|
+
* 0 when it has no `z` of its own, so the read returns 1.0 before loading
|
|
93
|
+
* anything. The two combine by `min`, the least active wins, as in
|
|
94
|
+
* markActivity: a series on the colour field cannot dim twice.
|
|
95
|
+
*
|
|
96
|
+
* Throws for a renderer that reads a band axis, whose call is
|
|
97
|
+
* markActivityWGSL, and for one that reads a series it was given no
|
|
98
|
+
* arguments for.
|
|
83
99
|
*/
|
|
84
|
-
export declare function
|
|
100
|
+
export declare function connectedActivityWGSL(reads: ActivityReads, args: {
|
|
85
101
|
color: string;
|
|
102
|
+
series?: string;
|
|
86
103
|
group: string;
|
|
87
104
|
}): string;
|
|
88
|
-
/**
|
|
89
|
-
* The WGSL `markActivity(...)` call for `reads`: each activity the renderer
|
|
90
|
-
* reads, and 1.0 for each it does not. `color` is markColorActivity's first
|
|
91
|
-
* three arguments; `x` and `y` are the band channel values; `group` the mark's
|
|
92
|
-
* group index.
|
|
93
|
-
*/
|
|
94
105
|
/**
|
|
95
106
|
* The activity of an Other row: the same terms as markActivityWGSL without the
|
|
96
107
|
* band axes', and without colour's when colour is the band's own field
|
|
@@ -103,6 +114,12 @@ export declare function otherRowActivityWGSL(reads: ActivityReads, args: {
|
|
|
103
114
|
group: string;
|
|
104
115
|
skipColor: string;
|
|
105
116
|
}): string;
|
|
117
|
+
/**
|
|
118
|
+
* The WGSL `markActivity(...)` call for `reads`: each activity the renderer
|
|
119
|
+
* reads, and 1.0 for each it does not. `color` is markColorActivity's first
|
|
120
|
+
* three arguments; `x` and `y` are the band channel values; `group` the mark's
|
|
121
|
+
* group index.
|
|
122
|
+
*/
|
|
106
123
|
export declare function markActivityWGSL(reads: ActivityReads, args: {
|
|
107
124
|
color: string;
|
|
108
125
|
x: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Which selection activities a mark reads: its ordinal colour, its band x,
|
|
3
|
-
* its band y. One answer per renderer, used
|
|
3
|
+
* its band y, and a line's or area's series. One answer per renderer, used
|
|
4
|
+
* twice:
|
|
4
5
|
*
|
|
5
6
|
* - The renderer builds its shader's `markActivity` call from it, so a read
|
|
6
7
|
* the table does not list is passed as 1.0 and cannot happen.
|
|
@@ -20,18 +21,14 @@
|
|
|
20
21
|
* axis, belongs to no category on it, and must not dim by it.
|
|
21
22
|
*/
|
|
22
23
|
import { NO_GROUP } from '../../gpu/identity-slot-packing';
|
|
23
|
-
const ALL = { color: true, x: true, y: true };
|
|
24
|
-
const
|
|
24
|
+
const ALL = { color: true, x: true, y: true, series: false };
|
|
25
|
+
const CONNECTED = { color: true, x: false, y: false, series: true };
|
|
26
|
+
const COLOR_ONLY = { color: true, x: false, y: false, series: false };
|
|
25
27
|
/**
|
|
26
28
|
* What a renderer reads. `hasExtent` is a rule's: RuleX with y1/y2, RuleY with
|
|
27
|
-
* x1/x2. Lines
|
|
28
|
-
* a band axis spans its categories.
|
|
29
|
-
*
|
|
30
|
-
* Not yet supported: a line or area grouped by `z` that is not its colour
|
|
31
|
-
* field. Its series ids reach the shader, but only to break the line between
|
|
32
|
-
* series; no activity is read through them, and the series field is not among
|
|
33
|
-
* the mark's reads. So a selection on that field filters the mark in other
|
|
34
|
-
* charts and does nothing in its own, instead of dimming the other series.
|
|
29
|
+
* x1/x2. Lines and areas dim by colour and by series (`z`), never by a band
|
|
30
|
+
* axis: a line over a band axis spans its categories. Parallel coordinates
|
|
31
|
+
* have no `z` and dim by colour only.
|
|
35
32
|
*/
|
|
36
33
|
export function activityReads(renderer, hasExtent = false) {
|
|
37
34
|
switch (renderer) {
|
|
@@ -40,11 +37,12 @@ export function activityReads(renderer, hasExtent = false) {
|
|
|
40
37
|
case 'text':
|
|
41
38
|
return ALL;
|
|
42
39
|
case 'rulex':
|
|
43
|
-
return { color: true, x: true, y: hasExtent };
|
|
40
|
+
return { color: true, x: true, y: hasExtent, series: false };
|
|
44
41
|
case 'ruley':
|
|
45
|
-
return { color: true, x: hasExtent, y: true };
|
|
42
|
+
return { color: true, x: hasExtent, y: true, series: false };
|
|
46
43
|
case 'lines':
|
|
47
44
|
case 'areas':
|
|
45
|
+
return CONNECTED;
|
|
48
46
|
case 'parallel':
|
|
49
47
|
return COLOR_ONLY;
|
|
50
48
|
}
|
|
@@ -91,7 +89,8 @@ export function rendererForMark(markType) {
|
|
|
91
89
|
* sorted, from what its renderer reads and the identity key of each of its
|
|
92
90
|
* categorical scales (null for a channel with no such scale, or a scale with
|
|
93
91
|
* no identity: a field with no identity has no activity to dim by, so a
|
|
94
|
-
* selection on it filters the mark).
|
|
92
|
+
* selection on it filters the mark). `series` is null unless the mark has a
|
|
93
|
+
* `z` of its own; a series that is the colour field is already in `color`.
|
|
95
94
|
*/
|
|
96
95
|
export function readsFor(reads, keys) {
|
|
97
96
|
const out = [];
|
|
@@ -101,6 +100,8 @@ export function readsFor(reads, keys) {
|
|
|
101
100
|
out.push(keys.x);
|
|
102
101
|
if (reads.y && keys.y)
|
|
103
102
|
out.push(keys.y);
|
|
103
|
+
if (reads.series && keys.series)
|
|
104
|
+
out.push(keys.series);
|
|
104
105
|
if (out.length === 0)
|
|
105
106
|
return NO_READS;
|
|
106
107
|
return [...new Set(out)].sort();
|
|
@@ -108,31 +109,47 @@ export function readsFor(reads, keys) {
|
|
|
108
109
|
/** A mark that reads no activity. Shared, so its reads never look changed. */
|
|
109
110
|
export const NO_READS = [];
|
|
110
111
|
export { NO_GROUP };
|
|
111
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* Whether a selection can dim the mark: only under 'auto'. A 'filter' mark is
|
|
114
|
+
* filtered instead, and an 'ignore' mark neither.
|
|
115
|
+
*/
|
|
116
|
+
export function dimsBySelection(response) {
|
|
117
|
+
return response !== 'filter' && response !== 'ignore';
|
|
118
|
+
}
|
|
119
|
+
/** A mark's reads under its selection response: none for a mark that never dims. */
|
|
112
120
|
export function readsForResponse(response, reads) {
|
|
113
|
-
return response
|
|
121
|
+
return dimsBySelection(response) ? reads : NO_READS;
|
|
114
122
|
}
|
|
115
|
-
/** The group index a mark's shader reads activity with: NO_GROUP for
|
|
123
|
+
/** The group index a mark's shader reads activity with: NO_GROUP for a mark that never dims. */
|
|
116
124
|
export function groupIndexForResponse(response, groupIndex) {
|
|
117
|
-
return response
|
|
125
|
+
return dimsBySelection(response) ? groupIndex : NO_GROUP;
|
|
118
126
|
}
|
|
119
127
|
/**
|
|
120
|
-
* The WGSL activity of a renderer that reads
|
|
121
|
-
* parallel coordinates):
|
|
122
|
-
*
|
|
123
|
-
*
|
|
128
|
+
* The WGSL activity of a renderer that reads no band axis (lines, areas,
|
|
129
|
+
* parallel coordinates): its colour activity and, for lines and areas, its
|
|
130
|
+
* series activity, 1.0 for each the table says it does not read.
|
|
131
|
+
*
|
|
132
|
+
* `series` is markColorActivity's first three arguments for the series scale,
|
|
133
|
+
* the same lookup as colour on another scale and buffer. The mark passes mode
|
|
134
|
+
* 0 when it has no `z` of its own, so the read returns 1.0 before loading
|
|
135
|
+
* anything. The two combine by `min`, the least active wins, as in
|
|
136
|
+
* markActivity: a series on the colour field cannot dim twice.
|
|
137
|
+
*
|
|
138
|
+
* Throws for a renderer that reads a band axis, whose call is
|
|
139
|
+
* markActivityWGSL, and for one that reads a series it was given no
|
|
140
|
+
* arguments for.
|
|
124
141
|
*/
|
|
125
|
-
export function
|
|
142
|
+
export function connectedActivityWGSL(reads, args) {
|
|
126
143
|
if (reads.x || reads.y)
|
|
127
|
-
throw new Error('
|
|
128
|
-
|
|
144
|
+
throw new Error('connectedActivityWGSL: this renderer reads a band axis');
|
|
145
|
+
if (reads.series && !args.series) {
|
|
146
|
+
throw new Error('connectedActivityWGSL: this renderer reads a series; pass its arguments');
|
|
147
|
+
}
|
|
148
|
+
const color = reads.color ? `markColorActivity(${args.color}, ${args.group})` : '1.0';
|
|
149
|
+
if (!reads.series)
|
|
150
|
+
return color;
|
|
151
|
+
return `min(${color}, markColorActivity(${args.series}, ${args.group}))`;
|
|
129
152
|
}
|
|
130
|
-
/**
|
|
131
|
-
* The WGSL `markActivity(...)` call for `reads`: each activity the renderer
|
|
132
|
-
* reads, and 1.0 for each it does not. `color` is markColorActivity's first
|
|
133
|
-
* three arguments; `x` and `y` are the band channel values; `group` the mark's
|
|
134
|
-
* group index.
|
|
135
|
-
*/
|
|
136
153
|
/**
|
|
137
154
|
* The activity of an Other row: the same terms as markActivityWGSL without the
|
|
138
155
|
* band axes', and without colour's when colour is the band's own field
|
|
@@ -146,6 +163,12 @@ export function otherRowActivityWGSL(reads, args) {
|
|
|
146
163
|
: '1.0';
|
|
147
164
|
return `markActivity(${color}, 1.0, 1.0)`;
|
|
148
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* The WGSL `markActivity(...)` call for `reads`: each activity the renderer
|
|
168
|
+
* reads, and 1.0 for each it does not. `color` is markColorActivity's first
|
|
169
|
+
* three arguments; `x` and `y` are the band channel values; `group` the mark's
|
|
170
|
+
* group index.
|
|
171
|
+
*/
|
|
149
172
|
export function markActivityWGSL(reads, args) {
|
|
150
173
|
const color = reads.color ? `markColorActivity(${args.color}, ${args.group})` : '1.0';
|
|
151
174
|
const x = reads.x ? `bandActivityX(${args.x}, ${args.group})` : '1.0';
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
export declare const PARALLEL_MAX_AXES = 16;
|
|
14
14
|
export declare const UNIFORM_BYTES: {
|
|
15
15
|
readonly dotsMarkConstants: 48;
|
|
16
|
-
readonly rectsMarkConstants:
|
|
16
|
+
readonly rectsMarkConstants: 64;
|
|
17
17
|
readonly ruleXMarkConstants: 48;
|
|
18
18
|
readonly ruleYMarkConstants: 48;
|
|
19
19
|
readonly linesMarkConstants: 64;
|
|
@@ -15,7 +15,7 @@ export const PARALLEL_MAX_AXES = 16;
|
|
|
15
15
|
const SCALE_PARAM_BYTES = 16;
|
|
16
16
|
export const UNIFORM_BYTES = {
|
|
17
17
|
dotsMarkConstants: 48,
|
|
18
|
-
rectsMarkConstants:
|
|
18
|
+
rectsMarkConstants: 64,
|
|
19
19
|
ruleXMarkConstants: 48,
|
|
20
20
|
ruleYMarkConstants: 48,
|
|
21
21
|
linesMarkConstants: 64,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EntranceGate } from '../animation/EntranceGate';
|
|
1
2
|
import type { SelectionResponse } from '../components/rendering/activity-reads';
|
|
2
3
|
import type { FieldRef, LODConfig, SortConfig, ColorScheme, CurveType, NullsResponse, Transform } from '../types';
|
|
3
4
|
import type { MarkLODSurface } from '../lod/rung-types';
|
|
@@ -27,6 +28,7 @@ export interface MarkEntry {
|
|
|
27
28
|
selectionResponse?: SelectionResponse;
|
|
28
29
|
contributeDomain?: boolean;
|
|
29
30
|
nulls?: NullsResponse;
|
|
31
|
+
holdsEntrance?: boolean;
|
|
30
32
|
limit?: number;
|
|
31
33
|
preferredXScaleType?: string | null;
|
|
32
34
|
preferredYScaleType?: string | null;
|
|
@@ -61,6 +63,11 @@ export interface ChartProps {
|
|
|
61
63
|
}
|
|
62
64
|
export declare class ChartConfig {
|
|
63
65
|
#private;
|
|
66
|
+
/**
|
|
67
|
+
* Holds the chart's entrance until its marks have their first data. One per
|
|
68
|
+
* container, shared by its facet cells, as this config is.
|
|
69
|
+
*/
|
|
70
|
+
readonly entrance: EntranceGate;
|
|
64
71
|
/**
|
|
65
72
|
* Register a mark with prop getters for each configurable property.
|
|
66
73
|
* Returns the reactive entry that the mark reads from.
|
|
@@ -12,10 +12,17 @@
|
|
|
12
12
|
// The entry outlives MarkLifecycle — registerMark returns the existing entry
|
|
13
13
|
// on re-registration, preventing infinite loops.
|
|
14
14
|
// =============================================================================
|
|
15
|
+
import { untrack } from 'svelte';
|
|
15
16
|
import { SvelteMap } from 'svelte/reactivity';
|
|
17
|
+
import { EntranceGate } from '../animation/EntranceGate';
|
|
16
18
|
import { createOverridable } from './overridable.svelte';
|
|
17
19
|
// ---- ChartConfig ----
|
|
18
20
|
export class ChartConfig {
|
|
21
|
+
/**
|
|
22
|
+
* Holds the chart's entrance until its marks have their first data. One per
|
|
23
|
+
* container, shared by its facet cells, as this config is.
|
|
24
|
+
*/
|
|
25
|
+
entrance = new EntranceGate();
|
|
19
26
|
/** Overridable channels per mark, for reset support. */
|
|
20
27
|
#channels = new Map();
|
|
21
28
|
/** Reactive entries — SvelteMap so iteration/size reads are tracked. */
|
|
@@ -45,6 +52,14 @@ export class ChartConfig {
|
|
|
45
52
|
const existing = this.#entries.get(id);
|
|
46
53
|
if (existing)
|
|
47
54
|
return existing;
|
|
55
|
+
// A data mark holds the chart's entrance from the moment it mounts, which
|
|
56
|
+
// is now: its lifecycle is built later, in an effect that waits for the
|
|
57
|
+
// chart's scales, and until something holds the gate the chart looks
|
|
58
|
+
// like one with no data marks and enters on its first drawable layer.
|
|
59
|
+
if (untrack(() => propGetters.table?.()) &&
|
|
60
|
+
untrack(() => propGetters.holdsEntrance?.()) !== false) {
|
|
61
|
+
this.entrance.hold(id);
|
|
62
|
+
}
|
|
48
63
|
const channels = new Map();
|
|
49
64
|
const entry = { id, markType };
|
|
50
65
|
for (const [key, getter] of Object.entries(propGetters)) {
|
|
@@ -66,6 +81,8 @@ export class ChartConfig {
|
|
|
66
81
|
return entry;
|
|
67
82
|
}
|
|
68
83
|
unregisterMark(id) {
|
|
84
|
+
// A mark that leaves before its first data must not hold the chart.
|
|
85
|
+
this.entrance.release(id);
|
|
69
86
|
this.#entries.delete(id);
|
|
70
87
|
this.#channels.delete(id);
|
|
71
88
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { type TransitionRecord } from '../animation/transition-log';
|
|
2
|
+
import type { EntranceMode } from '../types';
|
|
3
|
+
import type { EntranceGate } from '../animation/EntranceGate';
|
|
1
4
|
import type { RendererDefinition } from './ScaleTemplateSystem';
|
|
2
5
|
import type { ScaleRegistry } from '../scales/ScaleRegistry.svelte';
|
|
3
6
|
import type { FilterGroupRegistry } from '../query-engine/FilterGroupRegistry.svelte';
|
|
@@ -88,6 +91,18 @@ interface ChartRegistrationConfig {
|
|
|
88
91
|
zIndex?: number;
|
|
89
92
|
facetIndex?: number;
|
|
90
93
|
facetScale?: FacetScaleRef | null;
|
|
94
|
+
/** How the chart's marks enter when its data first draws. Default 'auto'. */
|
|
95
|
+
entrance?: EntranceMode;
|
|
96
|
+
/** Holds the entrance until the chart's marks have their first data. */
|
|
97
|
+
entranceGate?: EntranceGate | null;
|
|
98
|
+
}
|
|
99
|
+
/** A chart's entrance starting, for observeEntrances. */
|
|
100
|
+
export interface ChartEntrance {
|
|
101
|
+
chartId: string;
|
|
102
|
+
/** The chart's canvas, to find it in the page (a label on an ancestor). */
|
|
103
|
+
canvas: HTMLCanvasElement;
|
|
104
|
+
/** performance.now() when the entrance started. */
|
|
105
|
+
time: number;
|
|
91
106
|
}
|
|
92
107
|
/**
|
|
93
108
|
* One chart's pixels as the coordinator rendered them, for the scale-source
|
|
@@ -142,6 +157,12 @@ export declare class GPUCoordinator {
|
|
|
142
157
|
* left alone.
|
|
143
158
|
*/
|
|
144
159
|
writeScaleParams(scaleId: string, view: Float32Array, offset: number): boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Listen to every chart's entrance as it starts: when its marks have their
|
|
162
|
+
* first data and it first draws. For measuring load (how soon charts enter);
|
|
163
|
+
* returns the unsubscribe. Costs nothing while no one listens.
|
|
164
|
+
*/
|
|
165
|
+
observeEntrances(listener: (entrance: ChartEntrance) => void): () => void;
|
|
145
166
|
/**
|
|
146
167
|
* Configure canvases so the coordinator can copy from them. Test-only: set
|
|
147
168
|
* it before the charts mount, since a canvas reads it when it configures
|
|
@@ -263,10 +284,19 @@ export declare class GPUCoordinator {
|
|
|
263
284
|
removePhysicsCallback(fn: () => void): void;
|
|
264
285
|
registerChart(chartId: string, canvas: HTMLCanvasElement, config: ChartRegistrationConfig): ChartRegistrationResult;
|
|
265
286
|
unregisterChart(chartId: string): void;
|
|
287
|
+
/**
|
|
288
|
+
* Debug: every transition that starts, and whether it animates or lands at
|
|
289
|
+
* once (see transition-log). Returns the unsubscribe. Forwards to the
|
|
290
|
+
* page-wide log: records from every coordinator in the document arrive
|
|
291
|
+
* here, so filter by chart id.
|
|
292
|
+
*/
|
|
293
|
+
observeTransitions(listener: (record: TransitionRecord) => void): () => void;
|
|
294
|
+
/** Whether a registered chart is visible: in view (with the 200 px margin) and the page shown. */
|
|
295
|
+
isChartVisible(chartId: string): boolean;
|
|
266
296
|
/**
|
|
267
297
|
* Register a callback invoked when a chart's effective visibility changes.
|
|
268
298
|
* Effective visibility = IntersectionObserver visible AND page visible.
|
|
269
|
-
* Used by ChartCell to
|
|
299
|
+
* Used by ChartCell to report into the chart's ChartVisibility.
|
|
270
300
|
*/
|
|
271
301
|
setVisibilityCallback(chartId: string, callback: (visible: boolean) => void): () => void;
|
|
272
302
|
invalidateChart(chartId: string): void;
|