svelteplot 0.0.1-alpha.11 → 0.0.1-alpha.13
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 +6 -6
- package/dist/classes/Mark.svelte.js +4 -0
- package/dist/classes/Plot.svelte.js +47 -20
- package/dist/classes/Scale.svelte.js +95 -0
- package/dist/contants.d.ts +3 -3
- package/dist/contants.js +18 -16
- package/dist/helpers/autoTimeFormat.d.ts +2 -2
- package/dist/helpers/createScale.js +19 -6
- package/dist/helpers/curves.d.ts +3 -0
- package/dist/helpers/curves.js +42 -0
- package/dist/helpers/getBaseStyles.js +2 -2
- package/dist/helpers/getLogTicks.js +5 -5
- package/dist/helpers/isRawValue.d.ts +2 -0
- package/dist/helpers/isRawValue.js +5 -0
- package/dist/helpers/resolveChannel.d.ts +6 -2
- package/dist/helpers/resolveChannel.js +15 -5
- package/dist/helpers/wrapValueArray.d.ts +6 -0
- package/dist/helpers/wrapValueArray.js +5 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +11 -3
- package/dist/marks/Area.svelte +35 -21
- package/dist/marks/Area.svelte.d.ts +14 -1
- package/dist/marks/AreaX.svelte +8 -15
- package/dist/marks/AreaX.svelte.d.ts +17 -4
- package/dist/marks/AreaY.svelte +9 -10
- package/dist/marks/AreaY.svelte.d.ts +17 -4
- package/dist/marks/AxisX.svelte +7 -8
- package/dist/marks/AxisY.svelte +10 -6
- package/dist/marks/BarX.svelte +52 -0
- package/dist/marks/BarX.svelte.d.ts +25 -0
- package/dist/marks/BarY.svelte +52 -0
- package/dist/marks/BarY.svelte.d.ts +25 -0
- package/dist/marks/BaseMark.svelte +9 -2
- package/dist/marks/BaseMark.svelte.d.ts +2 -1
- package/dist/marks/Dot.svelte +26 -40
- package/dist/marks/Dot.svelte.d.ts +9 -1
- package/dist/marks/GridX.svelte +26 -15
- package/dist/marks/GridX.svelte.d.ts +3 -3
- package/dist/marks/GridY.svelte +15 -4
- package/dist/marks/Line.svelte +16 -27
- package/dist/marks/Line.svelte.d.ts +13 -1
- package/dist/marks/LineX.svelte +5 -7
- package/dist/marks/LineX.svelte.d.ts +11 -4
- package/dist/marks/LineY.svelte +4 -6
- package/dist/marks/LineY.svelte.d.ts +11 -3
- package/dist/marks/RuleX.svelte +15 -7
- package/dist/marks/RuleY.svelte +15 -7
- package/dist/marks/TickX.svelte +30 -0
- package/dist/marks/TickX.svelte.d.ts +15 -0
- package/dist/marks/TickY.svelte +30 -0
- package/dist/marks/TickY.svelte.d.ts +15 -0
- package/dist/transforms/normalize.d.ts +18 -0
- package/dist/transforms/normalize.js +25 -0
- package/dist/transforms/recordize.d.ts +3 -0
- package/dist/transforms/recordize.js +28 -0
- package/dist/transforms/rename.d.ts +4 -0
- package/dist/transforms/rename.js +10 -0
- package/dist/transforms/stack.d.ts +11 -0
- package/dist/transforms/stack.js +73 -0
- package/dist/types.d.ts +51 -35
- package/package.json +20 -15
- package/dist/classes/Channel.svelte.js +0 -74
package/dist/marks/GridX.svelte
CHANGED
|
@@ -5,29 +5,39 @@ import resolveChannel from "../helpers/resolveChannel.js";
|
|
|
5
5
|
import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
6
6
|
const BaseMark_GridX = BaseMark;
|
|
7
7
|
const plot = getContext("svelteplot");
|
|
8
|
-
let {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
...styleProps
|
|
14
|
-
} = $props();
|
|
15
|
-
let autoTickCount = $derived(plot.plotWidth / get(plot, "options.x.tickSpacing", 80));
|
|
8
|
+
let { ticks = [], automatic = false, ...channels } = $props();
|
|
9
|
+
let autoTickCount = $derived(
|
|
10
|
+
Math.max(2, Math.round(plot.plotWidth / (plot.options?.x?.tickSpacing || 80)))
|
|
11
|
+
);
|
|
12
|
+
$inspect(autoTickCount);
|
|
16
13
|
let autoTicks = $derived(
|
|
17
14
|
ticks.length > 0 ? ticks : get(plot, "options.x.ticks", plot.xScale.ticks(autoTickCount))
|
|
18
15
|
);
|
|
16
|
+
let { y1, y2 } = $derived(channels);
|
|
19
17
|
</script>
|
|
20
18
|
|
|
21
|
-
<BaseMark_GridX
|
|
19
|
+
<BaseMark_GridX
|
|
20
|
+
type="grid-x"
|
|
21
|
+
data={ticks.length ? ticks.map((tick) => ({ __x: tick })) : undefined}
|
|
22
|
+
channels={['y']}
|
|
23
|
+
x="__x"
|
|
24
|
+
{...channels}
|
|
25
|
+
{automatic}
|
|
26
|
+
>
|
|
22
27
|
<g class="grid-x">
|
|
23
|
-
{#each autoTicks as tick
|
|
24
|
-
<g
|
|
28
|
+
{#each autoTicks as tick}
|
|
29
|
+
<g
|
|
30
|
+
class="x-tick"
|
|
31
|
+
transform="translate({plot.xScale(tick) +
|
|
32
|
+
(plot.xScale.bandwidth ? plot.xScale.bandwidth() * 0.5 : 0)},{plot.margins
|
|
33
|
+
.top})"
|
|
34
|
+
>
|
|
25
35
|
<line
|
|
26
36
|
class="grid"
|
|
27
|
-
style={getBaseStyles(tick,
|
|
28
|
-
y1={y1 ? plot.yScale(resolveChannel('
|
|
37
|
+
style={getBaseStyles(tick, channels)}
|
|
38
|
+
y1={y1 ? plot.yScale(resolveChannel('y1', tick, channels)) : 0}
|
|
29
39
|
y2={y2
|
|
30
|
-
? plot.yScale(resolveChannel('
|
|
40
|
+
? plot.yScale(resolveChannel('y2', tick, channels))
|
|
31
41
|
: plot.height - plot.margins.top - plot.margins.bottom}
|
|
32
42
|
/>
|
|
33
43
|
</g>
|
|
@@ -37,6 +47,7 @@ let autoTicks = $derived(
|
|
|
37
47
|
|
|
38
48
|
<style>
|
|
39
49
|
.x-tick line.grid {
|
|
40
|
-
stroke:
|
|
50
|
+
stroke: currentColor;
|
|
51
|
+
stroke-opacity: 0.1;
|
|
41
52
|
}
|
|
42
53
|
</style>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import type { GridOptions } from '../types.js';
|
|
2
|
+
import type { GridOptions, ChannelAccessor } from '../types.js';
|
|
3
3
|
declare const __propDef: {
|
|
4
4
|
props: Partial<import("../types.js").MarkProps> & GridOptions & {
|
|
5
|
-
y1?:
|
|
6
|
-
y2?:
|
|
5
|
+
y1?: ChannelAccessor;
|
|
6
|
+
y2?: ChannelAccessor;
|
|
7
7
|
automatic?: boolean | undefined;
|
|
8
8
|
};
|
|
9
9
|
events: {
|
package/dist/marks/GridY.svelte
CHANGED
|
@@ -4,16 +4,26 @@ import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
|
4
4
|
import { get } from "underscore";
|
|
5
5
|
const plot = getContext("svelteplot");
|
|
6
6
|
let { ticks = [], automatic = false, ...styleProps } = $props();
|
|
7
|
-
let autoTickCount = $derived(plot.plotHeight /
|
|
7
|
+
let autoTickCount = $derived(plot.plotHeight / (plot.options.y?.tickSpacing || 80));
|
|
8
8
|
let autoTicks = $derived(
|
|
9
9
|
ticks.length > 0 ? ticks : plot.options.y?.ticks || plot.yScale.ticks(autoTickCount)
|
|
10
10
|
);
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
<BaseMark
|
|
13
|
+
<BaseMark
|
|
14
|
+
type="grid-y"
|
|
15
|
+
data={ticks.length ? ticks.map((tick) => ({ __y: tick })) : undefined}
|
|
16
|
+
channels={['y']}
|
|
17
|
+
y="__y"
|
|
18
|
+
{automatic}
|
|
19
|
+
>
|
|
14
20
|
<g class="grid-y">
|
|
15
21
|
{#each autoTicks as tick}
|
|
16
|
-
<g
|
|
22
|
+
<g
|
|
23
|
+
class="y-tick"
|
|
24
|
+
transform="translate({plot.margins.left},{plot.yScale(tick) +
|
|
25
|
+
(plot.yScale.bandwidth ? plot.yScale.bandwidth() * 0.5 : 0)})"
|
|
26
|
+
>
|
|
17
27
|
<line
|
|
18
28
|
style={getBaseStyles(tick, styleProps)}
|
|
19
29
|
class="grid"
|
|
@@ -26,6 +36,7 @@ let autoTicks = $derived(
|
|
|
26
36
|
|
|
27
37
|
<style>
|
|
28
38
|
.y-tick line.grid {
|
|
29
|
-
stroke:
|
|
39
|
+
stroke: currentColor;
|
|
40
|
+
stroke-opacity: 0.2;
|
|
30
41
|
}
|
|
31
42
|
</style>
|
package/dist/marks/Line.svelte
CHANGED
|
@@ -1,52 +1,41 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
1
3
|
<script>import resolveChannel from "../helpers/resolveChannel.js";
|
|
2
4
|
import { getContext } from "svelte";
|
|
3
5
|
import BaseMark from "./BaseMark.svelte";
|
|
4
6
|
import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
5
7
|
import { line } from "d3-shape";
|
|
6
8
|
import { groupBy } from "underscore";
|
|
7
|
-
import
|
|
9
|
+
import { maybeCurve } from "../helpers/curves.js";
|
|
8
10
|
const BaseMark_Line = BaseMark;
|
|
9
11
|
const plot = getContext("svelteplot");
|
|
10
|
-
let {
|
|
11
|
-
|
|
12
|
-
x = null,
|
|
13
|
-
y = null,
|
|
14
|
-
z = null,
|
|
15
|
-
fill,
|
|
16
|
-
stroke,
|
|
17
|
-
sort,
|
|
18
|
-
...styleProps
|
|
19
|
-
} = $props();
|
|
12
|
+
let { data, curve, tension, ...channels } = $props();
|
|
13
|
+
let { sort, z, fill, stroke } = $derived(channels);
|
|
20
14
|
let groups = $derived(
|
|
21
|
-
z || fill || stroke ? Object.values(groupBy(data, (d) => resolveChannel("z", d,
|
|
15
|
+
z || fill || stroke ? Object.values(groupBy(data, (d) => resolveChannel("z", d, channels))) : [data]
|
|
22
16
|
);
|
|
23
17
|
let sortedGroups = $derived(
|
|
24
18
|
sort ? groups.sort(
|
|
25
|
-
(a, b) => resolveChannel("sort", a[0],
|
|
19
|
+
(a, b) => resolveChannel("sort", a[0], channels) > resolveChannel("sort", b[0], channels) ? 1 : -1
|
|
26
20
|
) : groups
|
|
27
21
|
);
|
|
28
|
-
let linePath =
|
|
22
|
+
let linePath = $derived(
|
|
23
|
+
line().curve(maybeCurve(curve, tension)).x((d) => plot.xScale(resolveChannel("x", d, channels))).y((d) => plot.yScale(resolveChannel("y", d, channels)))
|
|
24
|
+
);
|
|
29
25
|
</script>
|
|
30
26
|
|
|
31
|
-
<BaseMark_Line
|
|
32
|
-
type="line"
|
|
33
|
-
{data}
|
|
34
|
-
channels={['x', 'y', 'color']}
|
|
35
|
-
{x}
|
|
36
|
-
{y}
|
|
37
|
-
{fill}
|
|
38
|
-
{stroke}
|
|
39
|
-
{...styleProps}
|
|
40
|
-
>
|
|
27
|
+
<BaseMark_Line type="line" {data} channels={['x', 'y', 'color']} {...channels}>
|
|
41
28
|
<g class="lines">
|
|
42
29
|
{#each sortedGroups as lineData}
|
|
43
30
|
<path
|
|
44
31
|
d={linePath(lineData)}
|
|
45
32
|
stroke={stroke
|
|
46
|
-
? plot.colorScale(resolveChannel('
|
|
33
|
+
? plot.colorScale(resolveChannel('stroke', lineData[0], channels))
|
|
47
34
|
: 'currentColor'}
|
|
48
|
-
fill={fill
|
|
49
|
-
|
|
35
|
+
fill={fill
|
|
36
|
+
? plot.colorScale(resolveChannel('fill', lineData[0], channels))
|
|
37
|
+
: 'none'}
|
|
38
|
+
style={getBaseStyles(lineData[0], channels)}
|
|
50
39
|
/>
|
|
51
40
|
{/each}
|
|
52
41
|
</g>
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import type {
|
|
2
|
+
import type { MarkProps, BaseMarkStyleProps, ChannelAccessor, Curve, DataRow } from '../types.js';
|
|
3
|
+
export type LineMarkProps = MarkProps & BaseMarkStyleProps & {
|
|
4
|
+
data: DataRow[];
|
|
5
|
+
x?: ChannelAccessor;
|
|
6
|
+
y?: ChannelAccessor;
|
|
7
|
+
z?: ChannelAccessor;
|
|
8
|
+
sort?: ChannelAccessor | {
|
|
9
|
+
channel: 'stroke' | 'fill';
|
|
10
|
+
};
|
|
11
|
+
curve: Curve | CurveFactory;
|
|
12
|
+
tension: number;
|
|
13
|
+
};
|
|
14
|
+
import { type CurveFactory } from 'd3-shape';
|
|
3
15
|
declare const __propDef: {
|
|
4
16
|
props: LineMarkProps;
|
|
5
17
|
events: {
|
package/dist/marks/LineX.svelte
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
<script
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
3
|
+
<script>import wrapValueArray from "../helpers/wrapValueArray.js";
|
|
4
|
+
import Line from "./Line.svelte";
|
|
2
5
|
let { data, ...rest } = $props();
|
|
3
6
|
</script>
|
|
4
7
|
|
|
5
|
-
<Line
|
|
6
|
-
data={data.map((value, index) => ({ value, index, ___orig___: value }))}
|
|
7
|
-
x="value"
|
|
8
|
-
y="index"
|
|
9
|
-
{...rest}
|
|
10
|
-
/>
|
|
8
|
+
<Line data={wrapValueArray(data)} x="value" y="index" {...rest} />
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import type { CurveFactory } from 'd3-shape';
|
|
3
|
+
import type { MarkProps, BaseMarkStyleProps, ChannelAccessor, Curve, RawValue } from '../types.js';
|
|
4
|
+
export type LineXMarkProps = MarkProps & BaseMarkStyleProps & {
|
|
5
|
+
data: RawValue[];
|
|
6
|
+
sort?: ChannelAccessor | {
|
|
7
|
+
channel: 'stroke' | 'fill';
|
|
6
8
|
};
|
|
9
|
+
curve?: Curve | CurveFactory;
|
|
10
|
+
tension?: number;
|
|
11
|
+
};
|
|
12
|
+
declare const __propDef: {
|
|
13
|
+
props: LineXMarkProps;
|
|
7
14
|
events: {
|
|
8
15
|
[evt: string]: CustomEvent<any>;
|
|
9
16
|
};
|
package/dist/marks/LineY.svelte
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
+
<script context="module"></script>
|
|
2
|
+
|
|
1
3
|
<script>import Line from "./Line.svelte";
|
|
4
|
+
import wrapValueArray from "../helpers/wrapValueArray.js";
|
|
2
5
|
let { data, ...rest } = $props();
|
|
3
6
|
</script>
|
|
4
7
|
|
|
5
|
-
<Line
|
|
6
|
-
data={data.map((value, index) => ({ value, index, ___orig___: value }))}
|
|
7
|
-
x="index"
|
|
8
|
-
y="value"
|
|
9
|
-
{...rest}
|
|
10
|
-
/>
|
|
8
|
+
<Line data={wrapValueArray(data)} x="index" y="value" {...rest} />
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { MarkProps, BaseMarkStyleProps, ChannelAccessor, Curve } from '../types.js';
|
|
3
|
+
export type LineYMarkProps = MarkProps & BaseMarkStyleProps & {
|
|
4
|
+
data: RawValue[];
|
|
5
|
+
sort?: ChannelAccessor | {
|
|
6
|
+
channel: 'stroke' | 'fill';
|
|
7
|
+
};
|
|
8
|
+
curve?: Curve | CurveFactory;
|
|
9
|
+
tension?: number;
|
|
10
|
+
};
|
|
2
11
|
import type { RawValue } from '../types.js';
|
|
12
|
+
import type { CurveFactory } from 'd3-shape';
|
|
3
13
|
declare const __propDef: {
|
|
4
|
-
props:
|
|
5
|
-
data: RawValue[];
|
|
6
|
-
};
|
|
14
|
+
props: LineYMarkProps;
|
|
7
15
|
events: {
|
|
8
16
|
[evt: string]: CustomEvent<any>;
|
|
9
17
|
};
|
package/dist/marks/RuleX.svelte
CHANGED
|
@@ -4,19 +4,27 @@ import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
|
4
4
|
import resolveChannel from "../helpers/resolveChannel.js";
|
|
5
5
|
const BaseMark_RuleX = BaseMark;
|
|
6
6
|
const plot = getContext("svelteplot");
|
|
7
|
-
let { data = [],
|
|
8
|
-
let
|
|
7
|
+
let { data = [], ...channels } = $props();
|
|
8
|
+
let { x, y1, y2 } = $derived(channels);
|
|
9
|
+
let dataWrapped = $derived(x ? data : data.map((d) => ({ __x: d, ___orig___: d })));
|
|
9
10
|
</script>
|
|
10
11
|
|
|
11
|
-
<BaseMark_RuleX
|
|
12
|
+
<BaseMark_RuleX
|
|
13
|
+
type="rule-x"
|
|
14
|
+
data={dataWrapped}
|
|
15
|
+
channels={['x', 'y1', 'y2']}
|
|
16
|
+
{...{ x: '__x', ...channels }}
|
|
17
|
+
>
|
|
12
18
|
<g class="rule-x">
|
|
13
19
|
{#each data as datum}
|
|
14
20
|
<line
|
|
15
|
-
transform="translate({plot.xScale(resolveChannel('x', datum,
|
|
16
|
-
style={getBaseStyles(datum,
|
|
17
|
-
y1={y1 != null
|
|
21
|
+
transform="translate({plot.xScale(resolveChannel('x', datum, channels))}, {0})"
|
|
22
|
+
style={getBaseStyles(datum, channels)}
|
|
23
|
+
y1={y1 != null
|
|
24
|
+
? plot.yScale(resolveChannel('y1', datum, channels))
|
|
25
|
+
: plot.margins.top}
|
|
18
26
|
y2={y2 != null
|
|
19
|
-
? plot.yScale(resolveChannel('
|
|
27
|
+
? plot.yScale(resolveChannel('y2', datum, channels))
|
|
20
28
|
: plot.plotHeight + plot.margins.top}
|
|
21
29
|
/>
|
|
22
30
|
{/each}
|
package/dist/marks/RuleY.svelte
CHANGED
|
@@ -4,19 +4,27 @@ import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
|
4
4
|
import resolveChannel from "../helpers/resolveChannel.js";
|
|
5
5
|
const BaseMark_RuleY = BaseMark;
|
|
6
6
|
const plot = getContext("svelteplot");
|
|
7
|
-
let { data = [],
|
|
8
|
-
let
|
|
7
|
+
let { data = [], ...channels } = $props();
|
|
8
|
+
let { y, x1, x2 } = $derived(channels);
|
|
9
|
+
let dataWrapped = $derived(y ? data : data.map((d) => ({ __y: d, ___orig___: d })));
|
|
9
10
|
</script>
|
|
10
11
|
|
|
11
|
-
<BaseMark_RuleY
|
|
12
|
+
<BaseMark_RuleY
|
|
13
|
+
type="rule-y"
|
|
14
|
+
data={dataWrapped}
|
|
15
|
+
channels={['y', 'x1', 'x2']}
|
|
16
|
+
{...{ y: '__y', ...channels }}
|
|
17
|
+
>
|
|
12
18
|
<g class="rule-y">
|
|
13
19
|
{#each data as datum}
|
|
14
20
|
<line
|
|
15
|
-
transform="translate(0,{plot.yScale(resolveChannel('y', datum,
|
|
16
|
-
style={getBaseStyles(datum,
|
|
17
|
-
x1={x1 != null
|
|
21
|
+
transform="translate(0,{plot.yScale(resolveChannel('y', datum, channels))})"
|
|
22
|
+
style={getBaseStyles(datum, channels)}
|
|
23
|
+
x1={x1 != null
|
|
24
|
+
? plot.xScale(resolveChannel('x1', datum, channels))
|
|
25
|
+
: plot.margins.left}
|
|
18
26
|
x2={x2 != null
|
|
19
|
-
? plot.xScale(resolveChannel('
|
|
27
|
+
? plot.xScale(resolveChannel('x2', datum, channels))
|
|
20
28
|
: plot.plotWidth + plot.margins.left}
|
|
21
29
|
/>
|
|
22
30
|
{/each}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script>import { getContext } from "svelte";
|
|
2
|
+
import BaseMark from "./BaseMark.svelte";
|
|
3
|
+
import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
4
|
+
import resolveChannel from "../helpers/resolveChannel.js";
|
|
5
|
+
const BaseMark_TickX = BaseMark;
|
|
6
|
+
const plot = getContext("svelteplot");
|
|
7
|
+
let { data = [], ...channels } = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<BaseMark_TickX type="tick-x" {data} channels={['x', 'y', 'stroke']} {...channels}>
|
|
11
|
+
<g class="tick-x">
|
|
12
|
+
{#each data as datum}
|
|
13
|
+
<line
|
|
14
|
+
transform="translate({plot.xScale(resolveChannel('x', datum, channels))}, {0})"
|
|
15
|
+
style:stroke={channels.stroke
|
|
16
|
+
? plot.colorScale(resolveChannel('stroke', datum, channels))
|
|
17
|
+
: null}
|
|
18
|
+
style={getBaseStyles(datum, channels)}
|
|
19
|
+
y1={plot.yScale(resolveChannel('y', datum, channels))}
|
|
20
|
+
y2={plot.yScale(resolveChannel('y', datum, channels)) + plot.yScale.bandwidth()}
|
|
21
|
+
/>
|
|
22
|
+
{/each}
|
|
23
|
+
</g>
|
|
24
|
+
</BaseMark_TickX>
|
|
25
|
+
|
|
26
|
+
<style>
|
|
27
|
+
.tick-x line {
|
|
28
|
+
stroke: currentColor;
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { TickMarkProps } from '../types.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: TickMarkProps;
|
|
5
|
+
events: {
|
|
6
|
+
[evt: string]: CustomEvent<any>;
|
|
7
|
+
};
|
|
8
|
+
slots: {};
|
|
9
|
+
};
|
|
10
|
+
export type TickXProps = typeof __propDef.props;
|
|
11
|
+
export type TickXEvents = typeof __propDef.events;
|
|
12
|
+
export type TickXSlots = typeof __propDef.slots;
|
|
13
|
+
export default class TickX extends SvelteComponent<TickXProps, TickXEvents, TickXSlots> {
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script>import { getContext } from "svelte";
|
|
2
|
+
import BaseMark from "./BaseMark.svelte";
|
|
3
|
+
import getBaseStyles from "../helpers/getBaseStyles.js";
|
|
4
|
+
import resolveChannel from "../helpers/resolveChannel.js";
|
|
5
|
+
const BaseMark_TickY = BaseMark;
|
|
6
|
+
const plot = getContext("svelteplot");
|
|
7
|
+
let { data = [], ...channels } = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<BaseMark_TickY type="tick-y" {data} channels={['x', 'y', 'stroke']} {...channels}>
|
|
11
|
+
<g class="tick-y">
|
|
12
|
+
{#each data as datum}
|
|
13
|
+
<line
|
|
14
|
+
transform="translate(0, {plot.yScale(resolveChannel('y', datum, channels))})"
|
|
15
|
+
style:stroke={channels.stroke
|
|
16
|
+
? plot.colorScale(resolveChannel('stroke', datum, channels))
|
|
17
|
+
: null}
|
|
18
|
+
style={getBaseStyles(datum, channels)}
|
|
19
|
+
x1={plot.xScale(resolveChannel('x', datum, channels))}
|
|
20
|
+
x2={plot.xScale(resolveChannel('x', datum, channels)) + plot.xScale.bandwidth()}
|
|
21
|
+
/>
|
|
22
|
+
{/each}
|
|
23
|
+
</g>
|
|
24
|
+
</BaseMark_TickY>
|
|
25
|
+
|
|
26
|
+
<style>
|
|
27
|
+
.tick-y line {
|
|
28
|
+
stroke: currentColor;
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { TickMarkProps } from '../types.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: TickMarkProps;
|
|
5
|
+
events: {
|
|
6
|
+
[evt: string]: CustomEvent<any>;
|
|
7
|
+
};
|
|
8
|
+
slots: {};
|
|
9
|
+
};
|
|
10
|
+
export type TickYProps = typeof __propDef.props;
|
|
11
|
+
export type TickYEvents = typeof __propDef.events;
|
|
12
|
+
export type TickYSlots = typeof __propDef.slots;
|
|
13
|
+
export default class TickY extends SvelteComponent<TickYProps, TickYEvents, TickYSlots> {
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare function normalizeY({ data, y, y1, y2, stroke, fill, z, ...restProps }: {
|
|
2
|
+
[x: string]: any;
|
|
3
|
+
data: any;
|
|
4
|
+
y: any;
|
|
5
|
+
y1: any;
|
|
6
|
+
y2: any;
|
|
7
|
+
stroke: any;
|
|
8
|
+
fill: any;
|
|
9
|
+
z: any;
|
|
10
|
+
}): {
|
|
11
|
+
data: any[];
|
|
12
|
+
y: any;
|
|
13
|
+
y1: any;
|
|
14
|
+
y2: any;
|
|
15
|
+
stroke: any;
|
|
16
|
+
fill: any;
|
|
17
|
+
z: any;
|
|
18
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import groupBy from 'underscore/modules/groupBy.js';
|
|
2
|
+
export function normalizeY({ data, y, y1, y2, stroke, fill, z, ...restProps }) {
|
|
3
|
+
const groupBy = stroke || fill || z;
|
|
4
|
+
const normalizedData = normalize(data, groupBy, ['y', 'y1', 'y2']);
|
|
5
|
+
return {
|
|
6
|
+
data: normalizedData,
|
|
7
|
+
y,
|
|
8
|
+
y1,
|
|
9
|
+
y2,
|
|
10
|
+
stroke,
|
|
11
|
+
fill,
|
|
12
|
+
z,
|
|
13
|
+
...restProps
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function normalize(data, groupKey, props) {
|
|
17
|
+
const filteredProps = props.filter((p) => data[0][p] != null);
|
|
18
|
+
const groups = Object.values(groupBy(data, groupKey));
|
|
19
|
+
return groups
|
|
20
|
+
.map((data) => data.map((datum) => ({
|
|
21
|
+
...datum,
|
|
22
|
+
...Object.fromEntries(filteredProps.map((prop) => [prop, datum[prop] / data[0][prop]]))
|
|
23
|
+
})))
|
|
24
|
+
.flat(1);
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import isDataRecord from "../helpers/isDataRecord.js";
|
|
2
|
+
// This transform takes an array of raw values as input and returns
|
|
3
|
+
export function recordizeX({ data, ...channels }) {
|
|
4
|
+
const dataIsRawValueArray = !isDataRecord(data[0]);
|
|
5
|
+
if (dataIsRawValueArray) {
|
|
6
|
+
return {
|
|
7
|
+
data: data.map((value, index) => ({ __value: value, __index: index, ___orig___: value })),
|
|
8
|
+
...channels,
|
|
9
|
+
x: '__value',
|
|
10
|
+
y: '__index',
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return { data, ...channels };
|
|
14
|
+
}
|
|
15
|
+
export function recordizeY({ data, ...channels }) {
|
|
16
|
+
if (!data)
|
|
17
|
+
return { data, ...channels };
|
|
18
|
+
const dataIsRawValueArray = !isDataRecord(data[0]);
|
|
19
|
+
if (dataIsRawValueArray) {
|
|
20
|
+
return {
|
|
21
|
+
data: data.map((value, index) => ({ __value: value, __index: index, ___orig___: value })),
|
|
22
|
+
...channels,
|
|
23
|
+
x: '__index',
|
|
24
|
+
y: '__value',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return { data, ...channels };
|
|
28
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function renameChannels({ data, ...channels }, options) {
|
|
2
|
+
const newChannels = channels;
|
|
3
|
+
for (const [from, to] of Object.entries(options)) {
|
|
4
|
+
if (newChannels[from] !== undefined) {
|
|
5
|
+
newChannels[to] = newChannels[from];
|
|
6
|
+
delete newChannels[from];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return { data, ...newChannels };
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TransformArg } from '../types.js';
|
|
2
|
+
type StackOrder = 'none' | 'appearance' | 'inside-out' | 'sum';
|
|
3
|
+
type StackOffset = 'none' | 'wiggle' | 'center' | 'normalize';
|
|
4
|
+
export type StackOptions = {
|
|
5
|
+
offset: null | StackOffset;
|
|
6
|
+
order: null | StackOrder;
|
|
7
|
+
reverse: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function stackY({ data, ...channels }: TransformArg, opts?: Partial<StackOptions>): TransformArg;
|
|
10
|
+
export declare function stackX({ data, ...channels }: TransformArg, opts?: Partial<StackOptions>): TransformArg;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import isDataRecord from '../helpers/isDataRecord.js';
|
|
2
|
+
import resolveChannel from '../helpers/resolveChannel.js';
|
|
3
|
+
import { stack, stackOffsetExpand, stackOffsetSilhouette, stackOffsetWiggle, stackOrderAppearance, stackOrderAscending, stackOrderInsideOut, stackOrderNone } from 'd3-shape';
|
|
4
|
+
import { index, union } from 'd3-array';
|
|
5
|
+
const DEFAULT_STACK_OPTIONS = {
|
|
6
|
+
order: null,
|
|
7
|
+
offset: null,
|
|
8
|
+
reverse: false
|
|
9
|
+
};
|
|
10
|
+
const STACK_ORDER = {
|
|
11
|
+
// null
|
|
12
|
+
// TODO: value: ,
|
|
13
|
+
none: stackOrderNone,
|
|
14
|
+
sum: stackOrderAscending,
|
|
15
|
+
appearance: stackOrderAppearance,
|
|
16
|
+
"inside-out": stackOrderInsideOut,
|
|
17
|
+
};
|
|
18
|
+
const STACK_OFFSET = {
|
|
19
|
+
none: null,
|
|
20
|
+
wiggle: stackOffsetWiggle,
|
|
21
|
+
center: stackOffsetSilhouette,
|
|
22
|
+
normalize: stackOffsetExpand
|
|
23
|
+
};
|
|
24
|
+
function stackXY(byDim, data, channels, options) {
|
|
25
|
+
const groupBy = channels.z ? 'z' : channels.fill ? 'fill' : channels.stroke ? 'stroke' : true;
|
|
26
|
+
const secondDim = byDim === 'x' ? 'y' : 'x';
|
|
27
|
+
const byLow = `${byDim}1`;
|
|
28
|
+
const byHigh = `${byDim}2`;
|
|
29
|
+
if (channels[byDim] !== undefined && channels[`${byLow}`] === undefined && channels[`${byHigh}`] === undefined) {
|
|
30
|
+
const resolvedData = data.map((d) => ({
|
|
31
|
+
...(isDataRecord(d) ? d : { __orig: d }),
|
|
32
|
+
[`__${secondDim}`]: resolveChannel(secondDim, d, channels),
|
|
33
|
+
__group: groupBy === true ? 'G' : resolveChannel(groupBy, d, channels),
|
|
34
|
+
[`__${byDim}`]: resolveChannel(byDim, d, channels)
|
|
35
|
+
}));
|
|
36
|
+
const indexed = index(resolvedData, (d) => d[`__${secondDim}`], (d) => d.__group);
|
|
37
|
+
const stackOrder = (series) => {
|
|
38
|
+
const f = STACK_ORDER[options.order || 'none'];
|
|
39
|
+
return options.reverse ? f(series).reverse() : f(series);
|
|
40
|
+
};
|
|
41
|
+
const series = stack()
|
|
42
|
+
.order(stackOrder)
|
|
43
|
+
.offset(STACK_OFFSET[options.offset])
|
|
44
|
+
.keys(union(resolvedData.map((d) => d.__group)))
|
|
45
|
+
.value(([, group], key) => group.get(key) ? group.get(key)[`__${byDim}`] : 0)(indexed);
|
|
46
|
+
const newData = series
|
|
47
|
+
.map((values) => {
|
|
48
|
+
const groupKey = values.key;
|
|
49
|
+
return values
|
|
50
|
+
.filter((d) => d.data[1].get(groupKey))
|
|
51
|
+
.map((d) => {
|
|
52
|
+
const { [`__${byDim}`]: unused1, [`__${secondDim}`]: unused2, ...datum } = d.data[1].get(groupKey);
|
|
53
|
+
return { ...datum, [`__${byLow}`]: d[0], [`__${byHigh}`]: d[1] };
|
|
54
|
+
});
|
|
55
|
+
})
|
|
56
|
+
.flat(1);
|
|
57
|
+
console.log({ newData });
|
|
58
|
+
return { data: newData, ...channels, [byDim]: undefined, ...{ [byLow]: `__${byLow}`, [byHigh]: `__${byHigh}` } };
|
|
59
|
+
}
|
|
60
|
+
return { data, ...channels };
|
|
61
|
+
}
|
|
62
|
+
export function stackY({ data, ...channels }, opts = {}) {
|
|
63
|
+
return stackXY('y', data, channels, applyDefaults(opts));
|
|
64
|
+
}
|
|
65
|
+
export function stackX({ data, ...channels }, opts = {}) {
|
|
66
|
+
return stackXY('x', data, channels, applyDefaults(opts));
|
|
67
|
+
}
|
|
68
|
+
function applyDefaults(opts) {
|
|
69
|
+
if (opts.offset === 'wiggle' && opts.order === undefined) {
|
|
70
|
+
return { ...DEFAULT_STACK_OPTIONS, order: 'inside-out', ...opts };
|
|
71
|
+
}
|
|
72
|
+
return { ...DEFAULT_STACK_OPTIONS, ...opts };
|
|
73
|
+
}
|