@motionscript/charts 0.1.1-alpha.0 → 0.1.1-alpha.2
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/CHANGELOG.md +34 -0
- package/README.md +109 -28
- package/dist/bar-chart/bar-chart.d.ts +265 -39
- package/dist/bar-chart/bar-chart.d.ts.map +1 -1
- package/dist/bar-chart/bar-chart.js +219 -171
- package/dist/bar-chart/bar-chart.js.map +1 -1
- package/dist/bar-chart/category-axis.d.ts +12 -7
- package/dist/bar-chart/category-axis.d.ts.map +1 -1
- package/dist/bar-chart/category-axis.js +56 -42
- package/dist/bar-chart/category-axis.js.map +1 -1
- package/dist/bar-chart/chart-bars.d.ts +76 -52
- package/dist/bar-chart/chart-bars.d.ts.map +1 -1
- package/dist/bar-chart/chart-bars.js +105 -89
- package/dist/bar-chart/chart-bars.js.map +1 -1
- package/dist/bar-chart/index.d.ts +4 -4
- package/dist/bar-chart/index.d.ts.map +1 -1
- package/dist/bar-chart/index.js +2 -2
- package/dist/bar-chart/index.js.map +1 -1
- package/dist/bar-chart/shared.d.ts +41 -65
- package/dist/bar-chart/shared.d.ts.map +1 -1
- package/dist/bar-chart/shared.js +73 -117
- package/dist/bar-chart/shared.js.map +1 -1
- package/dist/browser/chunks/chunk-7XCRX6GE.js +2 -0
- package/dist/browser/chunks/chunk-7XCRX6GE.js.map +7 -0
- package/dist/browser/index.js +1 -1
- package/dist/browser/index.js.map +4 -4
- package/dist/browser/kit.js +1 -1
- package/dist/browser/manifest.json +1 -1
- package/dist/engine.d.ts +5 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +5 -2
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/kit/cartesian.d.ts +51 -15
- package/dist/kit/cartesian.d.ts.map +1 -1
- package/dist/kit/cartesian.js +81 -29
- package/dist/kit/cartesian.js.map +1 -1
- package/dist/kit/chart-canvas.d.ts +32 -24
- package/dist/kit/chart-canvas.d.ts.map +1 -1
- package/dist/kit/chart-canvas.js +52 -46
- package/dist/kit/chart-canvas.js.map +1 -1
- package/dist/kit/chart-legend.d.ts +8 -4
- package/dist/kit/chart-legend.d.ts.map +1 -1
- package/dist/kit/chart-legend.js +30 -20
- package/dist/kit/chart-legend.js.map +1 -1
- package/dist/{line-chart → kit}/horizontal-axis.d.ts +31 -6
- package/dist/kit/horizontal-axis.d.ts.map +1 -0
- package/dist/{line-chart → kit}/horizontal-axis.js +23 -24
- package/dist/kit/horizontal-axis.js.map +1 -0
- package/dist/kit/motion.d.ts +5 -0
- package/dist/kit/motion.d.ts.map +1 -1
- package/dist/kit/motion.js +8 -0
- package/dist/kit/motion.js.map +1 -1
- package/dist/{pie-chart → kit}/pie-legend.d.ts +3 -3
- package/dist/kit/pie-legend.d.ts.map +1 -0
- package/dist/{pie-chart → kit}/pie-legend.js +11 -10
- package/dist/kit/pie-legend.js.map +1 -0
- package/dist/kit/polar.d.ts +31 -0
- package/dist/kit/polar.d.ts.map +1 -0
- package/dist/kit/polar.js +33 -0
- package/dist/kit/polar.js.map +1 -0
- package/dist/kit/shared.d.ts +11 -50
- package/dist/kit/shared.d.ts.map +1 -1
- package/dist/kit/shared.js +58 -141
- package/dist/kit/shared.js.map +1 -1
- package/dist/kit/style.d.ts +517 -0
- package/dist/kit/style.d.ts.map +1 -0
- package/dist/kit/style.js +292 -0
- package/dist/kit/style.js.map +1 -0
- package/dist/kit/vertical-axis.d.ts +22 -2
- package/dist/kit/vertical-axis.d.ts.map +1 -1
- package/dist/kit/vertical-axis.js +56 -43
- package/dist/kit/vertical-axis.js.map +1 -1
- package/dist/line-chart/chart-line.d.ts +95 -3
- package/dist/line-chart/chart-line.d.ts.map +1 -1
- package/dist/line-chart/chart-line.js +165 -53
- package/dist/line-chart/chart-line.js.map +1 -1
- package/dist/line-chart/chart-region.d.ts +1 -1
- package/dist/line-chart/chart-region.d.ts.map +1 -1
- package/dist/line-chart/chart-region.js +7 -8
- package/dist/line-chart/chart-region.js.map +1 -1
- package/dist/line-chart/index.d.ts +5 -6
- package/dist/line-chart/index.d.ts.map +1 -1
- package/dist/line-chart/index.js +3 -4
- package/dist/line-chart/index.js.map +1 -1
- package/dist/line-chart/line-chart.d.ts +281 -18
- package/dist/line-chart/line-chart.d.ts.map +1 -1
- package/dist/line-chart/line-chart.js +284 -134
- package/dist/line-chart/line-chart.js.map +1 -1
- package/dist/line-chart/shared.d.ts +51 -34
- package/dist/line-chart/shared.d.ts.map +1 -1
- package/dist/line-chart/shared.js +175 -83
- package/dist/line-chart/shared.js.map +1 -1
- package/dist/line-chart/x-scale.d.ts +2 -0
- package/dist/line-chart/x-scale.d.ts.map +1 -1
- package/dist/line-chart/x-scale.js +15 -0
- package/dist/line-chart/x-scale.js.map +1 -1
- package/dist/nodes.d.ts +3 -1
- package/dist/nodes.d.ts.map +1 -1
- package/dist/nodes.js +9 -1
- package/dist/nodes.js.map +1 -1
- package/dist/pie-chart/index.d.ts +2 -3
- package/dist/pie-chart/index.d.ts.map +1 -1
- package/dist/pie-chart/index.js +1 -2
- package/dist/pie-chart/index.js.map +1 -1
- package/dist/pie-chart/pie-chart.d.ts +114 -18
- package/dist/pie-chart/pie-chart.d.ts.map +1 -1
- package/dist/pie-chart/pie-chart.js +38 -24
- package/dist/pie-chart/pie-chart.js.map +1 -1
- package/dist/pie-chart/pie-ring.d.ts +16 -5
- package/dist/pie-chart/pie-ring.d.ts.map +1 -1
- package/dist/pie-chart/pie-ring.js +89 -55
- package/dist/pie-chart/pie-ring.js.map +1 -1
- package/dist/pie-chart/shared.d.ts +61 -62
- package/dist/pie-chart/shared.d.ts.map +1 -1
- package/dist/pie-chart/shared.js +44 -123
- package/dist/pie-chart/shared.js.map +1 -1
- package/dist/radar-chart/index.d.ts +5 -0
- package/dist/radar-chart/index.d.ts.map +1 -0
- package/dist/radar-chart/index.js +5 -0
- package/dist/radar-chart/index.js.map +1 -0
- package/dist/radar-chart/radar-chart.d.ts +212 -0
- package/dist/radar-chart/radar-chart.d.ts.map +1 -0
- package/dist/radar-chart/radar-chart.js +224 -0
- package/dist/radar-chart/radar-chart.js.map +1 -0
- package/dist/radar-chart/radar-grid.d.ts +49 -0
- package/dist/radar-chart/radar-grid.d.ts.map +1 -0
- package/dist/radar-chart/radar-grid.js +63 -0
- package/dist/radar-chart/radar-grid.js.map +1 -0
- package/dist/radar-chart/radar-series.d.ts +59 -0
- package/dist/radar-chart/radar-series.d.ts.map +1 -0
- package/dist/radar-chart/radar-series.js +71 -0
- package/dist/radar-chart/radar-series.js.map +1 -0
- package/dist/radar-chart/shared.d.ts +78 -0
- package/dist/radar-chart/shared.d.ts.map +1 -0
- package/dist/radar-chart/shared.js +129 -0
- package/dist/radar-chart/shared.js.map +1 -0
- package/dist/radial-chart/index.d.ts +6 -0
- package/dist/radial-chart/index.d.ts.map +1 -0
- package/dist/radial-chart/index.js +4 -0
- package/dist/radial-chart/index.js.map +1 -0
- package/dist/radial-chart/radial-chart.d.ts +210 -0
- package/dist/radial-chart/radial-chart.d.ts.map +1 -0
- package/dist/radial-chart/radial-chart.js +175 -0
- package/dist/radial-chart/radial-chart.js.map +1 -0
- package/dist/radial-chart/radial-rings.d.ts +121 -0
- package/dist/radial-chart/radial-rings.d.ts.map +1 -0
- package/dist/radial-chart/radial-rings.js +273 -0
- package/dist/radial-chart/radial-rings.js.map +1 -0
- package/dist/radial-chart/shared.d.ts +77 -0
- package/dist/radial-chart/shared.d.ts.map +1 -0
- package/dist/radial-chart/shared.js +78 -0
- package/dist/radial-chart/shared.js.map +1 -0
- package/package.json +4 -4
- package/registry.json +21 -6
- package/src/bar-chart/bar-chart.ts +263 -179
- package/src/bar-chart/category-axis.ts +46 -40
- package/src/bar-chart/chart-bars.ts +136 -117
- package/src/bar-chart/index.ts +7 -10
- package/src/bar-chart/shared.ts +88 -233
- package/src/engine.ts +5 -2
- package/src/index.ts +2 -0
- package/src/kit/cartesian.ts +121 -40
- package/src/kit/chart-canvas.ts +49 -54
- package/src/kit/chart-legend.ts +28 -20
- package/src/kit/horizontal-axis.ts +114 -0
- package/src/kit/motion.ts +7 -0
- package/src/{pie-chart → kit}/pie-legend.ts +12 -11
- package/src/kit/polar.ts +54 -0
- package/src/kit/shared.ts +55 -277
- package/src/kit/style.ts +353 -0
- package/src/kit/vertical-axis.ts +67 -48
- package/src/line-chart/chart-line.ts +176 -54
- package/src/line-chart/chart-region.ts +6 -10
- package/src/line-chart/index.ts +14 -10
- package/src/line-chart/line-chart.ts +353 -151
- package/src/line-chart/shared.ts +193 -174
- package/src/line-chart/x-scale.ts +13 -0
- package/src/nodes.ts +9 -1
- package/src/pie-chart/index.ts +2 -23
- package/src/pie-chart/pie-chart.ts +54 -35
- package/src/pie-chart/pie-ring.ts +92 -71
- package/src/pie-chart/shared.ts +80 -270
- package/src/radar-chart/index.ts +4 -0
- package/src/radar-chart/radar-chart.ts +290 -0
- package/src/radar-chart/radar-grid.ts +83 -0
- package/src/radar-chart/radar-series.ts +88 -0
- package/src/radar-chart/shared.ts +153 -0
- package/src/radial-chart/index.ts +5 -0
- package/src/radial-chart/radial-chart.ts +212 -0
- package/src/radial-chart/radial-rings.ts +328 -0
- package/src/radial-chart/shared.ts +126 -0
- package/dist/browser/chunks/chunk-4SMRCU24.js +0 -2
- package/dist/browser/chunks/chunk-4SMRCU24.js.map +0 -7
- package/dist/kit/chart-border.d.ts +0 -18
- package/dist/kit/chart-border.d.ts.map +0 -1
- package/dist/kit/chart-border.js +0 -23
- package/dist/kit/chart-border.js.map +0 -1
- package/dist/line-chart/horizontal-axis.d.ts.map +0 -1
- package/dist/line-chart/horizontal-axis.js.map +0 -1
- package/dist/pie-chart/pie-legend.d.ts.map +0 -1
- package/dist/pie-chart/pie-legend.js.map +0 -1
- package/src/kit/chart-border.ts +0 -36
- package/src/line-chart/horizontal-axis.ts +0 -122
package/src/kit/shared.ts
CHANGED
|
@@ -11,29 +11,22 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
|
-
fillOps,
|
|
15
14
|
lerpNumber,
|
|
16
|
-
shadowOps,
|
|
17
|
-
strokeOps,
|
|
18
|
-
insetsOps,
|
|
19
|
-
textOps,
|
|
20
15
|
type DataRecord,
|
|
21
16
|
type Fill,
|
|
22
|
-
type FillResolved,
|
|
23
17
|
type Insets,
|
|
24
|
-
type InsetsResolved,
|
|
25
18
|
type Shadow,
|
|
26
|
-
type ShadowResolved,
|
|
27
19
|
type Stroke,
|
|
28
|
-
type StrokeResolved,
|
|
29
20
|
type TextStyle,
|
|
30
21
|
} from "@motionscript/sdk"
|
|
22
|
+
import { niceStep } from "@motionscript/sdk/component"
|
|
31
23
|
|
|
32
24
|
/** One series of a chart: a column of the table, captioned and painted. */
|
|
33
25
|
export interface ChartSeries {
|
|
34
26
|
/** Key into each data row for this series' value. */
|
|
35
27
|
field: string
|
|
36
|
-
|
|
28
|
+
/** The legend caption; empty or absent shows `field`. */
|
|
29
|
+
label?: string
|
|
37
30
|
/** Overrides the theme palette's entry for this series' index, for its mark and legend swatch. */
|
|
38
31
|
fill?: Fill
|
|
39
32
|
/** Defaults to `true`. */
|
|
@@ -166,7 +159,7 @@ export function settleAxisDomain(domain: AxisDomainConfig, drawn: (domain: AxisD
|
|
|
166
159
|
}
|
|
167
160
|
|
|
168
161
|
/** The colour tokens the default themes are built from: a dark plot panel with warm-grey axis furniture. */
|
|
169
|
-
|
|
162
|
+
const CHART_PALETTE = {
|
|
170
163
|
plotFill: "#15130e",
|
|
171
164
|
borderColor: "#4a4036",
|
|
172
165
|
gridColor: "#2c2820",
|
|
@@ -176,15 +169,6 @@ export const CHART_PALETTE = {
|
|
|
176
169
|
regionColor: "#d99a3a",
|
|
177
170
|
} as const
|
|
178
171
|
|
|
179
|
-
/** The out-of-the-box series palette, cycled by series index. */
|
|
180
|
-
export const DEFAULT_SERIES_COLORS = [
|
|
181
|
-
"#d9603b",
|
|
182
|
-
"#8194ad",
|
|
183
|
-
"#e0a93b",
|
|
184
|
-
"#5e9d6b",
|
|
185
|
-
"#9ec85a",
|
|
186
|
-
] as const
|
|
187
|
-
|
|
188
172
|
/** Opacity an un-spotlighted series fades to, mark and legend entry alike. */
|
|
189
173
|
export const SPOTLIGHT_DIM = 0.2
|
|
190
174
|
|
|
@@ -269,13 +253,6 @@ export interface LegendConfig {
|
|
|
269
253
|
markerStyle: LegendMarkerConfig
|
|
270
254
|
}
|
|
271
255
|
|
|
272
|
-
/** The plot panel a cartesian chart draws its marks over. */
|
|
273
|
-
export interface PlotAreaConfig {
|
|
274
|
-
stroke: Stroke
|
|
275
|
-
fill: Fill
|
|
276
|
-
shadow: Shadow
|
|
277
|
-
}
|
|
278
|
-
|
|
279
256
|
const AXIS_LABEL_STYLE: TextStyle = {
|
|
280
257
|
fontSize: 24,
|
|
281
258
|
fontWeight: 700,
|
|
@@ -306,13 +283,6 @@ export const DEFAULT_Y_AXIS: AxisConfig = {
|
|
|
306
283
|
titlePadding: 24,
|
|
307
284
|
}
|
|
308
285
|
|
|
309
|
-
/** Unpainted but framed: a chart reads against the stage rather than punching a panel into it. */
|
|
310
|
-
export const DEFAULT_PLOT_AREA: PlotAreaConfig = {
|
|
311
|
-
fill: [],
|
|
312
|
-
stroke: { weight: 6, fill: CHART_PALETTE.borderColor },
|
|
313
|
-
shadow: [],
|
|
314
|
-
}
|
|
315
|
-
|
|
316
286
|
export const DEFAULT_LEGEND: LegendConfig = {
|
|
317
287
|
padding: 0,
|
|
318
288
|
textStyle: {
|
|
@@ -331,249 +301,6 @@ export const DEFAULT_LEGEND: LegendConfig = {
|
|
|
331
301
|
},
|
|
332
302
|
}
|
|
333
303
|
|
|
334
|
-
/** {@link DEFAULT_SERIES_COLORS} as 4px strokes. */
|
|
335
|
-
export const DEFAULT_SERIES_STROKES: Stroke[] = DEFAULT_SERIES_COLORS.map(
|
|
336
|
-
(fill) => ({ weight: 4, fill })
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
/** {@link DEFAULT_SERIES_COLORS} as solid fills. */
|
|
340
|
-
export const DEFAULT_SERIES_FILLS: Fill[] = DEFAULT_SERIES_COLORS.map(
|
|
341
|
-
(fill) => fill
|
|
342
|
-
)
|
|
343
|
-
|
|
344
|
-
export function resolveAxisConfig(
|
|
345
|
-
axis: Partial<AxisConfig> | undefined,
|
|
346
|
-
previous: AxisConfig
|
|
347
|
-
): AxisConfig {
|
|
348
|
-
return {
|
|
349
|
-
labelStyle: textOps.resolveStyle(axis?.labelStyle, previous.labelStyle),
|
|
350
|
-
titleStyle: textOps.resolveStyle(axis?.titleStyle, previous.titleStyle),
|
|
351
|
-
lineStyle: strokeOps.resolve(axis?.lineStyle ?? previous.lineStyle),
|
|
352
|
-
tickPadding: insetsOps.resolve(
|
|
353
|
-
axis?.tickPadding ?? previous.tickPadding,
|
|
354
|
-
previous.tickPadding as InsetsResolved
|
|
355
|
-
),
|
|
356
|
-
titlePadding: insetsOps.resolve(
|
|
357
|
-
axis?.titlePadding ?? previous.titlePadding,
|
|
358
|
-
previous.titlePadding as InsetsResolved
|
|
359
|
-
),
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
export function lerpAxisConfig(
|
|
364
|
-
from: AxisConfig,
|
|
365
|
-
to: AxisConfig,
|
|
366
|
-
t: number
|
|
367
|
-
): AxisConfig {
|
|
368
|
-
return {
|
|
369
|
-
labelStyle: textOps.lerpStyle(from.labelStyle, to.labelStyle, t),
|
|
370
|
-
titleStyle: textOps.lerpStyle(from.titleStyle, to.titleStyle, t),
|
|
371
|
-
lineStyle: strokeOps.lerp(
|
|
372
|
-
from.lineStyle as StrokeResolved[],
|
|
373
|
-
to.lineStyle as StrokeResolved[],
|
|
374
|
-
t
|
|
375
|
-
),
|
|
376
|
-
tickPadding: insetsOps.lerp(
|
|
377
|
-
from.tickPadding as InsetsResolved,
|
|
378
|
-
to.tickPadding as InsetsResolved,
|
|
379
|
-
t
|
|
380
|
-
),
|
|
381
|
-
titlePadding: insetsOps.lerp(
|
|
382
|
-
from.titlePadding as InsetsResolved,
|
|
383
|
-
to.titlePadding as InsetsResolved,
|
|
384
|
-
t
|
|
385
|
-
),
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
export function resolvePlotArea(
|
|
390
|
-
plotArea: Partial<PlotAreaConfig> | undefined,
|
|
391
|
-
previous: PlotAreaConfig
|
|
392
|
-
): PlotAreaConfig {
|
|
393
|
-
return {
|
|
394
|
-
fill: fillOps.resolve(plotArea?.fill ?? previous.fill),
|
|
395
|
-
stroke: strokeOps.resolve(plotArea?.stroke ?? previous.stroke),
|
|
396
|
-
shadow: shadowOps.resolve(plotArea?.shadow ?? previous.shadow),
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
export function lerpPlotArea(
|
|
401
|
-
from: PlotAreaConfig,
|
|
402
|
-
to: PlotAreaConfig,
|
|
403
|
-
t: number
|
|
404
|
-
): PlotAreaConfig {
|
|
405
|
-
return {
|
|
406
|
-
fill: fillOps.lerp(
|
|
407
|
-
from.fill as FillResolved[],
|
|
408
|
-
to.fill as FillResolved[],
|
|
409
|
-
t
|
|
410
|
-
),
|
|
411
|
-
stroke: strokeOps.lerp(
|
|
412
|
-
from.stroke as StrokeResolved[],
|
|
413
|
-
to.stroke as StrokeResolved[],
|
|
414
|
-
t
|
|
415
|
-
),
|
|
416
|
-
shadow: shadowOps.lerp(
|
|
417
|
-
from.shadow as ShadowResolved[],
|
|
418
|
-
to.shadow as ShadowResolved[],
|
|
419
|
-
t
|
|
420
|
-
),
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
function resolveLegendMarkerConfig(
|
|
425
|
-
marker: Partial<LegendMarkerConfig> | undefined,
|
|
426
|
-
previous: LegendMarkerConfig
|
|
427
|
-
): LegendMarkerConfig {
|
|
428
|
-
return {
|
|
429
|
-
width: marker?.width ?? previous.width,
|
|
430
|
-
height: marker?.height ?? previous.height,
|
|
431
|
-
borderRadius: marker?.borderRadius ?? previous.borderRadius,
|
|
432
|
-
stroke: strokeOps.resolve(marker?.stroke ?? previous.stroke),
|
|
433
|
-
shadow: shadowOps.resolve(marker?.shadow ?? previous.shadow),
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
function lerpLegendMarkerConfig(
|
|
438
|
-
from: LegendMarkerConfig,
|
|
439
|
-
to: LegendMarkerConfig,
|
|
440
|
-
t: number
|
|
441
|
-
): LegendMarkerConfig {
|
|
442
|
-
return {
|
|
443
|
-
width: lerpNumber(from.width, to.width, t),
|
|
444
|
-
height: lerpNumber(from.height, to.height, t),
|
|
445
|
-
borderRadius: lerpNumber(from.borderRadius, to.borderRadius, t),
|
|
446
|
-
stroke: strokeOps.lerp(
|
|
447
|
-
from.stroke as StrokeResolved[],
|
|
448
|
-
to.stroke as StrokeResolved[],
|
|
449
|
-
t
|
|
450
|
-
),
|
|
451
|
-
shadow: shadowOps.lerp(
|
|
452
|
-
from.shadow as ShadowResolved[],
|
|
453
|
-
to.shadow as ShadowResolved[],
|
|
454
|
-
t
|
|
455
|
-
),
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/** A legend theme as the author may state it: every branch optional. */
|
|
460
|
-
export type LegendTheme = Partial<Omit<LegendConfig, "markerStyle">> & {
|
|
461
|
-
markerStyle?: Partial<LegendMarkerConfig>
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
export function resolveLegendConfig(
|
|
465
|
-
legend: LegendTheme | undefined,
|
|
466
|
-
previous: LegendConfig
|
|
467
|
-
): LegendConfig {
|
|
468
|
-
return {
|
|
469
|
-
padding: insetsOps.resolve(
|
|
470
|
-
legend?.padding ?? previous.padding,
|
|
471
|
-
previous.padding as InsetsResolved
|
|
472
|
-
),
|
|
473
|
-
textStyle: textOps.resolveStyle(legend?.textStyle, previous.textStyle),
|
|
474
|
-
itemGap: legend?.itemGap ?? previous.itemGap,
|
|
475
|
-
markerStyle: resolveLegendMarkerConfig(
|
|
476
|
-
legend?.markerStyle,
|
|
477
|
-
previous.markerStyle
|
|
478
|
-
),
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
export function lerpLegendConfig(
|
|
483
|
-
from: LegendConfig,
|
|
484
|
-
to: LegendConfig,
|
|
485
|
-
t: number
|
|
486
|
-
): LegendConfig {
|
|
487
|
-
return {
|
|
488
|
-
padding: insetsOps.lerp(
|
|
489
|
-
from.padding as InsetsResolved,
|
|
490
|
-
to.padding as InsetsResolved,
|
|
491
|
-
t
|
|
492
|
-
),
|
|
493
|
-
textStyle: textOps.lerpStyle(from.textStyle, to.textStyle, t),
|
|
494
|
-
itemGap: lerpNumber(from.itemGap, to.itemGap, t),
|
|
495
|
-
markerStyle: lerpLegendMarkerConfig(from.markerStyle, to.markerStyle, t),
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
/** A palette override replaces the previous palette outright. */
|
|
500
|
-
export function resolveSeriesStrokes(
|
|
501
|
-
styles: Stroke[] | undefined,
|
|
502
|
-
previous: Stroke[]
|
|
503
|
-
): Stroke[] {
|
|
504
|
-
return (styles ?? previous).map((s) => strokeOps.resolve(s))
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/** Pairwise by index; a palette that grows/shrinks holds the longer side's tail. */
|
|
508
|
-
export function lerpSeriesStrokes(
|
|
509
|
-
from: Stroke[],
|
|
510
|
-
to: Stroke[],
|
|
511
|
-
t: number
|
|
512
|
-
): Stroke[] {
|
|
513
|
-
const n = Math.max(from.length, to.length)
|
|
514
|
-
const out: Stroke[] = []
|
|
515
|
-
for (let i = 0; i < n; i++) {
|
|
516
|
-
const a = (from[i] ?? to[i]) as StrokeResolved[]
|
|
517
|
-
const b = (to[i] ?? from[i]) as StrokeResolved[]
|
|
518
|
-
out.push(strokeOps.lerp(a, b, t))
|
|
519
|
-
}
|
|
520
|
-
return out
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/** The fill-palette twin of {@link resolveSeriesStrokes}, for filled marks. */
|
|
524
|
-
export function resolveSeriesFills(
|
|
525
|
-
fills: Fill[] | undefined,
|
|
526
|
-
previous: Fill[]
|
|
527
|
-
): Fill[] {
|
|
528
|
-
return (fills ?? previous).map((f) => fillOps.resolve(f))
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
/** The fill-palette twin of {@link lerpSeriesStrokes}. */
|
|
532
|
-
export function lerpSeriesFills(from: Fill[], to: Fill[], t: number): Fill[] {
|
|
533
|
-
const n = Math.max(from.length, to.length)
|
|
534
|
-
const out: Fill[] = []
|
|
535
|
-
for (let i = 0; i < n; i++) {
|
|
536
|
-
const a = (from[i] ?? to[i]) as FillResolved[]
|
|
537
|
-
const b = (to[i] ?? from[i]) as FillResolved[]
|
|
538
|
-
out.push(fillOps.lerp(a, b, t))
|
|
539
|
-
}
|
|
540
|
-
return out
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* The stroke for series `index`: the palette's entry at `index % palette.length`,
|
|
545
|
-
* with the series' own `fill`, if set, replacing just the topmost layer's colour.
|
|
546
|
-
*/
|
|
547
|
-
export function resolveSeriesStroke(
|
|
548
|
-
palette: Stroke[],
|
|
549
|
-
series: ChartSeries,
|
|
550
|
-
index: number
|
|
551
|
-
): Stroke {
|
|
552
|
-
const entry: Stroke =
|
|
553
|
-
palette.length > 0
|
|
554
|
-
? palette[index % palette.length]
|
|
555
|
-
: { weight: 4, fill: "white" }
|
|
556
|
-
if (series.fill == null) return entry
|
|
557
|
-
const layers = strokeOps.resolve(entry)
|
|
558
|
-
if (layers.length === 0) return { weight: 4, fill: series.fill }
|
|
559
|
-
const next = [...layers]
|
|
560
|
-
next[next.length - 1] = {
|
|
561
|
-
...next[next.length - 1],
|
|
562
|
-
fill: fillOps.resolve(series.fill),
|
|
563
|
-
}
|
|
564
|
-
return next
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
/** The colour {@link resolveSeriesStroke} draws series `index` in, for a legend swatch. */
|
|
568
|
-
export function resolveSeriesFill(
|
|
569
|
-
palette: Stroke[],
|
|
570
|
-
series: ChartSeries,
|
|
571
|
-
index: number
|
|
572
|
-
): Fill {
|
|
573
|
-
const layers = strokeOps.resolve(resolveSeriesStroke(palette, series, index))
|
|
574
|
-
return layers[layers.length - 1]?.fill ?? "white"
|
|
575
|
-
}
|
|
576
|
-
|
|
577
304
|
/**
|
|
578
305
|
* Format a marker value: integers plain, otherwise one decimal, or as many as
|
|
579
306
|
* the tick `step` needs to tell neighbours apart (a unit axis ticked every 0.05
|
|
@@ -619,3 +346,54 @@ export function markerValues([min, max]: Range, markerCount: number): number[] {
|
|
|
619
346
|
const n = Math.max(2, Math.round(markerCount))
|
|
620
347
|
return Array.from({ length: n + 1 }, (_, i) => min + ((max - min) / n) * i)
|
|
621
348
|
}
|
|
349
|
+
|
|
350
|
+
/** `[lo, hi]` nudged out to bounds a whole number of tidy steps apart, about `divisions` of them. */
|
|
351
|
+
export function niceRange([lo, hi]: Range, divisions: number): Range {
|
|
352
|
+
const segments = Math.max(1, Math.round(divisions))
|
|
353
|
+
if (hi === lo) return constantScale(lo, segments)
|
|
354
|
+
const step = niceStep((hi - lo) / segments)
|
|
355
|
+
return [Math.floor(lo / step) * step, Math.ceil(hi / step) * step]
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* The scale for constant data. A zero-width scale would put every tick on one
|
|
360
|
+
* value and the line on the floor, so it widens by a step sized to the
|
|
361
|
+
* magnitude (`5` gets `[3, 7]`), or `[0, 1]` for zero.
|
|
362
|
+
*/
|
|
363
|
+
function constantScale(value: number, segments: number): Range {
|
|
364
|
+
if (value === 0) return [0, 1]
|
|
365
|
+
const step = niceStep(Math.abs(value) / segments)
|
|
366
|
+
return [value - step, value + step]
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Ticks for a range worked out from the data: every multiple of the tidiest
|
|
371
|
+
* step (1, 2 or 5 times a power of ten) that divides it into about `divisions`
|
|
372
|
+
* parts, so zero is a tick whenever the range spans it. A range no such step
|
|
373
|
+
* divides (an author's) is split evenly instead.
|
|
374
|
+
*/
|
|
375
|
+
export function niceTicks([lo, hi]: Range, divisions: number): number[] {
|
|
376
|
+
const span = hi - lo
|
|
377
|
+
const target = Math.max(1, Math.round(divisions))
|
|
378
|
+
if (!(span > 0)) return markerValues([lo, hi], target)
|
|
379
|
+
const whole = (v: number) => Math.abs(v - Math.round(v)) < 1e-6
|
|
380
|
+
const base = niceStep(span / target)
|
|
381
|
+
let best: number | undefined
|
|
382
|
+
for (const step of ladder(base)) {
|
|
383
|
+
const parts = span / step
|
|
384
|
+
if (!whole(parts) || !whole(lo / step) || parts < 2 || parts > 8) continue
|
|
385
|
+
if (best === undefined || Math.abs(parts - target) < Math.abs(span / best - target)) best = step
|
|
386
|
+
}
|
|
387
|
+
if (best === undefined) return markerValues([lo, hi], target)
|
|
388
|
+
const first = Math.round(lo / best)
|
|
389
|
+
return Array.from({ length: Math.round(span / best) + 1 }, (_, k) => Number(((first + k) * best).toPrecision(12)))
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/** `step` and its neighbours on the 1-2-5 ladder, two either side. */
|
|
393
|
+
function ladder(step: number): number[] {
|
|
394
|
+
const mag = 10 ** Math.floor(Math.log10(step))
|
|
395
|
+
const rungs: number[] = []
|
|
396
|
+
for (const m of [mag / 10, mag, mag * 10]) for (const k of [1, 2, 5]) rungs.push(k * m)
|
|
397
|
+
const at = rungs.findIndex((r) => Math.abs(r - step) < step * 1e-9)
|
|
398
|
+
return rungs.slice(Math.max(0, at - 2), at + 3)
|
|
399
|
+
}
|