svelteplot 0.10.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Mark.svelte +42 -25
- package/dist/Mark.svelte.d.ts +111 -32
- package/dist/Plot.svelte +21 -15
- package/dist/core/Facet.svelte +1 -1
- package/dist/core/FacetAxes.svelte +13 -8
- package/dist/core/FacetGrid.svelte +4 -4
- package/dist/core/Plot.svelte +41 -35
- package/dist/helpers/autoScales.d.ts +3 -3
- package/dist/helpers/autoScales.js +28 -18
- package/dist/helpers/autoTicks.js +2 -0
- package/dist/helpers/callWithProps.d.ts +1 -2
- package/dist/helpers/facets.js +0 -1
- package/dist/helpers/index.js +1 -1
- package/dist/helpers/mergeDeep.d.ts +1 -3
- package/dist/helpers/mergeDeep.js +15 -16
- package/dist/helpers/projection.d.ts +4 -3
- package/dist/helpers/projection.js +17 -5
- package/dist/helpers/reduce.d.ts +4 -4
- package/dist/helpers/reduce.js +6 -4
- package/dist/helpers/regressionLoess.js +2 -1
- package/dist/helpers/resolve.d.ts +6 -3
- package/dist/helpers/resolve.js +25 -16
- package/dist/helpers/scales.d.ts +10 -10
- package/dist/helpers/scales.js +43 -13
- package/dist/helpers/time.d.ts +10 -3
- package/dist/helpers/time.js +2 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/plotDefaults.d.ts +3 -1
- package/dist/hooks/plotDefaults.js +33 -1
- package/dist/hooks/usePlot.svelte.d.ts +10 -25
- package/dist/hooks/usePlot.svelte.js +8 -7
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -3
- package/dist/marks/Area.svelte +24 -13
- package/dist/marks/Area.svelte.d.ts +118 -34
- package/dist/marks/AreaX.svelte +42 -8
- package/dist/marks/AreaX.svelte.d.ts +154 -71
- package/dist/marks/AreaY.svelte +42 -8
- package/dist/marks/AreaY.svelte.d.ts +154 -71
- package/dist/marks/Arrow.svelte +42 -23
- package/dist/marks/Arrow.svelte.d.ts +114 -35
- package/dist/marks/AxisX.svelte +43 -28
- package/dist/marks/AxisX.svelte.d.ts +125 -40
- package/dist/marks/AxisY.svelte +43 -26
- package/dist/marks/AxisY.svelte.d.ts +127 -40
- package/dist/marks/BarX.svelte +12 -10
- package/dist/marks/BarX.svelte.d.ts +104 -32
- package/dist/marks/BarY.svelte +11 -10
- package/dist/marks/BarY.svelte.d.ts +106 -34
- package/dist/marks/BollingerX.svelte +4 -7
- package/dist/marks/BollingerX.svelte.d.ts +105 -30
- package/dist/marks/BollingerY.svelte +3 -0
- package/dist/marks/BollingerY.svelte.d.ts +105 -30
- package/dist/marks/BoxX.svelte +3 -3
- package/dist/marks/BoxY.svelte +12 -9
- package/dist/marks/BoxY.svelte.d.ts +128 -53
- package/dist/marks/Brush.svelte +26 -21
- package/dist/marks/Brush.svelte.d.ts +119 -60
- package/dist/marks/Cell.svelte +13 -9
- package/dist/marks/Cell.svelte.d.ts +105 -30
- package/dist/marks/CellX.svelte +2 -1
- package/dist/marks/CellX.svelte.d.ts +105 -32
- package/dist/marks/CellY.svelte +2 -1
- package/dist/marks/CellY.svelte.d.ts +105 -32
- package/dist/marks/ColorLegend.svelte +24 -13
- package/dist/marks/ColorLegend.svelte.d.ts +1 -0
- package/dist/marks/CustomMark.svelte +16 -10
- package/dist/marks/CustomMark.svelte.d.ts +112 -31
- package/dist/marks/CustomMarkHTML.svelte +8 -2
- package/dist/marks/CustomMarkHTML.svelte.d.ts +8 -2
- package/dist/marks/DifferenceY.svelte +31 -20
- package/dist/marks/DifferenceY.svelte.d.ts +134 -55
- package/dist/marks/Dot.svelte +21 -11
- package/dist/marks/Dot.svelte.d.ts +117 -38
- package/dist/marks/DotX.svelte +2 -0
- package/dist/marks/DotX.svelte.d.ts +136 -62
- package/dist/marks/DotY.svelte +1 -0
- package/dist/marks/DotY.svelte.d.ts +135 -62
- package/dist/marks/Frame.svelte +47 -9
- package/dist/marks/Frame.svelte.d.ts +124 -41
- package/dist/marks/Geo.svelte +21 -12
- package/dist/marks/Geo.svelte.d.ts +105 -30
- package/dist/marks/Graticule.svelte +3 -0
- package/dist/marks/Graticule.svelte.d.ts +3 -0
- package/dist/marks/GridX.svelte +31 -16
- package/dist/marks/GridX.svelte.d.ts +108 -32
- package/dist/marks/GridY.svelte +30 -15
- package/dist/marks/GridY.svelte.d.ts +108 -32
- package/dist/marks/HTMLTooltip.svelte +14 -7
- package/dist/marks/HTMLTooltip.svelte.d.ts +7 -0
- package/dist/marks/Image.svelte +50 -25
- package/dist/marks/Image.svelte.d.ts +117 -35
- package/dist/marks/Line.svelte +67 -44
- package/dist/marks/Line.svelte.d.ts +119 -30
- package/dist/marks/LineX.svelte +2 -1
- package/dist/marks/LineX.svelte.d.ts +142 -69
- package/dist/marks/LineY.svelte +2 -1
- package/dist/marks/LineY.svelte.d.ts +142 -69
- package/dist/marks/Link.svelte +70 -46
- package/dist/marks/Link.svelte.d.ts +126 -41
- package/dist/marks/Pointer.svelte +24 -15
- package/dist/marks/Pointer.svelte.d.ts +7 -0
- package/dist/marks/Rect.svelte +13 -5
- package/dist/marks/Rect.svelte.d.ts +116 -35
- package/dist/marks/RectX.svelte +6 -3
- package/dist/marks/RectX.svelte.d.ts +158 -12
- package/dist/marks/RectY.svelte +6 -3
- package/dist/marks/RectY.svelte.d.ts +158 -12
- package/dist/marks/RegressionX.svelte +13 -6
- package/dist/marks/RegressionX.svelte.d.ts +8 -3
- package/dist/marks/RegressionY.svelte +13 -6
- package/dist/marks/RegressionY.svelte.d.ts +8 -3
- package/dist/marks/RuleX.svelte +18 -11
- package/dist/marks/RuleX.svelte.d.ts +112 -32
- package/dist/marks/RuleY.svelte +19 -12
- package/dist/marks/RuleY.svelte.d.ts +114 -34
- package/dist/marks/Spike.svelte +11 -5
- package/dist/marks/Spike.svelte.d.ts +146 -68
- package/dist/marks/Text.svelte +24 -7
- package/dist/marks/Text.svelte.d.ts +253 -75
- package/dist/marks/TickX.svelte +56 -48
- package/dist/marks/TickX.svelte.d.ts +114 -40
- package/dist/marks/TickY.svelte +59 -51
- package/dist/marks/TickY.svelte.d.ts +117 -43
- package/dist/marks/Trail.svelte +25 -13
- package/dist/marks/Trail.svelte.d.ts +116 -33
- package/dist/marks/Vector.svelte +20 -11
- package/dist/marks/Vector.svelte.d.ts +116 -35
- package/dist/marks/WaffleX.svelte +18 -16
- package/dist/marks/WaffleX.svelte.d.ts +131 -57
- package/dist/marks/WaffleY.svelte +16 -15
- package/dist/marks/WaffleY.svelte.d.ts +129 -56
- package/dist/marks/helpers/Anchor.svelte +17 -2
- package/dist/marks/helpers/Anchor.svelte.d.ts +16 -1
- package/dist/marks/helpers/AreaCanvas.svelte +8 -8
- package/dist/marks/helpers/BaseAxisX.svelte +38 -41
- package/dist/marks/helpers/BaseAxisX.svelte.d.ts +11 -17
- package/dist/marks/helpers/BaseAxisY.svelte +35 -35
- package/dist/marks/helpers/BaseAxisY.svelte.d.ts +12 -15
- package/dist/marks/helpers/Box.svelte +35 -28
- package/dist/marks/helpers/Box.svelte.d.ts +122 -50
- package/dist/marks/helpers/DotCanvas.svelte +11 -9
- package/dist/marks/helpers/GeoCanvas.svelte +7 -6
- package/dist/marks/helpers/LineCanvas.svelte +7 -7
- package/dist/marks/helpers/LinearGradientX.svelte +2 -2
- package/dist/marks/helpers/LinearGradientX.svelte.d.ts +1 -1
- package/dist/marks/helpers/LinearGradientY.svelte +2 -2
- package/dist/marks/helpers/LinearGradientY.svelte.d.ts +1 -1
- package/dist/marks/helpers/Marker.svelte +2 -2
- package/dist/marks/helpers/MarkerPath.svelte +15 -12
- package/dist/marks/helpers/MarkerPath.svelte.d.ts +105 -32
- package/dist/marks/helpers/MultilineText.svelte +24 -17
- package/dist/marks/helpers/MultilineText.svelte.d.ts +1 -1
- package/dist/marks/helpers/RectCanvas.svelte +31 -26
- package/dist/marks/helpers/RectPath.svelte +2 -2
- package/dist/marks/helpers/Regression.svelte +176 -86
- package/dist/marks/helpers/Regression.svelte.d.ts +20 -8
- package/dist/marks/helpers/RuleCanvas.svelte +9 -6
- package/dist/marks/helpers/TextCanvas.svelte +13 -9
- package/dist/marks/helpers/TextCanvas.svelte.d.ts +6 -6
- package/dist/marks/helpers/TickCanvas.svelte +6 -5
- package/dist/marks/helpers/TrailCanvas.svelte +16 -18
- package/dist/marks/helpers/TrailCanvas.svelte.d.ts +3 -5
- package/dist/marks/helpers/canvas.js +16 -9
- package/dist/marks/helpers/events.d.ts +2 -2
- package/dist/marks/helpers/events.js +14 -7
- package/dist/marks/helpers/waffle.d.ts +3 -3
- package/dist/marks/helpers/waffle.js +6 -4
- package/dist/regression/polynomial.d.ts +1 -1
- package/dist/regression/polynomial.js +5 -5
- package/dist/regression/utils/determination.d.ts +1 -1
- package/dist/regression/utils/determination.js +1 -1
- package/dist/regression/utils/geometry.d.ts +1 -1
- package/dist/regression/utils/interpose.d.ts +1 -1
- package/dist/regression/utils/interpose.js +1 -1
- package/dist/regression/utils/points.d.ts +1 -1
- package/dist/transforms/bin.d.ts +3 -3
- package/dist/transforms/bin.js +29 -20
- package/dist/transforms/bollinger.d.ts +8 -0
- package/dist/transforms/bollinger.js +9 -1
- package/dist/transforms/centroid.d.ts +4 -0
- package/dist/transforms/centroid.js +4 -0
- package/dist/transforms/density.d.ts +4 -4
- package/dist/transforms/density.js +20 -13
- package/dist/transforms/dodge.d.ts +12 -1
- package/dist/transforms/dodge.js +15 -6
- package/dist/transforms/group.d.ts +141 -4
- package/dist/transforms/group.js +4 -1
- package/dist/transforms/interval.d.ts +204 -60
- package/dist/transforms/jitter.d.ts +421 -4
- package/dist/transforms/jitter.js +10 -1
- package/dist/transforms/map.d.ts +412 -4
- package/dist/transforms/map.js +3 -3
- package/dist/transforms/normalize.d.ts +276 -5
- package/dist/transforms/normalize.js +5 -3
- package/dist/transforms/recordize.d.ts +17 -5
- package/dist/transforms/recordize.js +13 -9
- package/dist/transforms/rename.d.ts +11 -4
- package/dist/transforms/rename.js +7 -2
- package/dist/transforms/select.d.ts +722 -210
- package/dist/transforms/select.js +13 -1
- package/dist/transforms/shift.d.ts +8 -0
- package/dist/transforms/shift.js +20 -6
- package/dist/transforms/sort.d.ts +13 -258
- package/dist/transforms/sort.js +13 -10
- package/dist/transforms/stack.d.ts +58 -9
- package/dist/transforms/stack.js +27 -11
- package/dist/transforms/window.d.ts +221 -66
- package/dist/transforms/window.js +8 -2
- package/dist/types/axes.d.ts +43 -0
- package/dist/types/axes.js +1 -0
- package/dist/types/channel.d.ts +30 -2
- package/dist/types/data.d.ts +14 -1
- package/dist/types/facet.d.ts +5 -0
- package/dist/types/index.d.ts +33 -8
- package/dist/types/index.js +11 -7
- package/dist/types/mark.d.ts +124 -35
- package/dist/types/plot.d.ts +118 -16
- package/dist/types/scale.d.ts +125 -8
- package/package.json +178 -175
- package/dist/helpers/autoTicks.d.ts +0 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSS_URL, CSS_VAR } from '../../constants';
|
|
1
|
+
import { CSS_URL, CSS_VAR } from '../../constants.js';
|
|
2
2
|
export function resolveColor(color, canvas) {
|
|
3
3
|
if (`${color}`.toLowerCase() === 'currentcolor') {
|
|
4
4
|
color = getComputedStyle(canvas?.parentElement?.parentElement).getPropertyValue('color');
|
|
@@ -9,20 +9,27 @@ export function resolveColor(color, canvas) {
|
|
|
9
9
|
if (CSS_URL.test(color)) {
|
|
10
10
|
// might be a gradient we can parse!
|
|
11
11
|
const m = color.match(/^url\((#[^)]+)\)/);
|
|
12
|
+
if (!m)
|
|
13
|
+
return color;
|
|
12
14
|
const gradientId = m[1];
|
|
13
15
|
const gradient = canvas.ownerDocument.querySelector(gradientId);
|
|
14
16
|
if (gradient) {
|
|
15
17
|
// parse gradient
|
|
16
18
|
if (gradient.nodeName.toLowerCase() === 'lineargradient') {
|
|
17
|
-
const x0 = +gradient.getAttribute('x1');
|
|
18
|
-
const x1 = +gradient.getAttribute('x2');
|
|
19
|
-
const y0 = +gradient.getAttribute('y1');
|
|
20
|
-
const y1 = +gradient.getAttribute('y2');
|
|
21
|
-
const
|
|
19
|
+
const x0 = +(gradient.getAttribute('x1') ?? 0);
|
|
20
|
+
const x1 = +(gradient.getAttribute('x2') ?? 0);
|
|
21
|
+
const y0 = +(gradient.getAttribute('y1') ?? 0);
|
|
22
|
+
const y1 = +(gradient.getAttribute('y2') ?? 0);
|
|
23
|
+
const ctx = canvas.getContext('2d');
|
|
24
|
+
// If we cannot obtain a 2D context, fall back to a safe color instead of returning
|
|
25
|
+
// the original gradient URL (e.g., "url(#gradient1)"), which is not a valid canvas color.
|
|
26
|
+
if (!ctx)
|
|
27
|
+
return 'transparent';
|
|
28
|
+
const ctxGradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
22
29
|
for (const stop of gradient.querySelectorAll('stop')) {
|
|
23
|
-
const offset = +stop.getAttribute('offset');
|
|
24
|
-
const
|
|
25
|
-
ctxGradient.addColorStop(Math.min(1, Math.max(0, offset)),
|
|
30
|
+
const offset = +(stop.getAttribute('offset') ?? 0);
|
|
31
|
+
const stopColor = resolveColor(stop.getAttribute('stop-color') ?? '', canvas);
|
|
32
|
+
ctxGradient.addColorStop(Math.min(1, Math.max(0, offset)), stopColor);
|
|
26
33
|
}
|
|
27
34
|
return ctxGradient;
|
|
28
35
|
}
|
|
@@ -2,8 +2,8 @@ import type { BaseMarkProps, DataRecord, DataRow, PlotState } from '../../types/
|
|
|
2
2
|
import type { Attachment } from 'svelte/attachments';
|
|
3
3
|
declare global {
|
|
4
4
|
interface MouseEvent {
|
|
5
|
-
layerX
|
|
6
|
-
layerY
|
|
5
|
+
readonly layerX: number;
|
|
6
|
+
readonly layerY: number;
|
|
7
7
|
dataX?: number | string | Date;
|
|
8
8
|
dataY?: number | string | Date;
|
|
9
9
|
}
|
|
@@ -72,7 +72,10 @@ export function addEventHandlers({ options, datum, plot }) {
|
|
|
72
72
|
const relativeX = origEvent.clientX - facetRect.left + (plotOptions.marginLeft ?? 0);
|
|
73
73
|
const relativeY = origEvent.clientY - facetRect.top + (plotOptions.marginTop ?? 0);
|
|
74
74
|
if (scales.projection) {
|
|
75
|
-
const [x, y] = scales.projection.invert([
|
|
75
|
+
const [x, y] = scales.projection.invert([
|
|
76
|
+
relativeX,
|
|
77
|
+
relativeY
|
|
78
|
+
]);
|
|
76
79
|
origEvent.dataX = x;
|
|
77
80
|
origEvent.dataY = y;
|
|
78
81
|
}
|
|
@@ -100,13 +103,17 @@ export function addEventHandlers({ options, datum, plot }) {
|
|
|
100
103
|
}
|
|
101
104
|
function invertScale(scale, position) {
|
|
102
105
|
if (scale.type === 'band') {
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
const
|
|
106
|
+
const bandScale = scale.fn;
|
|
107
|
+
const range = bandScale.range();
|
|
108
|
+
const domain = bandScale.domain();
|
|
109
|
+
const eachBand = bandScale.step();
|
|
110
|
+
const start = range[0] ?? 0;
|
|
111
|
+
const end = range[1] ?? start;
|
|
112
|
+
const extent = end - start;
|
|
113
|
+
const posInRange = (position - start) * Math.sign(extent);
|
|
108
114
|
const index = Math.floor(posInRange / eachBand);
|
|
109
115
|
return domain[index];
|
|
110
116
|
}
|
|
111
|
-
|
|
117
|
+
const maybeInvert = scale.fn;
|
|
118
|
+
return maybeInvert.invert ? maybeInvert.invert(position) : undefined;
|
|
112
119
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Kept the comments from the original implementation for clarity.
|
|
6
6
|
*/
|
|
7
7
|
import type { Snippet } from 'svelte';
|
|
8
|
-
import type { StackOptions } from '../../transforms/stack';
|
|
9
|
-
import type { BorderRadius, ConstantAccessor, PlotScales, ScaledDataRecord } from '../../types';
|
|
8
|
+
import type { StackOptions } from '../../transforms/stack.js';
|
|
9
|
+
import type { BorderRadius, ConstantAccessor, PlotScales, ScaledDataRecord } from '../../types/index.js';
|
|
10
10
|
type Point = [number, number];
|
|
11
11
|
export type WaffleOptions<T> = {
|
|
12
12
|
/**
|
|
@@ -58,7 +58,7 @@ type WaffleProps = {
|
|
|
58
58
|
d: string;
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
|
-
export declare function wafflePolygon(y: 'x' | 'y', options: WaffleOptions
|
|
61
|
+
export declare function wafflePolygon(y: 'x' | 'y', options: WaffleOptions<any>, scales: PlotScales): (d: ScaledDataRecord) => WaffleProps;
|
|
62
62
|
export declare function wafflePoints(i1: number, i2: number, columns: number): Point[];
|
|
63
63
|
export declare function maybeRound(round: boolean | ((x: number) => number) | undefined): (x: number) => number;
|
|
64
64
|
export {};
|
|
@@ -4,18 +4,20 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Kept the comments from the original implementation for clarity.
|
|
6
6
|
*/
|
|
7
|
-
import { getPatternId } from '../../helpers/getBaseStyles';
|
|
7
|
+
import { getPatternId } from '../../helpers/getBaseStyles.js';
|
|
8
8
|
export function wafflePolygon(y, options, scales) {
|
|
9
9
|
const x = y === 'y' ? 'x' : 'y';
|
|
10
10
|
const y1 = `${y}1`;
|
|
11
11
|
const y2 = `${y}2`;
|
|
12
12
|
const xScale = scales[x];
|
|
13
13
|
const yScale = scales[y];
|
|
14
|
-
const
|
|
14
|
+
const xBandScale = xScale.fn;
|
|
15
|
+
const mapY = (value) => yScale.fn(value) ?? 0;
|
|
16
|
+
const barwidth = xBandScale.bandwidth();
|
|
15
17
|
const { unit = 1, gap = 1 } = options;
|
|
16
18
|
const round = maybeRound(options.round);
|
|
17
19
|
// The length of a unit along y in pixels.
|
|
18
|
-
const scale = Math.abs(
|
|
20
|
+
const scale = Math.abs(mapY(unit) - mapY(0));
|
|
19
21
|
// The number of cells on each row (or column) of the waffle.
|
|
20
22
|
const multiple = options.multiple ?? Math.max(1, Math.floor(Math.sqrt(barwidth / scale)));
|
|
21
23
|
// The outer size of each square cell, in pixels, including the gap.
|
|
@@ -26,7 +28,7 @@ export function wafflePolygon(y, options, scales) {
|
|
|
26
28
|
const transform = y === 'y' ? ([x, y]) => [x * cx, -y * cy] : ([x, y]) => [y * cy, x * cx];
|
|
27
29
|
// const mx = typeof x0 === 'function' ? (i) => x0(i) - barwidth / 2 : () => x0;
|
|
28
30
|
const [ix, iy] = y === 'y' ? [0, 1] : [1, 0];
|
|
29
|
-
const y0 =
|
|
31
|
+
const y0 = mapY(0);
|
|
30
32
|
const mx = -barwidth / 2;
|
|
31
33
|
return (d) => {
|
|
32
34
|
const y1val = d.resolved[y1];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Adapted from https://github.com/HarryStevens/d3-regression
|
|
3
3
|
*/
|
|
4
|
-
import type { PredictFunction, Accessor, DataPoint, Domain } from './types';
|
|
4
|
+
import type { PredictFunction, Accessor, DataPoint, Domain } from './types.js';
|
|
5
5
|
export type PolynomialOutput = [DataPoint, DataPoint] & {
|
|
6
6
|
coefficients: number[];
|
|
7
7
|
predict: PredictFunction;
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
// ...with ideas from vega-statistics by Jeffrey Heer
|
|
8
8
|
// Source: https://github.com/vega/vega/blob/f21cb8792b4e0cbe2b1a3fd44b0f5db370dbaadb/packages/vega-statistics/src/regression/poly.js
|
|
9
9
|
// License: https://github.com/vega/vega/blob/f058b099decad9db78301405dd0d2e9d8ba3d51a/LICENSE
|
|
10
|
-
import { determination } from './utils/determination';
|
|
11
|
-
import { interpose } from './utils/interpose';
|
|
12
|
-
import { points, visitPoints } from './utils/points';
|
|
13
|
-
import linear from './linear';
|
|
14
|
-
import quad from './quadratic';
|
|
10
|
+
import { determination } from './utils/determination.js';
|
|
11
|
+
import { interpose } from './utils/interpose.js';
|
|
12
|
+
import { points, visitPoints } from './utils/points.js';
|
|
13
|
+
import linear from './linear.js';
|
|
14
|
+
import quad from './quadratic.js';
|
|
15
15
|
export default function polynomial() {
|
|
16
16
|
let x = (d) => d[0], y = (d) => d[1], order = 3, domain;
|
|
17
17
|
const polynomialRegression = function polynomialRegression(data) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Accessor, PredictFunction } from '../types';
|
|
1
|
+
import type { Accessor, PredictFunction } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Given a dataset, x- and y-accessors, the mean center of the y-values (uY),
|
|
4
4
|
* and a prediction function, return the coefficient of determination, R^2.
|
package/dist/transforms/bin.d.ts
CHANGED
|
@@ -36,16 +36,16 @@ type BinOptions = BinBaseOptions & AdditionalOutputChannels;
|
|
|
36
36
|
* @param param0
|
|
37
37
|
* @param options
|
|
38
38
|
*/
|
|
39
|
-
export declare function binX
|
|
39
|
+
export declare function binX({ data, ...channels }: TransformArg<DataRecord>, options?: BinXOptions): TransformArg<DataRecord>;
|
|
40
40
|
/**
|
|
41
41
|
* Bins on y. Also groups on y and the first channel of z, fill, or stroke, if any.
|
|
42
42
|
*
|
|
43
43
|
* @param param0
|
|
44
44
|
* @param options
|
|
45
45
|
*/
|
|
46
|
-
export declare function binY
|
|
46
|
+
export declare function binY({ data, ...channels }: TransformArg<DataRecord>, options?: BinYOptions): TransformArg<DataRecord>;
|
|
47
47
|
/**
|
|
48
48
|
* for binning in x and y dimension simultaneously
|
|
49
49
|
*/
|
|
50
|
-
export declare function bin
|
|
50
|
+
export declare function bin({ data, ...channels }: TransformArg<DataRecord>, options?: BinOptions): TransformArg<DataRecord>;
|
|
51
51
|
export {};
|
package/dist/transforms/bin.js
CHANGED
|
@@ -4,7 +4,7 @@ import { bin as d3Bin, extent, thresholdFreedmanDiaconis, thresholdScott, thresh
|
|
|
4
4
|
import { reduceOutputs } from '../helpers/reduce.js';
|
|
5
5
|
import { groupFacetsAndZ } from '../helpers/group.js';
|
|
6
6
|
import { isDate } from '../helpers/typeChecks.js';
|
|
7
|
-
import { ORIGINAL_NAME_KEYS } from '../constants';
|
|
7
|
+
import { ORIGINAL_NAME_KEYS } from '../constants.js';
|
|
8
8
|
const CHANNELS = {
|
|
9
9
|
x: Symbol('x'),
|
|
10
10
|
x1: Symbol('x1'),
|
|
@@ -26,7 +26,9 @@ function binBy(byDim, { data, ...channels }, options) {
|
|
|
26
26
|
bin.domain(domain);
|
|
27
27
|
if (interval) {
|
|
28
28
|
const [lo, hi] = extent(data.map((d) => resolveChannel(byDim, d, channels)));
|
|
29
|
-
|
|
29
|
+
const iv = maybeInterval(interval);
|
|
30
|
+
if (iv)
|
|
31
|
+
bin.thresholds(iv.range(lo, hi));
|
|
30
32
|
}
|
|
31
33
|
else if (thresholds)
|
|
32
34
|
bin.thresholds(
|
|
@@ -58,13 +60,15 @@ function binBy(byDim, { data, ...channels }, options) {
|
|
|
58
60
|
const newData = [];
|
|
59
61
|
let passedGroups = [];
|
|
60
62
|
const bins = bin(data);
|
|
61
|
-
(options.cumulative < 0 ? bins.toReversed() : bins).forEach((group) => {
|
|
63
|
+
((options.cumulative ?? 0) < 0 ? bins.toReversed() : bins).forEach((group) => {
|
|
64
|
+
const x0 = group.x0;
|
|
65
|
+
const x1 = group.x1;
|
|
62
66
|
const itemBinProps = {
|
|
63
|
-
[CHANNELS[`${byDim}1`]]:
|
|
64
|
-
[CHANNELS[`${byDim}2`]]:
|
|
65
|
-
[CHANNELS[`${byDim}`]]: isDate(
|
|
66
|
-
? new Date(Math.round((
|
|
67
|
-
: (
|
|
67
|
+
[CHANNELS[`${byDim}1`]]: x0,
|
|
68
|
+
[CHANNELS[`${byDim}2`]]: x1,
|
|
69
|
+
[CHANNELS[`${byDim}`]]: isDate(x0)
|
|
70
|
+
? new Date(Math.round((x0.getTime() + x1.getTime()) * 0.5))
|
|
71
|
+
: ((x0 ?? 0) + (x1 ?? 0)) * 0.5
|
|
68
72
|
};
|
|
69
73
|
if (options.cumulative)
|
|
70
74
|
passedGroups = [...passedGroups, ...group];
|
|
@@ -99,7 +103,7 @@ export function binY({ data, ...channels }, options = { thresholds: 'auto', cumu
|
|
|
99
103
|
* for binning in x and y dimension simultaneously
|
|
100
104
|
*/
|
|
101
105
|
export function bin({ data, ...channels }, options = { thresholds: 'auto', cumulative: false }) {
|
|
102
|
-
const { domain, thresholds = 'auto', interval
|
|
106
|
+
const { domain, thresholds = 'auto', interval } = options;
|
|
103
107
|
const binX = d3Bin();
|
|
104
108
|
const binY = d3Bin();
|
|
105
109
|
if (domain) {
|
|
@@ -114,8 +118,11 @@ export function bin({ data, ...channels }, options = { thresholds: 'auto', cumul
|
|
|
114
118
|
if (interval) {
|
|
115
119
|
const [xlo, xhi] = extent(data.map((d) => resolveChannel('x', d, channels)));
|
|
116
120
|
const [ylo, yhi] = extent(data.map((d) => resolveChannel('y', d, channels)));
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
const ivl = maybeInterval(interval);
|
|
122
|
+
if (ivl) {
|
|
123
|
+
binX.thresholds(ivl.range(xlo, xhi));
|
|
124
|
+
binY.thresholds((yThresholds = ivl.range(ylo, yhi)));
|
|
125
|
+
}
|
|
119
126
|
}
|
|
120
127
|
else if (thresholds) {
|
|
121
128
|
// when binning in x and y, we need to ensure we are using consistent thresholds
|
|
@@ -150,17 +157,19 @@ export function bin({ data, ...channels }, options = { thresholds: 'auto', cumul
|
|
|
150
157
|
// consistent intervals
|
|
151
158
|
const newData = [];
|
|
152
159
|
binX(data).forEach((groupX) => {
|
|
160
|
+
const gx0 = groupX.x0;
|
|
161
|
+
const gx1 = groupX.x1;
|
|
153
162
|
const newRecordBaseX = {
|
|
154
|
-
[CHANNELS.x1]:
|
|
155
|
-
[CHANNELS.x2]:
|
|
156
|
-
[CHANNELS.x]: isDate(
|
|
157
|
-
? new Date(Math.round((
|
|
158
|
-
: (
|
|
163
|
+
[CHANNELS.x1]: gx0,
|
|
164
|
+
[CHANNELS.x2]: gx1,
|
|
165
|
+
[CHANNELS.x]: isDate(gx0)
|
|
166
|
+
? new Date(Math.round((gx0.getTime() + gx1.getTime()) * 0.5))
|
|
167
|
+
: ((gx0 ?? 0) + (gx1 ?? 0)) * 0.5
|
|
159
168
|
};
|
|
160
169
|
const [ylo, yhi] = extent(groupX.map((d) => resolveChannel('y', d, channels)));
|
|
161
|
-
const tExtentLo = yThresholds.filter((d) => d < ylo).at(-1);
|
|
162
|
-
const tExtentHi = yThresholds.filter((d) => d > yhi).at(0);
|
|
163
|
-
binY(groupX).forEach((groupY
|
|
170
|
+
const tExtentLo = yThresholds.filter((d) => d < ylo).at(-1) ?? ylo;
|
|
171
|
+
const tExtentHi = yThresholds.filter((d) => d > yhi).at(0) ?? yhi;
|
|
172
|
+
binY(groupX).forEach((groupY) => {
|
|
164
173
|
if (groupY.length === 0)
|
|
165
174
|
return;
|
|
166
175
|
// The first bin.x0 is always equal to the minimum domain value,
|
|
@@ -174,7 +183,7 @@ export function bin({ data, ...channels }, options = { thresholds: 'auto', cumul
|
|
|
174
183
|
[CHANNELS.y2]: y2,
|
|
175
184
|
[CHANNELS.y]: isDate(y1)
|
|
176
185
|
? new Date(Math.round((y1.getTime() + y2.getTime()) * 0.5))
|
|
177
|
-
: (y1 + y2) * 0.5
|
|
186
|
+
: ((y1 ?? 0) + (y2 ?? 0)) * 0.5
|
|
178
187
|
};
|
|
179
188
|
const newGroupChannels = groupFacetsAndZ(groupY, channels, (items, itemGroupProps) => {
|
|
180
189
|
const newRecord = {
|
|
@@ -9,6 +9,14 @@ export type BollingerOptions = {
|
|
|
9
9
|
*/
|
|
10
10
|
k?: number;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* computes Bollinger bands for the x channel, producing x1 (lower), x (mean),
|
|
14
|
+
* and x2 (upper) channels
|
|
15
|
+
*/
|
|
12
16
|
export declare function bollingerX<T>(args: TransformArg<T>, options?: BollingerOptions): TransformArg<T>;
|
|
17
|
+
/**
|
|
18
|
+
* computes Bollinger bands for the y channel, producing y1 (lower), y (mean),
|
|
19
|
+
* and y2 (upper) channels
|
|
20
|
+
*/
|
|
13
21
|
export declare function bollingerY<T>(args: TransformArg<T>, options?: BollingerOptions): TransformArg<T>;
|
|
14
22
|
export declare function bollingerDim<T>(dim: 'x' | 'y', { data, ...channels }: TransformArg<T>, options?: BollingerOptions): TransformArg<T>;
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { resolveChannel } from '../helpers/resolve.js';
|
|
2
|
+
/**
|
|
3
|
+
* computes Bollinger bands for the x channel, producing x1 (lower), x (mean),
|
|
4
|
+
* and x2 (upper) channels
|
|
5
|
+
*/
|
|
2
6
|
export function bollingerX(args, options = {}) {
|
|
3
7
|
return bollingerDim('x', args, options);
|
|
4
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* computes Bollinger bands for the y channel, producing y1 (lower), y (mean),
|
|
11
|
+
* and y2 (upper) channels
|
|
12
|
+
*/
|
|
5
13
|
export function bollingerY(args, options = {}) {
|
|
6
14
|
return bollingerDim('y', args, options);
|
|
7
15
|
}
|
|
@@ -38,7 +46,7 @@ function bollinger(values, N, K) {
|
|
|
38
46
|
const value = values[i];
|
|
39
47
|
((sum += value), (sumSquared += value ** 2));
|
|
40
48
|
}
|
|
41
|
-
for (let n = values.length
|
|
49
|
+
for (let n = values.length; i < n; ++i) {
|
|
42
50
|
const value = values[i];
|
|
43
51
|
((sum += value), (sumSquared += value ** 2));
|
|
44
52
|
const mean = sum / N;
|
|
@@ -3,6 +3,10 @@ declare const CENTROID: unique symbol;
|
|
|
3
3
|
type WithCentroid<T> = T & {
|
|
4
4
|
[CENTROID]: [number, number];
|
|
5
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
* computes the geographic centroid of each geometry feature, producing
|
|
8
|
+
* x (longitude) and y (latitude) channels
|
|
9
|
+
*/
|
|
6
10
|
export declare function geoCentroid<Datum extends DataRecord>({ data, ...options }: {
|
|
7
11
|
data: Datum[];
|
|
8
12
|
} & TransformArg<Datum>): TransformArg<WithCentroid<Datum>>;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { resolveProp } from '../helpers/resolve.js';
|
|
2
2
|
import { geoCentroid as d3GeoCentroid } from 'd3-geo';
|
|
3
3
|
const CENTROID = Symbol('centroid');
|
|
4
|
+
/**
|
|
5
|
+
* computes the geographic centroid of each geometry feature, producing
|
|
6
|
+
* x (longitude) and y (latitude) channels
|
|
7
|
+
*/
|
|
4
8
|
export function geoCentroid({ data, ...options }) {
|
|
5
9
|
const transformedData = data.map((d) => ({
|
|
6
10
|
...d,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* implementation based on science.js by Jason Davies
|
|
3
3
|
*/
|
|
4
|
-
import type { TransformArg } from '../types';
|
|
5
|
-
type
|
|
6
|
-
type
|
|
4
|
+
import type { TransformArg } from '../types/index.js';
|
|
5
|
+
export type KernelName = 'uniform' | 'triangular' | 'epanechnikov' | 'quartic' | 'triweight' | 'gaussian' | 'cosine';
|
|
6
|
+
export type Kernel = KernelName | ((u: number) => number);
|
|
7
|
+
export type DensityOptions<_T> = {
|
|
7
8
|
/**
|
|
8
9
|
* The kernel function to use for smoothing.
|
|
9
10
|
*/
|
|
@@ -37,4 +38,3 @@ export declare function densityX<T>(args: TransformArg<T>, options: DensityOptio
|
|
|
37
38
|
export declare function densityY<T>(args: TransformArg<T>, options: DensityOptions<T> & {
|
|
38
39
|
channel?: 'x' | 'x1' | 'x2';
|
|
39
40
|
}): TransformArg<T>;
|
|
40
|
-
export {};
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
import { extent, quantileSorted, variance } from 'd3-array';
|
|
12
|
-
import { isValid } from '../helpers';
|
|
13
|
-
import { maybeInterval } from '../helpers/autoTicks';
|
|
14
|
-
import { groupFacetsAndZ } from '../helpers/group';
|
|
15
|
-
import isDataRecord from '../helpers/isDataRecord';
|
|
16
|
-
import { resolveChannel } from '../helpers/resolve';
|
|
12
|
+
import { isValid } from '../helpers/index.js';
|
|
13
|
+
import { maybeInterval } from '../helpers/autoTicks.js';
|
|
14
|
+
import { groupFacetsAndZ } from '../helpers/group.js';
|
|
15
|
+
import isDataRecord from '../helpers/isDataRecord.js';
|
|
16
|
+
import { resolveChannel } from '../helpers/resolve.js';
|
|
17
17
|
import { ORIGINAL_NAME_KEYS } from '../constants.js';
|
|
18
18
|
// see https://github.com/jasondavies/science.js/blob/master/src/stats/kernel.js
|
|
19
19
|
const KERNEL = {
|
|
@@ -80,6 +80,9 @@ const BANDWIDTH_FACTOR = {
|
|
|
80
80
|
triweight: 3.15,
|
|
81
81
|
cosine: 1.06
|
|
82
82
|
};
|
|
83
|
+
function isKernelName(value) {
|
|
84
|
+
return value in KERNEL;
|
|
85
|
+
}
|
|
83
86
|
function bandwidthSilverman(x) {
|
|
84
87
|
const iqr = quantileSorted(x, 0.75) - quantileSorted(x, 0.25);
|
|
85
88
|
const xvar = variance(x);
|
|
@@ -128,17 +131,21 @@ function density1d(independent, { data, weight, ...channels }, options = {}) {
|
|
|
128
131
|
}))).filter((d) => isValid(d[VALUE]) && isValid(d[WEIGHT]) && d[WEIGHT] >= 0);
|
|
129
132
|
const values = resolvedData.map((d) => d[VALUE]);
|
|
130
133
|
// compute bandwidth from full data
|
|
134
|
+
const kernelName = typeof kernel === 'string' && isKernelName(kernel) ? kernel : null;
|
|
131
135
|
const bw = typeof bandwidth === 'function'
|
|
132
|
-
? (BANDWIDTH_FACTOR[
|
|
136
|
+
? ((kernelName ? BANDWIDTH_FACTOR[kernelName] : null) ?? 1) *
|
|
137
|
+
bandwidth(values.toSorted((a, b) => a - b))
|
|
133
138
|
: bandwidth;
|
|
134
139
|
const I = maybeInterval(interval ?? roundToTerminating(bw / 5));
|
|
135
140
|
let [min, max] = extent(values);
|
|
136
141
|
if (!trim) {
|
|
137
|
-
const r = max - min;
|
|
138
|
-
min = I.floor(min - r * 0.2);
|
|
139
|
-
max = I.floor(max + r * 0.2);
|
|
142
|
+
const r = (max ?? 0) - (min ?? 0);
|
|
143
|
+
min = I.floor((min ?? 0) - r * 0.2);
|
|
144
|
+
max = I.floor((max ?? 0) + r * 0.2);
|
|
140
145
|
}
|
|
141
|
-
const atValues = I
|
|
146
|
+
const atValues = I
|
|
147
|
+
.range(I.floor(min), I.offset(max))
|
|
148
|
+
.map((d) => +d.toFixed(5));
|
|
142
149
|
// let minX = Infinity;
|
|
143
150
|
// let maxX = -Infinity;
|
|
144
151
|
const res = groupFacetsAndZ(resolvedData, channels, (items, groupProps) => {
|
|
@@ -149,9 +156,9 @@ function density1d(independent, { data, weight, ...channels }, options = {}) {
|
|
|
149
156
|
.sort((a, b) => a[0] - b[0]);
|
|
150
157
|
if (!trim) {
|
|
151
158
|
// trim zero values at begin and end except first and last
|
|
152
|
-
const firstNonZero = kdeValues.findIndex(([
|
|
159
|
+
const firstNonZero = kdeValues.findIndex(([_x, v]) => v > 0);
|
|
153
160
|
// if (firstNonZero > 0) minX = Math.min(minX, kdeValues[firstNonZero - 1][0]);
|
|
154
|
-
const lastNonZero = kdeValues.length - 1 - [...kdeValues].reverse().findIndex(([
|
|
161
|
+
const lastNonZero = kdeValues.length - 1 - [...kdeValues].reverse().findIndex(([_x, v]) => v > 0);
|
|
155
162
|
// if (lastNonZero > -1 && lastNonZero < kdeValues.length - 1)
|
|
156
163
|
// maxX = Math.max(maxX, kdeValues[lastNonZero + 1][0]);
|
|
157
164
|
kdeValues = kdeValues.slice(firstNonZero < 1 ? 0 : firstNonZero - 1, lastNonZero < 0 ? kdeValues.length : lastNonZero + 1);
|
|
@@ -219,7 +226,7 @@ function kde1d(values, weights, atValues, kernel, bw, cumulative) {
|
|
|
219
226
|
function maybeKernel(kernel) {
|
|
220
227
|
if (typeof kernel === 'function')
|
|
221
228
|
return kernel;
|
|
222
|
-
return KERNEL[kernel]
|
|
229
|
+
return isKernelName(kernel) ? KERNEL[kernel] : KERNEL.epanechnikov;
|
|
223
230
|
}
|
|
224
231
|
// See <http://en.wikipedia.org/wiki/Kernel_(statistics)>.
|
|
225
232
|
// science.stats.kernel = {
|
|
@@ -1,17 +1,28 @@
|
|
|
1
|
-
import type { ScaledDataRecord, TransformArg, PlotState } from '../types';
|
|
1
|
+
import type { ScaledDataRecord, TransformArg, PlotState } from '../types/index.js';
|
|
2
2
|
type BaseDodgeOptions = {
|
|
3
|
+
/** the anchor side for placing dodged marks */
|
|
3
4
|
anchor?: string;
|
|
5
|
+
/** the padding between dodged marks, in pixels */
|
|
4
6
|
padding?: number;
|
|
7
|
+
/** the radius of dodged marks, in pixels */
|
|
5
8
|
r?: number;
|
|
6
9
|
};
|
|
7
10
|
type AnchorX = 'left' | 'right' | 'middle';
|
|
8
11
|
type AnchorY = 'top' | 'bottom' | 'middle';
|
|
12
|
+
/** options for horizontal dodge positioning; can be an anchor string or a full options object */
|
|
9
13
|
export type DodgeXOptions = AnchorX | (BaseDodgeOptions & {
|
|
10
14
|
anchor?: 'left' | 'right' | 'middle';
|
|
11
15
|
});
|
|
16
|
+
/** options for vertical dodge positioning; can be an anchor string or a full options object */
|
|
12
17
|
export type DodgeYOptions = AnchorY | (BaseDodgeOptions & {
|
|
13
18
|
anchor?: 'top' | 'bottom' | 'middle';
|
|
14
19
|
});
|
|
20
|
+
/**
|
|
21
|
+
* offsets marks horizontally to avoid overlap, using circle-packing
|
|
22
|
+
*/
|
|
15
23
|
export declare function dodgeX(args: TransformArg<ScaledDataRecord>, plotState: PlotState): ScaledDataRecord[];
|
|
24
|
+
/**
|
|
25
|
+
* offsets marks vertically to avoid overlap, using circle-packing
|
|
26
|
+
*/
|
|
16
27
|
export declare function dodgeY(args: TransformArg<ScaledDataRecord>, plotState: PlotState): ScaledDataRecord[];
|
|
17
28
|
export {};
|
package/dist/transforms/dodge.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import IntervalTree from 'interval-tree-1d';
|
|
2
|
-
import { groupFacetsAndZ } from '../helpers/group';
|
|
2
|
+
import { groupFacetsAndZ } from '../helpers/group.js';
|
|
3
|
+
/**
|
|
4
|
+
* offsets marks horizontally to avoid overlap, using circle-packing
|
|
5
|
+
*/
|
|
3
6
|
export function dodgeX(args, plotState) {
|
|
4
7
|
if (!args.dodgeX)
|
|
5
8
|
return args.data;
|
|
6
|
-
let { anchor = 'left', padding = 1, r = args.dodgeX
|
|
9
|
+
let { anchor = 'left', padding = 1, r = args.dodgeX?.r } = maybeAnchor(args.dodgeX);
|
|
7
10
|
let anchorFunction;
|
|
8
11
|
switch (`${anchor}`.toLowerCase()) {
|
|
9
12
|
case 'left':
|
|
@@ -20,10 +23,13 @@ export function dodgeX(args, plotState) {
|
|
|
20
23
|
}
|
|
21
24
|
return dodge('x', 'y', anchorFunction, Number(padding), r, args, plotState);
|
|
22
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* offsets marks vertically to avoid overlap, using circle-packing
|
|
28
|
+
*/
|
|
23
29
|
export function dodgeY(args, plotState) {
|
|
24
30
|
if (!args.dodgeY)
|
|
25
31
|
return args.data;
|
|
26
|
-
let { anchor = 'bottom', padding = 1, r = args.dodgeY
|
|
32
|
+
let { anchor = 'bottom', padding = 1, r = args.dodgeY?.r } = maybeAnchor(args.dodgeY);
|
|
27
33
|
let anchorFunction;
|
|
28
34
|
switch (`${anchor}`.toLowerCase()) {
|
|
29
35
|
case 'top':
|
|
@@ -57,7 +63,9 @@ function dodge(y, x, anchor, padding, r, { data, ...channels }, plotState) {
|
|
|
57
63
|
groupFacetsAndZ(data, { fx, fy }, (items) => {
|
|
58
64
|
// apply dodge within each facet
|
|
59
65
|
const tree = IntervalTree();
|
|
60
|
-
const data = items.filter((d) => (typeof d.r !== 'number' || d.r >= 0) &&
|
|
66
|
+
const data = items.filter((d) => (typeof d.r !== 'number' || d.r >= 0) &&
|
|
67
|
+
isFinite(d[x]) &&
|
|
68
|
+
isFinite(d[y]));
|
|
61
69
|
const intervals = new Float64Array(2 * data.length + 2);
|
|
62
70
|
data.forEach((d, i) => {
|
|
63
71
|
const ri = d.r ?? r ?? 3;
|
|
@@ -69,7 +77,8 @@ function dodge(y, x, anchor, padding, r, { data, ...channels }, plotState) {
|
|
|
69
77
|
// For any previously placed circles that may overlap this circle, compute
|
|
70
78
|
// the y-positions that place this circle tangent to these other circles.
|
|
71
79
|
// https://observablehq.com/@mbostock/circle-offset-along-line
|
|
72
|
-
tree.queryInterval(l - padding, h + padding, (
|
|
80
|
+
tree.queryInterval(l - padding, h + padding, (interval) => {
|
|
81
|
+
const j = interval[2];
|
|
73
82
|
const yj = data[j][y] - y0;
|
|
74
83
|
const dx = d[x] - data[j][x];
|
|
75
84
|
const dr = padding + (channels.r ? d.r + data[j].r : 2 * cr);
|
|
@@ -117,7 +126,7 @@ function anchorYTop({ options: { marginTop } }) {
|
|
|
117
126
|
function anchorYBottom({ facetHeight: height }) {
|
|
118
127
|
return [-1, height];
|
|
119
128
|
}
|
|
120
|
-
function anchorYMiddle({ facetHeight: height, options: { marginTop, marginBottom } }) {
|
|
129
|
+
function anchorYMiddle({ facetHeight: height, options: { marginTop, marginBottom: _marginBottom } }) {
|
|
121
130
|
return [0, (marginTop + height) / 2];
|
|
122
131
|
}
|
|
123
132
|
function compareSymmetric(a, b) {
|