uplot-webgpu 0.1.0 → 0.2.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/index.js +0 -17
- package/index.ts +5 -0
- package/package.json +4 -69
- package/paths/ts/bars.ts +253 -0
- package/paths/ts/catmullRomCentrip.ts +127 -0
- package/paths/ts/index.ts +9 -0
- package/paths/ts/linear.ts +172 -0
- package/paths/ts/monotoneCubic.ts +70 -0
- package/paths/ts/points.ts +70 -0
- package/paths/ts/spline.ts +105 -0
- package/paths/ts/stepped.ts +126 -0
- package/paths/ts/types.ts +143 -0
- package/paths/ts/utils.ts +303 -0
- package/scripts/ts/uPlot.ts +3732 -0
- package/scripts/ts/utils/dom.ts +124 -0
- package/scripts/ts/utils/domClasses.ts +22 -0
- package/scripts/ts/utils/feats.ts +13 -0
- package/scripts/ts/utils/fmtDate.ts +398 -0
- package/scripts/ts/utils/opts.ts +844 -0
- package/scripts/ts/utils/strings.ts +22 -0
- package/scripts/ts/utils/sync.ts +27 -0
- package/scripts/ts/utils/utils.ts +692 -0
- package/scripts/{webgpu → ts/webgpu}/GPUPath.ts +92 -41
- package/scripts/{webgpu → ts/webgpu}/WebGPURenderer.ts +176 -84
- package/scripts/ts/webgpu/exporters.ts +221 -0
- package/scripts/ts/webgpu/index.ts +31 -0
- package/scripts/{webgpu → ts/webgpu}/shaders.ts +0 -1
- package/scripts/uPlot.js +0 -2
- package/scripts/webgpu/GPUPath.js +513 -606
- package/scripts/webgpu/WebGPURenderer.js +3484 -4018
- package/scripts/webgpu/exporters.js +191 -201
- package/scripts/webgpu/index.js +12 -0
- package/scripts/webgpu/shaders.js +6 -3
- package/tinybuild.config.js +6 -6
- package/tsconfig.json +64 -0
- package/scripts/uPlot.d.ts +0 -26
- package/scripts/webgpu/GPUPath.d.ts +0 -46
- package/scripts/webgpu/WebGPURenderer.d.ts +0 -176
- package/scripts/webgpu/exporters.d.ts +0 -8
- package/scripts/webgpu/shaders.d.ts +0 -2
- package/scripts/webgpu/smokeTest.d.ts +0 -2
- package/scripts/webgpu/webgpu-ambient.d.ts +0 -41
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { GPUPath } from '../../scripts/ts/webgpu/GPUPath.js';
|
|
2
|
+
import { splineInterp } from "./spline.js";
|
|
3
|
+
import type { SplinePathOptions, PathBuilder } from './types.js';
|
|
4
|
+
|
|
5
|
+
export function monotoneCubic(opts: SplinePathOptions = {}): PathBuilder {
|
|
6
|
+
return splineInterp(_monotoneCubic, opts);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// Monotone Cubic Spline interpolation, adapted from the Chartist.js implementation:
|
|
10
|
+
// https://github.com/gionkunz/chartist-js/blob/e7e78201bffe9609915e5e53cfafa29a5d6c49f9/src/scripts/interpolation.js#L240-L369
|
|
11
|
+
function _monotoneCubic(xs, ys, moveTo, lineTo, bezierCurveTo, pxRound) {
|
|
12
|
+
const n = xs.length;
|
|
13
|
+
|
|
14
|
+
if (n < 2)
|
|
15
|
+
return null;
|
|
16
|
+
|
|
17
|
+
const path = new GPUPath();
|
|
18
|
+
|
|
19
|
+
moveTo(path, xs[0], ys[0]);
|
|
20
|
+
|
|
21
|
+
if (n == 2)
|
|
22
|
+
lineTo(path, xs[1], ys[1]);
|
|
23
|
+
else {
|
|
24
|
+
let ms = Array(n),
|
|
25
|
+
ds = Array(n - 1),
|
|
26
|
+
dys = Array(n - 1),
|
|
27
|
+
dxs = Array(n - 1);
|
|
28
|
+
|
|
29
|
+
// calc deltas and derivative
|
|
30
|
+
for (let i = 0; i < n - 1; i++) {
|
|
31
|
+
dys[i] = ys[i + 1] - ys[i];
|
|
32
|
+
dxs[i] = xs[i + 1] - xs[i];
|
|
33
|
+
ds[i] = dys[i] / dxs[i];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// determine desired slope (m) at each point using Fritsch-Carlson method
|
|
37
|
+
// http://math.stackexchange.com/questions/45218/implementation-of-monotone-cubic-interpolation
|
|
38
|
+
ms[0] = ds[0];
|
|
39
|
+
|
|
40
|
+
for (let i = 1; i < n - 1; i++) {
|
|
41
|
+
if (ds[i] === 0 || ds[i - 1] === 0 || (ds[i - 1] > 0) !== (ds[i] > 0))
|
|
42
|
+
ms[i] = 0;
|
|
43
|
+
else {
|
|
44
|
+
ms[i] = 3 * (dxs[i - 1] + dxs[i]) / (
|
|
45
|
+
(2 * dxs[i] + dxs[i - 1]) / ds[i - 1] +
|
|
46
|
+
(dxs[i] + 2 * dxs[i - 1]) / ds[i]
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
if (!isFinite(ms[i]))
|
|
50
|
+
ms[i] = 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ms[n - 1] = ds[n - 2];
|
|
55
|
+
|
|
56
|
+
for (let i = 0; i < n - 1; i++) {
|
|
57
|
+
bezierCurveTo(
|
|
58
|
+
path,
|
|
59
|
+
xs[i] + dxs[i] / 3,
|
|
60
|
+
ys[i] + ms[i] * dxs[i] / 3,
|
|
61
|
+
xs[i + 1] - dxs[i] / 3,
|
|
62
|
+
ys[i + 1] - ms[i + 1] * dxs[i] / 3,
|
|
63
|
+
xs[i + 1],
|
|
64
|
+
ys[i + 1],
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return path;
|
|
70
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { GPUPath } from '../../scripts/ts/webgpu/GPUPath.js';
|
|
2
|
+
import { orient, moveToH, moveToV, rectH, arcH, arcV, BAND_CLIP_FILL, BAND_CLIP_STROKE } from './utils.js';
|
|
3
|
+
import { roundDec, PI } from '../../scripts/ts/utils/utils.js';
|
|
4
|
+
import type { PathBuilder, PointPathOptions } from './types.js';
|
|
5
|
+
|
|
6
|
+
// TODO: drawWrap(seriesIdx, drawPoints) (save, restore, translate, clip)
|
|
7
|
+
export function points(opts: PointPathOptions = {}): PathBuilder {
|
|
8
|
+
return (u, seriesIdx, idx0, idx1, filtIdxs) => {
|
|
9
|
+
// log("drawPoints()", arguments);
|
|
10
|
+
let { pxRatio } = u;
|
|
11
|
+
|
|
12
|
+
return orient(u, seriesIdx, (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
|
|
13
|
+
let { pxRound, points } = series;
|
|
14
|
+
|
|
15
|
+
let moveTo, arc;
|
|
16
|
+
|
|
17
|
+
if (scaleX.ori == 0) {
|
|
18
|
+
moveTo = moveToH;
|
|
19
|
+
arc = arcH;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
moveTo = moveToV;
|
|
23
|
+
arc = arcV;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const width = roundDec(points.width * pxRatio, 3);
|
|
27
|
+
|
|
28
|
+
let rad = (points.size - points.width) / 2 * pxRatio;
|
|
29
|
+
let dia = roundDec(rad * 2, 3);
|
|
30
|
+
|
|
31
|
+
let fill = new GPUPath();
|
|
32
|
+
let clip = new GPUPath();
|
|
33
|
+
|
|
34
|
+
let { left: lft, top: top, width: wid, height: hgt } = u.bbox;
|
|
35
|
+
|
|
36
|
+
rectH(clip,
|
|
37
|
+
lft - dia,
|
|
38
|
+
top - dia,
|
|
39
|
+
wid + dia * 2,
|
|
40
|
+
hgt + dia * 2,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const drawPoint = pi => {
|
|
44
|
+
if (dataY[pi] != null) {
|
|
45
|
+
let x = pxRound(valToPosX(dataX[pi], scaleX, xDim, xOff));
|
|
46
|
+
let y = pxRound(valToPosY(dataY[pi], scaleY, yDim, yOff));
|
|
47
|
+
|
|
48
|
+
moveTo(fill, x + rad, y);
|
|
49
|
+
arc(fill, x, y, rad, 0, PI * 2);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
if (filtIdxs)
|
|
54
|
+
filtIdxs.forEach(drawPoint);
|
|
55
|
+
else {
|
|
56
|
+
for (let pi = idx0; pi <= idx1; pi++)
|
|
57
|
+
drawPoint(pi);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
stroke: width > 0 ? fill : null,
|
|
62
|
+
fill,
|
|
63
|
+
clip,
|
|
64
|
+
band: null,
|
|
65
|
+
gaps: null,
|
|
66
|
+
flags: BAND_CLIP_FILL | BAND_CLIP_STROKE,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { GPUPath } from '../../scripts/ts/webgpu/GPUPath.js';
|
|
2
|
+
import { ifNull, nonNullIdxs } from '../../scripts/ts/utils/utils.js';
|
|
3
|
+
import { orient, clipGaps, moveToH, moveToV, lineToH, lineToV, bezierCurveToH, bezierCurveToV, clipBandLine, BAND_CLIP_FILL, bandFillClipDirs, findGaps } from './utils.js';
|
|
4
|
+
import type { InterpolationFitter, PathBuilder, SplinePathOptions } from './types.js';
|
|
5
|
+
|
|
6
|
+
export function splineInterp(interp: InterpolationFitter, opts: SplinePathOptions = {}): PathBuilder {
|
|
7
|
+
return (u, seriesIdx, idx0, idx1) => {
|
|
8
|
+
return orient(u, seriesIdx, (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
|
|
9
|
+
[idx0, idx1] = nonNullIdxs(dataY, idx0, idx1);
|
|
10
|
+
|
|
11
|
+
let pxRound = series.pxRound;
|
|
12
|
+
|
|
13
|
+
let alignGaps = opts?.alignGaps ?? series.alignGaps ?? 0;
|
|
14
|
+
|
|
15
|
+
let pixelForX = val => pxRound(valToPosX(val, scaleX, xDim, xOff));
|
|
16
|
+
let pixelForY = val => pxRound(valToPosY(val, scaleY, yDim, yOff));
|
|
17
|
+
|
|
18
|
+
let moveTo, bezierCurveTo, lineTo;
|
|
19
|
+
|
|
20
|
+
if (scaleX.ori == 0) {
|
|
21
|
+
moveTo = moveToH;
|
|
22
|
+
lineTo = lineToH;
|
|
23
|
+
bezierCurveTo = bezierCurveToH;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
moveTo = moveToV;
|
|
27
|
+
lineTo = lineToV;
|
|
28
|
+
bezierCurveTo = bezierCurveToV;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const dir = scaleX.dir * (scaleX.ori == 0 ? 1 : -1);
|
|
32
|
+
|
|
33
|
+
let firstXPos = pixelForX(dataX[dir == 1 ? idx0 : idx1]);
|
|
34
|
+
let prevXPos = firstXPos;
|
|
35
|
+
|
|
36
|
+
let xCoords = [];
|
|
37
|
+
let yCoords = [];
|
|
38
|
+
|
|
39
|
+
let hasGap = false;
|
|
40
|
+
|
|
41
|
+
for (let i = dir == 1 ? idx0 : idx1; i >= idx0 && i <= idx1; i += dir) {
|
|
42
|
+
let yVal = dataY[i];
|
|
43
|
+
|
|
44
|
+
if (yVal != null) {
|
|
45
|
+
let xVal = dataX[i];
|
|
46
|
+
let xPos = pixelForX(xVal);
|
|
47
|
+
|
|
48
|
+
xCoords.push(prevXPos = xPos);
|
|
49
|
+
yCoords.push(pixelForY(dataY[i]));
|
|
50
|
+
}
|
|
51
|
+
else if (yVal === null)
|
|
52
|
+
hasGap = true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const _paths = {stroke: interp(xCoords, yCoords, moveTo, lineTo, bezierCurveTo, pxRound), fill: null, clip: null, band: null, gaps: null, flags: BAND_CLIP_FILL};
|
|
56
|
+
const stroke = _paths.stroke;
|
|
57
|
+
|
|
58
|
+
let [ bandFillDir, bandClipDir ] = bandFillClipDirs(u, seriesIdx);
|
|
59
|
+
|
|
60
|
+
if (series.fill != null || bandFillDir != 0) {
|
|
61
|
+
let fill = _paths.fill = new GPUPath(stroke);
|
|
62
|
+
|
|
63
|
+
let fillTo = series.fillTo(u, seriesIdx, series.min, series.max, bandFillDir);
|
|
64
|
+
let fillToY = pixelForY(fillTo);
|
|
65
|
+
|
|
66
|
+
lineTo(fill, prevXPos, fillToY);
|
|
67
|
+
lineTo(fill, firstXPos, fillToY);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!series.spanGaps) {
|
|
71
|
+
// console.time('gaps');
|
|
72
|
+
let gaps = hasGap ? findGaps(dataX, dataY, idx0, idx1, dir, pixelForX, alignGaps) : [];
|
|
73
|
+
|
|
74
|
+
// console.timeEnd('gaps');
|
|
75
|
+
|
|
76
|
+
// console.log('gaps', JSON.stringify(gaps));
|
|
77
|
+
|
|
78
|
+
_paths.gaps = gaps = series.gaps(u, seriesIdx, idx0, idx1, gaps);
|
|
79
|
+
|
|
80
|
+
_paths.clip = clipGaps(gaps, scaleX.ori, xOff, yOff, xDim, yDim);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (bandClipDir != 0) {
|
|
84
|
+
_paths.band = bandClipDir == 2 ? [
|
|
85
|
+
clipBandLine(u, seriesIdx, idx0, idx1, stroke, -1),
|
|
86
|
+
clipBandLine(u, seriesIdx, idx0, idx1, stroke, 1),
|
|
87
|
+
] : clipBandLine(u, seriesIdx, idx0, idx1, stroke, bandClipDir);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return _paths;
|
|
91
|
+
|
|
92
|
+
// if FEAT_PATHS: false in rollup.config.js
|
|
93
|
+
// u.ctx.save();
|
|
94
|
+
// u.ctx.beginPath();
|
|
95
|
+
// u.ctx.rect(u.bbox.left, u.bbox.top, u.bbox.width, u.bbox.height);
|
|
96
|
+
// u.ctx.clip();
|
|
97
|
+
// u.ctx.strokeStyle = u.series[sidx].stroke;
|
|
98
|
+
// u.ctx.stroke(stroke);
|
|
99
|
+
// u.ctx.fillStyle = u.series[sidx].fill;
|
|
100
|
+
// u.ctx.fill(fill);
|
|
101
|
+
// u.ctx.restore();
|
|
102
|
+
// return null;
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { GPUPath } from '../../scripts/ts/webgpu/GPUPath.js';
|
|
2
|
+
import { ifNull, nonNullIdxs } from '../../scripts/ts/utils/utils.js';
|
|
3
|
+
import { orient, clipGaps, lineToH, lineToV, clipBandLine, BAND_CLIP_FILL, bandFillClipDirs, findGaps } from './utils.js';
|
|
4
|
+
import type { PathBuilder, SteppedPathOptions } from './types.js';
|
|
5
|
+
|
|
6
|
+
// BUG: align: -1 behaves like align: 1 when scale.dir: -1
|
|
7
|
+
export function stepped(opts: SteppedPathOptions = {}): PathBuilder {
|
|
8
|
+
const align = ifNull(opts.align, 1);
|
|
9
|
+
// whether to draw ascenders/descenders at null/gap bondaries
|
|
10
|
+
const ascDesc = ifNull(opts.ascDesc, false);
|
|
11
|
+
const extend = ifNull(opts.extend, false);
|
|
12
|
+
|
|
13
|
+
return (u, seriesIdx, idx0, idx1) => {
|
|
14
|
+
let { pxRatio } = u;
|
|
15
|
+
|
|
16
|
+
return orient(u, seriesIdx, (series, dataX, dataY, scaleX, scaleY, valToPosX, valToPosY, xOff, yOff, xDim, yDim) => {
|
|
17
|
+
[idx0, idx1] = nonNullIdxs(dataY, idx0, idx1);
|
|
18
|
+
|
|
19
|
+
let pxRound = series.pxRound;
|
|
20
|
+
|
|
21
|
+
let alignGaps = opts?.alignGaps ?? series.alignGaps ?? 0;
|
|
22
|
+
|
|
23
|
+
let { left, width } = u.bbox;
|
|
24
|
+
|
|
25
|
+
let pixelForX = val => pxRound(valToPosX(val, scaleX, xDim, xOff));
|
|
26
|
+
let pixelForY = val => pxRound(valToPosY(val, scaleY, yDim, yOff));
|
|
27
|
+
|
|
28
|
+
let lineTo = scaleX.ori == 0 ? lineToH : lineToV;
|
|
29
|
+
|
|
30
|
+
const _paths = {stroke: new GPUPath(), fill: null, clip: null, band: null, gaps: null, flags: BAND_CLIP_FILL};
|
|
31
|
+
const stroke = _paths.stroke;
|
|
32
|
+
|
|
33
|
+
const dir = scaleX.dir * (scaleX.ori == 0 ? 1 : -1);
|
|
34
|
+
|
|
35
|
+
let hasGap = false;
|
|
36
|
+
|
|
37
|
+
let prevYPos = pixelForY(dataY[dir == 1 ? idx0 : idx1]);
|
|
38
|
+
let firstXPos = pixelForX(dataX[dir == 1 ? idx0 : idx1]);
|
|
39
|
+
let prevXPos = firstXPos;
|
|
40
|
+
|
|
41
|
+
let firstXPosExt = firstXPos;
|
|
42
|
+
|
|
43
|
+
if (extend && align == -1) {
|
|
44
|
+
firstXPosExt = left;
|
|
45
|
+
lineTo(stroke, firstXPosExt, prevYPos);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
lineTo(stroke, firstXPos, prevYPos);
|
|
49
|
+
|
|
50
|
+
for (let i = dir == 1 ? idx0 : idx1; i >= idx0 && i <= idx1; i += dir) {
|
|
51
|
+
let yVal1 = dataY[i];
|
|
52
|
+
|
|
53
|
+
if (yVal1 == null) {
|
|
54
|
+
if (yVal1 === null)
|
|
55
|
+
hasGap = true;
|
|
56
|
+
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let x1 = pixelForX(dataX[i]);
|
|
61
|
+
let y1 = pixelForY(yVal1);
|
|
62
|
+
|
|
63
|
+
if (align == 1)
|
|
64
|
+
lineTo(stroke, x1, prevYPos);
|
|
65
|
+
else
|
|
66
|
+
lineTo(stroke, prevXPos, y1);
|
|
67
|
+
|
|
68
|
+
lineTo(stroke, x1, y1);
|
|
69
|
+
|
|
70
|
+
prevYPos = y1;
|
|
71
|
+
prevXPos = x1;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let prevXPosExt = prevXPos;
|
|
75
|
+
|
|
76
|
+
if (extend && align == 1) {
|
|
77
|
+
prevXPosExt = left + width;
|
|
78
|
+
lineTo(stroke, prevXPosExt, prevYPos);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let [ bandFillDir, bandClipDir ] = bandFillClipDirs(u, seriesIdx);
|
|
82
|
+
|
|
83
|
+
if (series.fill != null || bandFillDir != 0) {
|
|
84
|
+
let fill = _paths.fill = new GPUPath(stroke);
|
|
85
|
+
|
|
86
|
+
let fillTo = series.fillTo(u, seriesIdx, series.min, series.max, bandFillDir);
|
|
87
|
+
let fillToY = pixelForY(fillTo);
|
|
88
|
+
|
|
89
|
+
lineTo(fill, prevXPosExt, fillToY);
|
|
90
|
+
lineTo(fill, firstXPosExt, fillToY);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!series.spanGaps) {
|
|
94
|
+
// console.time('gaps');
|
|
95
|
+
let gaps = hasGap ? findGaps(dataX, dataY, idx0, idx1, dir, pixelForX, alignGaps) : [];
|
|
96
|
+
|
|
97
|
+
// console.timeEnd('gaps');
|
|
98
|
+
|
|
99
|
+
// console.log('gaps', JSON.stringify(gaps));
|
|
100
|
+
|
|
101
|
+
// expand/contract clips for ascenders/descenders
|
|
102
|
+
let halfStroke = (series.width * pxRatio) / 2;
|
|
103
|
+
let startsOffset = (ascDesc || align == 1) ? halfStroke : -halfStroke;
|
|
104
|
+
let endsOffset = (ascDesc || align == -1) ? -halfStroke : halfStroke;
|
|
105
|
+
|
|
106
|
+
gaps.forEach(g => {
|
|
107
|
+
g[0] += startsOffset;
|
|
108
|
+
g[1] += endsOffset;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
_paths.gaps = gaps = series.gaps(u, seriesIdx, idx0, idx1, gaps);
|
|
112
|
+
|
|
113
|
+
_paths.clip = clipGaps(gaps, scaleX.ori, xOff, yOff, xDim, yDim);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (bandClipDir != 0) {
|
|
117
|
+
_paths.band = bandClipDir == 2 ? [
|
|
118
|
+
clipBandLine(u, seriesIdx, idx0, idx1, stroke, -1),
|
|
119
|
+
clipBandLine(u, seriesIdx, idx0, idx1, stroke, 1),
|
|
120
|
+
] : clipBandLine(u, seriesIdx, idx0, idx1, stroke, bandClipDir);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return _paths;
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { GPUPath } from '../../scripts/ts/webgpu/GPUPath.js';
|
|
2
|
+
|
|
3
|
+
export type PathValue = number | null | undefined;
|
|
4
|
+
export type PathData = ArrayLike<PathValue>;
|
|
5
|
+
export type PathXData = ArrayLike<number> & { map?: (callback: (value: number, index: number) => number) => number[] };
|
|
6
|
+
export type PixelRound = (value: number) => number;
|
|
7
|
+
export type ValueToPos = (value: number, scale: ScaleLike, dim: number, off: number) => number;
|
|
8
|
+
export type Direction = -1 | 0 | 1 | 2;
|
|
9
|
+
export type Orientation = 0 | 1;
|
|
10
|
+
export type Gap = [from: number, to: number];
|
|
11
|
+
export type GapList = Gap[];
|
|
12
|
+
|
|
13
|
+
export interface ScaleLike {
|
|
14
|
+
key?: string;
|
|
15
|
+
ori: Orientation;
|
|
16
|
+
dir: -1 | 1;
|
|
17
|
+
distr?: number;
|
|
18
|
+
min?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
[k: string]: any;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface BandLike {
|
|
24
|
+
series: [number, number];
|
|
25
|
+
dir: -1 | 0 | 1;
|
|
26
|
+
[k: string]: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SeriesLike {
|
|
30
|
+
scale?: string;
|
|
31
|
+
facets?: [{ scale: string }, { scale: string }];
|
|
32
|
+
pxRound: PixelRound;
|
|
33
|
+
width: number;
|
|
34
|
+
fill?: string | CanvasGradient | CanvasPattern | null;
|
|
35
|
+
_fill?: unknown;
|
|
36
|
+
_stroke?: unknown;
|
|
37
|
+
min?: number;
|
|
38
|
+
max?: number;
|
|
39
|
+
spanGaps?: boolean;
|
|
40
|
+
alignGaps?: number;
|
|
41
|
+
points?: any;
|
|
42
|
+
fillTo: (u: UPlotPathLike, seriesIdx: number, dataMin: number | undefined, dataMax: number | undefined, bandFillDir: number) => number;
|
|
43
|
+
gaps: (u: UPlotPathLike, seriesIdx: number, idx0: number, idx1: number, gaps: GapList) => GapList;
|
|
44
|
+
[k: string]: any;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface UPlotPathLike {
|
|
48
|
+
mode: number;
|
|
49
|
+
pxRatio: number;
|
|
50
|
+
_data: any;
|
|
51
|
+
data: any;
|
|
52
|
+
series: SeriesLike[];
|
|
53
|
+
scales: Record<string, ScaleLike>;
|
|
54
|
+
bbox: { left: number; top: number; width: number; height: number };
|
|
55
|
+
bands?: BandLike[];
|
|
56
|
+
valToPosH: ValueToPos;
|
|
57
|
+
valToPosV: ValueToPos;
|
|
58
|
+
posToVal: (pos: number, scaleKey: string, can?: boolean) => number;
|
|
59
|
+
[k: string]: any;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type PathPrimitive = GPUPath;
|
|
63
|
+
export type PathPrimitiveMap = Map<unknown, GPUPath>;
|
|
64
|
+
export type ClipPath = GPUPath | null;
|
|
65
|
+
export type BandClipPath = GPUPath | [GPUPath, GPUPath] | null;
|
|
66
|
+
|
|
67
|
+
export interface PathBuildResult {
|
|
68
|
+
stroke: GPUPath | PathPrimitiveMap | null;
|
|
69
|
+
fill: GPUPath | PathPrimitiveMap | null;
|
|
70
|
+
clip: ClipPath;
|
|
71
|
+
band: BandClipPath;
|
|
72
|
+
gaps: GapList | null;
|
|
73
|
+
flags: number;
|
|
74
|
+
_fill?: unknown;
|
|
75
|
+
width?: number;
|
|
76
|
+
[k: string]: unknown;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export type PathBuilder = (u: UPlotPathLike, seriesIdx: number, idx0: number, idx1: number, filtIdxs?: number[] | null) => PathBuildResult | null;
|
|
80
|
+
export type PathFactory<TOptions = unknown> = (opts?: TOptions) => PathBuilder;
|
|
81
|
+
|
|
82
|
+
export interface BarPathOptions {
|
|
83
|
+
size?: [factor?: number, maxWidth?: number, minWidth?: number];
|
|
84
|
+
align?: -1 | 0 | 1;
|
|
85
|
+
gap?: number;
|
|
86
|
+
radius?: number | [valueRadius: number, baselineRadius: number] | ((u: UPlotPathLike, seriesIdx: number) => [number, number]);
|
|
87
|
+
disp?: any;
|
|
88
|
+
each?: (u: UPlotPathLike, seriesIdx: number, idx: number, left: number, top: number, width: number, height: number) => void;
|
|
89
|
+
[k: string]: unknown;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface LinearPathOptions {
|
|
93
|
+
alignGaps?: number;
|
|
94
|
+
[k: string]: unknown;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface SteppedPathOptions extends LinearPathOptions {
|
|
98
|
+
align?: -1 | 1;
|
|
99
|
+
ascDesc?: boolean;
|
|
100
|
+
extend?: boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface PointPathOptions {
|
|
104
|
+
[k: string]: unknown;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface SplinePathOptions extends LinearPathOptions {
|
|
108
|
+
[k: string]: unknown;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type MoveToFn = (path: GPUPath, x: number, y: number) => void;
|
|
112
|
+
export type LineToFn = (path: GPUPath, x: number, y: number) => void;
|
|
113
|
+
export type RectFn = (path: GPUPath, x: number, y: number, width: number, height: number, endRadius?: number, baseRadius?: number) => void;
|
|
114
|
+
export type ArcFn = (path: GPUPath, x: number, y: number, radius: number, startAngle: number, endAngle: number) => void;
|
|
115
|
+
export type BezierCurveToFn = (path: GPUPath, bp1x: number, bp1y: number, bp2x: number, bp2y: number, p2x: number, p2y: number) => void;
|
|
116
|
+
|
|
117
|
+
export type OrientedPathCallback<T = unknown> = (
|
|
118
|
+
series: SeriesLike,
|
|
119
|
+
dataX: PathXData,
|
|
120
|
+
dataY: PathData,
|
|
121
|
+
scaleX: ScaleLike,
|
|
122
|
+
scaleY: ScaleLike,
|
|
123
|
+
valToPosX: ValueToPos,
|
|
124
|
+
valToPosY: ValueToPos,
|
|
125
|
+
xOff: number,
|
|
126
|
+
yOff: number,
|
|
127
|
+
xDim: number,
|
|
128
|
+
yDim: number,
|
|
129
|
+
moveTo: MoveToFn,
|
|
130
|
+
lineTo: LineToFn,
|
|
131
|
+
rect: RectFn,
|
|
132
|
+
arc: ArcFn,
|
|
133
|
+
bezierCurveTo: BezierCurveToFn,
|
|
134
|
+
) => T;
|
|
135
|
+
|
|
136
|
+
export type InterpolationFitter = (
|
|
137
|
+
xCoords: number[],
|
|
138
|
+
yCoords: number[],
|
|
139
|
+
moveTo: MoveToFn,
|
|
140
|
+
lineTo: LineToFn,
|
|
141
|
+
bezierCurveTo: BezierCurveToFn,
|
|
142
|
+
pxRound: PixelRound,
|
|
143
|
+
) => GPUPath;
|