minerva-design 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +21 -19
- package/dist/charts/core.cjs +1 -0
- package/dist/charts/core.d.cts +3 -0
- package/dist/charts/core.d.ts +3 -0
- package/dist/charts/core.js +3 -0
- package/dist/charts/engine/axis.cjs +2 -0
- package/dist/charts/engine/axis.cjs.map +1 -0
- package/dist/charts/engine/axis.d.cts +13 -0
- package/dist/charts/engine/axis.d.ts +13 -0
- package/dist/charts/engine/axis.js +38 -0
- package/dist/charts/engine/axis.js.map +1 -0
- package/dist/charts/engine/chart.cjs +3 -0
- package/dist/charts/engine/chart.cjs.map +1 -0
- package/dist/charts/engine/chart.d.cts +6 -0
- package/dist/charts/engine/chart.d.ts +6 -0
- package/dist/charts/engine/chart.js +624 -0
- package/dist/charts/engine/chart.js.map +1 -0
- package/dist/charts/engine/color.cjs +2 -0
- package/dist/charts/engine/color.cjs.map +1 -0
- package/dist/charts/engine/color.d.cts +23 -0
- package/dist/charts/engine/color.d.ts +23 -0
- package/dist/charts/engine/color.js +95 -0
- package/dist/charts/engine/color.js.map +1 -0
- package/dist/charts/engine/data.cjs +2 -0
- package/dist/charts/engine/data.cjs.map +1 -0
- package/dist/charts/engine/data.d.cts +29 -0
- package/dist/charts/engine/data.d.ts +29 -0
- package/dist/charts/engine/data.js +104 -0
- package/dist/charts/engine/data.js.map +1 -0
- package/dist/charts/engine/decimate.cjs +2 -0
- package/dist/charts/engine/decimate.cjs.map +1 -0
- package/dist/charts/engine/decimate.d.cts +13 -0
- package/dist/charts/engine/decimate.d.ts +13 -0
- package/dist/charts/engine/decimate.js +28 -0
- package/dist/charts/engine/decimate.js.map +1 -0
- package/dist/charts/engine/dom.cjs +2 -0
- package/dist/charts/engine/dom.cjs.map +1 -0
- package/dist/charts/engine/dom.d.cts +21 -0
- package/dist/charts/engine/dom.d.ts +21 -0
- package/dist/charts/engine/dom.js +125 -0
- package/dist/charts/engine/dom.js.map +1 -0
- package/dist/charts/engine/format.cjs +2 -0
- package/dist/charts/engine/format.cjs.map +1 -0
- package/dist/charts/engine/format.d.cts +9 -0
- package/dist/charts/engine/format.d.ts +9 -0
- package/dist/charts/engine/format.js +34 -0
- package/dist/charts/engine/format.js.map +1 -0
- package/dist/charts/engine/items.cjs +2 -0
- package/dist/charts/engine/items.cjs.map +1 -0
- package/dist/charts/engine/items.d.cts +8 -0
- package/dist/charts/engine/items.d.ts +8 -0
- package/dist/charts/engine/items.js +91 -0
- package/dist/charts/engine/items.js.map +1 -0
- package/dist/charts/engine/layout.cjs +2 -0
- package/dist/charts/engine/layout.cjs.map +1 -0
- package/dist/charts/engine/layout.d.cts +37 -0
- package/dist/charts/engine/layout.d.ts +37 -0
- package/dist/charts/engine/layout.js +26 -0
- package/dist/charts/engine/layout.js.map +1 -0
- package/dist/charts/engine/model.cjs +2 -0
- package/dist/charts/engine/model.cjs.map +1 -0
- package/dist/charts/engine/model.d.cts +74 -0
- package/dist/charts/engine/model.d.ts +74 -0
- package/dist/charts/engine/model.js +175 -0
- package/dist/charts/engine/model.js.map +1 -0
- package/dist/charts/engine/overlay.cjs +2 -0
- package/dist/charts/engine/overlay.cjs.map +1 -0
- package/dist/charts/engine/overlay.d.cts +62 -0
- package/dist/charts/engine/overlay.d.ts +62 -0
- package/dist/charts/engine/overlay.js +123 -0
- package/dist/charts/engine/overlay.js.map +1 -0
- package/dist/charts/engine/renderers/canvas2d.cjs +2 -0
- package/dist/charts/engine/renderers/canvas2d.cjs.map +1 -0
- package/dist/charts/engine/renderers/canvas2d.d.cts +4 -0
- package/dist/charts/engine/renderers/canvas2d.d.ts +4 -0
- package/dist/charts/engine/renderers/canvas2d.js +156 -0
- package/dist/charts/engine/renderers/canvas2d.js.map +1 -0
- package/dist/charts/engine/renderers/detect.cjs +2 -0
- package/dist/charts/engine/renderers/detect.cjs.map +1 -0
- package/dist/charts/engine/renderers/detect.d.cts +12 -0
- package/dist/charts/engine/renderers/detect.d.ts +12 -0
- package/dist/charts/engine/renderers/detect.js +33 -0
- package/dist/charts/engine/renderers/detect.js.map +1 -0
- package/dist/charts/engine/renderers/range.cjs +2 -0
- package/dist/charts/engine/renderers/range.cjs.map +1 -0
- package/dist/charts/engine/renderers/range.d.cts +5 -0
- package/dist/charts/engine/renderers/range.d.ts +5 -0
- package/dist/charts/engine/renderers/range.js +32 -0
- package/dist/charts/engine/renderers/range.js.map +1 -0
- package/dist/charts/engine/renderers/shaders.cjs +266 -0
- package/dist/charts/engine/renderers/shaders.cjs.map +1 -0
- package/dist/charts/engine/renderers/shaders.d.cts +20 -0
- package/dist/charts/engine/renderers/shaders.d.ts +20 -0
- package/dist/charts/engine/renderers/shaders.js +251 -0
- package/dist/charts/engine/renderers/shaders.js.map +1 -0
- package/dist/charts/engine/renderers/types.cjs +2 -0
- package/dist/charts/engine/renderers/types.cjs.map +1 -0
- package/dist/charts/engine/renderers/types.d.cts +83 -0
- package/dist/charts/engine/renderers/types.d.ts +83 -0
- package/dist/charts/engine/renderers/types.js +6 -0
- package/dist/charts/engine/renderers/types.js.map +1 -0
- package/dist/charts/engine/renderers/webgl2.cjs +2 -0
- package/dist/charts/engine/renderers/webgl2.cjs.map +1 -0
- package/dist/charts/engine/renderers/webgl2.d.cts +5 -0
- package/dist/charts/engine/renderers/webgl2.d.ts +5 -0
- package/dist/charts/engine/renderers/webgl2.js +134 -0
- package/dist/charts/engine/renderers/webgl2.js.map +1 -0
- package/dist/charts/engine/renderers/webgpu.cjs +2 -0
- package/dist/charts/engine/renderers/webgpu.cjs.map +1 -0
- package/dist/charts/engine/renderers/webgpu.d.cts +6 -0
- package/dist/charts/engine/renderers/webgpu.d.ts +6 -0
- package/dist/charts/engine/renderers/webgpu.js +220 -0
- package/dist/charts/engine/renderers/webgpu.js.map +1 -0
- package/dist/charts/engine/scale.cjs +2 -0
- package/dist/charts/engine/scale.cjs.map +1 -0
- package/dist/charts/engine/scale.d.cts +13 -0
- package/dist/charts/engine/scale.d.ts +13 -0
- package/dist/charts/engine/scale.js +37 -0
- package/dist/charts/engine/scale.js.map +1 -0
- package/dist/charts/engine/spatial.cjs +2 -0
- package/dist/charts/engine/spatial.cjs.map +1 -0
- package/dist/charts/engine/spatial.d.cts +18 -0
- package/dist/charts/engine/spatial.d.ts +18 -0
- package/dist/charts/engine/spatial.js +53 -0
- package/dist/charts/engine/spatial.js.map +1 -0
- package/dist/charts/engine/theme.cjs +2 -0
- package/dist/charts/engine/theme.cjs.map +1 -0
- package/dist/charts/engine/theme.d.cts +21 -0
- package/dist/charts/engine/theme.d.ts +21 -0
- package/dist/charts/engine/theme.js +70 -0
- package/dist/charts/engine/theme.js.map +1 -0
- package/dist/charts/engine/time.cjs +2 -0
- package/dist/charts/engine/time.cjs.map +1 -0
- package/dist/charts/engine/time.d.cts +10 -0
- package/dist/charts/engine/time.d.ts +10 -0
- package/dist/charts/engine/time.js +189 -0
- package/dist/charts/engine/time.js.map +1 -0
- package/dist/charts/engine/types.d.cts +289 -0
- package/dist/charts/engine/types.d.ts +289 -0
- package/dist/charts/engine/viewport.cjs +2 -0
- package/dist/charts/engine/viewport.cjs.map +1 -0
- package/dist/charts/engine/viewport.d.cts +12 -0
- package/dist/charts/engine/viewport.d.ts +12 -0
- package/dist/charts/engine/viewport.js +15 -0
- package/dist/charts/engine/viewport.js.map +1 -0
- package/dist/charts/index.cjs +1 -0
- package/dist/charts/index.d.cts +4 -0
- package/dist/charts/index.d.ts +4 -0
- package/dist/charts/index.js +7 -0
- package/dist/charts/react/Chart.cjs +2 -0
- package/dist/charts/react/Chart.cjs.map +1 -0
- package/dist/charts/react/Chart.d.cts +28 -0
- package/dist/charts/react/Chart.d.ts +28 -0
- package/dist/charts/react/Chart.js +75 -0
- package/dist/charts/react/Chart.js.map +1 -0
- package/dist/charts/react/charts.cjs +2 -0
- package/dist/charts/react/charts.cjs.map +1 -0
- package/dist/charts/react/charts.d.cts +13 -0
- package/dist/charts/react/charts.d.ts +13 -0
- package/dist/charts/react/charts.js +179 -0
- package/dist/charts/react/charts.js.map +1 -0
- package/dist/charts/react/types.d.cts +168 -0
- package/dist/charts/react/types.d.ts +168 -0
- package/package.json +28 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Rgba } from './color.js';
|
|
2
|
+
import { AxisTicks } from './axis.js';
|
|
3
|
+
import { Rect, Scales } from './layout.js';
|
|
4
|
+
import { AxisModel } from './model.js';
|
|
5
|
+
import { ChartTheme } from './theme.js';
|
|
6
|
+
import { ChartLabelPosition } from './types.js';
|
|
7
|
+
export interface ResolvedRect {
|
|
8
|
+
type: "rect";
|
|
9
|
+
x0?: number;
|
|
10
|
+
x1?: number;
|
|
11
|
+
y0?: number;
|
|
12
|
+
y1?: number;
|
|
13
|
+
color: Rgba;
|
|
14
|
+
opacity: number;
|
|
15
|
+
label?: string;
|
|
16
|
+
labelPosition: ChartLabelPosition;
|
|
17
|
+
labelColor: Rgba;
|
|
18
|
+
}
|
|
19
|
+
export interface ResolvedLine {
|
|
20
|
+
type: "line";
|
|
21
|
+
axis: "x" | "y";
|
|
22
|
+
value: number;
|
|
23
|
+
color: Rgba;
|
|
24
|
+
width: number;
|
|
25
|
+
dash: number[];
|
|
26
|
+
label?: string;
|
|
27
|
+
}
|
|
28
|
+
export type ResolvedAnnotation = ResolvedRect | ResolvedLine;
|
|
29
|
+
export interface PointLabel {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
/** Radius of the dot */
|
|
33
|
+
r: number;
|
|
34
|
+
text: string;
|
|
35
|
+
}
|
|
36
|
+
export declare const font: (theme: ChartTheme, size?: number, weight?: number) => string;
|
|
37
|
+
export interface BackgroundInput {
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
scales: Scales;
|
|
41
|
+
x: AxisModel;
|
|
42
|
+
y: AxisModel;
|
|
43
|
+
xTicks: AxisTicks;
|
|
44
|
+
yTicks: AxisTicks;
|
|
45
|
+
theme: ChartTheme;
|
|
46
|
+
annotations: readonly ResolvedAnnotation[];
|
|
47
|
+
}
|
|
48
|
+
export declare const drawBackground: (ctx: CanvasRenderingContext2D, input: BackgroundInput) => void;
|
|
49
|
+
/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */
|
|
50
|
+
export declare const placeLabels: (labels: readonly PointLabel[], plot: Rect, measure: (text: string) => number, height: number, occupied?: Rect[]) => {
|
|
51
|
+
label: PointLabel;
|
|
52
|
+
box: Rect;
|
|
53
|
+
}[];
|
|
54
|
+
export interface ForegroundInput {
|
|
55
|
+
width: number;
|
|
56
|
+
height: number;
|
|
57
|
+
scales: Scales;
|
|
58
|
+
theme: ChartTheme;
|
|
59
|
+
annotations: readonly ResolvedAnnotation[];
|
|
60
|
+
pointLabels: readonly PointLabel[];
|
|
61
|
+
}
|
|
62
|
+
export declare const drawForeground: (ctx: CanvasRenderingContext2D, input: ForegroundInput) => void;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { toCss as e } from "./color.js";
|
|
2
|
+
//#region src/engine/overlay.ts
|
|
3
|
+
var t = (e, t = e.fontSize, n = 400) => `${n} ${t}px ${e.fontFamily}`, n = (e) => Math.round(e) + .5, r = (e, t) => {
|
|
4
|
+
let { plot: n } = t, r = e.x0 === void 0 ? -Infinity : t.xToPx(e.x0), i = e.x1 === void 0 ? Infinity : t.xToPx(e.x1), a = e.y0 === void 0 ? Infinity : t.yToPx(e.y0), o = e.y1 === void 0 ? -Infinity : t.yToPx(e.y1), s = Math.max(n.x, Math.min(r, i)), c = Math.min(n.x + n.width, Math.max(r, i)), l = Math.max(n.y, Math.min(a, o)), u = Math.min(n.y + n.height, Math.max(a, o));
|
|
5
|
+
return {
|
|
6
|
+
x: s,
|
|
7
|
+
y: l,
|
|
8
|
+
width: c - s,
|
|
9
|
+
height: u - l
|
|
10
|
+
};
|
|
11
|
+
}, i = (i, a) => {
|
|
12
|
+
let { scales: o, theme: s, x: c, y: l, xTicks: u, yTicks: d } = a, { plot: f } = o;
|
|
13
|
+
i.clearRect(0, 0, a.width, a.height), i.save(), i.beginPath(), i.rect(f.x, f.y, f.width, f.height), i.clip();
|
|
14
|
+
for (let t of a.annotations) {
|
|
15
|
+
if (t.type !== "rect") continue;
|
|
16
|
+
let n = r(t, o);
|
|
17
|
+
n.width <= 0 || n.height <= 0 || (i.fillStyle = e(t.color, t.opacity), i.fillRect(n.x, n.y, n.width, n.height));
|
|
18
|
+
}
|
|
19
|
+
if (i.restore(), i.lineWidth = 1, i.strokeStyle = e(s.grid), i.beginPath(), l.grid) for (let e of d.values) {
|
|
20
|
+
let t = n(o.yToPx(e));
|
|
21
|
+
t < f.y - 1 || t > f.y + f.height + 1 || (i.moveTo(f.x, t), i.lineTo(f.x + f.width, t));
|
|
22
|
+
}
|
|
23
|
+
if (c.grid) for (let e of u.values) {
|
|
24
|
+
let t = n(o.xToPx(e));
|
|
25
|
+
t < f.x - 1 || t > f.x + f.width + 1 || (i.moveTo(t, f.y), i.lineTo(t, f.y + f.height));
|
|
26
|
+
}
|
|
27
|
+
i.stroke();
|
|
28
|
+
let p = Math.ceil(s.fontSize * 1.4);
|
|
29
|
+
if (i.font = t(s), i.fillStyle = e(s.textMuted), c.visible) {
|
|
30
|
+
i.strokeStyle = e(s.axis), i.beginPath();
|
|
31
|
+
let r = n(f.y + f.height);
|
|
32
|
+
i.moveTo(f.x, r), i.lineTo(f.x + f.width, r), i.stroke(), i.textBaseline = "top", i.textAlign = "center";
|
|
33
|
+
let l = -Infinity, d = u.values.map((e, t) => ({
|
|
34
|
+
px: o.xToPx(e),
|
|
35
|
+
text: u.labels[t]
|
|
36
|
+
})).sort((e, t) => e.px - t.px);
|
|
37
|
+
for (let { px: e, text: t } of d) {
|
|
38
|
+
if (e < f.x - .5 || e > f.x + f.width + .5) continue;
|
|
39
|
+
let n = i.measureText(t).width, r = Math.max(0, Math.min(a.width - n, e - n / 2));
|
|
40
|
+
r < l + 6 || (l = r + n, i.fillText(t, r + n / 2, f.y + f.height + 7));
|
|
41
|
+
}
|
|
42
|
+
c.title && (i.font = t(s, s.fontSize + 1, 500), i.fillStyle = e(s.text, .8), i.fillText(c.title, f.x + f.width / 2, f.y + f.height + p + 10));
|
|
43
|
+
}
|
|
44
|
+
l.visible && (i.font = t(s), i.fillStyle = e(s.textMuted), i.textAlign = "right", i.textBaseline = "middle", d.values.forEach((e, t) => {
|
|
45
|
+
let n = o.yToPx(e);
|
|
46
|
+
n < f.y - .5 || n > f.y + f.height + .5 || i.fillText(d.labels[t], f.x - 8, n);
|
|
47
|
+
}), l.title && (i.save(), i.font = t(s, s.fontSize + 1, 500), i.fillStyle = e(s.text, .8), i.translate(p / 2 + 4, f.y + f.height / 2), i.rotate(-Math.PI / 2), i.textAlign = "center", i.fillText(l.title, 0, 0), i.restore()));
|
|
48
|
+
}, a = (e, t) => e.x < t.x + t.width && t.x < e.x + e.width && e.y < t.y + t.height && t.y < e.y + e.height, o = (e, t) => e.x >= t.x && e.y >= t.y && e.x + e.width <= t.x + t.width && e.y + e.height <= t.y + t.height, s = (e, t, n, r, i, a) => {
|
|
49
|
+
e.lineWidth = 3, e.lineJoin = "round", e.strokeStyle = a, e.strokeText(t, n, r), e.fillStyle = i, e.fillText(t, n, r);
|
|
50
|
+
}, c = (e, t, n, r, i = []) => {
|
|
51
|
+
let s = [];
|
|
52
|
+
for (let c of e) {
|
|
53
|
+
let e = n(c.text), l = c.r + 4, u = [
|
|
54
|
+
{
|
|
55
|
+
x: c.x + l,
|
|
56
|
+
y: c.y - r / 2,
|
|
57
|
+
width: e,
|
|
58
|
+
height: r
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
x: c.x - l - e,
|
|
62
|
+
y: c.y - r / 2,
|
|
63
|
+
width: e,
|
|
64
|
+
height: r
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
x: c.x - e / 2,
|
|
68
|
+
y: c.y - l - r,
|
|
69
|
+
width: e,
|
|
70
|
+
height: r
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
x: c.x - e / 2,
|
|
74
|
+
y: c.y + l,
|
|
75
|
+
width: e,
|
|
76
|
+
height: r
|
|
77
|
+
}
|
|
78
|
+
].find((e) => o(e, t) && !i.some((t) => a(t, e)));
|
|
79
|
+
u && (i.push(u), s.push({
|
|
80
|
+
label: c,
|
|
81
|
+
box: u
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
return s;
|
|
85
|
+
}, l = (i, a) => {
|
|
86
|
+
let { scales: o, theme: l } = a, { plot: u } = o;
|
|
87
|
+
i.clearRect(0, 0, a.width, a.height), i.save(), i.beginPath(), i.rect(u.x, u.y, u.width, u.height), i.clip();
|
|
88
|
+
let d = e(l.background, .9), f = [], p = l.fontSize + 4;
|
|
89
|
+
for (let r of a.annotations) {
|
|
90
|
+
if (r.type !== "line") continue;
|
|
91
|
+
let a = e(r.color);
|
|
92
|
+
if (i.strokeStyle = a, i.lineWidth = r.width, i.setLineDash(r.dash), i.beginPath(), r.axis === "y") {
|
|
93
|
+
let e = n(o.yToPx(r.value));
|
|
94
|
+
i.moveTo(u.x, e), i.lineTo(u.x + u.width, e), i.stroke(), r.label && (i.setLineDash([]), i.font = t(l, l.fontSize, 500), i.textAlign = "right", i.textBaseline = "bottom", s(i, r.label, u.x + u.width - 6, e - 3, a, d));
|
|
95
|
+
} else {
|
|
96
|
+
let e = n(o.xToPx(r.value));
|
|
97
|
+
i.moveTo(e, u.y), i.lineTo(e, u.y + u.height), i.stroke(), r.label && (i.setLineDash([]), i.font = t(l, l.fontSize, 500), i.textAlign = "left", i.textBaseline = "top", s(i, r.label, e + 5, u.y + 5, a, d));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
i.setLineDash([]), i.font = t(l, l.fontSize + 1, 600);
|
|
101
|
+
for (let t of a.annotations) {
|
|
102
|
+
if (t.type !== "rect" || !t.label) continue;
|
|
103
|
+
let n = r(t, o);
|
|
104
|
+
if (n.width <= 0 || n.height <= 0) continue;
|
|
105
|
+
let a = i.measureText(t.label).width, s = t.labelPosition, c = s.endsWith("left") ? n.x + 10 : s.endsWith("right") ? n.x + n.width - 10 - a : n.x + (n.width - a) / 2, l = s.startsWith("top") ? n.y + 10 : s.startsWith("bottom") ? n.y + n.height - 10 - p : n.y + (n.height - p) / 2;
|
|
106
|
+
i.textAlign = "left", i.textBaseline = "top", i.fillStyle = e(t.labelColor), i.fillText(t.label, c, l), f.push({
|
|
107
|
+
x: c,
|
|
108
|
+
y: l,
|
|
109
|
+
width: a,
|
|
110
|
+
height: p
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
if (a.pointLabels.length) {
|
|
114
|
+
i.font = t(l), i.textAlign = "left", i.textBaseline = "middle";
|
|
115
|
+
let n = e(l.text, .85), r = c(a.pointLabels, u, (e) => i.measureText(e).width, p - 2, f);
|
|
116
|
+
for (let { label: e, box: t } of r) s(i, e.text, t.x, t.y + t.height / 2, n, d);
|
|
117
|
+
}
|
|
118
|
+
i.restore();
|
|
119
|
+
};
|
|
120
|
+
//#endregion
|
|
121
|
+
export { i as drawBackground, l as drawForeground, t as font, c as placeLabels };
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.js","names":["font","theme","weight","size","crisp","v","rectOf","s","xa","a","xb","ya","yb","left","plot","right","top","bottom","drawBackground","input","scales","ctx","r","toCss","y","yTicks","py","x","xTicks","px","line","base","lastRight","order","i","b","w","text","overlaps","inside","haloText","halo","color","placeLabels","placed","label","labels","measure","gap","box","height","c","occupied","o","drawForeground","labelHeight","pos","tx","ty","textColor","t"],"sources":["../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport type { Rect, Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\nconst rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n const xa = a.x0 === undefined ? -Infinity : s.xToPx(a.x0);\n const xb = a.x1 === undefined ? Infinity : s.xToPx(a.x1);\n const ya = a.y0 === undefined ? Infinity : s.yToPx(a.y0);\n const yb = a.y1 === undefined ? -Infinity : s.yToPx(a.y1);\n const left = Math.max(plot.x, Math.min(xa, xb));\n const right = Math.min(plot.x + plot.width, Math.max(xa, xb));\n const top = Math.max(plot.y, Math.min(ya, yb));\n const bottom = Math.min(plot.y + plot.height, Math.max(ya, yb));\n return { x: left, y: top, width: right - left, height: bottom - top };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, x, y, xTicks, yTicks } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of yTicks.values) {\n const py = crisp(scales.yToPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of xTicks.values) {\n const px = crisp(scales.xToPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = xTicks.values\n .map((v, i) => ({ px: scales.xToPx(v), text: xTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n yTicks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(yTicks.labels[i], plot.x - 8, py);\n });\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const candidates: Rect[] = [\n { x: label.x + gap, y: label.y - height / 2, width: w, height },\n { x: label.x - gap - w, y: label.y - height / 2, width: w, height },\n { x: label.x - w / 2, y: label.y - gap - height, width: w, height },\n { x: label.x - w / 2, y: label.y + gap, width: w, height },\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n if (a.axis === \"y\") {\n const py = crisp(scales.yToPx(a.value));\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(scales.xToPx(a.value));\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./types.cjs"),t=require("../decimate.cjs");var n=2e4,r=(e,t)=>`rgba(${Math.round(e[0]*255)},${Math.round(e[1]*255)},${Math.round(e[2]*255)},${e[3]*t})`,i=e=>[(e&255)/255,(e>>>8&255)/255,(e>>>16&255)/255,(e>>>24&255)/255],a=e=>!Number.isFinite(e)||Math.abs(e)>=15e37,o=(e,t,n)=>{let r=0,i=t;for(;r<i;){let t=r+i>>>1;e[t*2]<n?r=t+1:i=t}return r},s=n=>{let s=n.getContext(`2d`);if(!s)return null;let c=null,l=e=>{let{xScale:t,xOffset:n,yScale:r,yOffset:i}=e.transform,a=e.width,o=e.height;return{px:e=>((e*t+n)*.5+.5)*a,py:e=>(1-((e*r+i)*.5+.5))*o,xRange:()=>{let e=(-1-n)/t,r=(1-n)/t;return e<r?[e,r]:[r,e]}}},u=(n,r)=>{if(!n.sorted||n.count<=r.width*2)return{points:n.points,length:n.count};let i=l(r),[a,s]=i.xRange(),c=Math.max(0,o(n.points,n.count,a)-1),u=Math.min(n.count,o(n.points,n.count,s)+1),d=t.decimateMinMax(n.points,c,u,i.px,e.GAP*.5);return{points:d.points,length:d.length}},d=(e,t)=>{let n=l(t),{points:i,length:o}=u(e,t);s.beginPath();let c=!1;for(let e=0;e<o;e++){let t=i[e*2],r=i[e*2+1];if(a(t)||a(r)){c=!1;continue}c?s.lineTo(n.px(t),n.py(r)):s.moveTo(n.px(t),n.py(r)),c=!0}s.lineWidth=e.width*t.dpr,s.lineJoin=`round`,s.lineCap=`round`,s.strokeStyle=r(e.color,1),s.stroke()},f=(e,t)=>{let n=l(t),{points:i,length:o}=u(e,t),c=n.py(e.baseline),d=s.createLinearGradient(0,0,0,c);d.addColorStop(0,r(e.color,e.opacity)),d.addColorStop(1,r(e.color,e.opacity*.3)),s.fillStyle=d,s.beginPath();let f=-1,p=0,m=()=>{f<0||(s.lineTo(p,c),s.closePath(),f=-1)};for(let e=0;e<o;e++){let t=i[e*2],r=i[e*2+1];if(a(t)||a(r)){m();continue}let o=n.px(t);f<0&&(f=e,s.moveTo(o,c)),s.lineTo(o,n.py(r)),p=o}m(),s.fill()},p=(e,t)=>{let n=l(t),i=Math.max(Math.abs(e.halfWidth*t.transform.xScale)*.5*t.width,.5),o=e.radius*t.dpr;s.fillStyle=r(e.color,1),s.beginPath();let c=e.instances;for(let t=0;t<e.count;t++){let e=c[t*3],r=c[t*3+1],l=c[t*3+2];if(a(e)||a(r)||a(l))continue;let u=n.px(e),d=n.py(r),f=n.py(l),p=Math.min(d,f),m=Math.abs(d-f),h=Math.min(o,i,m/2);h>.5&&typeof s.roundRect==`function`?s.roundRect(u-i,p,i*2,m,h):s.rect(u-i,p,i*2,m)}s.fill()},m=(e,t)=>{let r=l(t),i=n.width,o=n.height;c??(c=document.createElement(`canvas`)),c.width=i,c.height=o;let u=c.getContext(`2d`);if(!u)return;let d=u.createImageData(i,o),f=d.data,p=new Float32Array(e.instances,0,e.count*4),m=new Uint32Array(e.instances,0,e.count*4);for(let n=0;n<e.count;n++){let s=p[n*4],c=p[n*4+1],l=p[n*4+2];if(a(s)||a(c)||!(l>0))continue;let u=r.px(s),d=r.py(c),h=Math.max(1,Math.round(l*t.dpr*.8)),g=Math.round(u-h/2),_=Math.round(d-h/2),v=m[n*4+3],y=(v>>>24&255)/255*Math.max(e.opacity,.6),b=v&255,x=v>>>8&255,S=v>>>16&255;for(let e=Math.max(0,_);e<Math.min(o,_+h);e++)for(let t=Math.max(0,g);t<Math.min(i,g+h);t++){let n=(e*i+t)*4,r=f[n+3]/255,a=y+r*(1-y);f[n]=(b*y+f[n]*r*(1-y))/a,f[n+1]=(x*y+f[n+1]*r*(1-y))/a,f[n+2]=(S*y+f[n+2]*r*(1-y))/a,f[n+3]=a*255}}u.putImageData(d,0,0),s.drawImage(c,0,0)},h=(e,t)=>{if(e.count>2e4){m(e,t);return}let n=l(t),o=new Float32Array(e.instances,0,e.count*4),c=new Uint32Array(e.instances,0,e.count*4),u=new Map;for(let t=0;t<e.count;t++){let e=c[t*4+3],n=u.get(e);n||u.set(e,n=[]),n.push(t)}let d=e.stroke*t.dpr;for(let[c,l]of u){let u=i(c);s.beginPath();for(let e of l){let r=o[e*4],i=o[e*4+1],c=o[e*4+2];if(a(r)||a(i)||!(c>0))continue;let l=n.px(r),u=n.py(i),d=c*t.dpr/2;s.moveTo(l+d,u),s.arc(l,u,d,0,Math.PI*2)}if(s.fillStyle=r(u,e.opacity),s.fill(),d>0){s.beginPath();for(let e of l){let r=o[e*4],i=o[e*4+1],c=o[e*4+2];if(a(r)||a(i)||!(c>0))continue;let l=Math.max(0,c*t.dpr/2-d/2),u=n.px(r),f=n.py(i);s.moveTo(u+l,f),s.arc(u,f,l,0,Math.PI*2)}s.lineWidth=d,s.strokeStyle=r(u,1),s.stroke()}}};return{kind:`canvas2d`,canvas:n,resize(e,t){n.width=Math.max(1,e),n.height=Math.max(1,t)},render(e,t){s.setTransform(1,0,0,1,0,0),s.clearRect(0,0,n.width,n.height);for(let n of e)switch(n.kind){case`line`:n.count>1&&d(n,t);break;case`area`:n.count>1&&f(n,t);break;case`bar`:p(n,t);break;default:h(n,t)}},destroy(){c=null,n.width=0,n.height=0}}};exports.SCATTER_PIXEL_THRESHOLD=n,exports.createCanvas2dRenderer=s;
|
|
2
|
+
//# sourceMappingURL=canvas2d.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas2d.cjs","names":["decimateMinMax","GAP","require_types","require_decimate","SCATTER_PIXEL_THRESHOLD","rgba","c","alpha","unpack","packed","isGap","v","lowerBoundX","lo","hi","count","mid","points","value","createCanvas2dRenderer","ctx","canvas","scratch","mapper","frame","w","h","x","xScale","xOffset","y","yScale","yOffset","a","b","visiblePoints","item","m","x0","x1","start","end","result","drawLine","pen","i","length","drawArea","base","gradient","runStart","lastX","close","px","drawBars","half","r","y0","y1","cx","top","height","radius","drawScatterPixels","sctx","image","data","f","u","size","cy","s","g","py","o","da","outA","drawScatter","groups","list","stroke","color","width","items"],"sources":["../../../../../charts/src/engine/renderers/canvas2d.ts"],"sourcesContent":["// Canvas2D backend: the fallback without GPU. Lines are decimated to a few\n// points per pixel column and very large scatter sets are written pixel by\n// pixel, so it stays usable with large data sets.\n\nimport { decimateMinMax } from \"../decimate\";\nimport type { Rgba } from \"../color\";\nimport {\n GAP,\n type ChartRenderer,\n type RenderFrame,\n type RenderItem,\n type ScatterItem,\n} from \"./types\";\n\n/** Scatter sets above this size are rasterized through ImageData */\nexport const SCATTER_PIXEL_THRESHOLD = 20000;\n\nconst rgba = (c: Rgba, alpha: number) =>\n `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${c[3] * alpha})`;\n\nconst unpack = (packed: number): Rgba => [\n (packed & 0xff) / 255,\n ((packed >>> 8) & 0xff) / 255,\n ((packed >>> 16) & 0xff) / 255,\n ((packed >>> 24) & 0xff) / 255,\n];\n\nconst isGap = (v: number) => !Number.isFinite(v) || Math.abs(v) >= GAP * 0.5;\n\n/** First point index whose relative x is >= value (sorted, interleaved) */\nconst lowerBoundX = (points: Float32Array, count: number, value: number) => {\n let lo = 0;\n let hi = count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (points[mid * 2] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n};\n\nexport const createCanvas2dRenderer = (\n canvas: HTMLCanvasElement,\n): ChartRenderer | null => {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n let scratch: HTMLCanvasElement | null = null;\n\n const mapper = (frame: RenderFrame) => {\n const { xScale, xOffset, yScale, yOffset } = frame.transform;\n const w = frame.width;\n const h = frame.height;\n return {\n px: (x: number) => ((x * xScale + xOffset) * 0.5 + 0.5) * w,\n py: (y: number) => (1 - ((y * yScale + yOffset) * 0.5 + 0.5)) * h,\n /** Visible relative x range */\n xRange: (): [number, number] => {\n const a = (-1 - xOffset) / xScale;\n const b = (1 - xOffset) / xScale;\n return a < b ? [a, b] : [b, a];\n },\n };\n };\n\n /** Points actually drawn: decimated when there are many per pixel */\n const visiblePoints = (\n item: Extract<RenderItem, { kind: \"line\" | \"area\" }>,\n frame: RenderFrame,\n ): { points: ArrayLike<number>; length: number } => {\n if (!item.sorted || item.count <= frame.width * 2) {\n return { points: item.points, length: item.count };\n }\n const m = mapper(frame);\n const [x0, x1] = m.xRange();\n const start = Math.max(0, lowerBoundX(item.points, item.count, x0) - 1);\n const end = Math.min(\n item.count,\n lowerBoundX(item.points, item.count, x1) + 1,\n );\n const result = decimateMinMax(item.points, start, end, m.px, GAP * 0.5);\n return { points: result.points, length: result.length };\n };\n\n const drawLine = (\n item: Extract<RenderItem, { kind: \"line\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n ctx.beginPath();\n let pen = false;\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n pen = false;\n continue;\n }\n if (pen) ctx.lineTo(m.px(x), m.py(y));\n else ctx.moveTo(m.px(x), m.py(y));\n pen = true;\n }\n ctx.lineWidth = item.width * frame.dpr;\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n ctx.strokeStyle = rgba(item.color, 1);\n ctx.stroke();\n };\n\n const drawArea = (\n item: Extract<RenderItem, { kind: \"area\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n const base = m.py(item.baseline);\n const gradient = ctx.createLinearGradient(0, 0, 0, base);\n gradient.addColorStop(0, rgba(item.color, item.opacity));\n gradient.addColorStop(1, rgba(item.color, item.opacity * 0.3));\n ctx.fillStyle = gradient;\n ctx.beginPath();\n let runStart = -1;\n let lastX = 0;\n const close = () => {\n if (runStart < 0) return;\n ctx.lineTo(lastX, base);\n ctx.closePath();\n runStart = -1;\n };\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n close();\n continue;\n }\n const px = m.px(x);\n if (runStart < 0) {\n runStart = i;\n ctx.moveTo(px, base);\n }\n ctx.lineTo(px, m.py(y));\n lastX = px;\n }\n close();\n ctx.fill();\n };\n\n const drawBars = (\n item: Extract<RenderItem, { kind: \"bar\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const half = Math.max(\n Math.abs(item.halfWidth * frame.transform.xScale) * 0.5 * frame.width,\n 0.5,\n );\n const r = item.radius * frame.dpr;\n ctx.fillStyle = rgba(item.color, 1);\n ctx.beginPath();\n const v = item.instances;\n for (let i = 0; i < item.count; i++) {\n const x = v[i * 3];\n const y0 = v[i * 3 + 1];\n const y1 = v[i * 3 + 2];\n if (isGap(x) || isGap(y0) || isGap(y1)) continue;\n const cx = m.px(x);\n const a = m.py(y0);\n const b = m.py(y1);\n const top = Math.min(a, b);\n const height = Math.abs(a - b);\n const radius = Math.min(r, half, height / 2);\n if (radius > 0.5 && typeof ctx.roundRect === \"function\") {\n ctx.roundRect(cx - half, top, half * 2, height, radius);\n } else {\n ctx.rect(cx - half, top, half * 2, height);\n }\n }\n ctx.fill();\n };\n\n const drawScatterPixels = (item: ScatterItem, frame: RenderFrame) => {\n const m = mapper(frame);\n const w = canvas.width;\n const h = canvas.height;\n scratch ??= document.createElement(\"canvas\");\n scratch.width = w;\n scratch.height = h;\n const sctx = scratch.getContext(\"2d\");\n if (!sctx) return;\n const image = sctx.createImageData(w, h);\n const data = image.data;\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n for (let i = 0; i < item.count; i++) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const s = Math.max(1, Math.round(size * frame.dpr * 0.8));\n const x0 = Math.round(cx - s / 2);\n const y0 = Math.round(cy - s / 2);\n const packed = u[i * 4 + 3];\n const alpha =\n (((packed >>> 24) & 0xff) / 255) * Math.max(item.opacity, 0.6);\n const r = packed & 0xff;\n const g = (packed >>> 8) & 0xff;\n const b = (packed >>> 16) & 0xff;\n for (let py = Math.max(0, y0); py < Math.min(h, y0 + s); py++) {\n for (let px = Math.max(0, x0); px < Math.min(w, x0 + s); px++) {\n const o = (py * w + px) * 4;\n const da = data[o + 3] / 255;\n const outA = alpha + da * (1 - alpha);\n // straight-alpha \"over\"\n data[o] = (r * alpha + data[o] * da * (1 - alpha)) / outA;\n data[o + 1] = (g * alpha + data[o + 1] * da * (1 - alpha)) / outA;\n data[o + 2] = (b * alpha + data[o + 2] * da * (1 - alpha)) / outA;\n data[o + 3] = outA * 255;\n }\n }\n }\n sctx.putImageData(image, 0, 0);\n ctx.drawImage(scratch, 0, 0);\n };\n\n const drawScatter = (item: ScatterItem, frame: RenderFrame) => {\n if (item.count > SCATTER_PIXEL_THRESHOLD) {\n drawScatterPixels(item, frame);\n return;\n }\n const m = mapper(frame);\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n const groups = new Map<number, number[]>();\n for (let i = 0; i < item.count; i++) {\n const packed = u[i * 4 + 3];\n let list = groups.get(packed);\n if (!list) groups.set(packed, (list = []));\n list.push(i);\n }\n const stroke = item.stroke * frame.dpr;\n for (const [packed, list] of groups) {\n const color = unpack(packed);\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const r = (size * frame.dpr) / 2;\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.fillStyle = rgba(color, item.opacity);\n ctx.fill();\n if (stroke > 0) {\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const r = Math.max(0, (size * frame.dpr) / 2 - stroke / 2);\n const cx = m.px(x);\n const cy = m.py(y);\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.lineWidth = stroke;\n ctx.strokeStyle = rgba(color, 1);\n ctx.stroke();\n }\n }\n };\n\n return {\n kind: \"canvas2d\",\n canvas,\n resize(width, height) {\n canvas.width = Math.max(1, width);\n canvas.height = Math.max(1, height);\n },\n render(items, frame) {\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const item of items) {\n switch (item.kind) {\n case \"line\":\n if (item.count > 1) drawLine(item, frame);\n break;\n case \"area\":\n if (item.count > 1) drawArea(item, frame);\n break;\n case \"bar\":\n drawBars(item, frame);\n break;\n default:\n drawScatter(item, frame);\n break;\n }\n }\n },\n destroy() {\n scratch = null;\n canvas.width = 0;\n canvas.height = 0;\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { GAP as e } from "./types.js";
|
|
2
|
+
import { decimateMinMax as t } from "../decimate.js";
|
|
3
|
+
//#region src/engine/renderers/canvas2d.ts
|
|
4
|
+
var n = 2e4, r = (e, t) => `rgba(${Math.round(e[0] * 255)},${Math.round(e[1] * 255)},${Math.round(e[2] * 255)},${e[3] * t})`, i = (e) => [
|
|
5
|
+
(e & 255) / 255,
|
|
6
|
+
(e >>> 8 & 255) / 255,
|
|
7
|
+
(e >>> 16 & 255) / 255,
|
|
8
|
+
(e >>> 24 & 255) / 255
|
|
9
|
+
], a = (e) => !Number.isFinite(e) || Math.abs(e) >= 15e37, o = (e, t, n) => {
|
|
10
|
+
let r = 0, i = t;
|
|
11
|
+
for (; r < i;) {
|
|
12
|
+
let t = r + i >>> 1;
|
|
13
|
+
e[t * 2] < n ? r = t + 1 : i = t;
|
|
14
|
+
}
|
|
15
|
+
return r;
|
|
16
|
+
}, s = (n) => {
|
|
17
|
+
let s = n.getContext("2d");
|
|
18
|
+
if (!s) return null;
|
|
19
|
+
let c = null, l = (e) => {
|
|
20
|
+
let { xScale: t, xOffset: n, yScale: r, yOffset: i } = e.transform, a = e.width, o = e.height;
|
|
21
|
+
return {
|
|
22
|
+
px: (e) => ((e * t + n) * .5 + .5) * a,
|
|
23
|
+
py: (e) => (1 - ((e * r + i) * .5 + .5)) * o,
|
|
24
|
+
xRange: () => {
|
|
25
|
+
let e = (-1 - n) / t, r = (1 - n) / t;
|
|
26
|
+
return e < r ? [e, r] : [r, e];
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}, u = (n, r) => {
|
|
30
|
+
if (!n.sorted || n.count <= r.width * 2) return {
|
|
31
|
+
points: n.points,
|
|
32
|
+
length: n.count
|
|
33
|
+
};
|
|
34
|
+
let i = l(r), [a, s] = i.xRange(), c = Math.max(0, o(n.points, n.count, a) - 1), u = Math.min(n.count, o(n.points, n.count, s) + 1), d = t(n.points, c, u, i.px, e * .5);
|
|
35
|
+
return {
|
|
36
|
+
points: d.points,
|
|
37
|
+
length: d.length
|
|
38
|
+
};
|
|
39
|
+
}, d = (e, t) => {
|
|
40
|
+
let n = l(t), { points: i, length: o } = u(e, t);
|
|
41
|
+
s.beginPath();
|
|
42
|
+
let c = !1;
|
|
43
|
+
for (let e = 0; e < o; e++) {
|
|
44
|
+
let t = i[e * 2], r = i[e * 2 + 1];
|
|
45
|
+
if (a(t) || a(r)) {
|
|
46
|
+
c = !1;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
c ? s.lineTo(n.px(t), n.py(r)) : s.moveTo(n.px(t), n.py(r)), c = !0;
|
|
50
|
+
}
|
|
51
|
+
s.lineWidth = e.width * t.dpr, s.lineJoin = "round", s.lineCap = "round", s.strokeStyle = r(e.color, 1), s.stroke();
|
|
52
|
+
}, f = (e, t) => {
|
|
53
|
+
let n = l(t), { points: i, length: o } = u(e, t), c = n.py(e.baseline), d = s.createLinearGradient(0, 0, 0, c);
|
|
54
|
+
d.addColorStop(0, r(e.color, e.opacity)), d.addColorStop(1, r(e.color, e.opacity * .3)), s.fillStyle = d, s.beginPath();
|
|
55
|
+
let f = -1, p = 0, m = () => {
|
|
56
|
+
f < 0 || (s.lineTo(p, c), s.closePath(), f = -1);
|
|
57
|
+
};
|
|
58
|
+
for (let e = 0; e < o; e++) {
|
|
59
|
+
let t = i[e * 2], r = i[e * 2 + 1];
|
|
60
|
+
if (a(t) || a(r)) {
|
|
61
|
+
m();
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
let o = n.px(t);
|
|
65
|
+
f < 0 && (f = e, s.moveTo(o, c)), s.lineTo(o, n.py(r)), p = o;
|
|
66
|
+
}
|
|
67
|
+
m(), s.fill();
|
|
68
|
+
}, p = (e, t) => {
|
|
69
|
+
let n = l(t), i = Math.max(Math.abs(e.halfWidth * t.transform.xScale) * .5 * t.width, .5), o = e.radius * t.dpr;
|
|
70
|
+
s.fillStyle = r(e.color, 1), s.beginPath();
|
|
71
|
+
let c = e.instances;
|
|
72
|
+
for (let t = 0; t < e.count; t++) {
|
|
73
|
+
let e = c[t * 3], r = c[t * 3 + 1], l = c[t * 3 + 2];
|
|
74
|
+
if (a(e) || a(r) || a(l)) continue;
|
|
75
|
+
let u = n.px(e), d = n.py(r), f = n.py(l), p = Math.min(d, f), m = Math.abs(d - f), h = Math.min(o, i, m / 2);
|
|
76
|
+
h > .5 && typeof s.roundRect == "function" ? s.roundRect(u - i, p, i * 2, m, h) : s.rect(u - i, p, i * 2, m);
|
|
77
|
+
}
|
|
78
|
+
s.fill();
|
|
79
|
+
}, m = (e, t) => {
|
|
80
|
+
let r = l(t), i = n.width, o = n.height;
|
|
81
|
+
c ?? (c = document.createElement("canvas")), c.width = i, c.height = o;
|
|
82
|
+
let u = c.getContext("2d");
|
|
83
|
+
if (!u) return;
|
|
84
|
+
let d = u.createImageData(i, o), f = d.data, p = new Float32Array(e.instances, 0, e.count * 4), m = new Uint32Array(e.instances, 0, e.count * 4);
|
|
85
|
+
for (let n = 0; n < e.count; n++) {
|
|
86
|
+
let s = p[n * 4], c = p[n * 4 + 1], l = p[n * 4 + 2];
|
|
87
|
+
if (a(s) || a(c) || !(l > 0)) continue;
|
|
88
|
+
let u = r.px(s), d = r.py(c), h = Math.max(1, Math.round(l * t.dpr * .8)), g = Math.round(u - h / 2), _ = Math.round(d - h / 2), v = m[n * 4 + 3], y = (v >>> 24 & 255) / 255 * Math.max(e.opacity, .6), b = v & 255, x = v >>> 8 & 255, S = v >>> 16 & 255;
|
|
89
|
+
for (let e = Math.max(0, _); e < Math.min(o, _ + h); e++) for (let t = Math.max(0, g); t < Math.min(i, g + h); t++) {
|
|
90
|
+
let n = (e * i + t) * 4, r = f[n + 3] / 255, a = y + r * (1 - y);
|
|
91
|
+
f[n] = (b * y + f[n] * r * (1 - y)) / a, f[n + 1] = (x * y + f[n + 1] * r * (1 - y)) / a, f[n + 2] = (S * y + f[n + 2] * r * (1 - y)) / a, f[n + 3] = a * 255;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
u.putImageData(d, 0, 0), s.drawImage(c, 0, 0);
|
|
95
|
+
}, h = (e, t) => {
|
|
96
|
+
if (e.count > 2e4) {
|
|
97
|
+
m(e, t);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let n = l(t), o = new Float32Array(e.instances, 0, e.count * 4), c = new Uint32Array(e.instances, 0, e.count * 4), u = /* @__PURE__ */ new Map();
|
|
101
|
+
for (let t = 0; t < e.count; t++) {
|
|
102
|
+
let e = c[t * 4 + 3], n = u.get(e);
|
|
103
|
+
n || u.set(e, n = []), n.push(t);
|
|
104
|
+
}
|
|
105
|
+
let d = e.stroke * t.dpr;
|
|
106
|
+
for (let [c, l] of u) {
|
|
107
|
+
let u = i(c);
|
|
108
|
+
s.beginPath();
|
|
109
|
+
for (let e of l) {
|
|
110
|
+
let r = o[e * 4], i = o[e * 4 + 1], c = o[e * 4 + 2];
|
|
111
|
+
if (a(r) || a(i) || !(c > 0)) continue;
|
|
112
|
+
let l = n.px(r), u = n.py(i), d = c * t.dpr / 2;
|
|
113
|
+
s.moveTo(l + d, u), s.arc(l, u, d, 0, Math.PI * 2);
|
|
114
|
+
}
|
|
115
|
+
if (s.fillStyle = r(u, e.opacity), s.fill(), d > 0) {
|
|
116
|
+
s.beginPath();
|
|
117
|
+
for (let e of l) {
|
|
118
|
+
let r = o[e * 4], i = o[e * 4 + 1], c = o[e * 4 + 2];
|
|
119
|
+
if (a(r) || a(i) || !(c > 0)) continue;
|
|
120
|
+
let l = Math.max(0, c * t.dpr / 2 - d / 2), u = n.px(r), f = n.py(i);
|
|
121
|
+
s.moveTo(u + l, f), s.arc(u, f, l, 0, Math.PI * 2);
|
|
122
|
+
}
|
|
123
|
+
s.lineWidth = d, s.strokeStyle = r(u, 1), s.stroke();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
kind: "canvas2d",
|
|
129
|
+
canvas: n,
|
|
130
|
+
resize(e, t) {
|
|
131
|
+
n.width = Math.max(1, e), n.height = Math.max(1, t);
|
|
132
|
+
},
|
|
133
|
+
render(e, t) {
|
|
134
|
+
s.setTransform(1, 0, 0, 1, 0, 0), s.clearRect(0, 0, n.width, n.height);
|
|
135
|
+
for (let n of e) switch (n.kind) {
|
|
136
|
+
case "line":
|
|
137
|
+
n.count > 1 && d(n, t);
|
|
138
|
+
break;
|
|
139
|
+
case "area":
|
|
140
|
+
n.count > 1 && f(n, t);
|
|
141
|
+
break;
|
|
142
|
+
case "bar":
|
|
143
|
+
p(n, t);
|
|
144
|
+
break;
|
|
145
|
+
default: h(n, t);
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
destroy() {
|
|
149
|
+
c = null, n.width = 0, n.height = 0;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
//#endregion
|
|
154
|
+
export { n as SCATTER_PIXEL_THRESHOLD, s as createCanvas2dRenderer };
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=canvas2d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas2d.js","names":["SCATTER_PIXEL_THRESHOLD","rgba","c","alpha","unpack","packed","isGap","v","lowerBoundX","lo","hi","count","mid","points","value","createCanvas2dRenderer","ctx","canvas","scratch","mapper","frame","w","h","x","xScale","xOffset","y","yScale","yOffset","a","b","visiblePoints","item","m","x0","x1","start","end","result","decimateMinMax","GAP","drawLine","pen","i","length","drawArea","base","gradient","runStart","lastX","close","px","drawBars","half","r","y0","y1","cx","top","height","radius","drawScatterPixels","sctx","image","data","f","u","size","cy","s","g","py","o","da","outA","drawScatter","groups","list","stroke","color","width","items"],"sources":["../../../../../charts/src/engine/renderers/canvas2d.ts"],"sourcesContent":["// Canvas2D backend: the fallback without GPU. Lines are decimated to a few\n// points per pixel column and very large scatter sets are written pixel by\n// pixel, so it stays usable with large data sets.\n\nimport { decimateMinMax } from \"../decimate\";\nimport type { Rgba } from \"../color\";\nimport {\n GAP,\n type ChartRenderer,\n type RenderFrame,\n type RenderItem,\n type ScatterItem,\n} from \"./types\";\n\n/** Scatter sets above this size are rasterized through ImageData */\nexport const SCATTER_PIXEL_THRESHOLD = 20000;\n\nconst rgba = (c: Rgba, alpha: number) =>\n `rgba(${Math.round(c[0] * 255)},${Math.round(c[1] * 255)},${Math.round(c[2] * 255)},${c[3] * alpha})`;\n\nconst unpack = (packed: number): Rgba => [\n (packed & 0xff) / 255,\n ((packed >>> 8) & 0xff) / 255,\n ((packed >>> 16) & 0xff) / 255,\n ((packed >>> 24) & 0xff) / 255,\n];\n\nconst isGap = (v: number) => !Number.isFinite(v) || Math.abs(v) >= GAP * 0.5;\n\n/** First point index whose relative x is >= value (sorted, interleaved) */\nconst lowerBoundX = (points: Float32Array, count: number, value: number) => {\n let lo = 0;\n let hi = count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (points[mid * 2] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n};\n\nexport const createCanvas2dRenderer = (\n canvas: HTMLCanvasElement,\n): ChartRenderer | null => {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return null;\n let scratch: HTMLCanvasElement | null = null;\n\n const mapper = (frame: RenderFrame) => {\n const { xScale, xOffset, yScale, yOffset } = frame.transform;\n const w = frame.width;\n const h = frame.height;\n return {\n px: (x: number) => ((x * xScale + xOffset) * 0.5 + 0.5) * w,\n py: (y: number) => (1 - ((y * yScale + yOffset) * 0.5 + 0.5)) * h,\n /** Visible relative x range */\n xRange: (): [number, number] => {\n const a = (-1 - xOffset) / xScale;\n const b = (1 - xOffset) / xScale;\n return a < b ? [a, b] : [b, a];\n },\n };\n };\n\n /** Points actually drawn: decimated when there are many per pixel */\n const visiblePoints = (\n item: Extract<RenderItem, { kind: \"line\" | \"area\" }>,\n frame: RenderFrame,\n ): { points: ArrayLike<number>; length: number } => {\n if (!item.sorted || item.count <= frame.width * 2) {\n return { points: item.points, length: item.count };\n }\n const m = mapper(frame);\n const [x0, x1] = m.xRange();\n const start = Math.max(0, lowerBoundX(item.points, item.count, x0) - 1);\n const end = Math.min(\n item.count,\n lowerBoundX(item.points, item.count, x1) + 1,\n );\n const result = decimateMinMax(item.points, start, end, m.px, GAP * 0.5);\n return { points: result.points, length: result.length };\n };\n\n const drawLine = (\n item: Extract<RenderItem, { kind: \"line\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n ctx.beginPath();\n let pen = false;\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n pen = false;\n continue;\n }\n if (pen) ctx.lineTo(m.px(x), m.py(y));\n else ctx.moveTo(m.px(x), m.py(y));\n pen = true;\n }\n ctx.lineWidth = item.width * frame.dpr;\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n ctx.strokeStyle = rgba(item.color, 1);\n ctx.stroke();\n };\n\n const drawArea = (\n item: Extract<RenderItem, { kind: \"area\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const { points, length } = visiblePoints(item, frame);\n const base = m.py(item.baseline);\n const gradient = ctx.createLinearGradient(0, 0, 0, base);\n gradient.addColorStop(0, rgba(item.color, item.opacity));\n gradient.addColorStop(1, rgba(item.color, item.opacity * 0.3));\n ctx.fillStyle = gradient;\n ctx.beginPath();\n let runStart = -1;\n let lastX = 0;\n const close = () => {\n if (runStart < 0) return;\n ctx.lineTo(lastX, base);\n ctx.closePath();\n runStart = -1;\n };\n for (let i = 0; i < length; i++) {\n const x = points[i * 2];\n const y = points[i * 2 + 1];\n if (isGap(x) || isGap(y)) {\n close();\n continue;\n }\n const px = m.px(x);\n if (runStart < 0) {\n runStart = i;\n ctx.moveTo(px, base);\n }\n ctx.lineTo(px, m.py(y));\n lastX = px;\n }\n close();\n ctx.fill();\n };\n\n const drawBars = (\n item: Extract<RenderItem, { kind: \"bar\" }>,\n frame: RenderFrame,\n ) => {\n const m = mapper(frame);\n const half = Math.max(\n Math.abs(item.halfWidth * frame.transform.xScale) * 0.5 * frame.width,\n 0.5,\n );\n const r = item.radius * frame.dpr;\n ctx.fillStyle = rgba(item.color, 1);\n ctx.beginPath();\n const v = item.instances;\n for (let i = 0; i < item.count; i++) {\n const x = v[i * 3];\n const y0 = v[i * 3 + 1];\n const y1 = v[i * 3 + 2];\n if (isGap(x) || isGap(y0) || isGap(y1)) continue;\n const cx = m.px(x);\n const a = m.py(y0);\n const b = m.py(y1);\n const top = Math.min(a, b);\n const height = Math.abs(a - b);\n const radius = Math.min(r, half, height / 2);\n if (radius > 0.5 && typeof ctx.roundRect === \"function\") {\n ctx.roundRect(cx - half, top, half * 2, height, radius);\n } else {\n ctx.rect(cx - half, top, half * 2, height);\n }\n }\n ctx.fill();\n };\n\n const drawScatterPixels = (item: ScatterItem, frame: RenderFrame) => {\n const m = mapper(frame);\n const w = canvas.width;\n const h = canvas.height;\n scratch ??= document.createElement(\"canvas\");\n scratch.width = w;\n scratch.height = h;\n const sctx = scratch.getContext(\"2d\");\n if (!sctx) return;\n const image = sctx.createImageData(w, h);\n const data = image.data;\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n for (let i = 0; i < item.count; i++) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const s = Math.max(1, Math.round(size * frame.dpr * 0.8));\n const x0 = Math.round(cx - s / 2);\n const y0 = Math.round(cy - s / 2);\n const packed = u[i * 4 + 3];\n const alpha =\n (((packed >>> 24) & 0xff) / 255) * Math.max(item.opacity, 0.6);\n const r = packed & 0xff;\n const g = (packed >>> 8) & 0xff;\n const b = (packed >>> 16) & 0xff;\n for (let py = Math.max(0, y0); py < Math.min(h, y0 + s); py++) {\n for (let px = Math.max(0, x0); px < Math.min(w, x0 + s); px++) {\n const o = (py * w + px) * 4;\n const da = data[o + 3] / 255;\n const outA = alpha + da * (1 - alpha);\n // straight-alpha \"over\"\n data[o] = (r * alpha + data[o] * da * (1 - alpha)) / outA;\n data[o + 1] = (g * alpha + data[o + 1] * da * (1 - alpha)) / outA;\n data[o + 2] = (b * alpha + data[o + 2] * da * (1 - alpha)) / outA;\n data[o + 3] = outA * 255;\n }\n }\n }\n sctx.putImageData(image, 0, 0);\n ctx.drawImage(scratch, 0, 0);\n };\n\n const drawScatter = (item: ScatterItem, frame: RenderFrame) => {\n if (item.count > SCATTER_PIXEL_THRESHOLD) {\n drawScatterPixels(item, frame);\n return;\n }\n const m = mapper(frame);\n const f = new Float32Array(item.instances, 0, item.count * 4);\n const u = new Uint32Array(item.instances, 0, item.count * 4);\n const groups = new Map<number, number[]>();\n for (let i = 0; i < item.count; i++) {\n const packed = u[i * 4 + 3];\n let list = groups.get(packed);\n if (!list) groups.set(packed, (list = []));\n list.push(i);\n }\n const stroke = item.stroke * frame.dpr;\n for (const [packed, list] of groups) {\n const color = unpack(packed);\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const cx = m.px(x);\n const cy = m.py(y);\n const r = (size * frame.dpr) / 2;\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.fillStyle = rgba(color, item.opacity);\n ctx.fill();\n if (stroke > 0) {\n ctx.beginPath();\n for (const i of list) {\n const x = f[i * 4];\n const y = f[i * 4 + 1];\n const size = f[i * 4 + 2];\n if (isGap(x) || isGap(y) || !(size > 0)) continue;\n const r = Math.max(0, (size * frame.dpr) / 2 - stroke / 2);\n const cx = m.px(x);\n const cy = m.py(y);\n ctx.moveTo(cx + r, cy);\n ctx.arc(cx, cy, r, 0, Math.PI * 2);\n }\n ctx.lineWidth = stroke;\n ctx.strokeStyle = rgba(color, 1);\n ctx.stroke();\n }\n }\n };\n\n return {\n kind: \"canvas2d\",\n canvas,\n resize(width, height) {\n canvas.width = Math.max(1, width);\n canvas.height = Math.max(1, height);\n },\n render(items, frame) {\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n for (const item of items) {\n switch (item.kind) {\n case \"line\":\n if (item.count > 1) drawLine(item, frame);\n break;\n case \"area\":\n if (item.count > 1) drawArea(item, frame);\n break;\n case \"bar\":\n drawBars(item, frame);\n break;\n default:\n drawScatter(item, frame);\n break;\n }\n }\n },\n destroy() {\n scratch = null;\n canvas.width = 0;\n canvas.height = 0;\n },\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require("./canvas2d.cjs"),t=require("./webgl2.cjs"),n=require("./webgpu.cjs");var r=[`webgpu`,`webgl2`,`canvas2d`],i=(e,t=new Set)=>{let n=e===`auto`?0:r.indexOf(e);return r.slice(Math.max(0,n)).filter(e=>!t.has(e))},a=async(r,i,a,o)=>{switch(r){case`webgpu`:return n.createWebGpuRenderer(i,a,o);case`webgl2`:return t.createWebGl2Renderer(i,a,o);default:return e.createCanvas2dRenderer(i)}},o=async(e,t,n,r)=>{for(let o of i(e,r)){let r;try{r=await a(o,t(),()=>n(o),e===`auto`||e!==o)}catch{r=null}if(r)return r}return null};exports.RENDERER_ORDER=r,exports.createRenderer=o,exports.rendererCandidates=i;
|
|
2
|
+
//# sourceMappingURL=detect.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.cjs","names":["createWebGpuRenderer","createWebGl2Renderer","createCanvas2dRenderer","require_canvas2d","require_webgl2","require_webgpu","RENDERER_ORDER","rendererCandidates","start","preference","exclude","k","create","kind","canvas","onLost","requireHardware","createRenderer","renderer","makeCanvas"],"sources":["../../../../../charts/src/engine/renderers/detect.ts"],"sourcesContent":["// Backend selection: WebGPU -> WebGL2 -> Canvas2D.\n\nimport type { ChartRendererKind, ChartRendererPreference } from \"../types\";\nimport { createCanvas2dRenderer } from \"./canvas2d\";\nimport type { ChartRenderer, RendererLostHandler } from \"./types\";\nimport { createWebGl2Renderer } from \"./webgl2\";\nimport { createWebGpuRenderer } from \"./webgpu\";\n\nexport const RENDERER_ORDER: readonly ChartRendererKind[] = [\n \"webgpu\",\n \"webgl2\",\n \"canvas2d\",\n];\n\n/** Backends to try for a preference, best first */\nexport const rendererCandidates = (\n preference: ChartRendererPreference,\n exclude: ReadonlySet<ChartRendererKind> = new Set(),\n): ChartRendererKind[] => {\n const start = preference === \"auto\" ? 0 : RENDERER_ORDER.indexOf(preference);\n return RENDERER_ORDER.slice(Math.max(0, start)).filter(\n (k) => !exclude.has(k),\n );\n};\n\nconst create = async (\n kind: ChartRendererKind,\n canvas: HTMLCanvasElement,\n onLost: RendererLostHandler,\n requireHardware: boolean,\n): Promise<ChartRenderer | null> => {\n switch (kind) {\n case \"webgpu\":\n return createWebGpuRenderer(canvas, onLost, requireHardware);\n case \"webgl2\":\n return createWebGl2Renderer(canvas, onLost, requireHardware);\n default:\n return createCanvas2dRenderer(canvas);\n }\n};\n\n/**\n * Creates the first backend that works. A canvas only ever gets one kind\n * of context, so every attempt uses a fresh canvas from `makeCanvas`.\n * With `auto`, GPU backends running in software (no hardware acceleration)\n * are skipped: the decimating Canvas2D backend is much faster there.\n */\nexport const createRenderer = async (\n preference: ChartRendererPreference,\n makeCanvas: () => HTMLCanvasElement,\n onLost: (kind: ChartRendererKind) => void,\n exclude?: ReadonlySet<ChartRendererKind>,\n): Promise<ChartRenderer | null> => {\n for (const kind of rendererCandidates(preference, exclude)) {\n let renderer: ChartRenderer | null;\n try {\n renderer = await create(\n kind,\n makeCanvas(),\n () => onLost(kind),\n preference === \"auto\" || preference !== kind,\n );\n } catch {\n renderer = null;\n }\n if (renderer) return renderer;\n }\n return null;\n};\n"],"mappings":"sFAQA,IAAaM,EAA+C,CAC1D,SACA,SACA,UACF,EAGaC,GACX,EACA,EAA0C,IAAI,MACtB,CACxB,IAAMC,EAAQC,IAAe,OAAS,EAAIH,EAAe,QAAQG,CAAU,EAC3E,OAAOH,EAAe,MAAM,KAAK,IAAI,EAAGE,CAAK,CAAC,CAAC,CAAC,OAC7C,GAAM,CAACE,EAAQ,IAAIC,CAAC,CACvB,CACF,EAEMC,EAAS,MACb,EACA,EACA,EACA,IACkC,CAClC,OAAQC,EAAR,CACE,IAAK,SACH,OAAOb,EAAAA,qBAAqBc,EAAQC,EAAQC,CAAe,EAC7D,IAAK,SACH,OAAOf,EAAAA,qBAAqBa,EAAQC,EAAQC,CAAe,EAC7D,QACE,OAAOd,EAAAA,uBAAuBY,CAAM,CACxC,CACF,EAQaG,EAAiB,MAC5B,EACA,EACA,EACA,IACkC,CAClC,IAAK,IAAMJ,KAAQN,EAAmBE,EAAYC,CAAO,EAAG,CAC1D,IAAIQ,EACJ,GAAI,CACF,EAAW,MAAMN,EACfC,EACAM,EAAW,MACLJ,EAAOF,CAAI,EACjBJ,IAAe,QAAUA,IAAeI,CAC1C,CACF,MAAQ,CACN,EAAW,IACb,CACA,GAAIK,EAAU,OAAOA,CACvB,CACA,OAAO,IACT"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChartRendererKind, ChartRendererPreference } from '../types.cjs';
|
|
2
|
+
import { ChartRenderer } from './types.cjs';
|
|
3
|
+
export declare const RENDERER_ORDER: readonly ChartRendererKind[];
|
|
4
|
+
/** Backends to try for a preference, best first */
|
|
5
|
+
export declare const rendererCandidates: (preference: ChartRendererPreference, exclude?: ReadonlySet<ChartRendererKind>) => ChartRendererKind[];
|
|
6
|
+
/**
|
|
7
|
+
* Creates the first backend that works. A canvas only ever gets one kind
|
|
8
|
+
* of context, so every attempt uses a fresh canvas from `makeCanvas`.
|
|
9
|
+
* With `auto`, GPU backends running in software (no hardware acceleration)
|
|
10
|
+
* are skipped: the decimating Canvas2D backend is much faster there.
|
|
11
|
+
*/
|
|
12
|
+
export declare const createRenderer: (preference: ChartRendererPreference, makeCanvas: () => HTMLCanvasElement, onLost: (kind: ChartRendererKind) => void, exclude?: ReadonlySet<ChartRendererKind>) => Promise<ChartRenderer | null>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ChartRendererKind, ChartRendererPreference } from '../types.js';
|
|
2
|
+
import { ChartRenderer } from './types.js';
|
|
3
|
+
export declare const RENDERER_ORDER: readonly ChartRendererKind[];
|
|
4
|
+
/** Backends to try for a preference, best first */
|
|
5
|
+
export declare const rendererCandidates: (preference: ChartRendererPreference, exclude?: ReadonlySet<ChartRendererKind>) => ChartRendererKind[];
|
|
6
|
+
/**
|
|
7
|
+
* Creates the first backend that works. A canvas only ever gets one kind
|
|
8
|
+
* of context, so every attempt uses a fresh canvas from `makeCanvas`.
|
|
9
|
+
* With `auto`, GPU backends running in software (no hardware acceleration)
|
|
10
|
+
* are skipped: the decimating Canvas2D backend is much faster there.
|
|
11
|
+
*/
|
|
12
|
+
export declare const createRenderer: (preference: ChartRendererPreference, makeCanvas: () => HTMLCanvasElement, onLost: (kind: ChartRendererKind) => void, exclude?: ReadonlySet<ChartRendererKind>) => Promise<ChartRenderer | null>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createCanvas2dRenderer as e } from "./canvas2d.js";
|
|
2
|
+
import { createWebGl2Renderer as t } from "./webgl2.js";
|
|
3
|
+
import { createWebGpuRenderer as n } from "./webgpu.js";
|
|
4
|
+
//#region src/engine/renderers/detect.ts
|
|
5
|
+
var r = [
|
|
6
|
+
"webgpu",
|
|
7
|
+
"webgl2",
|
|
8
|
+
"canvas2d"
|
|
9
|
+
], i = (e, t = /* @__PURE__ */ new Set()) => {
|
|
10
|
+
let n = e === "auto" ? 0 : r.indexOf(e);
|
|
11
|
+
return r.slice(Math.max(0, n)).filter((e) => !t.has(e));
|
|
12
|
+
}, a = async (r, i, a, o) => {
|
|
13
|
+
switch (r) {
|
|
14
|
+
case "webgpu": return n(i, a, o);
|
|
15
|
+
case "webgl2": return t(i, a, o);
|
|
16
|
+
default: return e(i);
|
|
17
|
+
}
|
|
18
|
+
}, o = async (e, t, n, r) => {
|
|
19
|
+
for (let o of i(e, r)) {
|
|
20
|
+
let r;
|
|
21
|
+
try {
|
|
22
|
+
r = await a(o, t(), () => n(o), e === "auto" || e !== o);
|
|
23
|
+
} catch {
|
|
24
|
+
r = null;
|
|
25
|
+
}
|
|
26
|
+
if (r) return r;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { r as RENDERER_ORDER, o as createRenderer, i as rendererCandidates };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","names":["RENDERER_ORDER","rendererCandidates","start","preference","exclude","k","create","kind","createWebGpuRenderer","canvas","onLost","requireHardware","createWebGl2Renderer","createCanvas2dRenderer","createRenderer","renderer","makeCanvas"],"sources":["../../../../../charts/src/engine/renderers/detect.ts"],"sourcesContent":["// Backend selection: WebGPU -> WebGL2 -> Canvas2D.\n\nimport type { ChartRendererKind, ChartRendererPreference } from \"../types\";\nimport { createCanvas2dRenderer } from \"./canvas2d\";\nimport type { ChartRenderer, RendererLostHandler } from \"./types\";\nimport { createWebGl2Renderer } from \"./webgl2\";\nimport { createWebGpuRenderer } from \"./webgpu\";\n\nexport const RENDERER_ORDER: readonly ChartRendererKind[] = [\n \"webgpu\",\n \"webgl2\",\n \"canvas2d\",\n];\n\n/** Backends to try for a preference, best first */\nexport const rendererCandidates = (\n preference: ChartRendererPreference,\n exclude: ReadonlySet<ChartRendererKind> = new Set(),\n): ChartRendererKind[] => {\n const start = preference === \"auto\" ? 0 : RENDERER_ORDER.indexOf(preference);\n return RENDERER_ORDER.slice(Math.max(0, start)).filter(\n (k) => !exclude.has(k),\n );\n};\n\nconst create = async (\n kind: ChartRendererKind,\n canvas: HTMLCanvasElement,\n onLost: RendererLostHandler,\n requireHardware: boolean,\n): Promise<ChartRenderer | null> => {\n switch (kind) {\n case \"webgpu\":\n return createWebGpuRenderer(canvas, onLost, requireHardware);\n case \"webgl2\":\n return createWebGl2Renderer(canvas, onLost, requireHardware);\n default:\n return createCanvas2dRenderer(canvas);\n }\n};\n\n/**\n * Creates the first backend that works. A canvas only ever gets one kind\n * of context, so every attempt uses a fresh canvas from `makeCanvas`.\n * With `auto`, GPU backends running in software (no hardware acceleration)\n * are skipped: the decimating Canvas2D backend is much faster there.\n */\nexport const createRenderer = async (\n preference: ChartRendererPreference,\n makeCanvas: () => HTMLCanvasElement,\n onLost: (kind: ChartRendererKind) => void,\n exclude?: ReadonlySet<ChartRendererKind>,\n): Promise<ChartRenderer | null> => {\n for (const kind of rendererCandidates(preference, exclude)) {\n let renderer: ChartRenderer | null;\n try {\n renderer = await create(\n kind,\n makeCanvas(),\n () => onLost(kind),\n preference === \"auto\" || preference !== kind,\n );\n } catch {\n renderer = null;\n }\n if (renderer) return renderer;\n }\n return null;\n};\n"],"mappings":";;;;AAQA,IAAaA,IAA+C;CAC1D;CACA;CACA;AACF,GAGaC,KACX,GACA,oBAA0C,IAAI,IAAI,MAC1B;CACxB,IAAMC,IAAQC,MAAe,SAAS,IAAIH,EAAe,QAAQG,CAAU;CAC3E,OAAOH,EAAe,MAAM,KAAK,IAAI,GAAGE,CAAK,CAAC,CAAC,CAAC,QAC7C,MAAM,CAACE,EAAQ,IAAIC,CAAC,CACvB;AACF,GAEMC,IAAS,OACb,GACA,GACA,GACA,MACkC;CAClC,QAAQC,GAAR;EACE,KAAK,UACH,OAAOC,EAAqBC,GAAQC,GAAQC,CAAe;EAC7D,KAAK,UACH,OAAOC,EAAqBH,GAAQC,GAAQC,CAAe;EAC7D,SACE,OAAOE,EAAuBJ,CAAM;CACxC;AACF,GAQaK,IAAiB,OAC5B,GACA,GACA,GACA,MACkC;CAClC,KAAK,IAAMP,KAAQN,EAAmBE,GAAYC,CAAO,GAAG;EAC1D,IAAIW;EACJ,IAAI;GACF,IAAW,MAAMT,EACfC,GACAS,EAAW,SACLN,EAAOH,CAAI,GACjBJ,MAAe,UAAUA,MAAeI,CAC1C;EACF,QAAQ;GACN,IAAW;EACb;EACA,IAAIQ,GAAU,OAAOA;CACvB;CACA,OAAO;AACT"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=(e,t,n,r)=>{let i=0,a=n;for(;i<a;){let n=i+a>>>1;e[n*t]<r?i=n+1:a=n}return i},t=e=>{let{xScale:t,xOffset:n}=e.transform,r=(-1-n)/t,i=(1-n)/t;return r<i?[r,i]:[i,r]},n=(n,r)=>{switch(n.kind){case`line`:case`area`:{let i=Math.max(0,n.count-1);if(!n.sorted||i===0)return[0,i];let[a,o]=t(r),s=Math.max(0,e(n.points,2,n.count,a)-1),c=Math.min(n.count-1,e(n.points,2,n.count,o));return[s,Math.max(0,c-s)]}case`bar`:{if(!n.sorted)return[0,n.count];let[i,a]=t(r),o=Math.abs(n.halfWidth),s=e(n.instances,3,n.count,i-o),c=e(n.instances,3,n.count,a+o);return[s,Math.max(0,c-s)]}default:return[0,n.count]}};exports.instanceRange=n,exports.visibleX=t;
|
|
2
|
+
//# sourceMappingURL=range.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range.cjs","names":["lowerBound","lo","hi","count","mid","values","stride","value","visibleX","frame","a","xOffset","xScale","b","instanceRange","item","segments","x0","x1","start","end","pad"],"sources":["../../../../../charts/src/engine/renderers/range.ts"],"sourcesContent":["// Instances to draw: sorted series only draw what is inside the view, so\n// zooming into a million points costs what is visible.\n\nimport type { RenderFrame, RenderItem } from \"./types\";\n\nconst lowerBound = (\n values: Float32Array,\n stride: number,\n count: number,\n value: number,\n) => {\n let lo = 0;\n let hi = count;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (values[mid * stride] < value) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n};\n\n/** Visible relative x range of a frame */\nexport const visibleX = (frame: RenderFrame): [number, number] => {\n const { xScale, xOffset } = frame.transform;\n const a = (-1 - xOffset) / xScale;\n const b = (1 - xOffset) / xScale;\n return a < b ? [a, b] : [b, a];\n};\n\n/** First instance and instance count to draw */\nexport const instanceRange = (\n item: RenderItem,\n frame: RenderFrame,\n): [number, number] => {\n switch (item.kind) {\n case \"line\":\n case \"area\": {\n const segments = Math.max(0, item.count - 1);\n if (!item.sorted || segments === 0) return [0, segments];\n const [x0, x1] = visibleX(frame);\n const start = Math.max(0, lowerBound(item.points, 2, item.count, x0) - 1);\n const end = Math.min(\n item.count - 1,\n lowerBound(item.points, 2, item.count, x1),\n );\n return [start, Math.max(0, end - start)];\n }\n case \"bar\": {\n if (!item.sorted) return [0, item.count];\n const [x0, x1] = visibleX(frame);\n const pad = Math.abs(item.halfWidth);\n const start = lowerBound(item.instances, 3, item.count, x0 - pad);\n const end = lowerBound(item.instances, 3, item.count, x1 + pad);\n return [start, Math.max(0, end - start)];\n }\n default:\n return [0, item.count];\n }\n};\n"],"mappings":"AAKA,IAAMA,GACJ,EACA,EACA,EACA,IACG,CACH,IAAIC,EAAK,EACLC,EAAKC,EACT,KAAOF,EAAKC,GAAI,CACd,IAAME,EAAOH,EAAKC,IAAQ,EACtBG,EAAOD,EAAME,GAAUC,EAAO,EAAKH,EAAM,EACxC,EAAKA,CACZ,CACA,OAAOH,CACT,EAGaO,EAAY,GAAyC,CAChE,GAAM,CAAE,SAAQ,WAAYC,EAAM,UAC5BC,GAAK,GAAKC,GAAWC,EACrBC,GAAK,EAAIF,GAAWC,EAC1B,OAAOF,EAAIG,EAAI,CAACH,EAAGG,CAAC,EAAI,CAACA,EAAGH,CAAC,CAC/B,EAGaI,GACX,EACA,IACqB,CACrB,OAAQC,EAAK,KAAb,CACE,IAAK,OACL,IAAK,OAAQ,CACX,IAAMC,EAAW,KAAK,IAAI,EAAGD,EAAK,MAAQ,CAAC,EAC3C,GAAI,CAACA,EAAK,QAAUC,IAAa,EAAG,MAAO,CAAC,EAAGA,CAAQ,EACvD,GAAM,CAACC,EAAIC,GAAMV,EAASC,CAAK,EACzBU,EAAQ,KAAK,IAAI,EAAGnB,EAAWe,EAAK,OAAQ,EAAGA,EAAK,MAAOE,CAAE,EAAI,CAAC,EAClEG,EAAM,KAAK,IACfL,EAAK,MAAQ,EACbf,EAAWe,EAAK,OAAQ,EAAGA,EAAK,MAAOG,CAAE,CAC3C,EACA,MAAO,CAACC,EAAO,KAAK,IAAI,EAAGC,EAAMD,CAAK,CAAC,CACzC,CACA,IAAK,MAAO,CACV,GAAI,CAACJ,EAAK,OAAQ,MAAO,CAAC,EAAGA,EAAK,KAAK,EACvC,GAAM,CAACE,EAAIC,GAAMV,EAASC,CAAK,EACzBY,EAAM,KAAK,IAAIN,EAAK,SAAS,EAC7BI,EAAQnB,EAAWe,EAAK,UAAW,EAAGA,EAAK,MAAOE,EAAKI,CAAG,EAC1DD,EAAMpB,EAAWe,EAAK,UAAW,EAAGA,EAAK,MAAOG,EAAKG,CAAG,EAC9D,MAAO,CAACF,EAAO,KAAK,IAAI,EAAGC,EAAMD,CAAK,CAAC,CACzC,CACA,QACE,MAAO,CAAC,EAAGJ,EAAK,KAAK,CACzB,CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RenderFrame, RenderItem } from './types.cjs';
|
|
2
|
+
/** Visible relative x range of a frame */
|
|
3
|
+
export declare const visibleX: (frame: RenderFrame) => [number, number];
|
|
4
|
+
/** First instance and instance count to draw */
|
|
5
|
+
export declare const instanceRange: (item: RenderItem, frame: RenderFrame) => [number, number];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RenderFrame, RenderItem } from './types.js';
|
|
2
|
+
/** Visible relative x range of a frame */
|
|
3
|
+
export declare const visibleX: (frame: RenderFrame) => [number, number];
|
|
4
|
+
/** First instance and instance count to draw */
|
|
5
|
+
export declare const instanceRange: (item: RenderItem, frame: RenderFrame) => [number, number];
|