svelteplot 0.0.1-alpha.9 → 0.1.3-next.3
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 -156
- package/dist/Plot.svelte.d.ts +15 -15
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +109 -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 +567 -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 +53 -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 +17 -0
- package/dist/helpers/resolve.js +152 -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 +81 -0
- package/dist/marks/BarX.svelte.d.ts +4 -0
- package/dist/marks/BarY.svelte +95 -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 +32 -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 +173 -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 +185 -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 +213 -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 +164 -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 +64 -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 +13 -0
- package/dist/transforms/recordize.js +75 -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 +61 -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 +79 -40
- 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,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2020-2023 Observable, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
6
|
+
* with or without fee is hereby granted, provided that the above copyright notice
|
|
7
|
+
* and this permission notice appear in all copies.
|
|
8
|
+
*/
|
|
9
|
+
import { ascending, descending } from 'd3-array';
|
|
10
|
+
const RADIANS = Math.PI / 180;
|
|
11
|
+
export function arrowPath(x1, y1, x2, y2, insetStart, insetEnd, headAngle, headLength, bend, strokeWidth, sweep) {
|
|
12
|
+
// The angle between the arrow’s shaft and one of the wings; the “head”
|
|
13
|
+
// angle between the wings is twice this value.
|
|
14
|
+
const wingAngle = (headAngle * RADIANS) / 2;
|
|
15
|
+
// The length of the arrowhead’s “wings” (the line segments that extend from
|
|
16
|
+
// the end point) relative to the stroke width.
|
|
17
|
+
const wingScale = headLength / 1.5;
|
|
18
|
+
// The start ⟨x1,y1⟩ and end ⟨x2,y2⟩ points may be inset, and the
|
|
19
|
+
// ending line angle may be altered for inset swoopy arrows.
|
|
20
|
+
const lineLength = Math.hypot(x2 - x1, y2 - y1);
|
|
21
|
+
if (lineLength <= insetStart + insetEnd)
|
|
22
|
+
return null;
|
|
23
|
+
let lineAngle = Math.atan2(y2 - y1, x2 - x1);
|
|
24
|
+
// We don’t allow the wing length to be too large relative to the
|
|
25
|
+
// length of the arrow. (Plot.vector allows arbitrarily large
|
|
26
|
+
// wings, but that’s okay since vectors are usually small.)
|
|
27
|
+
const headLength_ = Math.min(wingScale * strokeWidth, lineLength / 3);
|
|
28
|
+
// When bending, the offset between the straight line between the two points
|
|
29
|
+
// and the outgoing tangent from the start point. (Also the negative
|
|
30
|
+
// incoming tangent to the end point.) This must be within ±π/2. A positive
|
|
31
|
+
// angle will produce a clockwise curve; a negative angle will produce a
|
|
32
|
+
// counterclockwise curve; zero will produce a straight line.
|
|
33
|
+
const bendAngle = sweep(x1, y1, x2, y2) * bend * RADIANS;
|
|
34
|
+
// The radius of the circle that intersects with the two endpoints
|
|
35
|
+
// and has the specified bend angle.
|
|
36
|
+
const r = Math.hypot(lineLength / Math.tan(bendAngle), lineLength) / 2;
|
|
37
|
+
// Apply insets.
|
|
38
|
+
if (insetStart || insetEnd) {
|
|
39
|
+
if (r < 1e5) {
|
|
40
|
+
// For inset swoopy arrows, compute the circle-circle
|
|
41
|
+
// intersection between a circle centered around the
|
|
42
|
+
// respective arrow endpoint and the center of the circle
|
|
43
|
+
// segment that forms the shaft of the arrow.
|
|
44
|
+
const sign = Math.sign(bendAngle);
|
|
45
|
+
const [cx, cy] = pointPointCenter([x1, y1], [x2, y2], r, sign);
|
|
46
|
+
if (insetStart) {
|
|
47
|
+
[x1, y1] = circleCircleIntersect([cx, cy, r], [x1, y1, insetStart], -sign * Math.sign(insetStart));
|
|
48
|
+
}
|
|
49
|
+
// For the end inset, rotate the arrowhead so that it aligns
|
|
50
|
+
// with the truncated end of the arrow. Since the arrow is a
|
|
51
|
+
// segment of the circle centered at ⟨cx,cy⟩, we can compute
|
|
52
|
+
// the angular difference to the new endpoint.
|
|
53
|
+
if (insetEnd) {
|
|
54
|
+
const [x, y] = circleCircleIntersect([cx, cy, r], [x2, y2, insetEnd], sign * Math.sign(insetEnd));
|
|
55
|
+
lineAngle += Math.atan2(y - cy, x - cx) - Math.atan2(y2 - cy, x2 - cx);
|
|
56
|
+
(x2 = x), (y2 = y);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// For inset straight arrows, offset along the straight line.
|
|
61
|
+
const dx = x2 - x1, dy = y2 - y1, d = Math.hypot(dx, dy);
|
|
62
|
+
if (insetStart)
|
|
63
|
+
(x1 += (dx / d) * insetStart), (y1 += (dy / d) * insetStart);
|
|
64
|
+
if (insetEnd)
|
|
65
|
+
(x2 -= (dx / d) * insetEnd), (y2 -= (dy / d) * insetEnd);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// The angle of the arrow as it approaches the endpoint, and the
|
|
69
|
+
// angles of the adjacent wings. Here “left” refers to if the
|
|
70
|
+
// arrow is pointing up.
|
|
71
|
+
const endAngle = lineAngle + bendAngle;
|
|
72
|
+
const leftAngle = endAngle + wingAngle;
|
|
73
|
+
const rightAngle = endAngle - wingAngle;
|
|
74
|
+
// The endpoints of the two wings.
|
|
75
|
+
const x3 = x2 - headLength_ * Math.cos(leftAngle);
|
|
76
|
+
const y3 = y2 - headLength_ * Math.sin(leftAngle);
|
|
77
|
+
const x4 = x2 - headLength_ * Math.cos(rightAngle);
|
|
78
|
+
const y4 = y2 - headLength_ * Math.sin(rightAngle);
|
|
79
|
+
// If the radius is very large (or even infinite, as when the bend
|
|
80
|
+
// angle is zero), then render a straight line.
|
|
81
|
+
const a = r < 1e5 ? `A${r},${r} 0,0,${bendAngle > 0 ? 1 : 0} ` : `L`;
|
|
82
|
+
const h = headLength_ ? `M${x3},${y3}L${x2},${y2}L${x4},${y4}` : '';
|
|
83
|
+
return `M${x1},${y1}${a}${x2},${y2}${h}`;
|
|
84
|
+
}
|
|
85
|
+
// Returns the center of a circle that goes through the two given points ⟨ax,ay⟩
|
|
86
|
+
// and ⟨bx,by⟩ and has radius r. There are two such points; use the sign +1 or
|
|
87
|
+
// -1 to choose between them. Returns [NaN, NaN] if r is too small.
|
|
88
|
+
function pointPointCenter([ax, ay], [bx, by], r, sign) {
|
|
89
|
+
const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
|
|
90
|
+
const k = (sign * Math.sqrt(r * r - (d * d) / 4)) / d;
|
|
91
|
+
return [(ax + bx) / 2 - dy * k, (ay + by) / 2 + dx * k];
|
|
92
|
+
}
|
|
93
|
+
// Given two circles, one centered at ⟨ax,ay⟩ with radius ar, and the other
|
|
94
|
+
// centered at ⟨bx,by⟩ with radius br, returns a point at which the two circles
|
|
95
|
+
// intersect. There are typically two such points; use the sign +1 or -1 to
|
|
96
|
+
// chose between them. Returns [NaN, NaN] if there is no intersection.
|
|
97
|
+
// https://mathworld.wolfram.com/Circle-CircleIntersection.html
|
|
98
|
+
function circleCircleIntersect([ax, ay, ar], [bx, by, br], sign) {
|
|
99
|
+
const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
|
|
100
|
+
const x = (dx * dx + dy * dy - br * br + ar * ar) / (2 * d);
|
|
101
|
+
const y = sign * Math.sqrt(ar * ar - x * x);
|
|
102
|
+
return [ax + (dx * x + dy * y) / d, ay + (dy * x - dx * y) / d];
|
|
103
|
+
}
|
|
104
|
+
export function constant(x) {
|
|
105
|
+
return () => x;
|
|
106
|
+
}
|
|
107
|
+
// Validates the specified required string against the allowed list of keywords.
|
|
108
|
+
export function keyword(input, name, allowed) {
|
|
109
|
+
const i = `${input}`.toLowerCase();
|
|
110
|
+
if (!allowed.includes(i))
|
|
111
|
+
throw new Error(`invalid ${name}: ${input}`);
|
|
112
|
+
return i;
|
|
113
|
+
}
|
|
114
|
+
export function maybeSweep(sweep = 1) {
|
|
115
|
+
if (typeof sweep === 'number')
|
|
116
|
+
return constant(Math.sign(sweep));
|
|
117
|
+
if (typeof sweep === 'function')
|
|
118
|
+
return (x1, y1, x2, y2) => Math.sign(sweep(x1, y1, x2, y2));
|
|
119
|
+
switch (keyword(sweep, 'sweep', ['+x', '-x', '+y', '-y'])) {
|
|
120
|
+
case '+x':
|
|
121
|
+
return (x1, y1, x2) => ascending(x1, x2);
|
|
122
|
+
case '-x':
|
|
123
|
+
return (x1, y1, x2) => descending(x1, x2);
|
|
124
|
+
case '+y':
|
|
125
|
+
return (x1, y1, x2, y2) => ascending(y1, y2);
|
|
126
|
+
case '-y':
|
|
127
|
+
return (x1, y1, x2, y2) => descending(y1, y2);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare function namedProjection(projection: string): {
|
|
2
|
+
type: ({ width, height, rotate, precision, clip }: {
|
|
3
|
+
width: any;
|
|
4
|
+
height: any;
|
|
5
|
+
rotate: any;
|
|
6
|
+
precision?: number | undefined;
|
|
7
|
+
clip: any;
|
|
8
|
+
}) => any;
|
|
9
|
+
aspectRatio: number;
|
|
10
|
+
} | {
|
|
11
|
+
type: () => {
|
|
12
|
+
stream: (stream: any) => any;
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
type: () => {
|
|
16
|
+
invert(x: any, y: any): any[];
|
|
17
|
+
stream(s: import("d3-geo").GeoStream): import("d3-geo").GeoTransformPrototype & import("d3-geo").GeoStream;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { geoAlbers, geoAlbersUsa, geoAzimuthalEqualArea, geoAzimuthalEquidistant, geoConicConformal, geoConicEqualArea, geoConicEquidistant, geoEqualEarth, geoEquirectangular, geoGnomonic, geoMercator, geoOrthographic, geoStereographic, geoTransverseMercator, geoTransform } from 'd3-geo';
|
|
2
|
+
import { constant } from './index.js';
|
|
3
|
+
const identity = constant({ stream: (stream) => stream });
|
|
4
|
+
const reflectY = constant({
|
|
5
|
+
...geoTransform({
|
|
6
|
+
point(x, y) {
|
|
7
|
+
this.stream.point(x, -y);
|
|
8
|
+
}
|
|
9
|
+
}),
|
|
10
|
+
invert(x, y) {
|
|
11
|
+
return [x, -y];
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
const pi = Math.PI;
|
|
15
|
+
const tau = 2 * pi;
|
|
16
|
+
export function namedProjection(projection) {
|
|
17
|
+
switch (`${projection}`.toLowerCase()) {
|
|
18
|
+
case 'albers-usa':
|
|
19
|
+
return scaleProjection(geoAlbersUsa, 0.7463, 0.4673);
|
|
20
|
+
case 'albers':
|
|
21
|
+
return conicProjection(geoAlbers, 0.7463, 0.4673);
|
|
22
|
+
case 'azimuthal-equal-area':
|
|
23
|
+
return scaleProjection(geoAzimuthalEqualArea, 4, 4);
|
|
24
|
+
case 'azimuthal-equidistant':
|
|
25
|
+
return scaleProjection(geoAzimuthalEquidistant, tau, tau);
|
|
26
|
+
case 'conic-conformal':
|
|
27
|
+
return conicProjection(geoConicConformal, tau, tau);
|
|
28
|
+
case 'conic-equal-area':
|
|
29
|
+
return conicProjection(geoConicEqualArea, 6.1702, 2.9781);
|
|
30
|
+
case 'conic-equidistant':
|
|
31
|
+
return conicProjection(geoConicEquidistant, 7.312, 3.6282);
|
|
32
|
+
case 'equal-earth':
|
|
33
|
+
return scaleProjection(geoEqualEarth, 5.4133, 2.6347);
|
|
34
|
+
case 'equirectangular':
|
|
35
|
+
return scaleProjection(geoEquirectangular, tau, pi);
|
|
36
|
+
case 'gnomonic':
|
|
37
|
+
return scaleProjection(geoGnomonic, 3.4641, 3.4641);
|
|
38
|
+
case 'identity':
|
|
39
|
+
return { type: identity };
|
|
40
|
+
case 'reflect-y':
|
|
41
|
+
return { type: reflectY };
|
|
42
|
+
case 'mercator':
|
|
43
|
+
return scaleProjection(geoMercator, tau, tau);
|
|
44
|
+
case 'orthographic':
|
|
45
|
+
return scaleProjection(geoOrthographic, 2, 2);
|
|
46
|
+
case 'stereographic':
|
|
47
|
+
return scaleProjection(geoStereographic, 2, 2);
|
|
48
|
+
case 'transverse-mercator':
|
|
49
|
+
return scaleProjection(geoTransverseMercator, tau, tau);
|
|
50
|
+
default:
|
|
51
|
+
throw new Error(`unknown projection type: ${projection}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function scaleProjection(createProjection, kx, ky) {
|
|
55
|
+
return {
|
|
56
|
+
type: ({ width, height, rotate, precision = 0.15, clip }) => {
|
|
57
|
+
const projection = createProjection();
|
|
58
|
+
if (precision != null)
|
|
59
|
+
projection.precision?.(precision);
|
|
60
|
+
if (rotate != null)
|
|
61
|
+
projection.rotate?.(rotate);
|
|
62
|
+
if (typeof clip === 'number')
|
|
63
|
+
projection.clipAngle?.(clip);
|
|
64
|
+
projection.scale(Math.min(width / kx, height / ky));
|
|
65
|
+
projection.translate([width / 2, height / 2]);
|
|
66
|
+
return projection;
|
|
67
|
+
},
|
|
68
|
+
aspectRatio: ky / kx
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function conicProjection(createProjection, kx, ky) {
|
|
72
|
+
const { type, aspectRatio } = scaleProjection(createProjection, kx, ky);
|
|
73
|
+
return {
|
|
74
|
+
type: (options) => {
|
|
75
|
+
const { parallels, domain, width, height } = options;
|
|
76
|
+
const projection = type(options);
|
|
77
|
+
if (parallels != null) {
|
|
78
|
+
projection.parallels(parallels);
|
|
79
|
+
if (domain === undefined) {
|
|
80
|
+
projection.fitSize([width, height], { type: 'Sphere' });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return projection;
|
|
84
|
+
},
|
|
85
|
+
aspectRatio
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ColorScaleOptions, PlotDefaults, PlotOptions, RawValue, ScaleName, ScaleOptions, ScaleType } from '../types.js';
|
|
2
|
+
export declare function autoScale({ name, type, domain, scaleOptions, plotOptions, plotWidth, plotHeight, plotHasFilledDotMarks, plotDefaults }: {
|
|
3
|
+
name: ScaleName;
|
|
4
|
+
type: ScaleType;
|
|
5
|
+
domain: RawValue[];
|
|
6
|
+
scaleOptions: ScaleOptions;
|
|
7
|
+
plotOptions: PlotOptions;
|
|
8
|
+
plotWidth: number;
|
|
9
|
+
plotHeight: number;
|
|
10
|
+
plotHasFilledDotMarks: boolean;
|
|
11
|
+
plotDefaults: PlotDefaults;
|
|
12
|
+
}): Record<string, (v: any) => void>;
|
|
13
|
+
export declare function autoScaleColor({ type, domain, scaleOptions, plotOptions, plotWidth, plotHeight, plotHasFilledDotMarks, plotDefaults }: {
|
|
14
|
+
name: ScaleName;
|
|
15
|
+
type: ScaleType;
|
|
16
|
+
domain: RawValue[];
|
|
17
|
+
scaleOptions: ColorScaleOptions;
|
|
18
|
+
plotOptions: PlotOptions;
|
|
19
|
+
plotWidth: number;
|
|
20
|
+
plotHeight: number;
|
|
21
|
+
plotHasFilledDotMarks: boolean;
|
|
22
|
+
plotDefaults: PlotDefaults;
|
|
23
|
+
}): any;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { scaleBand, scaleDiverging, scaleDivergingLog, scaleDivergingPow, scaleDivergingSqrt, scaleDivergingSymlog, scaleLinear, scaleLog, scaleOrdinal, scalePoint, scalePow, scaleQuantile, scaleQuantize, scaleSequential, scaleSequentialLog, scaleSequentialPow, scaleSequentialQuantile, scaleSequentialSqrt, scaleSequentialSymlog, scaleSqrt, scaleSymlog, scaleThreshold, scaleTime } from 'd3-scale';
|
|
2
|
+
import { range as d3Range } from 'd3-array';
|
|
3
|
+
import { categoricalSchemes, isCategoricalScheme, isDivergingScheme, isOrdinalScheme, isQuantitativeScheme, ordinalScheme, quantitativeScheme } from './colors.js';
|
|
4
|
+
import callWithProps from './callWithProps.js';
|
|
5
|
+
import { interpolateLab, interpolateRound } from 'd3-interpolate';
|
|
6
|
+
import { coalesce, maybeNumber } from './index.js';
|
|
7
|
+
import { getLogTicks } from './getLogTicks.js';
|
|
8
|
+
const Scales = {
|
|
9
|
+
point: scalePoint,
|
|
10
|
+
band: scaleBand,
|
|
11
|
+
linear: scaleLinear,
|
|
12
|
+
time: scaleTime,
|
|
13
|
+
sqrt: scaleSqrt,
|
|
14
|
+
pow: scalePow,
|
|
15
|
+
log: scaleLog,
|
|
16
|
+
symlog: scaleSymlog,
|
|
17
|
+
ordinal: scaleOrdinal,
|
|
18
|
+
sequential: scaleSequential,
|
|
19
|
+
diverging: scaleDiverging
|
|
20
|
+
};
|
|
21
|
+
const SequentialScales = {
|
|
22
|
+
linear: scaleSequential,
|
|
23
|
+
log: scaleSequentialLog,
|
|
24
|
+
symlog: scaleSequentialSymlog,
|
|
25
|
+
pow: scaleSequentialPow,
|
|
26
|
+
sqrt: scaleSequentialSqrt,
|
|
27
|
+
'quantile-cont': scaleSequentialQuantile
|
|
28
|
+
};
|
|
29
|
+
const DivergingScales = {
|
|
30
|
+
diverging: scaleDiverging,
|
|
31
|
+
'diverging-log': scaleDivergingLog,
|
|
32
|
+
'diverging-symlog': scaleDivergingSymlog,
|
|
33
|
+
'diverging-pow': scaleDivergingPow,
|
|
34
|
+
'diverging-sqrt': scaleDivergingSqrt
|
|
35
|
+
};
|
|
36
|
+
const ThresholdScales = {
|
|
37
|
+
// custom thresholds
|
|
38
|
+
threshold: scaleThreshold,
|
|
39
|
+
// quantile scales
|
|
40
|
+
quantize: scaleQuantize,
|
|
41
|
+
quantile: scaleQuantile
|
|
42
|
+
};
|
|
43
|
+
export function autoScale({ name, type, domain, scaleOptions, plotOptions, plotWidth, plotHeight, plotHasFilledDotMarks, plotDefaults }) {
|
|
44
|
+
let fn;
|
|
45
|
+
let range;
|
|
46
|
+
range =
|
|
47
|
+
scaleOptions?.range ||
|
|
48
|
+
getScaleRange(name, scaleOptions, plotOptions, plotWidth, plotHeight, plotHasFilledDotMarks);
|
|
49
|
+
if (scaleOptions.reverse)
|
|
50
|
+
range.reverse();
|
|
51
|
+
const niceTickCount = name === 'x' || name === 'y'
|
|
52
|
+
? Math.round(Math.abs(range[0] - range[1]) / scaleOptions.tickSpacing)
|
|
53
|
+
: undefined;
|
|
54
|
+
const scaleProps = {
|
|
55
|
+
domain,
|
|
56
|
+
range,
|
|
57
|
+
...((type === 'linear' || type === 'log') && scaleOptions.nice
|
|
58
|
+
? {
|
|
59
|
+
nice: scaleOptions.nice ? niceTickCount : true
|
|
60
|
+
}
|
|
61
|
+
: {}),
|
|
62
|
+
...(type === 'linear'
|
|
63
|
+
? {
|
|
64
|
+
clamp: scaleOptions.clamp,
|
|
65
|
+
...(scaleOptions.round ? { interpolate: interpolateRound } : {})
|
|
66
|
+
}
|
|
67
|
+
: {}),
|
|
68
|
+
...(type === 'log'
|
|
69
|
+
? {
|
|
70
|
+
base: scaleOptions.base || 10
|
|
71
|
+
}
|
|
72
|
+
: {}),
|
|
73
|
+
...(type === 'symlog'
|
|
74
|
+
? {
|
|
75
|
+
constant: scaleOptions.constant || 1
|
|
76
|
+
}
|
|
77
|
+
: {}),
|
|
78
|
+
...(type === 'band' || type === 'point'
|
|
79
|
+
? {
|
|
80
|
+
align: scaleOptions.align,
|
|
81
|
+
padding: maybeNumber(coalesce(scaleOptions.padding, plotOptions.padding, 0.15))
|
|
82
|
+
}
|
|
83
|
+
: {})
|
|
84
|
+
};
|
|
85
|
+
fn = callWithProps(Scales[type], [], scaleProps);
|
|
86
|
+
if (type === 'band' || type === 'point') {
|
|
87
|
+
fn.ticks = () => domain;
|
|
88
|
+
}
|
|
89
|
+
if (type === 'log') {
|
|
90
|
+
fn.ticks = (count) => getLogTicks(domain, count);
|
|
91
|
+
}
|
|
92
|
+
else if (type === 'symlog') {
|
|
93
|
+
const maxabs = Math.max(Math.abs(domain[0]), Math.abs(domain[1]));
|
|
94
|
+
fn.ticks = (count) => {
|
|
95
|
+
const ticks = getLogTicks([scaleProps.constant + 1, maxabs], count / 2);
|
|
96
|
+
return [...ticks.map((t) => -t).reverse(), 0, ...ticks];
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return fn;
|
|
100
|
+
}
|
|
101
|
+
export function autoScaleColor({ type, domain, scaleOptions, plotOptions, plotWidth, plotHeight, plotHasFilledDotMarks, plotDefaults }) {
|
|
102
|
+
let fn;
|
|
103
|
+
let range;
|
|
104
|
+
// special treatment for color scales
|
|
105
|
+
const { scheme, interpolate, pivot, n = type === 'threshold' ? domain.length + 1 : 9 } = scaleOptions;
|
|
106
|
+
if (type === 'categorical' || type === 'ordinal') {
|
|
107
|
+
// categorical
|
|
108
|
+
const scheme_ = scheme || plotDefaults.categoricalColorScheme;
|
|
109
|
+
// categorical scale
|
|
110
|
+
range = Array.isArray(scheme_)
|
|
111
|
+
? scheme_
|
|
112
|
+
: isCategoricalScheme(scheme_)
|
|
113
|
+
? categoricalSchemes.get(scheme_)
|
|
114
|
+
: ordinalScheme(scheme_)(domain.length);
|
|
115
|
+
fn = scaleOrdinal().domain(domain).range(range);
|
|
116
|
+
}
|
|
117
|
+
else if (!!ThresholdScales[type]) {
|
|
118
|
+
const scheme_ = scheme || plotDefaults.colorScheme;
|
|
119
|
+
range =
|
|
120
|
+
Array.isArray(scheme_) && (scaleOptions.n == null || scaleOptions.n === scheme_.length)
|
|
121
|
+
? scheme_.slice(0)
|
|
122
|
+
: Array.isArray(scheme_)
|
|
123
|
+
? // interpolate n colors from custom colors
|
|
124
|
+
d3Range(n)
|
|
125
|
+
.map((i) => i / (n - 1))
|
|
126
|
+
.map(scaleLinear(scheme_.map((c, i) => i / (scheme_.length - 1)), scheme_).interpolate(interpolateLab))
|
|
127
|
+
: interpolate
|
|
128
|
+
? d3Range(n).map((i) => interpolate(i / (n - 1)))
|
|
129
|
+
: isOrdinalScheme(scheme_)
|
|
130
|
+
? ordinalScheme(scheme_)(n)
|
|
131
|
+
: null;
|
|
132
|
+
if (range == null) {
|
|
133
|
+
throw new Error('unknown ordinal scheme ' + scheme_);
|
|
134
|
+
}
|
|
135
|
+
if (scaleOptions.reverse)
|
|
136
|
+
range = range.toReversed();
|
|
137
|
+
fn = ThresholdScales[type]().domain(domain).range(range);
|
|
138
|
+
}
|
|
139
|
+
else if (!!SequentialScales[type] || !!DivergingScales[type]) {
|
|
140
|
+
// continuous color scale
|
|
141
|
+
const scale = SequentialScales[type] || DivergingScales[type];
|
|
142
|
+
const scheme_ = scheme || plotDefaults.colorScheme;
|
|
143
|
+
if (interpolate) {
|
|
144
|
+
// user-defined interpolation function [0, 1] -> color
|
|
145
|
+
fn = scale(domain, interpolate);
|
|
146
|
+
}
|
|
147
|
+
else if (Array.isArray(scheme_)) {
|
|
148
|
+
// custom user-defined colors to interpolate from
|
|
149
|
+
const step = 1 / (scheme_.length - 1);
|
|
150
|
+
fn = scale(domain, (type === 'linear' ? scaleLinear : scaleLog)(d3Range(0, 1 + step / 2, step), scheme_).interpolate(interpolateLab));
|
|
151
|
+
}
|
|
152
|
+
else if (!!DivergingScales[type] ||
|
|
153
|
+
(scaleOptions.type === 'auto' && isDivergingScheme(scheme_))) {
|
|
154
|
+
// diverging color scheme, explicit or auto-detected
|
|
155
|
+
const maxabs = Math.max(Math.abs(domain[0]), Math.abs(domain[1]));
|
|
156
|
+
const domain_ = pivot != null ? [domain[0], pivot, domain[1]] : [-maxabs, 0, maxabs];
|
|
157
|
+
fn = scale(domain_, quantitativeScheme(scheme_));
|
|
158
|
+
}
|
|
159
|
+
else if (!!SequentialScales[type] ||
|
|
160
|
+
(scaleOptions.type === 'auto' && isQuantitativeScheme(scheme_))) {
|
|
161
|
+
// sequential
|
|
162
|
+
fn = scale(domain, quantitativeScheme(scheme_));
|
|
163
|
+
}
|
|
164
|
+
if (type === 'log') {
|
|
165
|
+
fn.ticks = (count) => getLogTicks(domain, count);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!fn) {
|
|
169
|
+
console.warn('color problem', type);
|
|
170
|
+
// problem
|
|
171
|
+
fn = () => 'red';
|
|
172
|
+
fn.range = () => ['red'];
|
|
173
|
+
}
|
|
174
|
+
return fn;
|
|
175
|
+
}
|
|
176
|
+
function getScaleRange(name, scaleOptions, plotOptions, plotWidth, plotHeight, plotHasFilledDotMarks) {
|
|
177
|
+
const { marginTop, marginLeft, inset } = plotOptions;
|
|
178
|
+
const { insetLeft, insetRight, insetTop, insetBottom } = scaleOptions;
|
|
179
|
+
return name === 'opacity'
|
|
180
|
+
? [0, 1]
|
|
181
|
+
: name === 'length'
|
|
182
|
+
? [0, 20]
|
|
183
|
+
: name === 'x'
|
|
184
|
+
? [
|
|
185
|
+
marginLeft + (insetLeft || inset || 0),
|
|
186
|
+
marginLeft + plotWidth - (insetRight || inset || 0)
|
|
187
|
+
]
|
|
188
|
+
: name === 'y'
|
|
189
|
+
? [
|
|
190
|
+
plotHeight + marginTop - (insetBottom || inset || 0),
|
|
191
|
+
marginTop + (insetTop || inset || 0)
|
|
192
|
+
]
|
|
193
|
+
: name === 'r'
|
|
194
|
+
? [0, 10]
|
|
195
|
+
: name === 'symbol'
|
|
196
|
+
? // Plot is smart enough to pick different default shapes depending on wether
|
|
197
|
+
// or not there are filled dot marks in the plot, so we have to pass this
|
|
198
|
+
// information all the way here
|
|
199
|
+
plotHasFilledDotMarks
|
|
200
|
+
? ['circle', 'cross', 'diamond', 'square', 'star', 'triangle', 'wye']
|
|
201
|
+
: ['circle', 'plus', 'times', 'triangle2', 'asterisk', 'square2', 'diamond2']
|
|
202
|
+
: [];
|
|
203
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RawValue, ScaleType } from '../types.js';
|
|
2
|
+
export declare function maybeInterval(interval: null | number | string | (<T>(d: T) => T)): any;
|
|
3
|
+
export declare function autoTicks(type: ScaleType, ticks: RawValue[], interval: string | number | null, domain: RawValue[], scaleFn: any, count: number): any;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { maybeTimeInterval } from './time.js';
|
|
2
|
+
import { range as rangei } from 'd3-array';
|
|
3
|
+
export function maybeInterval(interval) {
|
|
4
|
+
if (interval == null)
|
|
5
|
+
return;
|
|
6
|
+
if (typeof interval === 'number') {
|
|
7
|
+
if (0 < interval && interval < 1 && Number.isInteger(1 / interval))
|
|
8
|
+
interval = -1 / interval;
|
|
9
|
+
const n = Math.abs(interval);
|
|
10
|
+
return interval < 0
|
|
11
|
+
? {
|
|
12
|
+
floor: (d) => Math.floor(d * n) / n,
|
|
13
|
+
round: (d) => Math.round(d * n) / n,
|
|
14
|
+
offset: (d) => (d * n + 1) / n, // note: no optional step for simplicity
|
|
15
|
+
range: (lo, hi) => rangei(Math.ceil(lo * n), hi * n).map((x) => x / n)
|
|
16
|
+
}
|
|
17
|
+
: {
|
|
18
|
+
floor: (d) => Math.floor(d / n) * n,
|
|
19
|
+
round: (d) => Math.round(d / n) * n,
|
|
20
|
+
offset: (d) => d + n, // note: no optional step for simplicity
|
|
21
|
+
range: (lo, hi) => rangei(Math.ceil(lo / n), hi / n).map((x) => x * n)
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (typeof interval === 'string')
|
|
25
|
+
return maybeTimeInterval(interval);
|
|
26
|
+
if (typeof interval.floor !== 'function')
|
|
27
|
+
throw new Error('invalid interval; missing floor method');
|
|
28
|
+
if (typeof interval.offset !== 'function')
|
|
29
|
+
throw new Error('invalid interval; missing offset method');
|
|
30
|
+
return interval;
|
|
31
|
+
}
|
|
32
|
+
export function autoTicks(type, ticks, interval, domain, scaleFn, count) {
|
|
33
|
+
return ticks
|
|
34
|
+
? ticks
|
|
35
|
+
: interval
|
|
36
|
+
? maybeInterval(interval, type).range(domain[0], domain[1])
|
|
37
|
+
: typeof scaleFn.ticks === 'function'
|
|
38
|
+
? scaleFn.ticks(count)
|
|
39
|
+
: [];
|
|
40
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export default function autoTimeFormat(x:
|
|
1
|
+
import type { Scale } from '../classes/Scale.svelte.js';
|
|
2
|
+
export default function autoTimeFormat(x: Scale, plotWidth: number, plotLocale: string): (date: Date) => string[];
|
|
@@ -1,9 +1,38 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { isDate } from './typeChecks';
|
|
2
|
+
const DATE_TIME = {
|
|
3
|
+
hour: 'numeric',
|
|
4
|
+
minute: 'numeric',
|
|
5
|
+
month: 'short',
|
|
6
|
+
day: 'numeric'
|
|
7
|
+
};
|
|
8
|
+
const autoFormatDateTime = (locale) => {
|
|
9
|
+
const format = new Intl.DateTimeFormat(locale, DATE_TIME).format;
|
|
10
|
+
return (date) => format(date).replace(', ', '\n');
|
|
11
|
+
};
|
|
12
|
+
const DAY_MONTH = {
|
|
13
|
+
month: 'short',
|
|
14
|
+
day: 'numeric'
|
|
15
|
+
};
|
|
16
|
+
const autoFormatDayMonth = (locale) => {
|
|
17
|
+
const format = new Intl.DateTimeFormat(locale, DAY_MONTH).format;
|
|
18
|
+
return (date) => format(date).replace(' ', '\n');
|
|
19
|
+
};
|
|
20
|
+
const MONTH_YEAR = {
|
|
21
|
+
month: 'short',
|
|
22
|
+
year: 'numeric'
|
|
23
|
+
};
|
|
24
|
+
const autoFormatMonthYear = (locale) => {
|
|
25
|
+
const format = new Intl.DateTimeFormat(locale, MONTH_YEAR).format;
|
|
26
|
+
return (date) => format(date).replace(' ', '\n');
|
|
27
|
+
};
|
|
28
|
+
export default function autoTimeFormat(x, plotWidth, plotLocale) {
|
|
4
29
|
const daysPer100Px = ((toNumber(x.domain[1]) - toNumber(x.domain[0])) / plotWidth / 864e5) * 100;
|
|
5
|
-
const format = daysPer100Px < 1
|
|
6
|
-
|
|
30
|
+
const format = daysPer100Px < 1
|
|
31
|
+
? autoFormatDateTime(plotLocale)
|
|
32
|
+
: daysPer100Px < 30
|
|
33
|
+
? autoFormatDayMonth(plotLocale)
|
|
34
|
+
: autoFormatMonthYear(plotLocale);
|
|
35
|
+
return (date) => format(date).split('\n');
|
|
7
36
|
}
|
|
8
37
|
function toNumber(d) {
|
|
9
38
|
return isDate(d) ? d.getTime() : +d;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RawValue } from '../types.js';
|
|
2
|
+
type Setter = (v: any) => void;
|
|
3
|
+
/**
|
|
4
|
+
* Helper function to call a D3 "function class" while also calling
|
|
5
|
+
* porperty setter functions on the result.
|
|
6
|
+
*/
|
|
7
|
+
export default function (d3func: () => Record<string, Setter>, args: RawValue[], props?: Record<string, RawValue>): Record<string, Setter>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper function to call a D3 "function class" while also calling
|
|
3
|
+
* porperty setter functions on the result.
|
|
4
|
+
*/
|
|
5
|
+
export default function (d3func, args, props = {}) {
|
|
6
|
+
const res = d3func(...args);
|
|
7
|
+
for (const [key, val] of Object.entries(props)) {
|
|
8
|
+
if (typeof res[key] !== 'function')
|
|
9
|
+
throw new Error(`function ${key} does not exist`);
|
|
10
|
+
res[key](val);
|
|
11
|
+
}
|
|
12
|
+
return res;
|
|
13
|
+
}
|
package/dist/helpers/colors.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { interpolateBlues, interpolateBrBG, interpolateBuGn, interpolateBuPu, interpolateGnBu, interpolateGreens, interpolateGreys, interpolateOranges, interpolateOrRd, interpolatePiYG, interpolatePRGn, interpolatePuBu, interpolatePuBuGn, interpolatePuOr, interpolatePuRd, interpolatePurples, interpolateRdBu, interpolateRdGy, interpolateRdPu, interpolateRdYlBu, interpolateRdYlGn, interpolateReds, interpolateSpectral, interpolateYlGn, interpolateYlGnBu, interpolateYlOrBr, interpolateYlOrRd, interpolateTurbo, interpolateViridis, interpolateMagma, interpolateInferno, interpolatePlasma, interpolateCividis, interpolateCubehelixDefault, interpolateWarm, interpolateCool, interpolateRainbow, interpolateSinebow, schemeAccent, schemeBlues, schemeBrBG, schemeBuGn, schemeBuPu, schemeCategory10, schemeDark2, schemeGnBu, schemeGreens, schemeGreys, schemeOranges, schemeOrRd, schemePaired, schemePastel1, schemePastel2, schemePiYG, schemePRGn, schemePuBu, schemePuBuGn, schemePuOr, schemePuRd, schemePurples, schemeRdBu, schemeRdGy, schemeRdPu, schemeRdYlBu, schemeRdYlGn, schemeReds, schemeSet1, schemeSet2, schemeSet3, schemeSpectral, schemeTableau10, schemeYlGn, schemeYlGnBu, schemeYlOrBr, schemeYlOrRd } from 'd3-scale-chromatic';
|
|
2
2
|
import { quantize } from 'd3-interpolate';
|
|
3
|
+
const schemeObservable10 = [
|
|
4
|
+
'#4269d0',
|
|
5
|
+
'#efb118',
|
|
6
|
+
'#ff725c',
|
|
7
|
+
'#6cc5b0',
|
|
8
|
+
'#3ca951',
|
|
9
|
+
'#ff8ab7',
|
|
10
|
+
'#a463f2',
|
|
11
|
+
'#97bbf5',
|
|
12
|
+
'#9c6b4e',
|
|
13
|
+
'#9498a0'
|
|
14
|
+
];
|
|
3
15
|
export const categoricalSchemes = new Map([
|
|
4
16
|
['accent', schemeAccent],
|
|
5
17
|
['category10', schemeCategory10],
|
|
6
18
|
['dark2', schemeDark2],
|
|
19
|
+
['observable10', schemeObservable10],
|
|
7
20
|
['paired', schemePaired],
|
|
8
21
|
['pastel1', schemePastel1],
|
|
9
22
|
['pastel2', schemePastel2],
|
|
@@ -32,6 +45,7 @@ const ordinalSchemes = new Map([
|
|
|
32
45
|
// sequential (single-hue)
|
|
33
46
|
['blues', scheme9(schemeBlues, interpolateBlues)],
|
|
34
47
|
['greens', scheme9(schemeGreens, interpolateGreens)],
|
|
48
|
+
['grays', scheme9(schemeGreys, interpolateGreys)],
|
|
35
49
|
['greys', scheme9(schemeGreys, interpolateGreys)],
|
|
36
50
|
['oranges', scheme9(schemeOranges, interpolateOranges)],
|
|
37
51
|
['purples', scheme9(schemePurples, interpolatePurples)],
|
|
@@ -63,7 +77,7 @@ const ordinalSchemes = new Map([
|
|
|
63
77
|
['sinebow', schemeicyclical(interpolateSinebow)]
|
|
64
78
|
]);
|
|
65
79
|
export function isOrdinalScheme(scheme) {
|
|
66
|
-
return ordinalSchemes.has(scheme);
|
|
80
|
+
return ordinalSchemes.has(`${scheme}`.toLowerCase());
|
|
67
81
|
}
|
|
68
82
|
function scheme9(scheme, interpolate) {
|
|
69
83
|
return (n) => {
|
|
@@ -143,6 +157,7 @@ const quantitativeSchemes = new Map([
|
|
|
143
157
|
// sequential (single-hue)
|
|
144
158
|
['blues', interpolateBlues],
|
|
145
159
|
['greens', interpolateGreens],
|
|
160
|
+
['grays', interpolateGreys],
|
|
146
161
|
['greys', interpolateGreys],
|
|
147
162
|
['purples', interpolatePurples],
|
|
148
163
|
['reds', interpolateReds],
|
|
@@ -174,7 +189,7 @@ const quantitativeSchemes = new Map([
|
|
|
174
189
|
['sinebow', interpolateSinebow]
|
|
175
190
|
]);
|
|
176
191
|
export function isQuantitativeScheme(scheme) {
|
|
177
|
-
return quantitativeSchemes.has(scheme);
|
|
192
|
+
return quantitativeSchemes.has(String(scheme).toLowerCase());
|
|
178
193
|
}
|
|
179
194
|
export function quantitativeScheme(scheme) {
|
|
180
195
|
const s = `${scheme}`.toLowerCase();
|