svelteplot 0.1.3-next.7 → 0.1.3-next.9
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/Mark.svelte +20 -19
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/core/Plot.svelte +3 -3
- package/dist/helpers/index.js +3 -1
- package/dist/helpers/scales.js +1 -1
- package/dist/marks/BarX.svelte +3 -1
- package/dist/marks/BarY.svelte +1 -1
- package/dist/marks/Cell.svelte +1 -1
- package/dist/marks/Dot.svelte +1 -1
- package/dist/marks/Frame.svelte +14 -7
- package/dist/marks/Geo.svelte +1 -1
- package/dist/marks/Link.svelte +1 -1
- package/dist/marks/Text.svelte +12 -4
- package/dist/marks/Vector.svelte +6 -0
- package/dist/marks/helpers/events.js +16 -6
- package/dist/transforms/recordize.d.ts +1 -0
- package/dist/transforms/recordize.js +4 -0
- package/dist/transforms/sort.d.ts +1 -1
- package/dist/transforms/sort.js +8 -3
- package/package.json +10 -10
package/dist/Mark.svelte
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getContext, untrack, type Snippet } from 'svelte';
|
|
3
3
|
|
|
4
|
-
import { CHANNEL_SCALE } from './constants.js';
|
|
4
|
+
import { CHANNEL_SCALE, INDEX } from './constants.js';
|
|
5
5
|
import type {
|
|
6
6
|
ScaledChannelName,
|
|
7
7
|
MarkType,
|
|
@@ -126,24 +126,26 @@
|
|
|
126
126
|
const testFacet = $derived(getTestFacet());
|
|
127
127
|
|
|
128
128
|
const resolvedData: ResolvedDataRecord[] = $derived(
|
|
129
|
-
data
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
//
|
|
142
|
-
|
|
129
|
+
data
|
|
130
|
+
.map((d, i) => ({ ...d, [INDEX]: i }))
|
|
131
|
+
.flatMap((row) => {
|
|
132
|
+
const channels = options as Record<ChannelName, ChannelAccessor>;
|
|
133
|
+
if (!testFacet(row, channels) || !testFilter(row, channels)) return [];
|
|
134
|
+
const out: ResolvedDataRecord = {
|
|
135
|
+
datum: row
|
|
136
|
+
};
|
|
137
|
+
for (const [channel] of Object.entries(CHANNEL_SCALE) as [
|
|
138
|
+
ScaledChannelName,
|
|
139
|
+
ScaleName
|
|
140
|
+
][]) {
|
|
141
|
+
// check if the mark has defined an accessor for this channel
|
|
142
|
+
if (options?.[channel] !== undefined && out[channel] === undefined) {
|
|
143
|
+
// resolve value
|
|
144
|
+
out[channel] = resolveChannel(channel, row, options);
|
|
145
|
+
}
|
|
143
146
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
})
|
|
147
|
+
return [out];
|
|
148
|
+
})
|
|
147
149
|
);
|
|
148
150
|
|
|
149
151
|
let prevResolvedData: ResolvedDataRecord[] = [];
|
|
@@ -156,7 +158,6 @@
|
|
|
156
158
|
}
|
|
157
159
|
});
|
|
158
160
|
|
|
159
|
-
|
|
160
161
|
function isDifferent(array1: ResolvedDataRecord[], array2: ResolvedDataRecord[]) {
|
|
161
162
|
if (array1.length !== array2.length) return true;
|
|
162
163
|
for (let i = 0; i < array1.length; i++) {
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
|
@@ -94,6 +94,7 @@ export const CSS_COLOR_MIX = /^color-mix\(/; // just check for prefix
|
|
|
94
94
|
export const CSS_COLOR_CONTRAST = /^color-contrast\(/; // just check for prefix
|
|
95
95
|
export const CSS_RGBA = /^rgba\(/; // just check for prefix
|
|
96
96
|
export const CSS_URL = /^url\(#/; // just check for prefix
|
|
97
|
+
export const INDEX = Symbol('index');
|
|
97
98
|
// export const CHANNEL_MAP: Record<ScaleName, ValueOf<typeof SCALE_TYPES>> = {
|
|
98
99
|
// x: SCALE_TYPES.x,
|
|
99
100
|
// y: SCALE_TYPES.y,
|
package/dist/core/Plot.svelte
CHANGED
|
@@ -108,8 +108,6 @@
|
|
|
108
108
|
inset?: number;
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
-
let scaleCounter = $state(0);
|
|
112
|
-
|
|
113
111
|
/**
|
|
114
112
|
* the marks used in the plot
|
|
115
113
|
*/
|
|
@@ -177,7 +175,9 @@
|
|
|
177
175
|
|
|
178
176
|
const hasProjection = $derived(!!preScales.projection);
|
|
179
177
|
|
|
180
|
-
const plotWidth = $derived(
|
|
178
|
+
const plotWidth = $derived(
|
|
179
|
+
(fixedWidth || width) - plotOptions.marginLeft - plotOptions.marginRight
|
|
180
|
+
);
|
|
181
181
|
|
|
182
182
|
// the facet and y domain counts are used for computing the automatic height
|
|
183
183
|
const xFacetCount = $derived(Math.max(1, preScales.fx.domain.length));
|
package/dist/helpers/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveProp } from './resolve.js';
|
|
2
2
|
import { isDate } from './typeChecks';
|
|
3
|
+
import { RAW_VALUE } from '../transforms/recordize.js';
|
|
3
4
|
/**
|
|
4
5
|
* Returns first argument that is not null or undefined
|
|
5
6
|
*/
|
|
@@ -12,7 +13,8 @@ export function coalesce(...args) {
|
|
|
12
13
|
return null; // Return null if all arguments are null or undefined
|
|
13
14
|
}
|
|
14
15
|
export function testFilter(datum, options) {
|
|
15
|
-
return options.filter == null ||
|
|
16
|
+
return (options.filter == null ||
|
|
17
|
+
resolveProp(options.filter, datum?.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum));
|
|
16
18
|
}
|
|
17
19
|
export function randomId() {
|
|
18
20
|
return Math.ceil(1e9 + Math.random() * 1e9).toString(36);
|
package/dist/helpers/scales.js
CHANGED
|
@@ -147,7 +147,7 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
|
|
|
147
147
|
valueArr.sort(ascending);
|
|
148
148
|
}
|
|
149
149
|
const domain = scaleOptions.domain
|
|
150
|
-
? scaleOptions.domain
|
|
150
|
+
? extent(scaleOptions.zero ? [0, ...scaleOptions.domain] : scaleOptions.domain)
|
|
151
151
|
: type === 'band' ||
|
|
152
152
|
type === 'point' ||
|
|
153
153
|
type === 'ordinal' ||
|
package/dist/marks/BarX.svelte
CHANGED
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
stack
|
|
47
47
|
)
|
|
48
48
|
);
|
|
49
|
+
|
|
50
|
+
$inspect({ args });
|
|
49
51
|
</script>
|
|
50
52
|
|
|
51
53
|
<Mark
|
|
@@ -71,7 +73,7 @@
|
|
|
71
73
|
transform="translate({[minx + dx, d.y + inset + dy - bw * 0.5]})"
|
|
72
74
|
use:addEventHandlers={{
|
|
73
75
|
getPlotState,
|
|
74
|
-
options:
|
|
76
|
+
options: args,
|
|
75
77
|
datum: d.datum
|
|
76
78
|
}} />
|
|
77
79
|
{/if}
|
package/dist/marks/BarY.svelte
CHANGED
package/dist/marks/Cell.svelte
CHANGED
package/dist/marks/Dot.svelte
CHANGED
package/dist/marks/Frame.svelte
CHANGED
|
@@ -14,10 +14,17 @@
|
|
|
14
14
|
let { automatic, class: className = null, ...options }: FrameMarkProps = $props();
|
|
15
15
|
|
|
16
16
|
const { getPlotState } = getContext<PlotContext>('svelteplot');
|
|
17
|
-
|
|
17
|
+
const plot = $derived(getPlotState());
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const dx = $derived(resolveProp(options.dx, null, 0));
|
|
20
|
+
const dy = $derived(resolveProp(options.dy, null, 0));
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
insetLeft = options.inset || 0,
|
|
24
|
+
insetTop = options.inset || 0,
|
|
25
|
+
insetRight = options.inset || 0,
|
|
26
|
+
insetBottom = options.inset || 0
|
|
27
|
+
} = $derived(options);
|
|
21
28
|
</script>
|
|
22
29
|
|
|
23
30
|
<Mark type="frame" {automatic}>
|
|
@@ -25,12 +32,12 @@
|
|
|
25
32
|
class={['frame', className]}
|
|
26
33
|
transform={dx || dy ? `translate(${dx},${dy})` : null}
|
|
27
34
|
style={resolveScaledStyles({}, options, {}, plot, 'stroke')}
|
|
28
|
-
x={plot.options.marginLeft}
|
|
29
|
-
y={plot.options.marginTop}
|
|
35
|
+
x={plot.options.marginLeft + +insetLeft}
|
|
36
|
+
y={plot.options.marginTop + +insetTop}
|
|
30
37
|
rx={resolveProp(options.rx, null, null)}
|
|
31
38
|
ry={resolveProp(options.ry, null, null)}
|
|
32
|
-
width={plot.facetWidth}
|
|
33
|
-
height={plot.facetHeight}
|
|
39
|
+
width={plot.facetWidth - (insetLeft || 0) - (insetRight || 0)}
|
|
40
|
+
height={plot.facetHeight - (insetBottom || 0) - (insetTop || 0)}
|
|
34
41
|
use:addEventHandlers={{ getPlotState, options: options, datum: {} }} />
|
|
35
42
|
</Mark>
|
|
36
43
|
|
package/dist/marks/Geo.svelte
CHANGED
package/dist/marks/Link.svelte
CHANGED
package/dist/marks/Text.svelte
CHANGED
|
@@ -131,8 +131,13 @@
|
|
|
131
131
|
{@const [style, styleClass] = resolveStyles(
|
|
132
132
|
plot,
|
|
133
133
|
{ ...d, __tspanIndex: 0 },
|
|
134
|
-
{
|
|
135
|
-
|
|
134
|
+
{
|
|
135
|
+
fontSize: 12,
|
|
136
|
+
fontWeight: 500,
|
|
137
|
+
strokeWidth: 1.6,
|
|
138
|
+
textAnchor: isLeft ? 'start' : isRight ? 'end' : 'middle',
|
|
139
|
+
...args
|
|
140
|
+
},
|
|
136
141
|
'fill',
|
|
137
142
|
usedScales
|
|
138
143
|
)}
|
|
@@ -156,8 +161,11 @@
|
|
|
156
161
|
fontSize
|
|
157
162
|
)
|
|
158
163
|
]})"
|
|
159
|
-
>{#each textLines as line, l}<tspan
|
|
160
|
-
|
|
164
|
+
>{#each textLines as line, l}<tspan
|
|
165
|
+
x="0"
|
|
166
|
+
dy={l ? fontSize : 0}
|
|
167
|
+
class={styleClass}
|
|
168
|
+
{style}>{line}</tspan
|
|
161
169
|
>{/each}{#if title}<title>{title}</title>{/if}</text>
|
|
162
170
|
{:else}
|
|
163
171
|
<!-- singleline text-->
|
package/dist/marks/Vector.svelte
CHANGED
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
import Mark from '../Mark.svelte';
|
|
49
49
|
//import DotCanvas from './helpers/DotCanvas.svelte';
|
|
50
50
|
import { maybeData, testFilter, isValid } from '../helpers/index.js';
|
|
51
|
+
import { addEventHandlers } from './helpers/events.js';
|
|
51
52
|
|
|
52
53
|
const defaultRadius = 3.5;
|
|
53
54
|
|
|
@@ -198,6 +199,11 @@
|
|
|
198
199
|
? `translate(0, ${d.length})`
|
|
199
200
|
: `translate(0, ${d.length / 2})`}"
|
|
200
201
|
{style}
|
|
202
|
+
use:addEventHandlers={{
|
|
203
|
+
getPlotState,
|
|
204
|
+
options: args,
|
|
205
|
+
datum: d.datum
|
|
206
|
+
}}
|
|
201
207
|
class={[styleClass]} />
|
|
202
208
|
{/if}
|
|
203
209
|
{/each}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { pick } from 'es-toolkit';
|
|
1
|
+
import { invert, pick } from 'es-toolkit';
|
|
2
|
+
import { RAW_VALUE } from '../../transforms/recordize.js';
|
|
3
|
+
import { INDEX } from '../../constants.js';
|
|
2
4
|
export function addEventHandlers(node, { options, datum, getPlotState }) {
|
|
3
5
|
const events = pick(options, [
|
|
4
6
|
'onclick',
|
|
@@ -38,13 +40,11 @@ export function addEventHandlers(node, { options, datum, getPlotState }) {
|
|
|
38
40
|
origEvent.dataY = y;
|
|
39
41
|
}
|
|
40
42
|
else {
|
|
41
|
-
origEvent.dataX =
|
|
42
|
-
|
|
43
|
-
origEvent.dataY =
|
|
44
|
-
scales.y.fn.invert && scales.y.fn.invert(origEvent.layerY);
|
|
43
|
+
origEvent.dataX = invertScale(scales.x, origEvent.layerX);
|
|
44
|
+
origEvent.dataY = invertScale(scales.y, origEvent.layerY);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
eventHandler(origEvent, datum.
|
|
47
|
+
eventHandler(origEvent, datum.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum, datum[INDEX]);
|
|
48
48
|
};
|
|
49
49
|
listeners.set(eventName, wrappedHandler);
|
|
50
50
|
node.addEventListener(eventName.substring(2), wrappedHandler);
|
|
@@ -62,3 +62,13 @@ export function addEventHandlers(node, { options, datum, getPlotState }) {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
+
function invertScale(scale, position) {
|
|
66
|
+
if (scale.type === 'band') {
|
|
67
|
+
// invert band scale since scaleBand doesn't have an invert function
|
|
68
|
+
const eachBand = scale.fn.step();
|
|
69
|
+
console.log({ eachBand, position });
|
|
70
|
+
const index = Math.floor(position / eachBand);
|
|
71
|
+
return scale.fn.domain()[index];
|
|
72
|
+
}
|
|
73
|
+
return scale.fn.invert ? scale.fn.invert(position) : undefined;
|
|
74
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import isDataRecord from '../helpers/isDataRecord.js';
|
|
2
|
+
export const RAW_VALUE = Symbol();
|
|
2
3
|
/*
|
|
3
4
|
* This transform takes an array of raw values as input and returns data records
|
|
4
5
|
* in which the values are interpreted as x channel and their index as y
|
|
@@ -10,6 +11,8 @@ export function recordizeX({ data, ...channels }, { withIndex } = { withIndex: t
|
|
|
10
11
|
data: data.map((value, index) => ({
|
|
11
12
|
__value: value,
|
|
12
13
|
...(withIndex ? { __index: index } : {}),
|
|
14
|
+
[RAW_VALUE]: value,
|
|
15
|
+
// TODO: remove ___orig___ references
|
|
13
16
|
___orig___: value
|
|
14
17
|
})),
|
|
15
18
|
...channels,
|
|
@@ -32,6 +35,7 @@ export function recordizeY({ data, ...channels }, { withIndex } = { withIndex: t
|
|
|
32
35
|
data: Array.from(data).map((value, index) => ({
|
|
33
36
|
__value: value,
|
|
34
37
|
...(withIndex ? { __index: index } : {}),
|
|
38
|
+
[RAW_VALUE]: value,
|
|
35
39
|
___orig___: value
|
|
36
40
|
})),
|
|
37
41
|
...channels,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { DataRecord, DataRow, TransformArg } from '../types.js';
|
|
2
|
+
export declare const SORT_KEY: unique symbol;
|
|
2
3
|
export declare function sort({ data, ...channels }: TransformArg<DataRecord>, options?: {
|
|
3
4
|
reverse?: boolean;
|
|
4
5
|
}): {
|
|
5
6
|
sort: null;
|
|
6
7
|
data: {
|
|
7
|
-
__sortkey: import("../types.js").RawValue;
|
|
8
8
|
___orig___?: import("../types.js").RawValue | [import("../types.js").RawValue, import("../types.js").RawValue];
|
|
9
9
|
}[];
|
|
10
10
|
} | {
|
package/dist/transforms/sort.js
CHANGED
|
@@ -2,6 +2,7 @@ import isDataRecord from '../helpers/isDataRecord.js';
|
|
|
2
2
|
import { resolveChannel } from '../helpers/resolve.js';
|
|
3
3
|
import { shuffler } from 'd3-array';
|
|
4
4
|
import { randomLcg } from 'd3-random';
|
|
5
|
+
export const SORT_KEY = Symbol('sortKey');
|
|
5
6
|
export function sort({ data, ...channels }, options = {}) {
|
|
6
7
|
if (!Array.isArray(data))
|
|
7
8
|
return { data, ...channels };
|
|
@@ -16,11 +17,15 @@ export function sort({ data, ...channels }, options = {}) {
|
|
|
16
17
|
// sort data
|
|
17
18
|
return {
|
|
18
19
|
data: data
|
|
19
|
-
.map((d) => ({
|
|
20
|
-
|
|
20
|
+
.map((d) => ({
|
|
21
|
+
...d,
|
|
22
|
+
[SORT_KEY]: resolveChannel('sort', d, { ...channels, sort })
|
|
23
|
+
}))
|
|
24
|
+
.toSorted((a, b) => (a[SORT_KEY] > b[SORT_KEY] ? 1 : a[SORT_KEY] < b[SORT_KEY] ? -1 : 0) *
|
|
21
25
|
(options.reverse || (isDataRecord(sort) && sort?.order === 'descending')
|
|
22
26
|
? -1
|
|
23
|
-
: 1))
|
|
27
|
+
: 1))
|
|
28
|
+
.map(({ [SORT_KEY]: a, ...rest }) => rest),
|
|
24
29
|
...channels,
|
|
25
30
|
// set the sort channel to null to disable the implicit alphabetical
|
|
26
31
|
// ordering of ordinal domains, and also to avoid double sorting in case
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelteplot",
|
|
3
|
-
"version": "0.1.3-next.
|
|
3
|
+
"version": "0.1.3-next.9",
|
|
4
4
|
"license": "ISC",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Gregor Aisch",
|
|
@@ -67,12 +67,12 @@
|
|
|
67
67
|
"@types/d3-scale": "^4.0.9",
|
|
68
68
|
"@types/d3-scale-chromatic": "^3.1.0",
|
|
69
69
|
"@types/d3-shape": "^3.1.7",
|
|
70
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
71
|
-
"@typescript-eslint/parser": "^8.
|
|
70
|
+
"@typescript-eslint/eslint-plugin": "^8.31.1",
|
|
71
|
+
"@typescript-eslint/parser": "^8.31.1",
|
|
72
72
|
"d3-dsv": "^3.0.1",
|
|
73
73
|
"d3-fetch": "^3.0.1",
|
|
74
74
|
"d3-force": "^3.0.0",
|
|
75
|
-
"eslint": "^9.25.
|
|
75
|
+
"eslint": "^9.25.1",
|
|
76
76
|
"eslint-config-prettier": "^10.1.2",
|
|
77
77
|
"eslint-plugin-svelte": "3.5.1",
|
|
78
78
|
"jsdom": "^26.1.0",
|
|
@@ -81,17 +81,17 @@
|
|
|
81
81
|
"remark-code-extra": "^1.0.1",
|
|
82
82
|
"remark-code-frontmatter": "^1.0.0",
|
|
83
83
|
"resize-observer-polyfill": "^1.5.1",
|
|
84
|
-
"sass": "^1.
|
|
84
|
+
"sass": "^1.87.0",
|
|
85
85
|
"svelte-check": "^4.1.6",
|
|
86
86
|
"svelte-eslint-parser": "1.1.3",
|
|
87
87
|
"svelte-highlight": "^7.8.3",
|
|
88
88
|
"topojson-client": "^3.1.0",
|
|
89
89
|
"tslib": "^2.8.1",
|
|
90
90
|
"typedoc": "^0.28.3",
|
|
91
|
-
"typedoc-plugin-markdown": "^4.6.
|
|
91
|
+
"typedoc-plugin-markdown": "^4.6.3",
|
|
92
92
|
"typescript": "^5.8.3",
|
|
93
|
-
"vite": "^6.3.
|
|
94
|
-
"vitest": "^3.1.
|
|
93
|
+
"vite": "^6.3.3",
|
|
94
|
+
"vitest": "^3.1.2"
|
|
95
95
|
},
|
|
96
96
|
"types": "./dist/index.d.ts",
|
|
97
97
|
"type": "module",
|
|
@@ -109,9 +109,9 @@
|
|
|
109
109
|
"d3-scale-chromatic": "^3.1.0",
|
|
110
110
|
"d3-shape": "^3.2.0",
|
|
111
111
|
"d3-time": "^3.1.0",
|
|
112
|
-
"es-toolkit": "^1.
|
|
112
|
+
"es-toolkit": "^1.36.0",
|
|
113
113
|
"fast-equals": "^5.2.2",
|
|
114
114
|
"merge-deep": "^3.0.3",
|
|
115
|
-
"svelte": "5.28.
|
|
115
|
+
"svelte": "5.28.2"
|
|
116
116
|
}
|
|
117
117
|
}
|