svelteplot 0.0.1-alpha.7 → 0.0.1-alpha.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/Plot.svelte +4 -0
- package/dist/classes/Channel.svelte.js +3 -1
- package/dist/classes/Plot.svelte.js +3 -3
- package/dist/helpers/createScale.d.ts +2 -1
- package/dist/helpers/createScale.js +18 -8
- package/dist/marks/AxisX.svelte +6 -5
- package/dist/marks/AxisY.svelte +4 -3
- package/dist/marks/Line.svelte +17 -5
- package/dist/types.d.ts +11 -1
- package/package.json +2 -2
package/dist/Plot.svelte
CHANGED
|
@@ -70,6 +70,7 @@ function onMouseMove(evt) {
|
|
|
70
70
|
if (onmousemove)
|
|
71
71
|
onmousemove({ ...evt, plot });
|
|
72
72
|
}
|
|
73
|
+
$inspect(plot.x.domain);
|
|
73
74
|
let hasLegend = $derived(color?.legend || symbol?.legend);
|
|
74
75
|
</script>
|
|
75
76
|
|
|
@@ -149,6 +150,9 @@ let hasLegend = $derived(color?.legend || symbol?.legend);
|
|
|
149
150
|
figure .plot-header {
|
|
150
151
|
order: 1;
|
|
151
152
|
}
|
|
153
|
+
h2, h3 {
|
|
154
|
+
margin: 0;
|
|
155
|
+
}
|
|
152
156
|
svg {
|
|
153
157
|
order: 2;
|
|
154
158
|
overflow: visible;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createScale, createColorScale } from '../helpers/createScale.js';
|
|
2
2
|
import mergeDeep from '../helpers/mergeDeep.js';
|
|
3
3
|
import { Channel } from './Channel.svelte';
|
|
4
|
+
import { get } from 'underscore';
|
|
4
5
|
export const DEFAULT_PLOT_OPTIONS = {
|
|
5
6
|
title: '',
|
|
6
7
|
subtitle: '',
|
|
@@ -76,7 +77,7 @@ export class Plot {
|
|
|
76
77
|
symbolScale = $derived(createScale('ordinal', this.symbol.domain, this.options.symbol?.range || this.hasFilledDotMarks
|
|
77
78
|
? ['circle', 'cross', 'diamond', 'square', 'star', 'triangle', 'wye']
|
|
78
79
|
: ['circle', 'plus', 'times', 'triangle2', 'asterisk', 'square2', 'diamond2']));
|
|
79
|
-
colorScale = $derived(createColorScale(this.color.scaleType, this.color.domain, this.options.color.scheme));
|
|
80
|
+
colorScale = $derived(createColorScale(this.color.scaleType, this.color.domain, this.options.color?.range || null, this.options.color?.scheme));
|
|
80
81
|
hasAxisXMark = $derived(!!this.marks.find((mark) => mark.type === 'axis-x' && !mark.automatic));
|
|
81
82
|
hasAxisYMark = $derived(!!this.marks.find((mark) => mark.type === 'axis-y' && !mark.automatic));
|
|
82
83
|
constructor(width, height, options) {
|
|
@@ -89,8 +90,7 @@ export class Plot {
|
|
|
89
90
|
// console.log('addMark: ' + mark);
|
|
90
91
|
this.marks = [...this.marks, mark];
|
|
91
92
|
// add mark to respective channels
|
|
92
|
-
|
|
93
|
-
console.log(this.color.uniqueMarkProps);
|
|
93
|
+
// console.log(this.x.domain);
|
|
94
94
|
}
|
|
95
95
|
removeMark(removeMark) {
|
|
96
96
|
this.marks = this.marks.filter((mark) => mark.id !== removeMark.id);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
+
import type { ColorScheme, RawValue } from '../types.js';
|
|
1
2
|
declare const Scales: Record<string, (domain: number[], range: [number, number]) => (val: any) => any>;
|
|
2
3
|
export declare function createScale(type: keyof typeof Scales, domain: any, range: any, options?: {}): (val: any) => any;
|
|
3
|
-
export declare function createColorScale(type: any, domain: string[] | [number, number] | [Date, Date] | [boolean | boolean], scheme:
|
|
4
|
+
export declare function createColorScale(type: any, domain: string[] | [number, number] | [Date, Date] | [boolean | boolean], range: RawValue[] | null, scheme: ColorScheme | null): ((d: any) => any) | (unknown[] & string[] & import("d3-scale").ScaleOrdinal<string, unknown, never>) | import("d3-scale").ScaleSequential<string, never>;
|
|
4
5
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { scaleBand, scaleLinear, scaleTime, scaleSqrt, scaleLog, scaleOrdinal } from 'd3-scale';
|
|
2
|
+
import { scaleSequential, scaleDiverging } from 'd3-scale';
|
|
2
3
|
import { getLogTicks } from './getLogTicks.js';
|
|
3
|
-
import { categoricalSchemes, isCategoricalScheme, ordinalScheme } from './colors.js';
|
|
4
|
+
import { categoricalSchemes, isCategoricalScheme, isQuantitativeScheme, ordinalScheme, quantitativeScheme } from './colors.js';
|
|
4
5
|
import { isColorOrNull } from './typeChecks.js';
|
|
5
6
|
const Scales = {
|
|
6
7
|
band: scaleBand,
|
|
@@ -8,7 +9,9 @@ const Scales = {
|
|
|
8
9
|
time: scaleTime,
|
|
9
10
|
sqrt: scaleSqrt,
|
|
10
11
|
log: scaleLog,
|
|
11
|
-
ordinal: scaleOrdinal
|
|
12
|
+
ordinal: scaleOrdinal,
|
|
13
|
+
sequential: scaleSequential,
|
|
14
|
+
diverging: scaleDiverging
|
|
12
15
|
};
|
|
13
16
|
export function createScale(type, domain, range, options = {}) {
|
|
14
17
|
const scale = Scales[type](domain, range);
|
|
@@ -28,20 +31,27 @@ export function createScale(type, domain, range, options = {}) {
|
|
|
28
31
|
return scale;
|
|
29
32
|
}
|
|
30
33
|
const identity = (d) => d;
|
|
31
|
-
export function createColorScale(type, domain, scheme) {
|
|
34
|
+
export function createColorScale(type, domain, range, scheme) {
|
|
35
|
+
if (type === 'identity')
|
|
36
|
+
return identity;
|
|
32
37
|
if (type === 'band') {
|
|
33
38
|
if (domain.every(isColorOrNull)) {
|
|
34
|
-
console.log('domain is colors', domain);
|
|
35
39
|
return identity;
|
|
36
40
|
}
|
|
37
|
-
const colorRange =
|
|
38
|
-
?
|
|
39
|
-
:
|
|
40
|
-
?
|
|
41
|
+
const colorRange = Array.isArray(range)
|
|
42
|
+
? range
|
|
43
|
+
: !scheme
|
|
44
|
+
? categoricalSchemes.get('tableau10')
|
|
41
45
|
: isCategoricalScheme(scheme)
|
|
42
46
|
? categoricalSchemes.get(scheme)
|
|
43
47
|
: ordinalScheme(scheme)(domain.length);
|
|
44
48
|
return scaleOrdinal().domain(domain).range(colorRange);
|
|
45
49
|
}
|
|
50
|
+
else if (type === 'linear') {
|
|
51
|
+
const colorInterpolator = isQuantitativeScheme(scheme)
|
|
52
|
+
? quantitativeScheme(scheme)
|
|
53
|
+
: quantitativeScheme('blues');
|
|
54
|
+
return scaleSequential(domain, colorInterpolator);
|
|
55
|
+
}
|
|
46
56
|
return (d) => d;
|
|
47
57
|
}
|
package/dist/marks/AxisX.svelte
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script>import { getContext } from "svelte";
|
|
2
2
|
import dayjs from "dayjs";
|
|
3
|
-
import { get } from "underscore";
|
|
4
3
|
import BaseMark from "./BaseMark.svelte";
|
|
5
4
|
import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
6
5
|
import removeIdenticalLines from "../helpers/removeIdenticalLines.js";
|
|
@@ -19,9 +18,11 @@ let {
|
|
|
19
18
|
fill = null,
|
|
20
19
|
...styleProps
|
|
21
20
|
} = $props();
|
|
22
|
-
let autoTickCount = $derived(plot.plotWidth /
|
|
21
|
+
let autoTickCount = $derived(Math.max(2, Math.round(plot.plotWidth / (plot.options?.x?.tickSpacing || 80))));
|
|
22
|
+
$inspect(autoTickCount);
|
|
23
|
+
$inspect(ticks.length);
|
|
23
24
|
let autoTicks = $derived(
|
|
24
|
-
ticks.length > 0 ? ticks :
|
|
25
|
+
ticks.length > 0 ? ticks : plot.options?.x?.ticks ?? plot.xScale.ticks(autoTickCount)
|
|
25
26
|
);
|
|
26
27
|
let useTickFormat = $derived(
|
|
27
28
|
typeof tickFormat === "function" ? tickFormat : plot.x.scaleType === "time" ? typeof tickFormat === "string" ? (d) => dayjs(d).format(tickFormat).split("\n") : autoTimeFormat(plot.x, plot.plotWidth) : (d) => String(d)
|
|
@@ -33,7 +34,7 @@ let tickTexts = $derived(
|
|
|
33
34
|
);
|
|
34
35
|
let optionsLabel = $derived(plot.options?.x?.label);
|
|
35
36
|
let useTitle = $derived(
|
|
36
|
-
title || (optionsLabel === null ? null : optionsLabel
|
|
37
|
+
title || (optionsLabel === null ? null : optionsLabel !== void 0 ? optionsLabel : `${plot.x.autoTitle} \u2192`)
|
|
37
38
|
);
|
|
38
39
|
</script>
|
|
39
40
|
|
|
@@ -44,7 +45,7 @@ let useTitle = $derived(
|
|
|
44
45
|
x={plot.plotWidth + plot.margins.left}
|
|
45
46
|
y={plot.height - 10}
|
|
46
47
|
class="axis-title"
|
|
47
|
-
dominant-baseline="hanging">{useTitle}
|
|
48
|
+
dominant-baseline="hanging">{useTitle}</text
|
|
48
49
|
>
|
|
49
50
|
{/if}
|
|
50
51
|
{#each autoTicks as tick, t}
|
package/dist/marks/AxisY.svelte
CHANGED
|
@@ -20,16 +20,17 @@ let autoTickCount = $derived(plot.plotHeight / get(plot, "options.y.tickSpacing"
|
|
|
20
20
|
let autoTicks = $derived(
|
|
21
21
|
ticks.length > 0 ? ticks : get(plot, "options.y.ticks", plot.yScale.ticks(autoTickCount))
|
|
22
22
|
);
|
|
23
|
-
let optionsLabel = $derived(
|
|
23
|
+
let optionsLabel = $derived(plot.options.y?.label);
|
|
24
24
|
let useTitle = $derived(
|
|
25
|
-
title || (optionsLabel === null ? null : optionsLabel
|
|
25
|
+
title || (optionsLabel === null ? null : optionsLabel !== void 0 ? optionsLabel : `\u2191 ${plot.y.autoTitle}`)
|
|
26
26
|
);
|
|
27
|
+
$inspect(optionsLabel);
|
|
27
28
|
</script>
|
|
28
29
|
|
|
29
30
|
<BaseMark_AxisX type="axis-y" data={ticks} channels={['y']} {automatic}>
|
|
30
31
|
<g class="axis-y">
|
|
31
32
|
{#if useTitle}
|
|
32
|
-
<text x={0} y={5} class="axis-title" dominant-baseline="hanging"
|
|
33
|
+
<text x={0} y={5} class="axis-title" dominant-baseline="hanging">{useTitle}</text>
|
|
33
34
|
{/if}
|
|
34
35
|
{#each autoTicks as tick}
|
|
35
36
|
<g
|
package/dist/marks/Line.svelte
CHANGED
|
@@ -4,6 +4,7 @@ import BaseMark from "./BaseMark.svelte";
|
|
|
4
4
|
import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
5
5
|
import { line } from "d3-shape";
|
|
6
6
|
import { groupBy } from "underscore";
|
|
7
|
+
import isDataRecord from "../helpers/isDataRecord.js";
|
|
7
8
|
const BaseMark_Line = BaseMark;
|
|
8
9
|
const plot = getContext("svelteplot");
|
|
9
10
|
let {
|
|
@@ -14,10 +15,16 @@ let {
|
|
|
14
15
|
fill,
|
|
15
16
|
stroke,
|
|
16
17
|
r = 5,
|
|
18
|
+
sort,
|
|
17
19
|
...styleProps
|
|
18
20
|
} = $props();
|
|
19
21
|
let groups = $derived(
|
|
20
|
-
z ? Object.values(groupBy(data, (d) => resolveChannel("z", d, z))) : [data]
|
|
22
|
+
z || fill || stroke ? Object.values(groupBy(data, (d) => resolveChannel("z", d, z || fill || stroke))) : [data]
|
|
23
|
+
);
|
|
24
|
+
let sortedGroups = $derived(
|
|
25
|
+
sort ? groups.sort(
|
|
26
|
+
(a, b) => resolveChannel("sort", a[0], sort) > resolveChannel("sort", b[0], sort) ? 1 : -1
|
|
27
|
+
) : groups
|
|
21
28
|
);
|
|
22
29
|
let linePath = line().x((d) => plot.xScale(resolveChannel("x", d, x))).y((d) => plot.yScale(resolveChannel("y", d, y)));
|
|
23
30
|
</script>
|
|
@@ -34,16 +41,21 @@ let linePath = line().x((d) => plot.xScale(resolveChannel("x", d, x))).y((d) =>
|
|
|
34
41
|
{...styleProps}
|
|
35
42
|
>
|
|
36
43
|
<g class="lines">
|
|
37
|
-
{#each
|
|
38
|
-
<path
|
|
44
|
+
{#each sortedGroups as lineData}
|
|
45
|
+
<path
|
|
46
|
+
d={linePath(lineData)}
|
|
47
|
+
stroke={stroke
|
|
48
|
+
? plot.colorScale(resolveChannel('color', lineData[0], stroke))
|
|
49
|
+
: 'currentColor'}
|
|
50
|
+
fill={fill ? plot.colorScale(resolveChannel('color', lineData[0], fill)) : 'none'}
|
|
51
|
+
style={getBaseStyles(lineData[0], styleProps)}
|
|
52
|
+
/>
|
|
39
53
|
{/each}
|
|
40
54
|
</g>
|
|
41
55
|
</BaseMark_Line>
|
|
42
56
|
|
|
43
57
|
<style>
|
|
44
58
|
.lines path {
|
|
45
|
-
stroke: currentColor;
|
|
46
|
-
fill: none;
|
|
47
59
|
stroke-width: 1.4px;
|
|
48
60
|
}
|
|
49
61
|
</style>
|
package/dist/types.d.ts
CHANGED
|
@@ -30,6 +30,11 @@ export type Datasets = {
|
|
|
30
30
|
body_mass_g: number;
|
|
31
31
|
sex: string;
|
|
32
32
|
}[];
|
|
33
|
+
bls: {
|
|
34
|
+
division: string;
|
|
35
|
+
date: Date;
|
|
36
|
+
unemployment: number;
|
|
37
|
+
}[];
|
|
33
38
|
};
|
|
34
39
|
export type AxisXAnchor = 'bottom' | 'top' | 'both';
|
|
35
40
|
export type AxisYAnchor = 'left' | 'right' | 'both';
|
|
@@ -80,7 +85,9 @@ export type PlotProps = {
|
|
|
80
85
|
legend?: boolean;
|
|
81
86
|
} | null;
|
|
82
87
|
color?: {
|
|
83
|
-
|
|
88
|
+
range?: string[];
|
|
89
|
+
domain: RawValue[];
|
|
90
|
+
scheme?: ColorScheme;
|
|
84
91
|
legend?: boolean;
|
|
85
92
|
} | null;
|
|
86
93
|
};
|
|
@@ -133,6 +140,9 @@ export type LineMarkProps = MarkProps & BaseMarkStyleProps & {
|
|
|
133
140
|
x?: ChannelAccessor;
|
|
134
141
|
y?: ChannelAccessor;
|
|
135
142
|
z?: ChannelAccessor;
|
|
143
|
+
sort?: ChannelAccessor | {
|
|
144
|
+
channel: 'stroke' | 'fill';
|
|
145
|
+
};
|
|
136
146
|
};
|
|
137
147
|
export type GridOptions = {
|
|
138
148
|
ticks?: RawValue[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelteplot",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.9",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev",
|
|
6
6
|
"build": "vite build",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"prettier": "^3.1.0",
|
|
50
50
|
"prettier-plugin-svelte": "^3.1.2",
|
|
51
51
|
"sass": "^1.69.5",
|
|
52
|
-
"svelte": "5.0.0-next.
|
|
52
|
+
"svelte": "5.0.0-next.22",
|
|
53
53
|
"svelte-check": "^3.6.2",
|
|
54
54
|
"svelte-highlight": "^7.4.2",
|
|
55
55
|
"tslib": "^2.6.2",
|