svelteplot 0.0.1-alpha.9 → 0.1.3-next.12
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 -35
- package/dist/Mark.svelte +292 -0
- package/dist/Mark.svelte.d.ts +22 -0
- package/dist/Plot.svelte +148 -156
- 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 +311 -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 +93 -0
- package/dist/marks/BarX.svelte.d.ts +4 -0
- package/dist/marks/BarY.svelte +103 -0
- package/dist/marks/BarY.svelte.d.ts +25 -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 +1 -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 +15 -0
- package/dist/transforms/recordize.js +78 -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 +24 -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,171 @@
|
|
|
1
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
2
|
+
import { maybeInterval } from '../helpers/autoTicks.js';
|
|
3
|
+
import { bin as d3Bin, extent, groups as d3Groups, thresholdFreedmanDiaconis, thresholdScott, thresholdSturges } from 'd3-array';
|
|
4
|
+
import { Reducer, reduceOutputs } from '../helpers/reduce.js';
|
|
5
|
+
import { groupFacetsAndZ } from '../helpers/group.js';
|
|
6
|
+
import { isDate } from '../helpers/typeChecks';
|
|
7
|
+
const ThresholdGenerators = {
|
|
8
|
+
auto: thresholdScott,
|
|
9
|
+
scott: thresholdScott,
|
|
10
|
+
sturges: thresholdSturges,
|
|
11
|
+
'freedman-diaconis': thresholdFreedmanDiaconis
|
|
12
|
+
};
|
|
13
|
+
function binBy(byDim, { data, ...channels }, options) {
|
|
14
|
+
const { domain, thresholds = 'auto', interval } = options;
|
|
15
|
+
const bin = d3Bin();
|
|
16
|
+
if (domain)
|
|
17
|
+
bin.domain(domain);
|
|
18
|
+
if (interval) {
|
|
19
|
+
const [lo, hi] = extent(data.map((d) => resolveChannel(byDim, d, channels)));
|
|
20
|
+
bin.thresholds(maybeInterval(interval).range(lo, hi));
|
|
21
|
+
}
|
|
22
|
+
else if (thresholds)
|
|
23
|
+
bin.thresholds(
|
|
24
|
+
// use a generator
|
|
25
|
+
typeof thresholds === 'string' && ThresholdGenerators[thresholds] !== undefined
|
|
26
|
+
? ThresholdGenerators[thresholds]
|
|
27
|
+
: thresholds);
|
|
28
|
+
// channels.x is the input
|
|
29
|
+
bin.value((d) => resolveChannel(byDim, d, channels));
|
|
30
|
+
// y, y1, y2, fill, stroke, etc are outputs
|
|
31
|
+
const outputs = [
|
|
32
|
+
...(byDim === 'x' ? ['y', 'y1', 'y2'] : ['x', 'x1', 'x2']),
|
|
33
|
+
'fill',
|
|
34
|
+
'stroke',
|
|
35
|
+
'r',
|
|
36
|
+
'opacity',
|
|
37
|
+
'fillOpacity',
|
|
38
|
+
'strokeOpacity'
|
|
39
|
+
];
|
|
40
|
+
let newChannels = {
|
|
41
|
+
[byDim === 'x' ? 'insetLeft' : 'insetTop']: 0.5,
|
|
42
|
+
[byDim === 'x' ? 'insetRight' : 'insetBottom']: 0.5,
|
|
43
|
+
...channels,
|
|
44
|
+
[`${byDim}`]: `__${byDim}`,
|
|
45
|
+
[`${byDim}1`]: `__${byDim}1`,
|
|
46
|
+
[`${byDim}2`]: `__${byDim}2`,
|
|
47
|
+
[`__${byDim}_origField`]: typeof channels[byDim] === 'string' ? channels[byDim] : null
|
|
48
|
+
};
|
|
49
|
+
const newData = [];
|
|
50
|
+
let passedGroups = [];
|
|
51
|
+
const bins = bin(data);
|
|
52
|
+
(options.cumulative < 0 ? bins.toReversed() : bins).forEach((group) => {
|
|
53
|
+
const itemBinProps = {
|
|
54
|
+
[`__${byDim}1`]: group.x0,
|
|
55
|
+
[`__${byDim}2`]: group.x1,
|
|
56
|
+
[`__${byDim}`]: isDate(group.x0)
|
|
57
|
+
? new Date(Math.round((group.x0.getTime() + group.x1.getTime()) * 0.5))
|
|
58
|
+
: (group.x0 + group.x1) * 0.5
|
|
59
|
+
};
|
|
60
|
+
if (options.cumulative)
|
|
61
|
+
passedGroups = [...passedGroups, ...group];
|
|
62
|
+
const newGroupChannels = groupFacetsAndZ(options.cumulative ? passedGroups : group, channels, (items, itemGroupProps) => {
|
|
63
|
+
const item = { ...itemBinProps, ...itemGroupProps };
|
|
64
|
+
reduceOutputs(item, items, options, outputs, channels, newChannels);
|
|
65
|
+
newData.push(item);
|
|
66
|
+
});
|
|
67
|
+
newChannels = { ...newChannels, ...newGroupChannels };
|
|
68
|
+
});
|
|
69
|
+
return { data: options.reverse ? newData.toReversed() : newData, ...newChannels };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Bins on x. Also groups on y and the first channel of z, fill, or stroke, if any.
|
|
73
|
+
*
|
|
74
|
+
* @param param0
|
|
75
|
+
* @param options
|
|
76
|
+
*/
|
|
77
|
+
export function binX({ data, ...channels }, options = { thresholds: 'auto', cumulative: false }) {
|
|
78
|
+
return binBy('x', { data, ...channels }, options);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Bins on y. Also groups on y and the first channel of z, fill, or stroke, if any.
|
|
82
|
+
*
|
|
83
|
+
* @param param0
|
|
84
|
+
* @param options
|
|
85
|
+
*/
|
|
86
|
+
export function binY({ data, ...channels }, options = { thresholds: 'auto', cumulative: false }) {
|
|
87
|
+
return binBy('y', { data, ...channels }, options);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* for binning in x and y dimension simulatenously
|
|
91
|
+
*/
|
|
92
|
+
export function bin({ data, ...channels }, options = { thresholds: 'auto', cumulative: false }) {
|
|
93
|
+
const { domain, thresholds = 'auto', interval, cumulative = false } = options;
|
|
94
|
+
const binX = d3Bin();
|
|
95
|
+
const binY = d3Bin();
|
|
96
|
+
if (domain) {
|
|
97
|
+
// this really doesn't make sense...
|
|
98
|
+
binX.domain(domain);
|
|
99
|
+
binY.domain(domain);
|
|
100
|
+
}
|
|
101
|
+
// channels.x is the input
|
|
102
|
+
binX.value((d) => resolveChannel('x', d, channels));
|
|
103
|
+
binY.value((d) => resolveChannel('y', d, channels));
|
|
104
|
+
if (interval) {
|
|
105
|
+
const [xlo, xhi] = extent(data.map((d) => resolveChannel('x', d, channels)));
|
|
106
|
+
const [ylo, yhi] = extent(data.map((d) => resolveChannel('y', d, channels)));
|
|
107
|
+
binX.thresholds(maybeInterval(interval).range(xlo, xhi));
|
|
108
|
+
binY.thresholds(maybeInterval(interval).range(ylo, yhi));
|
|
109
|
+
}
|
|
110
|
+
else if (thresholds) {
|
|
111
|
+
// when binning in x and y, we need to ensure we are using consistent thresholds
|
|
112
|
+
const t = typeof thresholds === 'string' && ThresholdGenerators[thresholds] !== undefined
|
|
113
|
+
? ThresholdGenerators[thresholds]
|
|
114
|
+
: thresholds;
|
|
115
|
+
binX.thresholds(t);
|
|
116
|
+
binY.thresholds(t);
|
|
117
|
+
const yThresholds = binY(data)
|
|
118
|
+
.slice(1)
|
|
119
|
+
.map((g) => g.x0);
|
|
120
|
+
binY.thresholds(yThresholds);
|
|
121
|
+
}
|
|
122
|
+
// y, y1, y2, fill, stroke, etc are outputs
|
|
123
|
+
const outputs = ['fill', 'stroke', 'r', 'opacity', 'fillOpacity', 'strokeOpacity'];
|
|
124
|
+
let newChannels = {
|
|
125
|
+
inset: 0.5,
|
|
126
|
+
...channels,
|
|
127
|
+
x: '__x',
|
|
128
|
+
x1: '__x1',
|
|
129
|
+
x2: '__x2',
|
|
130
|
+
y: '__y',
|
|
131
|
+
y1: '__y1',
|
|
132
|
+
y2: '__y2',
|
|
133
|
+
__x_origField: typeof channels.x === 'string' ? channels.x : null,
|
|
134
|
+
__y_origField: typeof channels.y === 'string' ? channels.y : null
|
|
135
|
+
};
|
|
136
|
+
const groupBy = channels.z ? 'z' : channels.fill ? 'fill' : channels.stroke ? 'stroke' : true;
|
|
137
|
+
const groupByPropName = groupBy !== true && typeof channels[groupBy] === 'string' ? channels[groupBy] : '__group';
|
|
138
|
+
if (groupBy !== true)
|
|
139
|
+
newChannels[groupBy] = groupByPropName;
|
|
140
|
+
// consistent intervals
|
|
141
|
+
const newData = [];
|
|
142
|
+
binX(data).forEach((groupX) => {
|
|
143
|
+
const newRecordBaseX = {
|
|
144
|
+
__x1: groupX.x0,
|
|
145
|
+
__x2: groupX.x1,
|
|
146
|
+
__x: isDate(groupX.x0)
|
|
147
|
+
? new Date(Math.round((groupX.x0.getTime() + groupX.x1.getTime()) * 0.5))
|
|
148
|
+
: (groupX.x0 + groupX.x1) * 0.5
|
|
149
|
+
};
|
|
150
|
+
binY(groupX).forEach((groupY) => {
|
|
151
|
+
const newRecordBaseY = {
|
|
152
|
+
...newRecordBaseX,
|
|
153
|
+
__y1: groupY.x0,
|
|
154
|
+
__y2: groupY.x1,
|
|
155
|
+
__y: isDate(groupY.x0)
|
|
156
|
+
? new Date(Math.round((groupY.x0.getTime() + groupY.x1.getTime()) * 0.5))
|
|
157
|
+
: (groupY.x0 + groupY.x1) * 0.5
|
|
158
|
+
};
|
|
159
|
+
const newGroupChannels = groupFacetsAndZ(groupY, channels, (items, itemGroupProps) => {
|
|
160
|
+
const newRecord = {
|
|
161
|
+
...newRecordBaseY,
|
|
162
|
+
...itemGroupProps
|
|
163
|
+
};
|
|
164
|
+
reduceOutputs(newRecord, items, options, outputs, channels, newChannels);
|
|
165
|
+
newData.push(newRecord);
|
|
166
|
+
});
|
|
167
|
+
newChannels = { ...newChannels, ...newGroupChannels };
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
return { data: options.reverse ? newData.toReversed() : newData, ...newChannels };
|
|
171
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DataRecord, TransformArg } from '../types.js';
|
|
2
|
+
export type BollingerOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* the window size (the window transform’s k option), an integer; defaults to 20
|
|
5
|
+
*/
|
|
6
|
+
n?: number;
|
|
7
|
+
/**
|
|
8
|
+
* the band radius, a number representing a multiple of standard deviations; defaults to 2
|
|
9
|
+
*/
|
|
10
|
+
k?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function bollingerX(args: TransformArg<DataRecord>, options?: BollingerOptions): TransformArg<DataRecord>;
|
|
13
|
+
export declare function bollingerY(args: TransformArg<DataRecord>, options?: BollingerOptions): TransformArg<DataRecord>;
|
|
14
|
+
export declare function bollingerDim(dim: 'x' | 'y', { data, ...channels }: TransformArg<DataRecord>, options?: BollingerOptions): {
|
|
15
|
+
data: {
|
|
16
|
+
__x: import("../types.js").RawValue;
|
|
17
|
+
__lo: number;
|
|
18
|
+
__avg: number;
|
|
19
|
+
__hi: number;
|
|
20
|
+
}[];
|
|
21
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
2
|
+
export function bollingerX(args, options = {}) {
|
|
3
|
+
return bollingerDim('x', args, options);
|
|
4
|
+
}
|
|
5
|
+
export function bollingerY(args, options = {}) {
|
|
6
|
+
return bollingerDim('y', args, options);
|
|
7
|
+
}
|
|
8
|
+
export function bollingerDim(dim, { data, ...channels }, options = {}) {
|
|
9
|
+
const { n = 20, k = 2 } = options;
|
|
10
|
+
const bands = bollinger(data.map((datum) => resolveChannel(dim, datum, channels)), n, [-k, 0, k]);
|
|
11
|
+
const otherDim = dim === 'x' ? 'y' : 'x';
|
|
12
|
+
return {
|
|
13
|
+
data: data.map((datum, i) => ({
|
|
14
|
+
__x: resolveChannel(otherDim, datum, channels),
|
|
15
|
+
__lo: bands[0][i],
|
|
16
|
+
__avg: bands[1][i],
|
|
17
|
+
__hi: bands[2][i]
|
|
18
|
+
})),
|
|
19
|
+
...channels,
|
|
20
|
+
[otherDim]: '__x',
|
|
21
|
+
[dim]: '__avg',
|
|
22
|
+
[`${otherDim}1`]: '__x',
|
|
23
|
+
[`${dim}1`]: '__lo',
|
|
24
|
+
[`${dim}2`]: '__hi'
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* taken from https://observablehq.com/@d3/bollinger-bands/
|
|
29
|
+
*/
|
|
30
|
+
function bollinger(values, N, K) {
|
|
31
|
+
let i = 0;
|
|
32
|
+
let sum = 0;
|
|
33
|
+
let sumSquared = 0;
|
|
34
|
+
// initialize bands
|
|
35
|
+
const bands = K.map(() => new Float64Array(values.length).fill(NaN));
|
|
36
|
+
// compute sum and square of sums
|
|
37
|
+
for (let n = Math.min(N - 1, values.length); i < n; ++i) {
|
|
38
|
+
const value = values[i];
|
|
39
|
+
(sum += value), (sumSquared += value ** 2);
|
|
40
|
+
}
|
|
41
|
+
for (let n = values.length, m = bands.length; i < n; ++i) {
|
|
42
|
+
const value = values[i];
|
|
43
|
+
(sum += value), (sumSquared += value ** 2);
|
|
44
|
+
const mean = sum / N;
|
|
45
|
+
const deviation = Math.sqrt((sumSquared - sum ** 2 / N) / (N - 1));
|
|
46
|
+
for (let j = 0; j < K.length; ++j) {
|
|
47
|
+
bands[j][i] = mean + deviation * K[j];
|
|
48
|
+
}
|
|
49
|
+
const value0 = values[i - N + 1];
|
|
50
|
+
(sum -= value0), (sumSquared -= value0 ** 2);
|
|
51
|
+
}
|
|
52
|
+
return bands;
|
|
53
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DataRecord, TransformArg } from '../types.js';
|
|
2
|
+
export declare function geoCentroid({ data, ...options }: TransformArg<DataRecord>): {
|
|
3
|
+
x: (d: any) => any;
|
|
4
|
+
y: (d: any) => any;
|
|
5
|
+
data: {
|
|
6
|
+
__centroid__: [number, number];
|
|
7
|
+
___orig___?: import("../types.js").RawValue | [import("../types.js").RawValue, import("../types.js").RawValue];
|
|
8
|
+
}[];
|
|
9
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { resolveProp } from '../helpers/resolve.js';
|
|
2
|
+
import { geoCentroid as d3GeoCentroid } from 'd3-geo';
|
|
3
|
+
export function geoCentroid({ data, ...options }) {
|
|
4
|
+
return {
|
|
5
|
+
data: data.map((d) => ({
|
|
6
|
+
...d,
|
|
7
|
+
__centroid__: d3GeoCentroid(resolveProp(options.geometry, d, d))
|
|
8
|
+
})),
|
|
9
|
+
...options,
|
|
10
|
+
x: (d) => d.__centroid__[0],
|
|
11
|
+
y: (d) => d.__centroid__[1]
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type ReducerName } from '../helpers/reduce.js';
|
|
2
|
+
import type { DataRecord, DataRow, RawValue, TransformArg } from '../types.js';
|
|
3
|
+
type ReducerFunc = (group: DataRow[]) => RawValue;
|
|
4
|
+
type ReducerOption = ReducerName | ReducerFunc;
|
|
5
|
+
type GroupBaseOptions = {
|
|
6
|
+
domain?: [number, number];
|
|
7
|
+
thresholds?: NamedThresholdsGenerator | number | number[] | ThresholdCountGenerator;
|
|
8
|
+
interval?: number | string;
|
|
9
|
+
cumulative?: false | 1 | -1;
|
|
10
|
+
reverse?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* copy properties from the first element of each group
|
|
13
|
+
*/
|
|
14
|
+
copy?: string[];
|
|
15
|
+
};
|
|
16
|
+
type AdditionalOutputChannels = Partial<{
|
|
17
|
+
fill: ReducerOption;
|
|
18
|
+
stroke: ReducerOption;
|
|
19
|
+
r: ReducerOption;
|
|
20
|
+
opacity: ReducerOption;
|
|
21
|
+
fillOpacity: ReducerOption;
|
|
22
|
+
strokeOpacity: ReducerOption;
|
|
23
|
+
}>;
|
|
24
|
+
type GroupXOptions = GroupBaseOptions & AdditionalOutputChannels & Partial<{
|
|
25
|
+
y: ReducerOption;
|
|
26
|
+
y1: ReducerOption;
|
|
27
|
+
y2: ReducerOption;
|
|
28
|
+
xPropName: string;
|
|
29
|
+
}>;
|
|
30
|
+
type GroupYOptions = GroupBaseOptions & AdditionalOutputChannels & Partial<{
|
|
31
|
+
x: ReducerOption;
|
|
32
|
+
x1: ReducerOption;
|
|
33
|
+
x2: ReducerOption;
|
|
34
|
+
yPropName: string;
|
|
35
|
+
}>;
|
|
36
|
+
type GroupZOptions = GroupXOptions | GroupYOptions;
|
|
37
|
+
/**
|
|
38
|
+
* groups the dataset by x and y channel and optionally reduces the group items
|
|
39
|
+
* to output channels fill, stroke, r, opacity, fillOpacity, or strokeOpacity
|
|
40
|
+
*/
|
|
41
|
+
export declare function group({ data, ...channels }: TransformArg<T, DataRecord>, options?: GroupXOptions): {
|
|
42
|
+
data: DataRecord[];
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* groups the dataset by the x channel and optionally reduces the group items
|
|
46
|
+
* to output channels y, y1, y2, fill, stroke, r, opacity, fillOpacity, or strokeOpacity
|
|
47
|
+
*/
|
|
48
|
+
export declare function groupX(input: TransformArg<T, DataRecord>, options?: GroupXOptions): {
|
|
49
|
+
data: DataRecord[];
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* groups the dataset by the y channel and optionally reduces the group items
|
|
53
|
+
* to output channels x, x1, x2, fill, stroke, r, opacity, fillOpacity, or strokeOpacity
|
|
54
|
+
*/
|
|
55
|
+
export declare function groupY(input: TransformArg<T, DataRecord>, options?: GroupYOptions): {
|
|
56
|
+
data: DataRecord[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* groups the dataset by the z channel and optionally reduces the group items
|
|
60
|
+
* to output channels x, x1, x2, y, y1, y2, fill, stroke, r, opacity, fillOpacity,
|
|
61
|
+
* or strokeOpacity
|
|
62
|
+
*/
|
|
63
|
+
export declare function groupZ(input: TransformArg<T, DataRecord>, options?: GroupZOptions): {
|
|
64
|
+
data: DataRecord[];
|
|
65
|
+
};
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { groupFacetsAndZ } from '../helpers/group.js';
|
|
2
|
+
import { testFilter } from '../helpers/index.js';
|
|
3
|
+
import { reduceOutputs } from '../helpers/reduce.js';
|
|
4
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
5
|
+
import { groups as d3Groups } from 'd3-array';
|
|
6
|
+
import { omit } from '../helpers';
|
|
7
|
+
import { maybeInterval } from '../helpers/autoTicks.js';
|
|
8
|
+
/**
|
|
9
|
+
* groups the dataset by x and y channel and optionally reduces the group items
|
|
10
|
+
* to output channels fill, stroke, r, opacity, fillOpacity, or strokeOpacity
|
|
11
|
+
*/
|
|
12
|
+
export function group({ data, ...channels }, options = {}) {
|
|
13
|
+
if (channels.x == null || channels.y == null)
|
|
14
|
+
throw new Error('you must provide an x and y channel to group on');
|
|
15
|
+
// group by x or y
|
|
16
|
+
const groups = d3Groups(data.filter((d) => testFilter(d, channels)), (d) => resolveChannel('x', d, channels), (d) => resolveChannel('y', d, channels));
|
|
17
|
+
const newData = [];
|
|
18
|
+
const xChannel = typeof channels.x === 'string' ? channels.x : '__x';
|
|
19
|
+
const yChannel = typeof channels.y === 'string' ? channels.y : '__y';
|
|
20
|
+
let newChannels = omit({ ...channels, x: xChannel, y: yChannel }, 'filter');
|
|
21
|
+
const outputs = ['fill', 'stroke', 'r', 'opacity', 'fillOpacity', 'strokeOpacity'];
|
|
22
|
+
groups.forEach(([xGroupKey, xGroups]) => {
|
|
23
|
+
xGroups.forEach(([yGroupKey, items]) => {
|
|
24
|
+
const baseRecord = { [xChannel]: xGroupKey, [yChannel]: yGroupKey }; // dim === 'z' ? {} : { [`__${dim}`]: groupKey };
|
|
25
|
+
// copy properties from first item of each group
|
|
26
|
+
options.copy?.forEach((prop) => {
|
|
27
|
+
baseRecord[prop] = items[0][prop];
|
|
28
|
+
});
|
|
29
|
+
const newGroupChannels = groupFacetsAndZ(items, channels, (items, itemGroupProps) => {
|
|
30
|
+
const item = { ...baseRecord, ...itemGroupProps };
|
|
31
|
+
reduceOutputs(item, items, options, outputs, channels, newChannels);
|
|
32
|
+
newData.push(item);
|
|
33
|
+
});
|
|
34
|
+
newChannels = { ...newChannels, ...newGroupChannels };
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
return { data: newData, ...newChannels };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* groups the dataset by the x channel and optionally reduces the group items
|
|
41
|
+
* to output channels y, y1, y2, fill, stroke, r, opacity, fillOpacity, or strokeOpacity
|
|
42
|
+
*/
|
|
43
|
+
export function groupX(input, options = {}) {
|
|
44
|
+
return groupXYZ('x', input, options);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* groups the dataset by the y channel and optionally reduces the group items
|
|
48
|
+
* to output channels x, x1, x2, fill, stroke, r, opacity, fillOpacity, or strokeOpacity
|
|
49
|
+
*/
|
|
50
|
+
export function groupY(input, options = {}) {
|
|
51
|
+
return groupXYZ('y', input, options);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* groups the dataset by the z channel and optionally reduces the group items
|
|
55
|
+
* to output channels x, x1, x2, y, y1, y2, fill, stroke, r, opacity, fillOpacity,
|
|
56
|
+
* or strokeOpacity
|
|
57
|
+
*/
|
|
58
|
+
export function groupZ(input, options = {}) {
|
|
59
|
+
return groupXYZ('z', input, options);
|
|
60
|
+
}
|
|
61
|
+
function groupXYZ(dim, { data, ...channels }, options = {}) {
|
|
62
|
+
if ((dim === 'z' ? channels.z || channels.fill || channels.stroke : channels[dim]) == null)
|
|
63
|
+
throw new Error('you must provide a channel to group on ' + dim);
|
|
64
|
+
const propName = options[`${dim}PropName`] != null
|
|
65
|
+
? options[`${dim}PropName`]
|
|
66
|
+
: typeof channels[dim] === 'string' && !options.interval
|
|
67
|
+
? channels[dim]
|
|
68
|
+
: `__${dim}`;
|
|
69
|
+
const interval = options.interval ? maybeInterval(options.interval) : null;
|
|
70
|
+
// group by x or y
|
|
71
|
+
const groups = dim === 'z'
|
|
72
|
+
? [[null, data]]
|
|
73
|
+
: d3Groups(data.filter((d) => testFilter(d, channels)), (d) => {
|
|
74
|
+
const v = resolveChannel(dim, d, channels);
|
|
75
|
+
return interval ? interval.round(v) : v;
|
|
76
|
+
});
|
|
77
|
+
const newData = [];
|
|
78
|
+
let newChannels = omit({ ...channels }, 'filter');
|
|
79
|
+
if (dim !== 'z')
|
|
80
|
+
newChannels[dim] = propName;
|
|
81
|
+
const outputs = [
|
|
82
|
+
...(dim === 'x'
|
|
83
|
+
? ['y', 'y1', 'y2']
|
|
84
|
+
: dim === 'y'
|
|
85
|
+
? ['x', 'x1', 'x2']
|
|
86
|
+
: ['x', 'x1', 'x2', 'y', 'y1', 'y2']),
|
|
87
|
+
'fill',
|
|
88
|
+
'stroke',
|
|
89
|
+
'r',
|
|
90
|
+
'opacity',
|
|
91
|
+
'fillOpacity',
|
|
92
|
+
'strokeOpacity'
|
|
93
|
+
];
|
|
94
|
+
groups.forEach(([groupKey, items]) => {
|
|
95
|
+
const baseRecord = dim === 'z' ? {} : { [propName]: groupKey };
|
|
96
|
+
const newGroupChannels = groupFacetsAndZ(items, channels, (items, itemGroupProps) => {
|
|
97
|
+
const copiedProps = {};
|
|
98
|
+
// copy properties from first item of each group
|
|
99
|
+
options.copy?.forEach((prop) => {
|
|
100
|
+
copiedProps[prop] = items[0][prop];
|
|
101
|
+
});
|
|
102
|
+
const item = { ...baseRecord, ...copiedProps, ...itemGroupProps };
|
|
103
|
+
reduceOutputs(item, items, options, outputs, channels, newChannels);
|
|
104
|
+
newData.push(item);
|
|
105
|
+
});
|
|
106
|
+
newChannels = { ...newChannels, ...newGroupChannels };
|
|
107
|
+
});
|
|
108
|
+
return { data: newData, ...newChannels };
|
|
109
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PlotState, TransformArg } from '../types.js';
|
|
2
|
+
export declare function intervalX<T>(args: TransformArg<T>, { plot }: {
|
|
3
|
+
plot: PlotState;
|
|
4
|
+
}): {
|
|
5
|
+
data: T[];
|
|
6
|
+
};
|
|
7
|
+
export declare function intervalY<T>(args: TransformArg<T>, { plot }: {
|
|
8
|
+
plot: PlotState;
|
|
9
|
+
}): {
|
|
10
|
+
data: T[];
|
|
11
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { maybeInterval } from '../helpers/autoTicks.js';
|
|
2
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
3
|
+
export function intervalX(args, { plot }) {
|
|
4
|
+
return interval('x', plot, args);
|
|
5
|
+
}
|
|
6
|
+
export function intervalY(args, { plot }) {
|
|
7
|
+
return interval('y', plot, args);
|
|
8
|
+
}
|
|
9
|
+
function interval(dim, plot, { data, ...options }) {
|
|
10
|
+
if (options.interval &&
|
|
11
|
+
options[dim] &&
|
|
12
|
+
options[`${dim}1`] == null &&
|
|
13
|
+
options[`${dim}2`] == null) {
|
|
14
|
+
// derive x1 and x2 from x+interval
|
|
15
|
+
const interval = maybeInterval(options.interval, plot.scales[dim].type);
|
|
16
|
+
const newData = data.map((row) => {
|
|
17
|
+
const val = resolveChannel(dim, row, options);
|
|
18
|
+
return {
|
|
19
|
+
...row,
|
|
20
|
+
[`__${dim}1`]: interval.floor(val),
|
|
21
|
+
[`__${dim}2`]: interval.offset(interval.floor(val))
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
return {
|
|
25
|
+
data: newData,
|
|
26
|
+
// set default inset
|
|
27
|
+
[`inset${dim === 'x' ? 'Right' : 'Bottom'}`]: 1,
|
|
28
|
+
...options,
|
|
29
|
+
[`${dim}1`]: `__${dim}1`,
|
|
30
|
+
[`${dim}2`]: `__${dim}2`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return { data, ...options };
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TransformArg, MapOptions, MapMethod, DataRecord } from '../types.js';
|
|
2
|
+
export declare function map<T>(args: TransformArg<T>, options: MapOptions): {
|
|
3
|
+
data: DataRecord[];
|
|
4
|
+
};
|
|
5
|
+
export declare function mapX<T>(args: TransformArg<T>, mapper: MapMethod): {
|
|
6
|
+
data: DataRecord[];
|
|
7
|
+
};
|
|
8
|
+
export declare function mapY<T>(args: TransformArg<T>, mapper: MapMethod): {
|
|
9
|
+
data: DataRecord[];
|
|
10
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { identity } from '../helpers/index.js';
|
|
2
|
+
import { count, rank } from 'd3-array';
|
|
3
|
+
import { groupFacetsAndZ } from '../helpers/group.js';
|
|
4
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
5
|
+
export function map(args, options) {
|
|
6
|
+
const { data, ...channels } = args;
|
|
7
|
+
const newChannels = {};
|
|
8
|
+
const newData = [];
|
|
9
|
+
groupFacetsAndZ(data, channels, (groupedData) => {
|
|
10
|
+
for (const [channel, map] of Object.entries(options)) {
|
|
11
|
+
const mapper = maybeMap(map);
|
|
12
|
+
const values = groupedData.map((d) => resolveChannel(channel, d, channels));
|
|
13
|
+
const indices = groupedData.map((d, i) => i);
|
|
14
|
+
const mappedValues = new Array(values.length);
|
|
15
|
+
mapper.mapIndex(indices, values, mappedValues);
|
|
16
|
+
newChannels[channel] = `__${channel}`;
|
|
17
|
+
for (let i = 0; i < values.length; ++i) {
|
|
18
|
+
const datum = { ...groupedData[i], [`__${channel}`]: mappedValues[i] };
|
|
19
|
+
newData.push(datum);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return { data: newData, ...channels, ...newChannels };
|
|
24
|
+
}
|
|
25
|
+
export function mapX(args, mapper) {
|
|
26
|
+
let { x, x1, x2 } = args;
|
|
27
|
+
if (x === undefined && x1 === undefined && x2 === undefined)
|
|
28
|
+
args = { ...args, x: identity };
|
|
29
|
+
const outputs = {};
|
|
30
|
+
if (x != null)
|
|
31
|
+
outputs.x = mapper;
|
|
32
|
+
if (x1 != null)
|
|
33
|
+
outputs.x1 = mapper;
|
|
34
|
+
if (x2 != null)
|
|
35
|
+
outputs.x2 = mapper;
|
|
36
|
+
return map(args, outputs);
|
|
37
|
+
}
|
|
38
|
+
export function mapY(args, mapper) {
|
|
39
|
+
let { y, y1, y2 } = args;
|
|
40
|
+
if (y === undefined && y1 === undefined && y2 === undefined)
|
|
41
|
+
args = { ...args, y: identity };
|
|
42
|
+
const outputs = {};
|
|
43
|
+
if (y != null)
|
|
44
|
+
outputs.y = mapper;
|
|
45
|
+
if (y1 != null)
|
|
46
|
+
outputs.y1 = mapper;
|
|
47
|
+
if (y2 != null)
|
|
48
|
+
outputs.y2 = mapper;
|
|
49
|
+
return map(args, outputs);
|
|
50
|
+
}
|
|
51
|
+
function maybeMap(map) {
|
|
52
|
+
if (map == null)
|
|
53
|
+
throw new Error('missing map');
|
|
54
|
+
if (typeof map === 'object' && typeof map.mapIndex === 'function')
|
|
55
|
+
return map;
|
|
56
|
+
if (typeof map === 'function')
|
|
57
|
+
return mapFunction(map);
|
|
58
|
+
switch (`${map}`.toLowerCase()) {
|
|
59
|
+
case 'cumsum':
|
|
60
|
+
return mapCumsum;
|
|
61
|
+
case 'rank':
|
|
62
|
+
return mapFunction((I, V) => rank(I, (i) => V[i]));
|
|
63
|
+
case 'quantile':
|
|
64
|
+
return mapFunction((I, V) => rankQuantile(I, (i) => V[i]));
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`invalid map: ${map}`);
|
|
67
|
+
}
|
|
68
|
+
function rankQuantile(I, f) {
|
|
69
|
+
const n = count(I, f) - 1;
|
|
70
|
+
return rank(I, f).map((r) => r / n);
|
|
71
|
+
}
|
|
72
|
+
function mapFunction(f) {
|
|
73
|
+
return {
|
|
74
|
+
mapIndex(I, S, T) {
|
|
75
|
+
const M = f(I, S);
|
|
76
|
+
if (M.length !== I.length)
|
|
77
|
+
throw new Error('map function returned a mismatched length');
|
|
78
|
+
for (let i = 0, n = I.length; i < n; ++i)
|
|
79
|
+
T[I[i]] = M[i];
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const mapCumsum = {
|
|
84
|
+
mapIndex(I, S, T) {
|
|
85
|
+
let sum = 0;
|
|
86
|
+
for (const i of I)
|
|
87
|
+
T[i] = sum += S[i];
|
|
88
|
+
}
|
|
89
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TransformArg, MapIndexObject } from '../types.js';
|
|
2
|
+
type NormalizeBasis = 'deviation' | 'first' | 'last' | 'min' | 'max' | 'mean' | 'median' | 'sum' | 'extent' | MapIndexObject;
|
|
3
|
+
export declare function normalizeX<T>(args: TransformArg<T>, basis: NormalizeBasis): {
|
|
4
|
+
data: import("../types.js").DataRecord[];
|
|
5
|
+
};
|
|
6
|
+
export declare function normalizeY<T>(args: TransformArg<T>, basis: NormalizeBasis): {
|
|
7
|
+
data: import("../types.js").DataRecord[];
|
|
8
|
+
};
|
|
9
|
+
export {};
|