svelteplot 0.1.3-next.9 → 0.2.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 +4 -2
- package/dist/Mark.svelte +6 -1
- package/dist/Plot.svelte +45 -29
- package/dist/helpers/index.d.ts +1 -1
- package/dist/helpers/resolve.js +1 -1
- package/dist/helpers/scales.js +3 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/marks/BarX.svelte +15 -5
- package/dist/marks/BarY.svelte +20 -12
- package/dist/marks/BarY.svelte.d.ts +22 -1
- package/dist/marks/Brush.svelte +364 -0
- package/dist/marks/Brush.svelte.d.ts +32 -0
- package/dist/marks/BrushX.svelte +7 -0
- package/dist/marks/BrushX.svelte.d.ts +4 -0
- package/dist/marks/BrushY.svelte +7 -0
- package/dist/marks/BrushY.svelte.d.ts +4 -0
- package/dist/marks/Cell.svelte +0 -7
- package/dist/marks/Dot.svelte +9 -18
- package/dist/marks/Dot.svelte.d.ts +8 -8
- package/dist/marks/Frame.svelte +10 -5
- package/dist/marks/Frame.svelte.d.ts +6 -1
- package/dist/marks/GridX.svelte +15 -6
- package/dist/marks/GridY.svelte +15 -6
- package/dist/marks/Pointer.svelte +2 -2
- package/dist/marks/Pointer.svelte.d.ts +2 -2
- package/dist/marks/Rect.svelte +12 -19
- package/dist/marks/Sphere.svelte.d.ts +14 -4
- package/dist/marks/Text.svelte +2 -2
- package/dist/marks/Text.svelte.d.ts +2 -2
- package/dist/marks/helpers/events.d.ts +13 -0
- package/dist/marks/helpers/events.js +32 -3
- package/dist/transforms/bin.d.ts +7 -7
- package/dist/transforms/recordize.d.ts +1 -0
- package/dist/transforms/recordize.js +4 -5
- package/dist/transforms/window.d.ts +2 -0
- package/dist/types.d.ts +29 -9
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# SveltePlot
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
SveltePlot is a visualization framework based on the [layered grammar of graphics](https://vita.had.co.nz/papers/layered-grammar.html) ideas. It's API is heavily inspired by [Observable Plot](https://github.com/observablehq/plot). Created by Gregor Aisch.
|
|
6
|
+
|
|
7
|
+
<img src="static/logo.png" alt="SveltePlot logo" width="401" />
|
package/dist/Mark.svelte
CHANGED
|
@@ -227,7 +227,12 @@
|
|
|
227
227
|
);
|
|
228
228
|
out[`x${suffix}`] = x;
|
|
229
229
|
out[`y${suffix}`] = y;
|
|
230
|
-
out.valid =
|
|
230
|
+
out.valid =
|
|
231
|
+
out.valid &&
|
|
232
|
+
isValid(row.x) &&
|
|
233
|
+
isValid(row.y) &&
|
|
234
|
+
isValid(x) &&
|
|
235
|
+
isValid(y);
|
|
231
236
|
}
|
|
232
237
|
}
|
|
233
238
|
}
|
package/dist/Plot.svelte
CHANGED
|
@@ -116,39 +116,47 @@
|
|
|
116
116
|
scales,
|
|
117
117
|
...restProps
|
|
118
118
|
})}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
{#if
|
|
122
|
-
|
|
119
|
+
<svelte:boundary onerror={(err) => console.warn(err)}>
|
|
120
|
+
<!-- implicit axes -->
|
|
121
|
+
{#if !hasProjection && !hasExplicitAxisX}
|
|
122
|
+
{#if options.axes && (options.x.axis === 'top' || options.x.axis === 'both')}
|
|
123
|
+
<AxisX anchor="top" automatic />
|
|
124
|
+
{/if}
|
|
125
|
+
{#if options.axes && (options.x.axis === 'bottom' || options.x.axis === 'both')}
|
|
126
|
+
<AxisX anchor="bottom" automatic />
|
|
127
|
+
{/if}
|
|
123
128
|
{/if}
|
|
124
|
-
{#if
|
|
125
|
-
|
|
129
|
+
{#if !hasProjection && !hasExplicitAxisY}
|
|
130
|
+
{#if options.axes && (options.y.axis === 'left' || options.y.axis === 'both')}
|
|
131
|
+
<AxisY anchor="left" automatic />
|
|
132
|
+
{/if}
|
|
133
|
+
{#if options.axes && (options.y.axis === 'right' || options.y.axis === 'both')}
|
|
134
|
+
<AxisY anchor="right" automatic />
|
|
135
|
+
{/if}
|
|
126
136
|
{/if}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
<AxisY anchor="left" automatic />
|
|
137
|
+
<!-- implicit grids -->
|
|
138
|
+
{#if !hasExplicitGridX && (options.grid || options.x.grid)}
|
|
139
|
+
<GridX automatic />
|
|
131
140
|
{/if}
|
|
132
|
-
{#if
|
|
133
|
-
<
|
|
141
|
+
{#if !hasExplicitGridY && (options.grid || options.y.grid)}
|
|
142
|
+
<GridY automatic />
|
|
134
143
|
{/if}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
})}
|
|
144
|
+
<!-- implicit frame -->
|
|
145
|
+
{#if options.frame}
|
|
146
|
+
<Frame automatic />
|
|
147
|
+
{/if}
|
|
148
|
+
{@render parentChildren?.({
|
|
149
|
+
options,
|
|
150
|
+
scales,
|
|
151
|
+
...restProps
|
|
152
|
+
})}
|
|
153
|
+
{#snippet failed(error, reset)}
|
|
154
|
+
<text class="error" transform="translate(10,10)">
|
|
155
|
+
{#each error.message.split('\n') as line, i}
|
|
156
|
+
<tspan x="0" dy={i ? 14 : 0}>{line}</tspan>
|
|
157
|
+
{/each}
|
|
158
|
+
</text>{/snippet}
|
|
159
|
+
</svelte:boundary>
|
|
152
160
|
{/snippet}
|
|
153
161
|
{#snippet facetAxes()}
|
|
154
162
|
<FacetAxes />
|
|
@@ -160,4 +168,12 @@
|
|
|
160
168
|
--plot-bg: white;
|
|
161
169
|
--plot-fg: currentColor;
|
|
162
170
|
}
|
|
171
|
+
text.error {
|
|
172
|
+
stroke: var(--plot-bg);
|
|
173
|
+
fill: crimson;
|
|
174
|
+
font-size: 11px;
|
|
175
|
+
stroke-width: 3px;
|
|
176
|
+
font-weight: bold;
|
|
177
|
+
paint-order: stroke fill;
|
|
178
|
+
}
|
|
163
179
|
</style>
|
package/dist/helpers/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { Snippet } from 'svelte';
|
|
|
4
4
|
* Returns first argument that is not null or undefined
|
|
5
5
|
*/
|
|
6
6
|
export declare function coalesce(...args: (RawValue | undefined | null)[]): RawValue | null;
|
|
7
|
-
export declare function testFilter(datum: DataRecord, options: Record<ChannelName, ChannelAccessor>): string | number | boolean | Date | null;
|
|
7
|
+
export declare function testFilter(datum: DataRecord, options: Record<ChannelName, ChannelAccessor>): string | number | boolean | symbol | Date | null;
|
|
8
8
|
export declare function randomId(): string;
|
|
9
9
|
export declare function isSnippet(value: unknown): value is Snippet;
|
|
10
10
|
export declare function isValid(value: RawValue | undefined): value is number | Date | string;
|
package/dist/helpers/resolve.js
CHANGED
|
@@ -51,7 +51,7 @@ function resolve(datum, accessor, channel, scale) {
|
|
|
51
51
|
// so we're passing the original value to accessor functions instead of our wrapped record
|
|
52
52
|
return accessor(datum.___orig___ != null ? datum.___orig___ : datum);
|
|
53
53
|
// use accessor string
|
|
54
|
-
if (typeof accessor === 'string' && datum[accessor] !== undefined)
|
|
54
|
+
if ((typeof accessor === 'string' || typeof accessor === 'symbol') && datum[accessor] !== undefined)
|
|
55
55
|
return datum[accessor];
|
|
56
56
|
// fallback to channel name as accessor
|
|
57
57
|
if (accessor === null && datum[channel] !== undefined)
|
package/dist/helpers/scales.js
CHANGED
|
@@ -147,7 +147,9 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
|
|
|
147
147
|
valueArr.sort(ascending);
|
|
148
148
|
}
|
|
149
149
|
const domain = scaleOptions.domain
|
|
150
|
-
?
|
|
150
|
+
? isOrdinal
|
|
151
|
+
? scaleOptions.domain
|
|
152
|
+
: extent(scaleOptions.zero ? [0, ...scaleOptions.domain] : scaleOptions.domain)
|
|
151
153
|
: type === 'band' ||
|
|
152
154
|
type === 'point' ||
|
|
153
155
|
type === 'ordinal' ||
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,9 @@ export { default as BollingerX } from './marks/BollingerX.svelte';
|
|
|
10
10
|
export { default as BollingerY } from './marks/BollingerY.svelte';
|
|
11
11
|
export { default as BoxX } from './marks/BoxX.svelte';
|
|
12
12
|
export { default as BoxY } from './marks/BoxY.svelte';
|
|
13
|
+
export { default as Brush } from './marks/Brush.svelte';
|
|
14
|
+
export { default as BrushX } from './marks/BrushX.svelte';
|
|
15
|
+
export { default as BrushY } from './marks/BrushY.svelte';
|
|
13
16
|
export { default as Cell } from './marks/Cell.svelte';
|
|
14
17
|
export { default as CellX } from './marks/CellX.svelte';
|
|
15
18
|
export { default as CellY } from './marks/CellY.svelte';
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,9 @@ export { default as BollingerX } from './marks/BollingerX.svelte';
|
|
|
11
11
|
export { default as BollingerY } from './marks/BollingerY.svelte';
|
|
12
12
|
export { default as BoxX } from './marks/BoxX.svelte';
|
|
13
13
|
export { default as BoxY } from './marks/BoxY.svelte';
|
|
14
|
+
export { default as Brush } from './marks/Brush.svelte';
|
|
15
|
+
export { default as BrushX } from './marks/BrushX.svelte';
|
|
16
|
+
export { default as BrushY } from './marks/BrushY.svelte';
|
|
14
17
|
export { default as Cell } from './marks/Cell.svelte';
|
|
15
18
|
export { default as CellX } from './marks/CellX.svelte';
|
|
16
19
|
export { default as CellY } from './marks/CellY.svelte';
|
package/dist/marks/BarX.svelte
CHANGED
|
@@ -46,8 +46,6 @@
|
|
|
46
46
|
stack
|
|
47
47
|
)
|
|
48
48
|
);
|
|
49
|
-
|
|
50
|
-
$inspect({ args });
|
|
51
49
|
</script>
|
|
52
50
|
|
|
53
51
|
<Mark
|
|
@@ -61,16 +59,28 @@
|
|
|
61
59
|
{@const bw = plot.scales.y.fn.bandwidth()}
|
|
62
60
|
{@const minx = Math.min(d.x1, d.x2)}
|
|
63
61
|
{@const maxx = Math.max(d.x1, d.x2)}
|
|
64
|
-
{@const
|
|
62
|
+
{@const insetLeft = resolveProp(args.insetLeft, d.datum, 0)}
|
|
63
|
+
{@const insetRight = resolveProp(args.insetRight, d.datum, 0)}
|
|
64
|
+
{@const insetTop = resolveProp(args.insetTop || args.inset, d.datum, 0)}
|
|
65
|
+
{@const insetBottom = resolveProp(args.insetBottom || args.inset, d.datum, 0)}
|
|
65
66
|
{@const dx = resolveProp(args.dx, d.datum, 0)}
|
|
66
67
|
{@const dy = resolveProp(args.dy, d.datum, 0)}
|
|
67
68
|
{#if d.valid}
|
|
68
69
|
{@const [style, styleClass] = resolveStyles(plot, d, args, 'fill', usedScales)}
|
|
69
70
|
<path
|
|
70
|
-
d={roundedRect(
|
|
71
|
+
d={roundedRect(
|
|
72
|
+
0,
|
|
73
|
+
0,
|
|
74
|
+
maxx - minx - insetLeft - insetRight,
|
|
75
|
+
bw - insetTop - insetBottom,
|
|
76
|
+
options.borderRadius
|
|
77
|
+
)}
|
|
71
78
|
class={[styleClass, className]}
|
|
72
79
|
{style}
|
|
73
|
-
transform="translate({[
|
|
80
|
+
transform="translate({[
|
|
81
|
+
minx + dx + insetLeft,
|
|
82
|
+
d.y + insetTop + dy - bw * 0.5
|
|
83
|
+
]})"
|
|
74
84
|
use:addEventHandlers={{
|
|
75
85
|
getPlotState,
|
|
76
86
|
options: args,
|
package/dist/marks/BarY.svelte
CHANGED
|
@@ -11,10 +11,8 @@
|
|
|
11
11
|
import {
|
|
12
12
|
type PlotContext,
|
|
13
13
|
type BaseMarkProps,
|
|
14
|
-
type RectMarkProps,
|
|
15
14
|
type ChannelAccessor,
|
|
16
|
-
type DataRow
|
|
17
|
-
type FacetContext
|
|
15
|
+
type DataRow
|
|
18
16
|
} from '../types.js';
|
|
19
17
|
import type { StackOptions } from '../transforms/stack.js';
|
|
20
18
|
import { maybeData } from '../helpers/index.js';
|
|
@@ -41,25 +39,23 @@
|
|
|
41
39
|
bottomRight?: number;
|
|
42
40
|
bottomLeft?: number;
|
|
43
41
|
};
|
|
44
|
-
}
|
|
42
|
+
};
|
|
45
43
|
|
|
46
44
|
let { data = [{}], class: className = null, stack, ...options }: BarYProps = $props();
|
|
47
45
|
|
|
48
46
|
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
49
|
-
|
|
47
|
+
const plot = $derived(getPlotState());
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
const args = $derived(
|
|
52
50
|
stackY(
|
|
53
51
|
intervalY(
|
|
54
52
|
// by default, sort by x channel (the ordinal labels)
|
|
55
|
-
sort(recordizeY({ data
|
|
53
|
+
sort(recordizeY({ data, sort: { channel: 'x' }, ...options })),
|
|
56
54
|
{ plot }
|
|
57
55
|
),
|
|
58
56
|
stack
|
|
59
57
|
)
|
|
60
58
|
);
|
|
61
|
-
|
|
62
|
-
const { getTestFacet } = getContext<FacetContext>('svelteplot/facet');
|
|
63
59
|
</script>
|
|
64
60
|
|
|
65
61
|
<Mark
|
|
@@ -73,16 +69,28 @@
|
|
|
73
69
|
{@const bw = plot.scales.x.fn.bandwidth()}
|
|
74
70
|
{@const miny = Math.min(d.y1, d.y2)}
|
|
75
71
|
{@const maxy = Math.max(d.y1, d.y2)}
|
|
76
|
-
{@const
|
|
72
|
+
{@const insetLeft = resolveProp(args.insetLeft || args.inset, d.datum, 0)}
|
|
73
|
+
{@const insetRight = resolveProp(args.insetRight || args.inset, d.datum, 0)}
|
|
74
|
+
{@const insetTop = resolveProp(args.insetTop, d.datum, 0)}
|
|
75
|
+
{@const insetBottom = resolveProp(args.insetBottom, d.datum, 0)}
|
|
77
76
|
{@const dx = resolveProp(args.dx, d.datum, 0)}
|
|
78
77
|
{@const dy = resolveProp(args.dy, d.datum, 0)}
|
|
79
78
|
{#if d.valid}
|
|
80
79
|
{@const [style, styleClass] = resolveStyles(plot, d, args, 'fill', usedScales)}
|
|
81
80
|
<path
|
|
82
|
-
d={roundedRect(
|
|
81
|
+
d={roundedRect(
|
|
82
|
+
0,
|
|
83
|
+
0,
|
|
84
|
+
bw - insetLeft - insetRight,
|
|
85
|
+
maxy - miny - insetTop - insetBottom,
|
|
86
|
+
options.borderRadius
|
|
87
|
+
)}
|
|
83
88
|
class={[styleClass, className]}
|
|
84
89
|
{style}
|
|
85
|
-
transform="translate({[
|
|
90
|
+
transform="translate({[
|
|
91
|
+
d.x + insetLeft + dx - bw * 0.5,
|
|
92
|
+
miny + dy + insetTop
|
|
93
|
+
]})"
|
|
86
94
|
use:addEventHandlers={{
|
|
87
95
|
getPlotState,
|
|
88
96
|
options: args,
|
|
@@ -1,4 +1,25 @@
|
|
|
1
|
+
import { type BaseMarkProps, type ChannelAccessor, type DataRow } from '../types.js';
|
|
2
|
+
import type { StackOptions } from '../transforms/stack.js';
|
|
3
|
+
type BarYProps = BaseMarkProps & {
|
|
4
|
+
data: DataRow[];
|
|
5
|
+
x?: ChannelAccessor;
|
|
6
|
+
y?: ChannelAccessor;
|
|
7
|
+
y1?: ChannelAccessor;
|
|
8
|
+
y2?: ChannelAccessor;
|
|
9
|
+
stack?: StackOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Converts y into y1/y2 ranges based on the provided interval. Disables the
|
|
12
|
+
* implicit stacking
|
|
13
|
+
*/
|
|
14
|
+
interval?: number | string;
|
|
15
|
+
borderRadius?: number | {
|
|
16
|
+
topLeft?: number;
|
|
17
|
+
topRight?: number;
|
|
18
|
+
bottomRight?: number;
|
|
19
|
+
bottomLeft?: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
1
22
|
/** For vertical column charts using a band scale as x axis */
|
|
2
|
-
declare const BarY: import("svelte").Component<
|
|
23
|
+
declare const BarY: import("svelte").Component<BarYProps, {}, "">;
|
|
3
24
|
type BarY = ReturnType<typeof BarY>;
|
|
4
25
|
export default BarY;
|