svelteplot 0.12.0 → 0.14.0-pr-545.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/Plot.svelte +3 -6
- package/dist/helpers/group.d.ts +1 -1
- package/dist/helpers/group.js +3 -3
- package/dist/helpers/scales.js +8 -0
- package/dist/helpers/vectorShapes.d.ts +13 -0
- package/dist/helpers/vectorShapes.js +57 -0
- package/dist/marks/Arrow.svelte +70 -59
- package/dist/marks/Arrow.svelte.d.ts +2 -0
- package/dist/marks/ColorLegend.svelte +7 -3
- package/dist/marks/Contour.svelte +684 -0
- package/dist/marks/Contour.svelte.d.ts +152 -0
- package/dist/marks/DelaunayLink.svelte +127 -0
- package/dist/marks/DelaunayLink.svelte.d.ts +175 -0
- package/dist/marks/DelaunayMesh.svelte +102 -0
- package/dist/marks/DelaunayMesh.svelte.d.ts +172 -0
- package/dist/marks/Density.svelte +552 -0
- package/dist/marks/Density.svelte.d.ts +108 -0
- package/dist/marks/Hull.svelte +103 -0
- package/dist/marks/Hull.svelte.d.ts +175 -0
- package/dist/marks/Image.svelte +37 -27
- package/dist/marks/Image.svelte.d.ts +2 -0
- package/dist/marks/Link.svelte +68 -50
- package/dist/marks/Link.svelte.d.ts +2 -0
- package/dist/marks/Raster.svelte +6 -1
- package/dist/marks/Vector.svelte +12 -81
- package/dist/marks/Vector.svelte.d.ts +2 -4
- package/dist/marks/Voronoi.svelte +118 -0
- package/dist/marks/Voronoi.svelte.d.ts +172 -0
- package/dist/marks/VoronoiMesh.svelte +109 -0
- package/dist/marks/VoronoiMesh.svelte.d.ts +172 -0
- package/dist/marks/helpers/ArrowCanvas.svelte +132 -0
- package/dist/marks/helpers/ArrowCanvas.svelte.d.ts +39 -0
- package/dist/marks/helpers/BaseAxisX.svelte +5 -7
- package/dist/marks/helpers/DensityCanvas.svelte +118 -0
- package/dist/marks/helpers/DensityCanvas.svelte.d.ts +18 -0
- package/dist/marks/helpers/GeoPathCanvas.svelte +130 -0
- package/dist/marks/helpers/GeoPathCanvas.svelte.d.ts +24 -0
- package/dist/marks/helpers/GeoPathGroup.svelte +104 -0
- package/dist/marks/helpers/GeoPathGroup.svelte.d.ts +37 -0
- package/dist/marks/helpers/ImageCanvas.svelte +126 -0
- package/dist/marks/helpers/ImageCanvas.svelte.d.ts +34 -0
- package/dist/marks/helpers/LinkCanvas.svelte +103 -0
- package/dist/marks/helpers/LinkCanvas.svelte.d.ts +32 -0
- package/dist/marks/helpers/PathGroup.svelte +100 -0
- package/dist/marks/helpers/PathGroup.svelte.d.ts +16 -0
- package/dist/marks/helpers/PathItems.svelte +112 -0
- package/dist/marks/helpers/PathItems.svelte.d.ts +16 -0
- package/dist/marks/helpers/VectorCanvas.svelte +127 -0
- package/dist/marks/helpers/VectorCanvas.svelte.d.ts +36 -0
- package/dist/marks/index.d.ts +7 -0
- package/dist/marks/index.js +7 -0
- package/dist/types/mark.d.ts +1 -1
- package/dist/types/plot.d.ts +33 -1
- package/package.json +185 -181
package/dist/core/Plot.svelte
CHANGED
|
@@ -210,11 +210,8 @@
|
|
|
210
210
|
(fixedWidth || width) - plotOptions.marginLeft - plotOptions.marginRight
|
|
211
211
|
);
|
|
212
212
|
|
|
213
|
-
// Width used for
|
|
214
|
-
// Excludes reactive auto-margins to prevent a feedback loop
|
|
215
|
-
// height → plotHeight → y-tick density → y-label widths → autoMarginLeft → plotWidth → height
|
|
216
|
-
// Using explicit user-specified margins (0 when set to 'auto') keeps height stable
|
|
217
|
-
// while still updating when the container width or user-specified margins change.
|
|
213
|
+
// Width used for geo-projection aspect-ratio height computation only.
|
|
214
|
+
// Excludes reactive auto-margins to prevent a feedback loop in projection mode.
|
|
218
215
|
const plotWidthForAspectRatio = $derived(
|
|
219
216
|
(fixedWidth || width) -
|
|
220
217
|
maybeMargin(
|
|
@@ -267,7 +264,7 @@
|
|
|
267
264
|
preScales.x,
|
|
268
265
|
preScales.y,
|
|
269
266
|
plotOptions.aspectRatio,
|
|
270
|
-
|
|
267
|
+
plotWidth,
|
|
271
268
|
plotOptions.marginTop,
|
|
272
269
|
plotOptions.marginBottom
|
|
273
270
|
)
|
package/dist/helpers/group.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import type { Channels } from '../types/index.js';
|
|
|
3
3
|
* Groups the data by the fx, fy and z channels and calls the reduce function
|
|
4
4
|
* for each group. Returns the new channels to be added in the transform.
|
|
5
5
|
*/
|
|
6
|
-
export declare function groupFacetsAndZ<T>(items: T[], channels: Channels<T>, reduce: (items: T[], groupProps?: Record<string, unknown>) => any): any;
|
|
6
|
+
export declare function groupFacetsAndZ<T>(items: T[], channels: Channels<T>, reduce: (items: T[], groupProps?: Record<string, unknown>) => any, implicitColorZ?: boolean): any;
|
package/dist/helpers/group.js
CHANGED
|
@@ -4,15 +4,15 @@ import { groups as d3Groups } from 'd3-array';
|
|
|
4
4
|
* Groups the data by the fx, fy and z channels and calls the reduce function
|
|
5
5
|
* for each group. Returns the new channels to be added in the transform.
|
|
6
6
|
*/
|
|
7
|
-
export function groupFacetsAndZ(items, channels, reduce) {
|
|
7
|
+
export function groupFacetsAndZ(items, channels, reduce, implicitColorZ = true) {
|
|
8
8
|
const groupBy = ['fx', 'fy', 'z'].map((groupChannel) => {
|
|
9
9
|
let groupByChannel = null;
|
|
10
10
|
if (groupChannel === 'z') {
|
|
11
11
|
if (channels.z)
|
|
12
12
|
groupByChannel = 'z';
|
|
13
|
-
else if (channels.fill)
|
|
13
|
+
else if (channels.fill && implicitColorZ)
|
|
14
14
|
groupByChannel = 'fill';
|
|
15
|
-
else if (channels.stroke)
|
|
15
|
+
else if (channels.stroke && implicitColorZ)
|
|
16
16
|
groupByChannel = 'stroke';
|
|
17
17
|
}
|
|
18
18
|
else if (channels[groupChannel]) {
|
package/dist/helpers/scales.js
CHANGED
|
@@ -151,6 +151,14 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
|
|
|
151
151
|
!mark.options[ORIGINAL_NAME_KEYS[name]].startsWith('__')) {
|
|
152
152
|
propNames.add(mark.options[ORIGINAL_NAME_KEYS[name]]);
|
|
153
153
|
}
|
|
154
|
+
// marks that use a Symbol as fill accessor (e.g. Contour) pass the
|
|
155
|
+
// original field name via ORIGINAL_NAME_KEYS.fill so the color scale
|
|
156
|
+
// can still derive an autoTitle
|
|
157
|
+
if (name === 'color' &&
|
|
158
|
+
mark.options[ORIGINAL_NAME_KEYS.fill] &&
|
|
159
|
+
!mark.options[ORIGINAL_NAME_KEYS.fill].startsWith('__')) {
|
|
160
|
+
propNames.add(mark.options[ORIGINAL_NAME_KEYS.fill]);
|
|
161
|
+
}
|
|
154
162
|
}
|
|
155
163
|
else {
|
|
156
164
|
// also skip marks without data to prevent exceptions
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { pathRound as path } from 'd3-path';
|
|
2
|
+
type D3Path = ReturnType<typeof path>;
|
|
3
|
+
export type ShapeRenderer = {
|
|
4
|
+
draw(context: D3Path, l: number, r: number): void;
|
|
5
|
+
};
|
|
6
|
+
declare const defaultRadius = 3;
|
|
7
|
+
export declare const shapeArrow: ShapeRenderer;
|
|
8
|
+
export declare const shapeSpike: ShapeRenderer;
|
|
9
|
+
export declare const shapeArrowFilled: ShapeRenderer;
|
|
10
|
+
export declare function isShapeObject(value: unknown): value is ShapeRenderer;
|
|
11
|
+
export declare function maybeShape(shape: string | ShapeRenderer): ShapeRenderer;
|
|
12
|
+
export declare function shapePath(shape: string | ShapeRenderer, l: number, r: number): string;
|
|
13
|
+
export { defaultRadius };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { pathRound as path } from 'd3-path';
|
|
2
|
+
const defaultRadius = 3;
|
|
3
|
+
const wingRatio = defaultRadius * 5;
|
|
4
|
+
export const shapeArrow = {
|
|
5
|
+
draw(context, l, r) {
|
|
6
|
+
const wing = (l * r) / wingRatio;
|
|
7
|
+
context.moveTo(0, 0);
|
|
8
|
+
context.lineTo(0, -l);
|
|
9
|
+
context.moveTo(-wing, wing - l);
|
|
10
|
+
context.lineTo(0, -l);
|
|
11
|
+
context.lineTo(wing, wing - l);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
export const shapeSpike = {
|
|
15
|
+
draw(context, l, r) {
|
|
16
|
+
context.moveTo(-r, 0);
|
|
17
|
+
context.lineTo(0, -l);
|
|
18
|
+
context.lineTo(r, 0);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
export const shapeArrowFilled = {
|
|
22
|
+
draw(context, l, r) {
|
|
23
|
+
const headLength = Math.max(3, l * 0.3);
|
|
24
|
+
const headSpike = headLength * 0.2;
|
|
25
|
+
const headWidth = Math.max(2, l * 0.3);
|
|
26
|
+
const tailWidth = Math.max(2, l * 0.3) * 0.3;
|
|
27
|
+
context.moveTo(0, 0);
|
|
28
|
+
context.lineTo(tailWidth * 0.5, -l + headLength - headSpike);
|
|
29
|
+
context.lineTo(headWidth * 0.5, -l + headLength);
|
|
30
|
+
context.lineTo(0, -l);
|
|
31
|
+
context.lineTo(-headWidth * 0.5, -l + headLength);
|
|
32
|
+
context.lineTo(-tailWidth * 0.5, -l + headLength - headSpike);
|
|
33
|
+
context.closePath();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const shapes = new Map([
|
|
37
|
+
['arrow', shapeArrow],
|
|
38
|
+
['arrow-filled', shapeArrowFilled],
|
|
39
|
+
['spike', shapeSpike]
|
|
40
|
+
]);
|
|
41
|
+
export function isShapeObject(value) {
|
|
42
|
+
return value != null && typeof value.draw === 'function';
|
|
43
|
+
}
|
|
44
|
+
export function maybeShape(shape) {
|
|
45
|
+
if (isShapeObject(shape))
|
|
46
|
+
return shape;
|
|
47
|
+
const value = shapes.get(`${shape}`.toLowerCase());
|
|
48
|
+
if (value)
|
|
49
|
+
return value;
|
|
50
|
+
throw new Error(`invalid shape: ${shape}`);
|
|
51
|
+
}
|
|
52
|
+
export function shapePath(shape, l, r) {
|
|
53
|
+
const context = path();
|
|
54
|
+
maybeShape(shape).draw(context, l, r);
|
|
55
|
+
return context.toString();
|
|
56
|
+
}
|
|
57
|
+
export { defaultRadius };
|
package/dist/marks/Arrow.svelte
CHANGED
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
inset?: ConstantAccessor<number, Datum>;
|
|
44
44
|
/** controls the sweep direction of the arrow arc; 1 or -1 */
|
|
45
45
|
sweep?: SweepOption;
|
|
46
|
+
/** if true, renders using Canvas instead of SVG */
|
|
47
|
+
canvas?: boolean;
|
|
46
48
|
}
|
|
47
49
|
import type {
|
|
48
50
|
DataRecord,
|
|
@@ -62,6 +64,7 @@
|
|
|
62
64
|
} from '../helpers/arrowPath.js';
|
|
63
65
|
import { replaceChannels } from '../transforms/rename.js';
|
|
64
66
|
import { addEventHandlers } from './helpers/events.js';
|
|
67
|
+
import ArrowCanvas from './helpers/ArrowCanvas.svelte';
|
|
65
68
|
import GroupMultiple from './helpers/GroupMultiple.svelte';
|
|
66
69
|
import { sort } from '../transforms/sort.js';
|
|
67
70
|
import { indexData } from '../transforms/recordize.js';
|
|
@@ -79,6 +82,7 @@
|
|
|
79
82
|
|
|
80
83
|
const {
|
|
81
84
|
data = [{} as Datum],
|
|
85
|
+
canvas = false,
|
|
82
86
|
class: className = '',
|
|
83
87
|
...options
|
|
84
88
|
}: ArrowMarkProps = $derived({
|
|
@@ -106,66 +110,73 @@
|
|
|
106
110
|
{#snippet children({ usedScales, scaledData })}
|
|
107
111
|
{@const sweep = maybeSweep(args.sweep) as SweepFunc}
|
|
108
112
|
<GroupMultiple class="arrow" length={scaledData.length}>
|
|
109
|
-
{#
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
args.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
strokeWidth: strokeWidth ?? 1.6
|
|
147
|
-
},
|
|
148
|
-
'stroke',
|
|
149
|
-
usedScales
|
|
150
|
-
)}
|
|
151
|
-
<g
|
|
152
|
-
class={[className]}
|
|
153
|
-
{@attach addEventHandlers({
|
|
113
|
+
{#if canvas}
|
|
114
|
+
<ArrowCanvas data={scaledData} options={args as any} {usedScales} />
|
|
115
|
+
{:else}
|
|
116
|
+
{#each scaledData as d, i (i)}
|
|
117
|
+
{#if d.valid}
|
|
118
|
+
{@const datum = d.datum as unknown as Datum}
|
|
119
|
+
{@const inset = resolveProp(args.inset, datum, 0)}
|
|
120
|
+
{@const insetStart = resolveProp(args.insetStart, datum)}
|
|
121
|
+
{@const insetEnd = resolveProp(args.insetEnd, datum)}
|
|
122
|
+
{@const headAngle = (resolveProp(args.headAngle, datum, 60) ??
|
|
123
|
+
60) as number}
|
|
124
|
+
{@const headLength = (resolveProp(args.headLength, datum, 8) ??
|
|
125
|
+
8) as number}
|
|
126
|
+
{@const bendVal =
|
|
127
|
+
args.bend === true
|
|
128
|
+
? 22.5
|
|
129
|
+
: (resolveProp(
|
|
130
|
+
args.bend as ConstantAccessor<number, Datum>,
|
|
131
|
+
datum,
|
|
132
|
+
0
|
|
133
|
+
) ?? 0)}
|
|
134
|
+
{@const strokeWidth = (resolveProp(args.strokeWidth, datum, 1) ??
|
|
135
|
+
1) as number}
|
|
136
|
+
{@const arrPath = arrowPath(
|
|
137
|
+
d.x1 ?? 0,
|
|
138
|
+
d.y1 ?? 0,
|
|
139
|
+
d.x2 ?? 0,
|
|
140
|
+
d.y2 ?? 0,
|
|
141
|
+
maybeNumber(coalesce(insetStart, inset)) ?? 0,
|
|
142
|
+
maybeNumber(coalesce(insetEnd, inset)) ?? 0,
|
|
143
|
+
headAngle,
|
|
144
|
+
headLength,
|
|
145
|
+
bendVal,
|
|
146
|
+
strokeWidth,
|
|
147
|
+
sweep
|
|
148
|
+
)}
|
|
149
|
+
{@const [style, styleClass] = resolveStyles(
|
|
154
150
|
plot,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
<
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
151
|
+
d,
|
|
152
|
+
{
|
|
153
|
+
strokeLinecap: 'round',
|
|
154
|
+
strokeLinejoin: 'round',
|
|
155
|
+
...args,
|
|
156
|
+
strokeWidth: strokeWidth ?? 1.6
|
|
157
|
+
},
|
|
158
|
+
'stroke',
|
|
159
|
+
usedScales
|
|
160
|
+
)}
|
|
161
|
+
<g
|
|
162
|
+
class={[className]}
|
|
163
|
+
{@attach addEventHandlers({
|
|
164
|
+
plot,
|
|
165
|
+
options: options as any,
|
|
166
|
+
datum: d?.datum
|
|
167
|
+
})}>
|
|
168
|
+
{#if options.onmouseenter || options.onclick}
|
|
169
|
+
<!-- add invisible path in bg for easier mouse access -->
|
|
170
|
+
<path
|
|
171
|
+
d={arrPath}
|
|
172
|
+
style="fill:none;stroke-width: {(strokeWidth || 1) +
|
|
173
|
+
10}; stroke: red; stroke-opacity:0" />
|
|
174
|
+
{/if}
|
|
175
|
+
<path class={[styleClass]} d={arrPath} {style} />
|
|
176
|
+
</g>
|
|
177
|
+
{/if}
|
|
178
|
+
{/each}
|
|
179
|
+
{/if}
|
|
169
180
|
</GroupMultiple>
|
|
170
181
|
{/snippet}
|
|
171
182
|
</Mark>
|
|
@@ -177,6 +177,8 @@ declare function $$render<Datum = DataRecord | GeoJSON.GeoJsonObject>(): {
|
|
|
177
177
|
inset?: ConstantAccessor<number, Datum>;
|
|
178
178
|
/** controls the sweep direction of the arrow arc; 1 or -1 */
|
|
179
179
|
sweep?: SweepOption;
|
|
180
|
+
/** if true, renders using Canvas instead of SVG */
|
|
181
|
+
canvas?: boolean;
|
|
180
182
|
};
|
|
181
183
|
exports: {};
|
|
182
184
|
bindings: "";
|
|
@@ -19,8 +19,12 @@
|
|
|
19
19
|
|
|
20
20
|
const DEFAULTS = getPlotDefaults();
|
|
21
21
|
|
|
22
|
-
const legendTitle = $derived(plot.options.color.label);
|
|
23
22
|
const scaleType = $derived(plot.scales.color.type);
|
|
23
|
+
const legendTitle = $derived(
|
|
24
|
+
scaleType === 'categorical'
|
|
25
|
+
? (plot.options.color.label ?? '')
|
|
26
|
+
: (plot.options.color.label ?? plot.scales.color?.autoTitle)
|
|
27
|
+
);
|
|
24
28
|
const tickFormat = $derived(
|
|
25
29
|
typeof plot.options.color?.tickFormat === 'function'
|
|
26
30
|
? plot.options.color.tickFormat
|
|
@@ -158,12 +162,12 @@
|
|
|
158
162
|
<style>
|
|
159
163
|
.color-legend {
|
|
160
164
|
text-align: left;
|
|
161
|
-
font-size:
|
|
165
|
+
font-size: 11px;
|
|
162
166
|
display: inline-block;
|
|
163
167
|
margin-right: 2em;
|
|
164
168
|
}
|
|
165
169
|
.title {
|
|
166
|
-
|
|
170
|
+
opacity: 0.8;
|
|
167
171
|
}
|
|
168
172
|
.item {
|
|
169
173
|
margin: 0 1em 0.5ex 0;
|