svelteplot 0.0.1-alpha.8 → 0.1.3-next.11
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/LICENSE.md +5 -0
- package/README.md +3 -36
- package/dist/Mark.svelte +292 -0
- package/dist/Mark.svelte.d.ts +22 -0
- package/dist/Plot.svelte +148 -153
- package/dist/Plot.svelte.d.ts +15 -15
- package/dist/constants.d.ts +15 -0
- package/dist/constants.js +110 -0
- package/dist/core/Facet.svelte +59 -0
- package/dist/core/Facet.svelte.d.ts +18 -0
- package/dist/core/FacetAxes.svelte +66 -0
- package/dist/core/FacetAxes.svelte.d.ts +4 -0
- package/dist/core/FacetGrid.svelte +86 -0
- package/dist/core/FacetGrid.svelte.d.ts +13 -0
- package/dist/core/Plot.svelte +568 -0
- package/dist/core/Plot.svelte.d.ts +14 -0
- package/dist/helpers/arrowPath.d.ts +14 -0
- package/dist/helpers/arrowPath.js +129 -0
- package/dist/helpers/autoProjection.d.ts +19 -0
- package/dist/helpers/autoProjection.js +87 -0
- package/dist/helpers/autoScales.d.ts +23 -0
- package/dist/helpers/autoScales.js +203 -0
- package/dist/helpers/autoTicks.d.ts +3 -0
- package/dist/helpers/autoTicks.js +40 -0
- package/dist/helpers/autoTimeFormat.d.ts +2 -2
- package/dist/helpers/autoTimeFormat.js +34 -5
- package/dist/helpers/callWithProps.d.ts +8 -0
- package/dist/helpers/callWithProps.js +13 -0
- package/dist/helpers/colors.js +17 -2
- package/dist/helpers/curves.d.ts +3 -0
- package/dist/helpers/curves.js +42 -0
- package/dist/helpers/data.d.ts +9 -0
- package/dist/helpers/data.js +16 -0
- package/dist/helpers/facets.d.ts +12 -0
- package/dist/helpers/facets.js +49 -0
- package/dist/helpers/formats.d.ts +3 -0
- package/dist/helpers/formats.js +3 -0
- package/dist/helpers/getBaseStyles.d.ts +7 -2
- package/dist/helpers/getBaseStyles.js +34 -10
- package/dist/helpers/getLogTicks.js +5 -5
- package/dist/helpers/group.d.ts +6 -0
- package/dist/helpers/group.js +53 -0
- package/dist/helpers/index.d.ts +18 -0
- package/dist/helpers/index.js +55 -0
- package/dist/helpers/isRawValue.d.ts +2 -0
- package/dist/helpers/isRawValue.js +5 -0
- package/dist/helpers/isValid.d.ts +6 -0
- package/dist/helpers/isValid.js +6 -0
- package/dist/helpers/math.d.ts +19 -0
- package/dist/helpers/math.js +116 -0
- package/dist/helpers/mergeDeep.d.ts +1 -1
- package/dist/helpers/noise.d.ts +1 -0
- package/dist/helpers/noise.js +72 -0
- package/dist/helpers/projection.d.ts +33 -0
- package/dist/helpers/projection.js +100 -0
- package/dist/helpers/reduce.d.ts +10 -0
- package/dist/helpers/reduce.js +85 -0
- package/dist/helpers/regressionLoess.d.ts +12 -0
- package/dist/helpers/regressionLoess.js +47 -0
- package/dist/helpers/removeIdenticalLines.d.ts +8 -1
- package/dist/helpers/removeIdenticalLines.js +14 -7
- package/dist/helpers/resolve.d.ts +21 -0
- package/dist/helpers/resolve.js +156 -0
- package/dist/helpers/roundedRect.d.ts +9 -0
- package/dist/helpers/roundedRect.js +31 -0
- package/dist/helpers/scales.d.ts +42 -0
- package/dist/helpers/scales.js +309 -0
- package/dist/helpers/time.d.ts +6 -0
- package/dist/helpers/time.js +282 -0
- package/dist/helpers/typeChecks.d.ts +8 -5
- package/dist/helpers/typeChecks.js +27 -6
- package/dist/index.d.ts +49 -1
- package/dist/index.js +53 -2
- package/dist/marks/Area.svelte +146 -0
- package/dist/marks/Area.svelte.d.ts +30 -0
- package/dist/marks/AreaX.svelte +27 -0
- package/dist/marks/AreaX.svelte.d.ts +12 -0
- package/dist/marks/AreaY.svelte +38 -0
- package/dist/marks/AreaY.svelte.d.ts +19 -0
- package/dist/marks/Arrow.svelte +139 -0
- package/dist/marks/Arrow.svelte.d.ts +44 -0
- package/dist/marks/AxisX.svelte +198 -93
- package/dist/marks/AxisX.svelte.d.ts +17 -16
- package/dist/marks/AxisY.svelte +176 -62
- package/dist/marks/AxisY.svelte.d.ts +17 -14
- package/dist/marks/BarX.svelte +86 -0
- package/dist/marks/BarX.svelte.d.ts +4 -0
- package/dist/marks/BarY.svelte +98 -0
- package/dist/marks/BarY.svelte.d.ts +4 -0
- package/dist/marks/BollingerX.svelte +44 -0
- package/dist/marks/BollingerX.svelte.d.ts +18 -0
- package/dist/marks/BollingerY.svelte +39 -0
- package/dist/marks/BollingerY.svelte.d.ts +18 -0
- package/dist/marks/BoxX.svelte +89 -0
- package/dist/marks/BoxX.svelte.d.ts +4 -0
- package/dist/marks/BoxY.svelte +110 -0
- package/dist/marks/BoxY.svelte.d.ts +29 -0
- package/dist/marks/Cell.svelte +110 -0
- package/dist/marks/Cell.svelte.d.ts +16 -0
- package/dist/marks/CellX.svelte +24 -0
- package/dist/marks/CellX.svelte.d.ts +3 -0
- package/dist/marks/CellY.svelte +24 -0
- package/dist/marks/CellY.svelte.d.ts +3 -0
- package/dist/marks/ColorLegend.svelte +148 -27
- package/dist/marks/ColorLegend.svelte.d.ts +12 -13
- package/dist/marks/CustomMark.svelte +43 -0
- package/dist/marks/CustomMark.svelte.d.ts +16 -0
- package/dist/marks/CustomMarkHTML.svelte +103 -0
- package/dist/marks/CustomMarkHTML.svelte.d.ts +17 -0
- package/dist/marks/DifferenceY.svelte +144 -0
- package/dist/marks/DifferenceY.svelte.d.ts +30 -0
- package/dist/marks/Dot.svelte +128 -73
- package/dist/marks/Dot.svelte.d.ts +24 -14
- package/dist/marks/DotX.svelte +15 -3
- package/dist/marks/DotX.svelte.d.ts +8 -16
- package/dist/marks/DotY.svelte +8 -3
- package/dist/marks/DotY.svelte.d.ts +5 -17
- package/dist/marks/Frame.svelte +39 -31
- package/dist/marks/Frame.svelte.d.ts +7 -14
- package/dist/marks/Geo.svelte +102 -0
- package/dist/marks/Geo.svelte.d.ts +10 -0
- package/dist/marks/Graticule.svelte +28 -0
- package/dist/marks/Graticule.svelte.d.ts +9 -0
- package/dist/marks/GridX.svelte +67 -36
- package/dist/marks/GridX.svelte.d.ts +7 -18
- package/dist/marks/GridY.svelte +64 -25
- package/dist/marks/GridY.svelte.d.ts +7 -14
- package/dist/marks/HTMLTooltip.svelte +91 -0
- package/dist/marks/HTMLTooltip.svelte.d.ts +11 -0
- package/dist/marks/Line.svelte +219 -58
- package/dist/marks/Line.svelte.d.ts +30 -14
- package/dist/marks/LineX.svelte +8 -8
- package/dist/marks/LineX.svelte.d.ts +4 -17
- package/dist/marks/LineY.svelte +7 -8
- package/dist/marks/LineY.svelte.d.ts +4 -17
- package/dist/marks/Link.svelte +180 -0
- package/dist/marks/Link.svelte.d.ts +21 -0
- package/dist/marks/Pointer.svelte +126 -0
- package/dist/marks/Pointer.svelte.d.ts +23 -0
- package/dist/marks/Rect.svelte +103 -0
- package/dist/marks/Rect.svelte.d.ts +15 -0
- package/dist/marks/RectX.svelte +33 -0
- package/dist/marks/RectX.svelte.d.ts +15 -0
- package/dist/marks/RectY.svelte +33 -0
- package/dist/marks/RectY.svelte.d.ts +15 -0
- package/dist/marks/RegressionX.svelte +26 -0
- package/dist/marks/RegressionX.svelte.d.ts +4 -0
- package/dist/marks/RegressionY.svelte +26 -0
- package/dist/marks/RegressionY.svelte.d.ts +4 -0
- package/dist/marks/RuleX.svelte +52 -28
- package/dist/marks/RuleX.svelte.d.ts +14 -14
- package/dist/marks/RuleY.svelte +52 -28
- package/dist/marks/RuleY.svelte.d.ts +14 -14
- package/dist/marks/Sphere.svelte +8 -0
- package/dist/marks/Sphere.svelte.d.ts +51 -0
- package/dist/marks/Spike.svelte +15 -0
- package/dist/marks/Spike.svelte.d.ts +4 -0
- package/dist/marks/SymbolLegend.svelte +27 -12
- package/dist/marks/SymbolLegend.svelte.d.ts +8 -14
- package/dist/marks/Text.svelte +189 -0
- package/dist/marks/Text.svelte.d.ts +26 -0
- package/dist/marks/TickX.svelte +89 -0
- package/dist/marks/TickX.svelte.d.ts +22 -0
- package/dist/marks/TickY.svelte +90 -0
- package/dist/marks/TickY.svelte.d.ts +22 -0
- package/dist/marks/Vector.svelte +219 -0
- package/dist/marks/Vector.svelte.d.ts +31 -0
- package/dist/marks/helpers/BaseAxisX.svelte +210 -0
- package/dist/marks/helpers/BaseAxisX.svelte.d.ts +24 -0
- package/dist/marks/helpers/BaseAxisY.svelte +187 -0
- package/dist/marks/helpers/BaseAxisY.svelte.d.ts +23 -0
- package/dist/marks/helpers/CanvasLayer.svelte +38 -0
- package/dist/marks/helpers/CanvasLayer.svelte.d.ts +13 -0
- package/dist/marks/helpers/DotCanvas.svelte +184 -0
- package/dist/marks/helpers/DotCanvas.svelte.d.ts +11 -0
- package/dist/marks/helpers/GeoCanvas.svelte +165 -0
- package/dist/marks/helpers/GeoCanvas.svelte.d.ts +13 -0
- package/dist/marks/helpers/GroupMultiple.svelte +17 -0
- package/dist/marks/helpers/GroupMultiple.svelte.d.ts +9 -0
- package/dist/marks/helpers/Marker.svelte +93 -0
- package/dist/marks/helpers/Marker.svelte.d.ts +10 -0
- package/dist/marks/helpers/MarkerPath.svelte +141 -0
- package/dist/marks/helpers/MarkerPath.svelte.d.ts +44 -0
- package/dist/marks/helpers/Regression.svelte +174 -0
- package/dist/marks/helpers/Regression.svelte.d.ts +26 -0
- package/dist/marks/helpers/events.d.ts +8 -0
- package/dist/marks/helpers/events.js +74 -0
- package/dist/transforms/bin.d.ts +51 -0
- package/dist/transforms/bin.js +171 -0
- package/dist/transforms/bollinger.d.ts +21 -0
- package/dist/transforms/bollinger.js +53 -0
- package/dist/transforms/centroid.d.ts +9 -0
- package/dist/transforms/centroid.js +13 -0
- package/dist/transforms/facet.d.ts +1 -0
- package/dist/transforms/facet.js +1 -0
- package/dist/transforms/filter.d.ts +2 -0
- package/dist/transforms/filter.js +8 -0
- package/dist/transforms/group.d.ts +66 -0
- package/dist/transforms/group.js +109 -0
- package/dist/transforms/interval.d.ts +11 -0
- package/dist/transforms/interval.js +34 -0
- package/dist/transforms/jitter.d.ts +0 -0
- package/dist/transforms/jitter.js +1 -0
- package/dist/transforms/map.d.ts +10 -0
- package/dist/transforms/map.js +89 -0
- package/dist/transforms/normalize.d.ts +9 -0
- package/dist/transforms/normalize.js +86 -0
- package/dist/transforms/recordize.d.ts +14 -0
- package/dist/transforms/recordize.js +79 -0
- package/dist/transforms/rename.d.ts +14 -0
- package/dist/transforms/rename.js +42 -0
- package/dist/transforms/select.d.ts +35 -0
- package/dist/transforms/select.js +55 -0
- package/dist/transforms/shift.d.ts +13 -0
- package/dist/transforms/shift.js +45 -0
- package/dist/transforms/sort.d.ts +28 -0
- package/dist/transforms/sort.js +66 -0
- package/dist/transforms/stack.d.ts +10 -0
- package/dist/transforms/stack.js +110 -0
- package/dist/transforms/window.d.ts +22 -0
- package/dist/transforms/window.js +73 -0
- package/dist/types.d.ts +625 -188
- package/dist/ui/Checkbox.svelte +6 -0
- package/dist/ui/Checkbox.svelte.d.ts +13 -0
- package/dist/ui/RadioInput.svelte +27 -0
- package/dist/ui/RadioInput.svelte.d.ts +9 -0
- package/dist/ui/Select.svelte +27 -0
- package/dist/ui/Select.svelte.d.ts +9 -0
- package/dist/ui/Slider.svelte +47 -0
- package/dist/ui/Slider.svelte.d.ts +11 -0
- package/dist/ui/Spiral.svelte +46 -0
- package/dist/ui/Spiral.svelte.d.ts +15 -0
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +4 -0
- package/package.json +81 -42
- package/LICENSE +0 -11
- package/dist/classes/Channel.svelte.js +0 -74
- package/dist/classes/Mark.svelte.js +0 -17
- package/dist/classes/Plot.svelte.js +0 -98
- package/dist/contants.d.ts +0 -3
- package/dist/contants.js +0 -40
- package/dist/helpers/GroupMultiple.svelte +0 -8
- package/dist/helpers/GroupMultiple.svelte.d.ts +0 -19
- package/dist/helpers/createScale.d.ts +0 -5
- package/dist/helpers/createScale.js +0 -57
- package/dist/helpers/resolveChannel.d.ts +0 -2
- package/dist/helpers/resolveChannel.js +0 -28
- package/dist/helpers/wrapArray.d.ts +0 -2
- package/dist/helpers/wrapArray.js +0 -4
- package/dist/marks/BaseMark.svelte +0 -22
- package/dist/marks/BaseMark.svelte.d.ts +0 -19
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DataRecord, TransformArg } from '../types.js';
|
|
2
|
+
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & {
|
|
3
|
+
[K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
|
|
4
|
+
}[Keys];
|
|
5
|
+
type ShiftXOptions = {
|
|
6
|
+
[key in 'x' | 'x1' | 'x2']: string | number;
|
|
7
|
+
};
|
|
8
|
+
export declare function shiftX({ data, ...channels }: TransformArg<DataRecord>, shiftBy: string | number | RequireAtLeastOne<ShiftXOptions>): TransformArg<DataRecord>;
|
|
9
|
+
type ShiftYOptions = {
|
|
10
|
+
[key in 'y' | 'y1' | 'y2']: string | number;
|
|
11
|
+
};
|
|
12
|
+
export declare function shiftY({ data, ...channels }: TransformArg<DataRecord>, shiftBy: string | number | RequireAtLeastOne<ShiftYOptions>): TransformArg<DataRecord>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
2
|
+
import { maybeTimeInterval } from '../helpers/time.js';
|
|
3
|
+
export function shiftX({ data, ...channels }, shiftBy) {
|
|
4
|
+
if (typeof shiftBy === 'number' || typeof shiftBy === 'string') {
|
|
5
|
+
shiftBy = { x: shiftBy };
|
|
6
|
+
}
|
|
7
|
+
if (shiftBy) {
|
|
8
|
+
if (shiftBy)
|
|
9
|
+
return shiftChannels('x', shiftBy, { data, ...channels });
|
|
10
|
+
}
|
|
11
|
+
return { data, ...channels };
|
|
12
|
+
}
|
|
13
|
+
export function shiftY({ data, ...channels }, shiftBy) {
|
|
14
|
+
if (typeof shiftBy === 'number' || typeof shiftBy === 'string') {
|
|
15
|
+
shiftBy = { y: shiftBy };
|
|
16
|
+
}
|
|
17
|
+
if (shiftBy)
|
|
18
|
+
return shiftChannels('y', shiftBy, { data, ...channels });
|
|
19
|
+
return { data, ...channels };
|
|
20
|
+
}
|
|
21
|
+
function shiftChannels(shiftDim, shiftBy, { data, ...channels }) {
|
|
22
|
+
return {
|
|
23
|
+
data: data.map((d) => {
|
|
24
|
+
const newRow = { ...d };
|
|
25
|
+
for (const [channel, shift] of Object.entries(shiftBy)) {
|
|
26
|
+
const shiftFrom = (channels[channel] != null ? channel : shiftDim);
|
|
27
|
+
if (typeof shift === 'number') {
|
|
28
|
+
newRow[`__shift_${channel}`] =
|
|
29
|
+
resolveChannel(shiftFrom, d, channels) + shift;
|
|
30
|
+
}
|
|
31
|
+
else if (typeof shift === 'string') {
|
|
32
|
+
const [, sign, value, unit] = shift.match(/^([+-])?(\d+)? ?([a-z]+)$/);
|
|
33
|
+
const step = (sign === '-' ? -1 : 1) * (value || 1);
|
|
34
|
+
const interval = maybeTimeInterval(unit);
|
|
35
|
+
if (!interval)
|
|
36
|
+
throw new Error(`Invalid shift interval: ${shift}`);
|
|
37
|
+
newRow[`__shift_${channel}`] = interval.offset(resolveChannel(shiftFrom, d, channels), step);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return newRow;
|
|
41
|
+
}),
|
|
42
|
+
...channels,
|
|
43
|
+
...Object.fromEntries(Object.keys(shiftBy).map((key) => [key, `__shift_${key}`]))
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DataRecord, DataRow, TransformArg } from '../types.js';
|
|
2
|
+
export declare const SORT_KEY: unique symbol;
|
|
3
|
+
export declare function sort({ data, ...channels }: TransformArg<DataRecord>, options?: {
|
|
4
|
+
reverse?: boolean;
|
|
5
|
+
}): {
|
|
6
|
+
sort: null;
|
|
7
|
+
data: {
|
|
8
|
+
___orig___?: import("../types.js").RawValue | [import("../types.js").RawValue, import("../types.js").RawValue];
|
|
9
|
+
}[];
|
|
10
|
+
} | {
|
|
11
|
+
data: DataRecord[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* reverses the data row order
|
|
15
|
+
*/
|
|
16
|
+
export declare function shuffle({ data, ...channels }: TransformArg<DataRow[]>, options?: {
|
|
17
|
+
seed?: number;
|
|
18
|
+
}): {
|
|
19
|
+
sort: null;
|
|
20
|
+
data: DataRow[][];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* reverses the data row order
|
|
24
|
+
*/
|
|
25
|
+
export declare function reverse({ data, ...channels }: TransformArg<DataRow[]>): {
|
|
26
|
+
sort: null;
|
|
27
|
+
data: DataRow[][];
|
|
28
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import isDataRecord from '../helpers/isDataRecord.js';
|
|
2
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
3
|
+
import { shuffler } from 'd3-array';
|
|
4
|
+
import { randomLcg } from 'd3-random';
|
|
5
|
+
export const SORT_KEY = Symbol('sortKey');
|
|
6
|
+
export function sort({ data, ...channels }, options = {}) {
|
|
7
|
+
if (!Array.isArray(data))
|
|
8
|
+
return { data, ...channels };
|
|
9
|
+
if (channels.sort) {
|
|
10
|
+
const { sort } = channels;
|
|
11
|
+
if (isDataRecord(sort) &&
|
|
12
|
+
typeof sort.channel === 'string' &&
|
|
13
|
+
sort.channel.charAt(0) === '-') {
|
|
14
|
+
sort.channel = sort.channel.substring(1);
|
|
15
|
+
sort.order = 'descending';
|
|
16
|
+
}
|
|
17
|
+
// sort data
|
|
18
|
+
return {
|
|
19
|
+
data: data
|
|
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) *
|
|
25
|
+
(options.reverse || (isDataRecord(sort) && sort?.order === 'descending')
|
|
26
|
+
? -1
|
|
27
|
+
: 1))
|
|
28
|
+
.map(({ [SORT_KEY]: a, ...rest }) => rest),
|
|
29
|
+
...channels,
|
|
30
|
+
// set the sort channel to null to disable the implicit alphabetical
|
|
31
|
+
// ordering of ordinal domains, and also to avoid double sorting in case
|
|
32
|
+
// this transform is used "outside" a mark
|
|
33
|
+
sort: null
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
data,
|
|
38
|
+
...channels
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* reverses the data row order
|
|
43
|
+
*/
|
|
44
|
+
export function shuffle({ data, ...channels }, options = {}) {
|
|
45
|
+
const random = randomLcg(options.seed);
|
|
46
|
+
const shuffle = shuffler(random);
|
|
47
|
+
return {
|
|
48
|
+
data: shuffle([...data]),
|
|
49
|
+
...channels,
|
|
50
|
+
// set the sort channel to null to disable the implicit
|
|
51
|
+
// alphabetical ordering of ordinal domains
|
|
52
|
+
sort: null
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* reverses the data row order
|
|
57
|
+
*/
|
|
58
|
+
export function reverse({ data, ...channels }) {
|
|
59
|
+
return {
|
|
60
|
+
data: data.toReversed(),
|
|
61
|
+
...channels,
|
|
62
|
+
// set the sort channel to null to disable the implicit
|
|
63
|
+
// alphabetical ordering of ordinal domains
|
|
64
|
+
sort: null
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TransformArg } from '../types.js';
|
|
2
|
+
export type StackOrder = 'none' | 'appearance' | 'inside-out' | 'sum';
|
|
3
|
+
export type StackOffset = 'none' | 'wiggle' | 'center' | 'normalize' | 'diverging';
|
|
4
|
+
export type StackOptions = {
|
|
5
|
+
offset: null | StackOffset;
|
|
6
|
+
order: null | StackOrder;
|
|
7
|
+
reverse: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function stackY<T>({ data, ...channels }: T, opts?: Partial<StackOptions>): T;
|
|
10
|
+
export declare function stackX({ data, ...channels }: TransformArg, opts?: Partial<StackOptions>): TransformArg;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import isDataRecord from '../helpers/isDataRecord.js';
|
|
2
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
3
|
+
import { stack, stackOffsetExpand, stackOffsetSilhouette, stackOffsetWiggle, stackOrderAppearance, stackOrderAscending, stackOrderInsideOut, stackOrderNone, stackOffsetDiverging } from 'd3-shape';
|
|
4
|
+
import { index, union, groups as d3Groups } 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
|
+
diverging: stackOffsetDiverging,
|
|
21
|
+
wiggle: stackOffsetWiggle,
|
|
22
|
+
center: stackOffsetSilhouette,
|
|
23
|
+
normalize: stackOffsetExpand
|
|
24
|
+
};
|
|
25
|
+
function stackXY(byDim, data, channels, options) {
|
|
26
|
+
// we need to stack the data for each facet separately
|
|
27
|
+
const groupFacetsBy = [
|
|
28
|
+
channels.fx != null ? 'fx' : null,
|
|
29
|
+
channels.fy != null ? 'fy' : null
|
|
30
|
+
].filter((d) => d !== null);
|
|
31
|
+
const groupBy = channels.z ? 'z' : channels.fill ? 'fill' : channels.stroke ? 'stroke' : true;
|
|
32
|
+
const secondDim = byDim === 'x' ? (channels.y1 != null ? 'y1' : 'y') : channels.x1 != null ? 'x1' : 'x';
|
|
33
|
+
const byLow = `${byDim}1`;
|
|
34
|
+
const byHigh = `${byDim}2`;
|
|
35
|
+
if (channels[byDim] != null &&
|
|
36
|
+
channels[`${byLow}`] === undefined &&
|
|
37
|
+
channels[`${byHigh}`] === undefined) {
|
|
38
|
+
// resolve all channels for easier computation below
|
|
39
|
+
const resolvedData = data.map((d) => ({
|
|
40
|
+
...(isDataRecord(d) ? d : { __orig: d }),
|
|
41
|
+
[`__${secondDim}`]: resolveChannel(secondDim, d, channels),
|
|
42
|
+
__group: groupBy === true ? 'G' : resolveChannel(groupBy, d, channels),
|
|
43
|
+
__facet: groupFacetsBy.length > 0
|
|
44
|
+
? groupFacetsBy
|
|
45
|
+
.map((channel) => String(resolveChannel(channel, d, channels)))
|
|
46
|
+
.join('---')
|
|
47
|
+
: 'F',
|
|
48
|
+
[`__${byDim}`]: resolveChannel(byDim, d, channels)
|
|
49
|
+
}));
|
|
50
|
+
// the final data ends up here
|
|
51
|
+
const out = [];
|
|
52
|
+
// first we group the dataset by facets to avoid stacking of rows that are
|
|
53
|
+
// in separate panels
|
|
54
|
+
const groups = d3Groups(resolvedData, (d) => d.__facet);
|
|
55
|
+
for (const [, facetData] of groups) {
|
|
56
|
+
// now we index the data on the second dimension, e.g. over x
|
|
57
|
+
// when stacking over y
|
|
58
|
+
const indexed = index(facetData, (d) => d[`__${secondDim}`], (d) => d.__group);
|
|
59
|
+
const stackOrder = (series) => {
|
|
60
|
+
const f = STACK_ORDER[options.order || 'none'];
|
|
61
|
+
return options.reverse ? f(series).reverse() : f(series);
|
|
62
|
+
};
|
|
63
|
+
// now stack the values for each index
|
|
64
|
+
const series = stack()
|
|
65
|
+
.order(stackOrder)
|
|
66
|
+
.offset(STACK_OFFSET[options.offset])
|
|
67
|
+
.keys(union(facetData.map((d) => d.__group)))
|
|
68
|
+
.value(([, group], key) => (group.get(key) ? group.get(key)[`__${byDim}`] : 0))(indexed);
|
|
69
|
+
// and combine it all back into a flat array
|
|
70
|
+
const newData = series
|
|
71
|
+
.map((values) => {
|
|
72
|
+
const groupKey = values.key;
|
|
73
|
+
return values
|
|
74
|
+
.filter((d) => d.data[1].get(groupKey))
|
|
75
|
+
.map((d) => {
|
|
76
|
+
const datum = d.data[1].get(groupKey);
|
|
77
|
+
// cleanup our internal keys
|
|
78
|
+
delete datum.__group;
|
|
79
|
+
delete datum.__facet;
|
|
80
|
+
return { ...datum, [`__${byLow}`]: d[0], [`__${byHigh}`]: d[1] };
|
|
81
|
+
});
|
|
82
|
+
})
|
|
83
|
+
.flat(1);
|
|
84
|
+
// which we then add to the output data
|
|
85
|
+
out.push(newData);
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
data: out.flat(1),
|
|
89
|
+
...channels,
|
|
90
|
+
[byDim]: undefined,
|
|
91
|
+
...(typeof channels[byDim] === 'string' && !channels[`__${byDim}_origField`]
|
|
92
|
+
? { [`__${byDim}_origField`]: channels[byDim] }
|
|
93
|
+
: {}),
|
|
94
|
+
...{ [byLow]: `__${byLow}`, [byHigh]: `__${byHigh}` }
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { data, ...channels };
|
|
98
|
+
}
|
|
99
|
+
export function stackY({ data, ...channels }, opts = {}) {
|
|
100
|
+
return stackXY('y', data, channels, applyDefaults(opts));
|
|
101
|
+
}
|
|
102
|
+
export function stackX({ data, ...channels }, opts = {}) {
|
|
103
|
+
return stackXY('x', data, channels, applyDefaults(opts));
|
|
104
|
+
}
|
|
105
|
+
function applyDefaults(opts) {
|
|
106
|
+
if (opts.offset === 'wiggle' && opts.order === undefined) {
|
|
107
|
+
return { ...DEFAULT_STACK_OPTIONS, order: 'inside-out', ...opts };
|
|
108
|
+
}
|
|
109
|
+
return { ...DEFAULT_STACK_OPTIONS, ...opts };
|
|
110
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ReducerName } from '../helpers/reduce.js';
|
|
2
|
+
import type { DataRecord, TransformArg } from '../types.js';
|
|
3
|
+
type WindowOptions = {
|
|
4
|
+
k: number;
|
|
5
|
+
interval: string;
|
|
6
|
+
anchor: 'start' | 'middle' | 'end';
|
|
7
|
+
reduce: ReducerName;
|
|
8
|
+
strict: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function windowX(args: TransformArg<DataRecord>, options: WindowOptions): {
|
|
11
|
+
data: {
|
|
12
|
+
[x: string]: import("../types.js").RawValue;
|
|
13
|
+
___orig___?: import("../types.js").RawValue | [import("../types.js").RawValue, import("../types.js").RawValue];
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
export declare function windowY(args: TransformArg<DataRecord>, options: WindowOptions): {
|
|
17
|
+
data: {
|
|
18
|
+
[x: string]: import("../types.js").RawValue;
|
|
19
|
+
___orig___?: import("../types.js").RawValue | [import("../types.js").RawValue, import("../types.js").RawValue];
|
|
20
|
+
}[];
|
|
21
|
+
};
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { maybeInterval } from '../helpers/autoTicks.js';
|
|
2
|
+
import { isValid } from '../helpers/index.js';
|
|
3
|
+
import { Reducer, mayberReducer } from '../helpers/reduce.js';
|
|
4
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
5
|
+
import { groups as d3Groups } from 'd3-array';
|
|
6
|
+
export function windowX(args, options) {
|
|
7
|
+
return windowDim('x', args, options);
|
|
8
|
+
}
|
|
9
|
+
export function windowY(args, options) {
|
|
10
|
+
return windowDim('y', args, options);
|
|
11
|
+
}
|
|
12
|
+
function windowDim(dim, { data, ...channels }, options) {
|
|
13
|
+
const { anchor = 'middle', reduce = 'mean', strict = false } = options;
|
|
14
|
+
let { k, interval } = options;
|
|
15
|
+
interval = maybeInterval(interval, 'time');
|
|
16
|
+
// we only change the data, but not the
|
|
17
|
+
if (!((k = Math.floor(k)) > 0))
|
|
18
|
+
throw new Error(`invalid k: ${k}`);
|
|
19
|
+
const reduceFn = mayberReducer(reduce);
|
|
20
|
+
// group by z, fill or stroke
|
|
21
|
+
const groupBy = channels.z != null
|
|
22
|
+
? 'z'
|
|
23
|
+
: channels.fill != null
|
|
24
|
+
? 'fill'
|
|
25
|
+
: channels.stroke != null
|
|
26
|
+
? 'stroke'
|
|
27
|
+
: false;
|
|
28
|
+
const groups = groupBy
|
|
29
|
+
? d3Groups(data, (d) => resolveChannel(groupBy, d, channels)).map(([, v]) => v)
|
|
30
|
+
: [data];
|
|
31
|
+
const out = [];
|
|
32
|
+
const reduceChannels = [dim, `${dim}1`, `${dim}2`].filter((d) => channels[d] != null);
|
|
33
|
+
const shift = anchor === 'start' ? 0 : anchor === 'end' ? k - 1 : (k - 1) >> 1;
|
|
34
|
+
for (const values of groups) {
|
|
35
|
+
// resolve all "x" values
|
|
36
|
+
const X = values.map((d) => Object.fromEntries(reduceChannels.map((channel) => [channel, resolveChannel(channel, d, channels)])));
|
|
37
|
+
const Y = interval
|
|
38
|
+
? values.map((d, index) => ({
|
|
39
|
+
index,
|
|
40
|
+
value: resolveChannel(dim === 'x' ? 'y' : 'x', d, channels)
|
|
41
|
+
}))
|
|
42
|
+
: [];
|
|
43
|
+
const L = values.length;
|
|
44
|
+
for (let i = 0; i < L; i++) {
|
|
45
|
+
const s0 = Math.max(0, i - shift);
|
|
46
|
+
const newDatum = { ...values[i] };
|
|
47
|
+
let yWindow = new Set();
|
|
48
|
+
if (interval) {
|
|
49
|
+
const minDate = interval.offset(Y[i].value, -shift);
|
|
50
|
+
const maxDate = interval.offset(Y[i].value, -shift + k);
|
|
51
|
+
yWindow = new Set(Y.filter(({ value }) => value >= minDate && value <= maxDate).map(({ index }) => index));
|
|
52
|
+
}
|
|
53
|
+
for (const channel of reduceChannels) {
|
|
54
|
+
const window = (interval
|
|
55
|
+
? // we select X values based on the interval
|
|
56
|
+
X.filter((d, i) => yWindow.has(i))
|
|
57
|
+
: X.slice(s0, Math.min(L, i - shift + k)))
|
|
58
|
+
.map((d) => d[channel])
|
|
59
|
+
.filter(isValid);
|
|
60
|
+
const reduced = strict && window.length < (strict === true ? k : strict)
|
|
61
|
+
? null
|
|
62
|
+
: reduceFn(window);
|
|
63
|
+
newDatum[`__reduced_${channel}__`] = reduced;
|
|
64
|
+
}
|
|
65
|
+
out.push(newDatum);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
data: out,
|
|
70
|
+
...channels,
|
|
71
|
+
...Object.fromEntries(reduceChannels.map((channel) => [channel, `__reduced_${channel}__`]))
|
|
72
|
+
};
|
|
73
|
+
}
|