@dou-ui/chart 0.0.0-stage → 0.1.0-alpha.1
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 +21 -0
- package/README.md +10 -2
- package/dist/chart.js +6 -0
- package/dist/chart.js.map +1 -0
- package/dist/chart.vue_vue_type_script_setup_true_lang.js +4245 -0
- package/dist/chart.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/area.js +6 -0
- package/dist/components/area.js.map +1 -0
- package/dist/components/area.vue_vue_type_script_setup_true_lang.js +55 -0
- package/dist/components/area.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/axis.js +6 -0
- package/dist/components/axis.js.map +1 -0
- package/dist/components/axis.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/components/axis.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/bar.js +6 -0
- package/dist/components/bar.js.map +1 -0
- package/dist/components/bar.vue_vue_type_script_setup_true_lang.js +46 -0
- package/dist/components/bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/boxplot.js +6 -0
- package/dist/components/boxplot.js.map +1 -0
- package/dist/components/boxplot.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/boxplot.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/brush.js +6 -0
- package/dist/components/brush.js.map +1 -0
- package/dist/components/brush.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/brush.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/funnel.js +6 -0
- package/dist/components/funnel.js.map +1 -0
- package/dist/components/funnel.vue_vue_type_script_setup_true_lang.js +41 -0
- package/dist/components/funnel.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/gauge.js +6 -0
- package/dist/components/gauge.js.map +1 -0
- package/dist/components/gauge.vue_vue_type_script_setup_true_lang.js +91 -0
- package/dist/components/gauge.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/heatmap.js +6 -0
- package/dist/components/heatmap.js.map +1 -0
- package/dist/components/heatmap.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/components/heatmap.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/histogram.js +6 -0
- package/dist/components/histogram.js.map +1 -0
- package/dist/components/histogram.vue_vue_type_script_setup_true_lang.js +61 -0
- package/dist/components/histogram.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/line.js +6 -0
- package/dist/components/line.js.map +1 -0
- package/dist/components/line.vue_vue_type_script_setup_true_lang.js +52 -0
- package/dist/components/line.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/marker.js +6 -0
- package/dist/components/marker.js.map +1 -0
- package/dist/components/marker.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/components/marker.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/pie.js +6 -0
- package/dist/components/pie.js.map +1 -0
- package/dist/components/pie.vue_vue_type_script_setup_true_lang.js +42 -0
- package/dist/components/pie.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/radar.js +6 -0
- package/dist/components/radar.js.map +1 -0
- package/dist/components/radar.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/components/radar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/range.js +6 -0
- package/dist/components/range.js.map +1 -0
- package/dist/components/range.vue_vue_type_script_setup_true_lang.js +27 -0
- package/dist/components/range.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/scatter.js +6 -0
- package/dist/components/scatter.js.map +1 -0
- package/dist/components/scatter.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/components/scatter.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/sunburst.js +6 -0
- package/dist/components/sunburst.js.map +1 -0
- package/dist/components/sunburst.vue_vue_type_script_setup_true_lang.js +36 -0
- package/dist/components/sunburst.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/tooltip.js +6 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/components/tooltip.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/components/tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/treemap.js +6 -0
- package/dist/components/treemap.js.map +1 -0
- package/dist/components/treemap.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/components/treemap.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/waterfall.js +6 -0
- package/dist/components/waterfall.js.map +1 -0
- package/dist/components/waterfall.vue_vue_type_script_setup_true_lang.js +49 -0
- package/dist/components/waterfall.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/zoom.js +6 -0
- package/dist/components/zoom.js.map +1 -0
- package/dist/components/zoom.vue_vue_type_script_setup_true_lang.js +37 -0
- package/dist/components/zoom.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/context.js +30 -0
- package/dist/context.js.map +1 -0
- package/dist/core/bar.js +223 -0
- package/dist/core/bar.js.map +1 -0
- package/dist/core/box.js +150 -0
- package/dist/core/box.js.map +1 -0
- package/dist/core/colors.js +58 -0
- package/dist/core/colors.js.map +1 -0
- package/dist/core/data.js +257 -0
- package/dist/core/data.js.map +1 -0
- package/dist/core/decimate.js +211 -0
- package/dist/core/decimate.js.map +1 -0
- package/dist/core/format.js +151 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/funnel.js +68 -0
- package/dist/core/funnel.js.map +1 -0
- package/dist/core/grid.js +87 -0
- package/dist/core/grid.js.map +1 -0
- package/dist/core/heatmap.js +187 -0
- package/dist/core/heatmap.js.map +1 -0
- package/dist/core/histogram.js +81 -0
- package/dist/core/histogram.js.map +1 -0
- package/dist/core/hit.js +115 -0
- package/dist/core/hit.js.map +1 -0
- package/dist/core/labels.js +141 -0
- package/dist/core/labels.js.map +1 -0
- package/dist/core/layout.js +1002 -0
- package/dist/core/layout.js.map +1 -0
- package/dist/core/line.js +230 -0
- package/dist/core/line.js.map +1 -0
- package/dist/core/marker.js +205 -0
- package/dist/core/marker.js.map +1 -0
- package/dist/core/model.js +391 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/painter.js +79 -0
- package/dist/core/painter.js.map +1 -0
- package/dist/core/pattern.js +102 -0
- package/dist/core/pattern.js.map +1 -0
- package/dist/core/pie.js +119 -0
- package/dist/core/pie.js.map +1 -0
- package/dist/core/radar.js +83 -0
- package/dist/core/radar.js.map +1 -0
- package/dist/core/scale.js +149 -0
- package/dist/core/scale.js.map +1 -0
- package/dist/core/scatter.js +263 -0
- package/dist/core/scatter.js.map +1 -0
- package/dist/core/svg.js +209 -0
- package/dist/core/svg.js.map +1 -0
- package/dist/core/sync.js +21 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/time.js +217 -0
- package/dist/core/time.js.map +1 -0
- package/dist/core/tree.js +348 -0
- package/dist/core/tree.js.map +1 -0
- package/dist/core/warn.js +11 -0
- package/dist/core/warn.js.map +1 -0
- package/dist/core/waterfall.js +134 -0
- package/dist/core/waterfall.js.map +1 -0
- package/dist/core/window.js +94 -0
- package/dist/core/window.js.map +1 -0
- package/dist/define.js +62 -0
- package/dist/define.js.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/locale.js +170 -0
- package/dist/locale.js.map +1 -0
- package/dist/overlay.js +6 -0
- package/dist/overlay.js.map +1 -0
- package/dist/overlay.vue_vue_type_script_setup_true_lang.js +207 -0
- package/dist/overlay.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/pointer.js +6 -0
- package/dist/pointer.js.map +1 -0
- package/dist/pointer.vue_vue_type_script_setup_true_lang.js +136 -0
- package/dist/pointer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/static.js +6 -0
- package/dist/static.js.map +1 -0
- package/dist/static.vue_vue_type_script_setup_true_lang.js +34 -0
- package/dist/static.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/style.d.ts +1 -0
- package/dist/style.js +3 -0
- package/dist/table.js +6 -0
- package/dist/table.js.map +1 -0
- package/dist/table.vue_vue_type_script_setup_true_lang.js +52 -0
- package/dist/table.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/types/chart.vue.d.ts +24 -0
- package/dist/types/components/area.vue.d.ts +16 -0
- package/dist/types/components/axis.vue.d.ts +8 -0
- package/dist/types/components/bar.vue.d.ts +14 -0
- package/dist/types/components/boxplot.vue.d.ts +14 -0
- package/dist/types/components/brush.vue.d.ts +22 -0
- package/dist/types/components/funnel.vue.d.ts +14 -0
- package/dist/types/components/gauge.vue.d.ts +17 -0
- package/dist/types/components/heatmap.vue.d.ts +14 -0
- package/dist/types/components/histogram.vue.d.ts +14 -0
- package/dist/types/components/line.vue.d.ts +16 -0
- package/dist/types/components/marker.vue.d.ts +6 -0
- package/dist/types/components/pie.vue.d.ts +23 -0
- package/dist/types/components/radar.vue.d.ts +16 -0
- package/dist/types/components/range.vue.d.ts +12 -0
- package/dist/types/components/scatter.vue.d.ts +14 -0
- package/dist/types/components/sunburst.vue.d.ts +17 -0
- package/dist/types/components/tooltip.vue.d.ts +13 -0
- package/dist/types/components/treemap.vue.d.ts +8 -0
- package/dist/types/components/waterfall.vue.d.ts +16 -0
- package/dist/types/components/zoom.vue.d.ts +18 -0
- package/dist/types/context.d.ts +87 -0
- package/dist/types/core/bar.d.ts +38 -0
- package/dist/types/core/box.d.ts +25 -0
- package/dist/types/core/colors.d.ts +16 -0
- package/dist/types/core/data.d.ts +72 -0
- package/dist/types/core/decimate.d.ts +39 -0
- package/dist/types/core/format.d.ts +33 -0
- package/dist/types/core/funnel.d.ts +15 -0
- package/dist/types/core/grid.d.ts +18 -0
- package/dist/types/core/heatmap.d.ts +17 -0
- package/dist/types/core/histogram.d.ts +23 -0
- package/dist/types/core/hit.d.ts +31 -0
- package/dist/types/core/labels.d.ts +45 -0
- package/dist/types/core/layout.d.ts +259 -0
- package/dist/types/core/line.d.ts +36 -0
- package/dist/types/core/marker.d.ts +67 -0
- package/dist/types/core/model.d.ts +86 -0
- package/dist/types/core/painter.d.ts +34 -0
- package/dist/types/core/pattern.d.ts +14 -0
- package/dist/types/core/pie.d.ts +66 -0
- package/dist/types/core/radar.d.ts +12 -0
- package/dist/types/core/scale.d.ts +60 -0
- package/dist/types/core/scatter.d.ts +16 -0
- package/dist/types/core/series.d.ts +228 -0
- package/dist/types/core/svg.d.ts +63 -0
- package/dist/types/core/sync.d.ts +8 -0
- package/dist/types/core/time.d.ts +20 -0
- package/dist/types/core/tree.d.ts +84 -0
- package/dist/types/core/warn.d.ts +4 -0
- package/dist/types/core/waterfall.d.ts +24 -0
- package/dist/types/core/window.d.ts +36 -0
- package/dist/types/define.d.ts +115 -0
- package/dist/types/index.d.ts +363 -0
- package/dist/types/locale.d.ts +100 -0
- package/dist/types/overlay.vue.d.ts +95 -0
- package/dist/types/pointer.vue.d.ts +53 -0
- package/dist/types/static.vue.d.ts +24 -0
- package/dist/types/table.vue.d.ts +19 -0
- package/dist/types/types.d.ts +555 -0
- package/dist/types/zoom-layer.vue.d.ts +41 -0
- package/dist/zoom-layer.js +6 -0
- package/dist/zoom-layer.js.map +1 -0
- package/dist/zoom-layer.vue_vue_type_script_setup_true_lang.js +210 -0
- package/dist/zoom-layer.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/package.json +53 -4
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type TimeInterval, type TimeUnit } from './time';
|
|
2
|
+
/**
|
|
3
|
+
* Formats the ticks of a number axis: as many decimals as the step needs,
|
|
4
|
+
* and in short form ("12万", "1.2M") once the numbers get long, with as
|
|
5
|
+
* many digits as it takes to tell the ticks apart. With `years`, whole
|
|
6
|
+
* numbers under 10000 go without separators, so 2019 doesn't read "2,019".
|
|
7
|
+
*/
|
|
8
|
+
export declare function numberTickFormat(locale: string, ticks: number[], { years }?: {
|
|
9
|
+
years?: boolean;
|
|
10
|
+
}): (value: number) => string;
|
|
11
|
+
/** Formats a value for reading in full (tooltips, the accessible summary). */
|
|
12
|
+
export declare function numberFormatFull(locale: string): (value: number) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Formats the ticks of a time axis. Most ticks show only the unit they
|
|
15
|
+
* step by ("15日", "09:00"); the first one and the first in each bigger
|
|
16
|
+
* unit say more ("11月2日", "2026年1月"), so the axis reads without a legend.
|
|
17
|
+
* `previous` is the tick before, if any.
|
|
18
|
+
*/
|
|
19
|
+
export declare function timeTickFormat(locale: string, interval: TimeInterval): (value: number, previous?: number) => string;
|
|
20
|
+
/**
|
|
21
|
+
* How precisely a point in time needs writing: as precise as the time
|
|
22
|
+
* itself (09:30 needs minutes), and as its neighbor is near (points 100ms
|
|
23
|
+
* apart need tenths of a second, even on a whole second). `digits` are
|
|
24
|
+
* the digits of a second, from 1 to 3.
|
|
25
|
+
*/
|
|
26
|
+
export declare function timePrecision(value: number, gap?: number): {
|
|
27
|
+
unit: "second" | "minute" | "day";
|
|
28
|
+
digits: 0 | 1 | 2 | 3;
|
|
29
|
+
};
|
|
30
|
+
/** Formats a point in time in full, as precise as `unit` (tooltips, the accessible summary). */
|
|
31
|
+
export declare function timeFormatFull(locale: string, unit?: TimeUnit,
|
|
32
|
+
/** Digits of a second, for times less than a second apart. */
|
|
33
|
+
digits?: 0 | 1 | 2 | 3): (value: number) => string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ChartSeries, ChartSeriesKind, ChartView } from './series';
|
|
2
|
+
export interface FunnelStyle {
|
|
3
|
+
/** Corner radius of the bars, in px. */
|
|
4
|
+
radius?: number;
|
|
5
|
+
}
|
|
6
|
+
/** How much of a stage's row its bar takes; the rest is the band to the next. */
|
|
7
|
+
export declare const FUNNEL_BAR = 0.7;
|
|
8
|
+
/** A stage's bar: its left, top, width and height, in px; `null` without a value. */
|
|
9
|
+
export declare function stageBar(series: ChartSeries<FunnelStyle>, view: ChartView, i: number): {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
} | null;
|
|
15
|
+
export declare const funnelKind: ChartSeriesKind<FunnelStyle>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface PointGrid {
|
|
2
|
+
/** The data's x and y stretch the cells cover. */
|
|
3
|
+
x0: number;
|
|
4
|
+
y0: number;
|
|
5
|
+
/** Cells across and down, and the size of one in data numbers. */
|
|
6
|
+
columns: number;
|
|
7
|
+
rows: number;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
/** Where each cell's points start in `items`; the cell after ends them. */
|
|
11
|
+
starts: Int32Array;
|
|
12
|
+
/** The points, cell by cell. */
|
|
13
|
+
items: Int32Array;
|
|
14
|
+
}
|
|
15
|
+
/** The grid of the points `(xs[i], ys[i])`; points with a `NaN` are left out. Cached per data. */
|
|
16
|
+
export declare function pointGrid(xs: Float64Array, ys: Float64Array): PointGrid;
|
|
17
|
+
/** Calls `visit` with each point in the cells that touch the data box from `(xa, ya)` to `(xb, yb)`. */
|
|
18
|
+
export declare function eachNear(grid: PointGrid, xa: number, xb: number, ya: number, yb: number, visit: (index: number) => void): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChartSeries, ChartSeriesKind } from './series';
|
|
2
|
+
export interface HeatmapStyle {
|
|
3
|
+
/** The value the scale starts at; by default the smallest. */
|
|
4
|
+
min?: number;
|
|
5
|
+
/** The value the scale ends at; by default the largest. */
|
|
6
|
+
max?: number;
|
|
7
|
+
}
|
|
8
|
+
/** The values a heatmap's scale runs between: `min` and `max` as given, else the data's ends. */
|
|
9
|
+
export declare function heatRange(series: Pick<ChartSeries<HeatmapStyle>, 'props' | 'y'>): [number, number] | null;
|
|
10
|
+
/** Where `value` falls on the scale, 0 to 1. */
|
|
11
|
+
export declare function heatShare(value: number, range: [number, number]): number;
|
|
12
|
+
/**
|
|
13
|
+
* The color at `share` (0 to 1) of a scale from `surface` to `color`,
|
|
14
|
+
* mixed in OKLab so equal steps look equal; the smallest still shows.
|
|
15
|
+
*/
|
|
16
|
+
export declare function heatColor(color: string, surface: string, share: number): string;
|
|
17
|
+
export declare const heatmapKind: ChartSeriesKind<HeatmapStyle>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type BarStyle } from './bar';
|
|
2
|
+
import type { ChartSeriesKind } from './series';
|
|
3
|
+
/** The most bins a histogram has: more would be thinner than a pixel, and slow. */
|
|
4
|
+
export declare const MAX_BINS = 1000;
|
|
5
|
+
export interface HistogramBin {
|
|
6
|
+
/** Where the bin starts, inclusive. */
|
|
7
|
+
x0: number;
|
|
8
|
+
/** Where it ends: exclusive, but for the last bin. */
|
|
9
|
+
x1: number;
|
|
10
|
+
/** Its middle, where the bar is placed. */
|
|
11
|
+
x: number;
|
|
12
|
+
count: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Counts `values` into bins of width `step`, or of a round width giving
|
|
16
|
+
* about `count` bins (by default, by the number of values: Sturges' rule).
|
|
17
|
+
* Values that aren't numbers are left out.
|
|
18
|
+
*/
|
|
19
|
+
export declare function histogramBins(values: ArrayLike<number>, { count, step }?: {
|
|
20
|
+
count?: number;
|
|
21
|
+
step?: number;
|
|
22
|
+
}): HistogramBin[];
|
|
23
|
+
export declare const histogramKind: ChartSeriesKind<BarStyle>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Scale } from './scale';
|
|
2
|
+
/** The indices of `values` from the smallest to the largest, `NaN` left out. Cached per array. */
|
|
3
|
+
export declare function sortedOrder(values: Float64Array): Int32Array;
|
|
4
|
+
/**
|
|
5
|
+
* Notes that `values` go up with no gaps, so their order is just
|
|
6
|
+
* 0, 1, 2…: shared, so it costs nothing to make.
|
|
7
|
+
*/
|
|
8
|
+
export declare function inOrder(values: Float64Array): void;
|
|
9
|
+
/** How far `value` is from the nearest other value of `values`; `Infinity` when there is none. */
|
|
10
|
+
export declare function neighborGap(values: Float64Array, value: number): number;
|
|
11
|
+
/** The row of `values` whose value is exactly `value`, or -1. */
|
|
12
|
+
export declare function rowAt(values: Float64Array, value: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* Of all the x values of `columns`, the one nearest to `pixel` along the
|
|
15
|
+
* x scale; `null` when there are none. Category axes snap to the nearest
|
|
16
|
+
* category.
|
|
17
|
+
*/
|
|
18
|
+
export declare function nearestX(columns: Float64Array[], scale: Scale, pixel: number): number | null;
|
|
19
|
+
/** The x values of `columns` together, from the smallest, each once. */
|
|
20
|
+
export declare function allX(columns: Float64Array[]): number[];
|
|
21
|
+
/**
|
|
22
|
+
* The point nearest to `(px, py)` among `n` points placed by `point`,
|
|
23
|
+
* if one is within `reach(i)` px of it. Points of equal distance go to the
|
|
24
|
+
* one drawn last, which is on top.
|
|
25
|
+
*/
|
|
26
|
+
export declare function nearestPoint(n: number, point: (i: number) => [number, number] | null, px: number, py: number, reach: (i: number) => number): {
|
|
27
|
+
index: number;
|
|
28
|
+
distance: number;
|
|
29
|
+
} | null;
|
|
30
|
+
/** Angles clockwise from 12 o'clock, as pies use them. */
|
|
31
|
+
export declare function angleAt(cx: number, cy: number, px: number, py: number): number;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Rect } from './painter';
|
|
2
|
+
import type { ChartLabelAnchor } from './series';
|
|
3
|
+
/** Height of a label's box, as tick labels. */
|
|
4
|
+
export declare const DATA_LABEL = 16;
|
|
5
|
+
export interface DataLabelInput {
|
|
6
|
+
key: string;
|
|
7
|
+
/** The series' index. */
|
|
8
|
+
series: number;
|
|
9
|
+
text: string;
|
|
10
|
+
anchor: ChartLabelAnchor;
|
|
11
|
+
/** Room from the point, past a dot or a line. */
|
|
12
|
+
offset?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PlacedDataLabel {
|
|
15
|
+
key: string;
|
|
16
|
+
series: number;
|
|
17
|
+
text: string;
|
|
18
|
+
/** The box's top left, in px from the chart's top left. */
|
|
19
|
+
left: number;
|
|
20
|
+
top: number;
|
|
21
|
+
/** Which end of the text `left` is. */
|
|
22
|
+
align: 'start' | 'middle' | 'end';
|
|
23
|
+
/** In a bar: the color of the bar, for text that reads on it. */
|
|
24
|
+
on?: string;
|
|
25
|
+
}
|
|
26
|
+
type Box = [left: number, top: number, right: number, bottom: number];
|
|
27
|
+
/**
|
|
28
|
+
* Places labels in the order given; one that covers a label placed before
|
|
29
|
+
* it (or one of `taken`), or doesn't fit in `bounds` (or in its bar), is
|
|
30
|
+
* left out.
|
|
31
|
+
*/
|
|
32
|
+
export declare function placeDataLabels(inputs: DataLabelInput[], bounds: Rect, measure: (text: string) => number,
|
|
33
|
+
/** Labels already there that these must not cover (the ends of lines, say). */
|
|
34
|
+
taken?: Box[]): PlacedDataLabel[];
|
|
35
|
+
/**
|
|
36
|
+
* Moves boxes of `height` centered at `centers` apart along one line so
|
|
37
|
+
* none overlaps the next, keeping each as near its own center as it can
|
|
38
|
+
* and all within `[from, to]`. Gives the new centers, in the same order.
|
|
39
|
+
*/
|
|
40
|
+
export declare function spread(centers: number[], height: number, from: number, to: number): number[];
|
|
41
|
+
/** Relative luminance of an `rgb()` / `rgba()` color (as the browser gives computed colors), 0 to 1. */
|
|
42
|
+
export declare function luminance(color: string): number | null;
|
|
43
|
+
/** Contrast ratio between two luminances. */
|
|
44
|
+
export declare const contrast: (a: number, b: number) => number;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import type { ChartModel } from './model';
|
|
2
|
+
import type { Rect } from './painter';
|
|
3
|
+
import { type Scale } from './scale';
|
|
4
|
+
import type { ChartValueAxis } from './series';
|
|
5
|
+
import { type Window } from './window';
|
|
6
|
+
/** Where an axis is drawn. */
|
|
7
|
+
export type ChartAxisPosition = 'bottom' | 'top' | 'left' | 'right';
|
|
8
|
+
/** What an axis measures: x, the values, or a second kind of values. */
|
|
9
|
+
export type ChartAxisRole = 'x' | ChartValueAxis;
|
|
10
|
+
export type ChartAxisType = 'linear' | 'log' | 'time' | 'category';
|
|
11
|
+
/** A tick value as `format` receives it: a number, a `Date` on time axes, the category on category axes. */
|
|
12
|
+
export type ChartTickValue = number | Date | string;
|
|
13
|
+
/** An axis as configured, with defaults filled in. `position` is where it is drawn. */
|
|
14
|
+
export interface AxisConfig {
|
|
15
|
+
position: ChartAxisPosition;
|
|
16
|
+
type?: ChartAxisType;
|
|
17
|
+
min?: number | string | Date;
|
|
18
|
+
max?: number | string | Date;
|
|
19
|
+
zero?: boolean;
|
|
20
|
+
nice?: boolean;
|
|
21
|
+
ticks?: number | Array<number | string | Date>;
|
|
22
|
+
format?: (value: any) => string;
|
|
23
|
+
grid: boolean;
|
|
24
|
+
title?: string;
|
|
25
|
+
hidden: boolean;
|
|
26
|
+
/** The room for tick labels down the side, in px, whatever they measure. */
|
|
27
|
+
labelWidth?: number;
|
|
28
|
+
/** Runs the other way: its scale's range is turned round. */
|
|
29
|
+
reverse?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** The axes by what they measure. */
|
|
32
|
+
export interface ChartAxes {
|
|
33
|
+
x: AxisConfig;
|
|
34
|
+
y: AxisConfig | null;
|
|
35
|
+
y2: AxisConfig | null;
|
|
36
|
+
}
|
|
37
|
+
export interface TickLabel {
|
|
38
|
+
text: string;
|
|
39
|
+
/** Where the label's box goes, in px from the chart's top left. */
|
|
40
|
+
left: number;
|
|
41
|
+
top: number;
|
|
42
|
+
width: number;
|
|
43
|
+
/** Whether the text is longer than `width` and is cut short with an ellipsis. */
|
|
44
|
+
clipped?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface AxisLayout {
|
|
47
|
+
/** Where the axis is drawn. */
|
|
48
|
+
position: ChartAxisPosition;
|
|
49
|
+
scale: Scale;
|
|
50
|
+
/** Tick values, as numbers on the scale. */
|
|
51
|
+
ticks: number[];
|
|
52
|
+
labels: TickLabel[];
|
|
53
|
+
grid: boolean;
|
|
54
|
+
title?: {
|
|
55
|
+
text: string;
|
|
56
|
+
left: number;
|
|
57
|
+
top: number;
|
|
58
|
+
align: 'start' | 'end';
|
|
59
|
+
};
|
|
60
|
+
/** The whole domain, when zoomed in to part of it (`scale.domain`). */
|
|
61
|
+
full: [number, number];
|
|
62
|
+
}
|
|
63
|
+
export interface ChartLayout {
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
plot: Rect;
|
|
67
|
+
x: AxisLayout;
|
|
68
|
+
/** The value axes, by what they measure. */
|
|
69
|
+
y: Partial<Record<ChartValueAxis, AxisLayout>>;
|
|
70
|
+
legend: LegendItem[];
|
|
71
|
+
/** The room the legend shows in; its entries scroll in it when they don't all fit. */
|
|
72
|
+
legendBox?: LegendBox;
|
|
73
|
+
/** Where the range strip goes: under the chart, or down its right side when horizontal. */
|
|
74
|
+
strip?: Rect;
|
|
75
|
+
}
|
|
76
|
+
/** Where a chart's legend goes. */
|
|
77
|
+
export type ChartLegendPlacement = 'top' | 'bottom' | 'right';
|
|
78
|
+
/** The room a legend shows in, in px from the chart's top left. */
|
|
79
|
+
export interface LegendBox extends Rect {
|
|
80
|
+
/** Its entries take more room than it has: they scroll in it. */
|
|
81
|
+
scroll: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** A legend entry, placed. */
|
|
84
|
+
export interface LegendItem {
|
|
85
|
+
/** The entry's position in the names given. */
|
|
86
|
+
index: number;
|
|
87
|
+
text: string;
|
|
88
|
+
left: number;
|
|
89
|
+
top: number;
|
|
90
|
+
width: number;
|
|
91
|
+
/** The name is longer than the room down the side, and is cut short. */
|
|
92
|
+
clipped?: boolean;
|
|
93
|
+
/** The swatch's width, when wider than a series' (a heatmap's scale). */
|
|
94
|
+
swatch?: number;
|
|
95
|
+
}
|
|
96
|
+
/** A legend entry's name, or its name and a wider swatch (a heatmap's scale). */
|
|
97
|
+
export type LegendName = string | {
|
|
98
|
+
text: string;
|
|
99
|
+
swatch: number;
|
|
100
|
+
};
|
|
101
|
+
/** Height of a line of tick text, and the room between it and the plot. */
|
|
102
|
+
export declare const LABEL_HEIGHT = 16;
|
|
103
|
+
export declare const LABEL_GAP = 8;
|
|
104
|
+
/** Room left around the plot so lines and dots at the edge aren't cut. */
|
|
105
|
+
export declare const EDGE = 8;
|
|
106
|
+
/** Room between text and the chart's sides. */
|
|
107
|
+
export declare const INSET = 4;
|
|
108
|
+
/** A heatmap's scale in the legend: wide enough to read from light to dark. */
|
|
109
|
+
export declare const HEAT_SWATCH = 40;
|
|
110
|
+
/** The range strip's height (its width when horizontal), and the room before it. */
|
|
111
|
+
export declare const STRIP = 32;
|
|
112
|
+
interface LayoutOptions {
|
|
113
|
+
model: ChartModel;
|
|
114
|
+
axes: ChartAxes;
|
|
115
|
+
/** x runs down the left side and values along the bottom (and the top). */
|
|
116
|
+
horizontal?: boolean;
|
|
117
|
+
width: number;
|
|
118
|
+
height: number;
|
|
119
|
+
locale: string;
|
|
120
|
+
measure: (text: string) => number;
|
|
121
|
+
/** Names for a legend, or none. */
|
|
122
|
+
legend?: LegendName[];
|
|
123
|
+
/** Rows of the legend far enough apart for a finger to press each (on a touch screen). */
|
|
124
|
+
coarse?: boolean;
|
|
125
|
+
/** Where the legend goes: under the chart (the default), above it, or down its right side. */
|
|
126
|
+
legendPlacement?: ChartLegendPlacement;
|
|
127
|
+
/**
|
|
128
|
+
* The stretches shown when zoomed in: of x in the scale's numbers
|
|
129
|
+
* (category indices, ms), of the values in those of `y` (or `y2` when
|
|
130
|
+
* it is alone; `y2` follows `y`).
|
|
131
|
+
*/
|
|
132
|
+
zoom?: {
|
|
133
|
+
x?: Window | null;
|
|
134
|
+
y?: Window | null;
|
|
135
|
+
};
|
|
136
|
+
/** Leave room for a range strip. */
|
|
137
|
+
strip?: boolean;
|
|
138
|
+
/** Room past the plot's end along x, in px, for labels at the ends of lines. */
|
|
139
|
+
trailing?: number;
|
|
140
|
+
}
|
|
141
|
+
/** Places the axes and works out the plot area, the scales and the tick labels. */
|
|
142
|
+
export declare function layoutChart(options: LayoutOptions): ChartLayout;
|
|
143
|
+
/**
|
|
144
|
+
* Places a legend's entries where it goes: in rows under or above the
|
|
145
|
+
* chart, or one under another down its right side. Gives the room it
|
|
146
|
+
* takes from the chart on each side, and the box it shows in: past three
|
|
147
|
+
* rows (or the chart's height, down the side), its entries scroll.
|
|
148
|
+
*/
|
|
149
|
+
export declare function placeLegendIn(names: LegendName[], at: ChartLegendPlacement, width: number, height: number, measure: (text: string) => number, coarse?: boolean): {
|
|
150
|
+
legend: LegendItem[];
|
|
151
|
+
box?: LegendBox;
|
|
152
|
+
room: {
|
|
153
|
+
top: number;
|
|
154
|
+
bottom: number;
|
|
155
|
+
right: number;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
/** Entries in rows that fit `width`, each row centered; `top` counts from the first row. */
|
|
159
|
+
export declare function placeLegend(names: LegendName[], width: number, measure: (text: string) => number, coarse?: boolean): LegendItem[];
|
|
160
|
+
export interface PieLayout {
|
|
161
|
+
width: number;
|
|
162
|
+
height: number;
|
|
163
|
+
/** The center and the outer radius, in px. */
|
|
164
|
+
cx: number;
|
|
165
|
+
cy: number;
|
|
166
|
+
radius: number;
|
|
167
|
+
/** The lowest the pie's labels may go: above the legend. */
|
|
168
|
+
bottom: number;
|
|
169
|
+
legend: LegendItem[];
|
|
170
|
+
legendBox?: LegendBox;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The box round the part of a circle of radius 1 from `start` to `end`
|
|
174
|
+
* (radians clockwise from 12 o'clock), its center included, in units of
|
|
175
|
+
* the radius from the center: a half circle is half as tall as a whole.
|
|
176
|
+
*/
|
|
177
|
+
export declare function arcBox(start: number, end: number): {
|
|
178
|
+
left: number;
|
|
179
|
+
right: number;
|
|
180
|
+
top: number;
|
|
181
|
+
bottom: number;
|
|
182
|
+
};
|
|
183
|
+
/** Room from a pie's edge to the labels outside it: the line out, and the gap before the text. */
|
|
184
|
+
export declare const PIE_LABEL_ROOM = 24;
|
|
185
|
+
/**
|
|
186
|
+
* A pie as large as fits above its legend; with labels outside, as large
|
|
187
|
+
* as leaves room for the widest of them on each side, moved over towards
|
|
188
|
+
* the side with the narrower labels.
|
|
189
|
+
*/
|
|
190
|
+
export declare function layoutPie({ width, height, measure, legend: names, coarse, legendPlacement, sideLabels, arc, }: Pick<LayoutOptions, 'width' | 'height' | 'measure' | 'legend' | 'coarse' | 'legendPlacement'> & {
|
|
191
|
+
/** The widest label outside the pie on each side, in px; 0 for none. */
|
|
192
|
+
sideLabels?: {
|
|
193
|
+
left: number;
|
|
194
|
+
right: number;
|
|
195
|
+
};
|
|
196
|
+
/** The part of the turn the pie takes (a half donut's), in radians from 12 o'clock. */
|
|
197
|
+
arc?: [number, number];
|
|
198
|
+
}): PieLayout;
|
|
199
|
+
/** A radar laid out: its center and radius, its rings and the names round it. */
|
|
200
|
+
export interface RadarLayout {
|
|
201
|
+
width: number;
|
|
202
|
+
height: number;
|
|
203
|
+
cx: number;
|
|
204
|
+
cy: number;
|
|
205
|
+
radius: number;
|
|
206
|
+
/** How many spokes: one per category. */
|
|
207
|
+
count: number;
|
|
208
|
+
/** From a value to its distance from the center, in px. */
|
|
209
|
+
scale: Scale;
|
|
210
|
+
/** The values of the rings. */
|
|
211
|
+
ticks: number[];
|
|
212
|
+
/** The spokes' names round the rim. */
|
|
213
|
+
labels: TickLabel[];
|
|
214
|
+
/** The rings' values, between the first two spokes. */
|
|
215
|
+
values: TickLabel[];
|
|
216
|
+
legend: LegendItem[];
|
|
217
|
+
legendBox?: LegendBox;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Lays out a radar: the legend first, then the largest circle that leaves
|
|
221
|
+
* room round it for the spokes' names (the categories), with rings at
|
|
222
|
+
* nice values from the center (0, or the smallest value below it) out.
|
|
223
|
+
*/
|
|
224
|
+
export declare function layoutRadar({ model, axes, width, height, locale, measure, legend: names, coarse, legendPlacement, spokes, }: Omit<LayoutOptions, 'horizontal' | 'zoom' | 'strip' | 'trailing'> & {
|
|
225
|
+
/** The spokes' names, in order from 12 o'clock. */
|
|
226
|
+
spokes: string[];
|
|
227
|
+
}): RadarLayout;
|
|
228
|
+
/** A funnel laid out: where its stages go, and their names and values beside them. */
|
|
229
|
+
export interface FunnelLayout {
|
|
230
|
+
width: number;
|
|
231
|
+
height: number;
|
|
232
|
+
/** Where the bars go: the widest takes its whole width. */
|
|
233
|
+
plot: Rect;
|
|
234
|
+
/** How many stages, and the height of each one's row. */
|
|
235
|
+
count: number;
|
|
236
|
+
step: number;
|
|
237
|
+
/** From a value to half its bar's width, in px. */
|
|
238
|
+
scale: Scale;
|
|
239
|
+
/** The stages' names, on the left. */
|
|
240
|
+
names: TickLabel[];
|
|
241
|
+
/** Their values, on the right, and the share each kept of the one before it. */
|
|
242
|
+
values: TickLabel[];
|
|
243
|
+
rates: TickLabel[];
|
|
244
|
+
legend: LegendItem[];
|
|
245
|
+
legendBox?: LegendBox;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Lays out a funnel: the legend, then the names in a column on the left
|
|
249
|
+
* and the values (with rates) on the right, and the bars between them.
|
|
250
|
+
*/
|
|
251
|
+
export declare function layoutFunnel({ width, height, measure, legend: names, coarse, legendPlacement, stages, values: written, rates: rateTexts, max, }: Pick<LayoutOptions, 'width' | 'height' | 'measure' | 'legend' | 'coarse' | 'legendPlacement'> & {
|
|
252
|
+
stages: string[];
|
|
253
|
+
values: string[];
|
|
254
|
+
/** The share each stage kept of the one before, written; `null` for the first. */
|
|
255
|
+
rates: Array<string | null>;
|
|
256
|
+
/** The largest value: its bar is the widest. */
|
|
257
|
+
max: number;
|
|
258
|
+
}): FunnelLayout;
|
|
259
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Painter } from './painter';
|
|
2
|
+
import type { ChartLabelAnchor, ChartSeries, ChartSeriesKind, ChartView } from './series';
|
|
3
|
+
export interface LineStyle {
|
|
4
|
+
smooth?: boolean;
|
|
5
|
+
dots?: boolean | 'auto';
|
|
6
|
+
dashed?: boolean;
|
|
7
|
+
lineWidth?: number;
|
|
8
|
+
connectNulls?: boolean;
|
|
9
|
+
step?: boolean | 'before' | 'after' | 'middle';
|
|
10
|
+
labelPosition?: 'point' | 'end';
|
|
11
|
+
/** An area's bottom of its own (a band); the model reads it into `base`. */
|
|
12
|
+
y0?: unknown;
|
|
13
|
+
}
|
|
14
|
+
type StepMode = 'before' | 'after' | 'middle';
|
|
15
|
+
/**
|
|
16
|
+
* The corners of a line that steps through `count` points: `after` holds
|
|
17
|
+
* each value until the next x, `before` takes the next value at once,
|
|
18
|
+
* `middle` changes halfway. Gives the corners' x, the values (`ys`, and
|
|
19
|
+
* `bs` for an area's bottom, stepped the same way) and how many there are.
|
|
20
|
+
*/
|
|
21
|
+
export declare function stepPoints(px: ArrayLike<number>, ys: ArrayLike<number>, bs: ArrayLike<number>, count: number, mode: StepMode): {
|
|
22
|
+
x: Float64Array;
|
|
23
|
+
y: Float64Array;
|
|
24
|
+
b: Float64Array;
|
|
25
|
+
count: number;
|
|
26
|
+
};
|
|
27
|
+
/** Draws a line, and with `area` the area under it (or under its slice of a stack). */
|
|
28
|
+
export declare function drawLine(painter: Painter, series: ChartSeries<LineStyle>, view: ChartView, area: boolean): void;
|
|
29
|
+
/**
|
|
30
|
+
* Where a line's labels go: above each point when there is room for them
|
|
31
|
+
* all, or beside the last point shown (`end`).
|
|
32
|
+
*/
|
|
33
|
+
export declare function lineLabels(series: ChartSeries<LineStyle>, view: ChartView): ChartLabelAnchor[];
|
|
34
|
+
export declare const lineKind: ChartSeriesKind<LineStyle>;
|
|
35
|
+
export declare const areaKind: ChartSeriesKind<LineStyle>;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Tone } from 'dou-ui';
|
|
2
|
+
import { type Painter, type Rect } from './painter';
|
|
3
|
+
import type { Scale } from './scale';
|
|
4
|
+
import type { ChartValueAxis } from './series';
|
|
5
|
+
/** A marker as the chart reads it: x already as a number on the x scale. */
|
|
6
|
+
export interface MarkerInput {
|
|
7
|
+
/** One x, or the two ends of a band of x; `null` when not given. */
|
|
8
|
+
x: [number, number] | number | null;
|
|
9
|
+
y: [number, number] | number | null;
|
|
10
|
+
/** The value axis `y` is on. */
|
|
11
|
+
axis: ChartValueAxis;
|
|
12
|
+
label?: string;
|
|
13
|
+
tone: Tone;
|
|
14
|
+
solid: boolean;
|
|
15
|
+
}
|
|
16
|
+
export type MarkerShape =
|
|
17
|
+
/** A line down the chart (`vertical`) or across it, at `at`, from `from` to `to`. */
|
|
18
|
+
{
|
|
19
|
+
kind: 'line';
|
|
20
|
+
vertical: boolean;
|
|
21
|
+
at: number;
|
|
22
|
+
from: number;
|
|
23
|
+
to: number;
|
|
24
|
+
} | ({
|
|
25
|
+
kind: 'area';
|
|
26
|
+
} & Rect) | {
|
|
27
|
+
kind: 'point';
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
};
|
|
31
|
+
export interface MarkerLabel {
|
|
32
|
+
text: string;
|
|
33
|
+
left: number;
|
|
34
|
+
top: number;
|
|
35
|
+
/** Which end of the text `left` is: its start, its middle or its end. */
|
|
36
|
+
align: 'start' | 'middle' | 'end';
|
|
37
|
+
}
|
|
38
|
+
export interface PlacedMarker {
|
|
39
|
+
shape: MarkerShape;
|
|
40
|
+
tone: Tone;
|
|
41
|
+
solid: boolean;
|
|
42
|
+
label: MarkerLabel | null;
|
|
43
|
+
}
|
|
44
|
+
/** A point's dot. */
|
|
45
|
+
export declare const MARKER_DOT = 4;
|
|
46
|
+
interface PlaceOptions {
|
|
47
|
+
plot: Rect;
|
|
48
|
+
/** The x scale; with `horizontal`, it runs down the left side. */
|
|
49
|
+
x: Scale;
|
|
50
|
+
/** A value axis' scale; `null` when the chart has no such axis. */
|
|
51
|
+
y: (axis: ChartValueAxis) => Scale | null;
|
|
52
|
+
horizontal: boolean;
|
|
53
|
+
measure: (text: string) => number;
|
|
54
|
+
}
|
|
55
|
+
/** Where each marker is drawn, and its label; markers wholly off the plot are left out. */
|
|
56
|
+
export declare function placeMarkers(markers: MarkerInput[], options: PlaceOptions): PlacedMarker[];
|
|
57
|
+
export interface MarkerColors {
|
|
58
|
+
line: string;
|
|
59
|
+
/** A point's dot: the line's color, solid. */
|
|
60
|
+
dot: string;
|
|
61
|
+
/** A band. */
|
|
62
|
+
fill: string;
|
|
63
|
+
surface: string;
|
|
64
|
+
}
|
|
65
|
+
/** Draws the bands (`under` the series) or the lines and points (over them). */
|
|
66
|
+
export declare function drawMarkers(painter: Painter, markers: PlacedMarker[], colors: (tone: Tone) => MarkerColors, dpr: number, under: boolean): void;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type ChartAccessor, type ChartData, type XColumn, type XKind } from './data';
|
|
2
|
+
import type { ChartSeriesKind, ChartSeriesProps, ChartValueAxis } from './series';
|
|
3
|
+
/** A series as registered by its component. */
|
|
4
|
+
export interface SeriesInput {
|
|
5
|
+
index: number;
|
|
6
|
+
kind: ChartSeriesKind<any>;
|
|
7
|
+
props: ChartSeriesProps & {
|
|
8
|
+
stack?: string | boolean;
|
|
9
|
+
/** An area's bottom of its own: a band from it up to `y`. */
|
|
10
|
+
y0?: ChartAccessor;
|
|
11
|
+
/** A heatmap's value of each cell (its `y` names the row's category). */
|
|
12
|
+
value?: ChartAccessor;
|
|
13
|
+
} & Record<string, unknown>;
|
|
14
|
+
/** Turned off (in the legend): left out of the axes and not drawn. */
|
|
15
|
+
hidden?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** What a series is called: its `name`, else its `y` key, else its place. */
|
|
18
|
+
export declare function seriesName(input: Pick<SeriesInput, 'index' | 'props'>): string;
|
|
19
|
+
/** A series with its data read, before colors are worked out. */
|
|
20
|
+
export interface ModelSeries {
|
|
21
|
+
input: SeriesInput;
|
|
22
|
+
name: string;
|
|
23
|
+
rows: ChartData;
|
|
24
|
+
axis: ChartValueAxis;
|
|
25
|
+
x: XColumn;
|
|
26
|
+
y: Float64Array;
|
|
27
|
+
top: Float64Array;
|
|
28
|
+
base: Float64Array | null;
|
|
29
|
+
stackEnds: {
|
|
30
|
+
up: Float64Array;
|
|
31
|
+
down: Float64Array;
|
|
32
|
+
} | null;
|
|
33
|
+
slot: {
|
|
34
|
+
index: number;
|
|
35
|
+
count: number;
|
|
36
|
+
} | null;
|
|
37
|
+
/** A heatmap's categories down the value axis, as read. */
|
|
38
|
+
yColumn?: XColumn;
|
|
39
|
+
}
|
|
40
|
+
export interface ChartModel {
|
|
41
|
+
series: ModelSeries[];
|
|
42
|
+
xKind: XKind;
|
|
43
|
+
categories: string[];
|
|
44
|
+
/** The smallest and largest x (for `category`: the first and last category index). */
|
|
45
|
+
x: [number, number] | null;
|
|
46
|
+
/** The smallest and largest value on each y axis, with 0 when a series grows from it. */
|
|
47
|
+
y: Record<ChartValueAxis, [number, number] | null>;
|
|
48
|
+
/** Whether each y axis must reach 0. */
|
|
49
|
+
zero: Record<ChartValueAxis, boolean>;
|
|
50
|
+
/** The categories of value axes that list them (a heatmap's rows), first at the top; `null` for number axes. */
|
|
51
|
+
yCategories: Record<ChartValueAxis, string[] | null>;
|
|
52
|
+
/** Whether every x is a whole number (years, counts): the x axis then has no ticks in between. */
|
|
53
|
+
xIntegers: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* For series that take a band of each x (bars) on a number or time axis:
|
|
56
|
+
* the smallest distance between two x values, which is one band. `NaN`
|
|
57
|
+
* when there is no such series or no two values.
|
|
58
|
+
*/
|
|
59
|
+
xStep: number;
|
|
60
|
+
/** The most room any series needs around its points, in px (bubbles). */
|
|
61
|
+
inset: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reads the data of every shown series into columns, lines up categories
|
|
65
|
+
* shared by series with their own data, stacks what stacks, and finds the
|
|
66
|
+
* range of each axis.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildModel(inputs: SeriesInput[], chart: {
|
|
69
|
+
data: ChartData;
|
|
70
|
+
x?: ChartAccessor;
|
|
71
|
+
xKind?: XKind;
|
|
72
|
+
/** The y axis of series that don't name one. */
|
|
73
|
+
axis?: ChartValueAxis;
|
|
74
|
+
/** Value axes whose stacks show each part's share of the whole (0 to 1). */
|
|
75
|
+
percent?: Partial<Record<ChartValueAxis, boolean>>;
|
|
76
|
+
/**
|
|
77
|
+
* The order of the categories along x: by their totals (the sum of the
|
|
78
|
+
* shown series' values), or as a function of two category names orders
|
|
79
|
+
* them. As they come in the data when not given.
|
|
80
|
+
*/
|
|
81
|
+
sort?: ChartCategorySort;
|
|
82
|
+
}): ChartModel;
|
|
83
|
+
/** How categories along x are ordered: by their totals, or by a comparison of their names. */
|
|
84
|
+
export type ChartCategorySort = 'asc' | 'desc' | ((a: string, b: string) => number);
|
|
85
|
+
/** The smallest distance between two different values, or `NaN` with fewer than two. */
|
|
86
|
+
export declare function smallestGap(values: Float64Array): number;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What drawing code may use of a 2D context. Series draw only through
|
|
3
|
+
* this, so the same code can later draw into something other than a
|
|
4
|
+
* canvas (an SVG for export) and look the same.
|
|
5
|
+
*/
|
|
6
|
+
export type Painter = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'beginPath' | 'closePath' | 'moveTo' | 'lineTo' | 'bezierCurveTo' | 'rect' | 'arc' | 'arcTo' | 'fill' | 'stroke' | 'clip' | 'setLineDash' | 'drawImage' | 'fillStyle' | 'strokeStyle' | 'lineWidth' | 'lineJoin' | 'lineCap' | 'globalAlpha'>;
|
|
7
|
+
/** A rectangle in CSS px. */
|
|
8
|
+
export interface Rect {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Moves a coordinate onto the pixel grid so a line `width` CSS px wide
|
|
16
|
+
* covers whole device pixels and stays sharp.
|
|
17
|
+
*/
|
|
18
|
+
export declare function crisp(value: number, dpr: number, width?: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Traces a line through the points `px[i], py[i]` into the current path.
|
|
21
|
+
* With `smooth`, a monotone curve: it bends through every point without
|
|
22
|
+
* swinging above or below a neighbor, so a peak in the curve is a peak in
|
|
23
|
+
* the data. `reverse` traces from the last point back to the first (the
|
|
24
|
+
* lower edge of an area); the curve is the same either way. With `swap`,
|
|
25
|
+
* `px` are tops and `py` lefts: the line runs down (a horizontal chart).
|
|
26
|
+
*/
|
|
27
|
+
export declare function tracePoints(painter: Painter, px: ArrayLike<number>, py: ArrayLike<number>, count: number, { smooth, reverse, join, swap }?: {
|
|
28
|
+
smooth?: boolean | undefined;
|
|
29
|
+
reverse?: boolean | undefined;
|
|
30
|
+
join?: boolean | undefined;
|
|
31
|
+
swap?: boolean | undefined;
|
|
32
|
+
}): void;
|
|
33
|
+
/** Slopes at each point that keep a cubic curve monotone between points (Fritsch–Carlson). */
|
|
34
|
+
export declare function monotoneTangents(px: ArrayLike<number>, py: ArrayLike<number>, count: number): Float64Array;
|