@chartts/gl 0.1.4 → 0.1.5
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/dist/bar3d.cjs +4 -4
- package/dist/bar3d.d.cts +2 -2
- package/dist/bar3d.d.ts +2 -2
- package/dist/bar3d.js +1 -1
- package/dist/{chunk-XGQDO4VO.js → chunk-AGG2KSBO.js} +265 -41
- package/dist/chunk-AGG2KSBO.js.map +1 -0
- package/dist/{chunk-JCECG2KY.cjs → chunk-OTQKQDB6.cjs} +266 -40
- package/dist/chunk-OTQKQDB6.cjs.map +1 -0
- package/dist/{factory-Cp9Kr7aa.d.cts → factory-jQSzXhK4.d.cts} +4 -1
- package/dist/{factory-Cp9Kr7aa.d.ts → factory-jQSzXhK4.d.ts} +4 -1
- package/dist/flow-gl.cjs +4 -4
- package/dist/flow-gl.d.cts +2 -2
- package/dist/flow-gl.d.ts +2 -2
- package/dist/flow-gl.js +1 -1
- package/dist/globe3d.cjs +4 -4
- package/dist/globe3d.d.cts +2 -2
- package/dist/globe3d.d.ts +2 -2
- package/dist/globe3d.js +1 -1
- package/dist/graph-gl.cjs +4 -4
- package/dist/graph-gl.d.cts +2 -2
- package/dist/graph-gl.d.ts +2 -2
- package/dist/graph-gl.js +1 -1
- package/dist/index.cjs +60 -52
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/line3d.cjs +4 -4
- package/dist/line3d.d.cts +2 -2
- package/dist/line3d.d.ts +2 -2
- package/dist/line3d.js +1 -1
- package/dist/lines-gl.cjs +4 -4
- package/dist/lines-gl.d.cts +2 -2
- package/dist/lines-gl.d.ts +2 -2
- package/dist/lines-gl.js +1 -1
- package/dist/lines3d.cjs +4 -4
- package/dist/lines3d.d.cts +2 -2
- package/dist/lines3d.d.ts +2 -2
- package/dist/lines3d.js +1 -1
- package/dist/map3d.cjs +4 -4
- package/dist/map3d.d.cts +2 -2
- package/dist/map3d.d.ts +2 -2
- package/dist/map3d.js +1 -1
- package/dist/scatter-gl.cjs +4 -4
- package/dist/scatter-gl.d.cts +2 -2
- package/dist/scatter-gl.d.ts +2 -2
- package/dist/scatter-gl.js +1 -1
- package/dist/scatter3d.cjs +4 -4
- package/dist/scatter3d.d.cts +2 -2
- package/dist/scatter3d.d.ts +2 -2
- package/dist/scatter3d.js +1 -1
- package/dist/surface3d.cjs +4 -4
- package/dist/surface3d.d.cts +2 -2
- package/dist/surface3d.d.ts +2 -2
- package/dist/surface3d.js +1 -1
- package/dist/torus3d-NpDo5Nb5.d.ts +15 -0
- package/dist/torus3d-fgZpxxQZ.d.cts +15 -0
- package/dist/torus3d.cjs +20 -0
- package/dist/torus3d.cjs.map +1 -0
- package/dist/torus3d.d.cts +2 -0
- package/dist/torus3d.d.ts +2 -0
- package/dist/torus3d.js +3 -0
- package/dist/torus3d.js.map +1 -0
- package/package.json +7 -2
- package/dist/chunk-JCECG2KY.cjs.map +0 -1
- package/dist/chunk-XGQDO4VO.js.map +0 -1
|
@@ -1840,6 +1840,7 @@ function createGlobe3DPlugin() {
|
|
|
1840
1840
|
let sphereIBO = null;
|
|
1841
1841
|
let sphereIndexCount = 0;
|
|
1842
1842
|
const modelMatrix = mat4();
|
|
1843
|
+
let locationColors = /* @__PURE__ */ new Map();
|
|
1843
1844
|
const normalMatrix = new Float32Array(9);
|
|
1844
1845
|
let screenPoints = [];
|
|
1845
1846
|
let seriesInfo = [];
|
|
@@ -1856,34 +1857,49 @@ function createGlobe3DPlugin() {
|
|
|
1856
1857
|
[...MESH_VERT_UNIFORMS, ...MESH_FRAG_UNIFORMS],
|
|
1857
1858
|
MESH_VERT_ATTRIBUTES
|
|
1858
1859
|
);
|
|
1859
|
-
const
|
|
1860
|
-
let maxVal = 0;
|
|
1861
|
-
for (const s of series) for (const v of s.values) if (Math.abs(v) > maxVal) maxVal = Math.abs(v);
|
|
1862
|
-
if (maxVal === 0) maxVal = 1;
|
|
1860
|
+
const locationMap = /* @__PURE__ */ new Map();
|
|
1863
1861
|
seriesInfo = [];
|
|
1864
1862
|
screenPoints = [];
|
|
1865
1863
|
for (let sIdx = 0; sIdx < series.length; sIdx++) {
|
|
1866
1864
|
const s = series[sIdx];
|
|
1867
1865
|
const colorHex = s.color ?? theme.colors[sIdx % theme.colors.length];
|
|
1868
|
-
const color = hexToRGB(colorHex);
|
|
1869
1866
|
seriesInfo.push({ name: s.name, color: colorHex });
|
|
1870
1867
|
for (let di = 0; di < s.values.length; di++) {
|
|
1871
1868
|
const lat = s.y?.[di] ?? 0, lng = s.x?.[di] ?? 0, value = s.values[di];
|
|
1872
|
-
const
|
|
1873
|
-
|
|
1869
|
+
const label = data.categories?.[di] ?? "";
|
|
1870
|
+
const key = `${lat.toFixed(1)}_${lng.toFixed(1)}`;
|
|
1871
|
+
let loc = locationMap.get(key);
|
|
1872
|
+
if (!loc) {
|
|
1873
|
+
loc = { lat, lng, totalValue: 0, label, entries: [] };
|
|
1874
|
+
locationMap.set(key, loc);
|
|
1875
|
+
}
|
|
1876
|
+
loc.totalValue += Math.abs(value);
|
|
1877
|
+
loc.entries.push({ si: sIdx, di, value });
|
|
1874
1878
|
const [wx, wy, wz] = latLngToXYZ(lat, lng, GLOBE_RADIUS);
|
|
1875
|
-
screenPoints.push({ si: sIdx, di, lat, lng, wx, wy, wz, value, name: s.name, label
|
|
1879
|
+
screenPoints.push({ si: sIdx, di, lat, lng, wx, wy, wz, value, name: s.name, label });
|
|
1876
1880
|
}
|
|
1877
1881
|
}
|
|
1882
|
+
const patches = [];
|
|
1883
|
+
locationColors = /* @__PURE__ */ new Map();
|
|
1884
|
+
let maxVal = 0;
|
|
1885
|
+
for (const loc of locationMap.values()) if (loc.totalValue > maxVal) maxVal = loc.totalValue;
|
|
1886
|
+
if (maxVal === 0) maxVal = 1;
|
|
1887
|
+
let locIdx = 0;
|
|
1888
|
+
for (const loc of locationMap.values()) {
|
|
1889
|
+
const colorHex = theme.colors[locIdx % theme.colors.length];
|
|
1890
|
+
locationColors.set(loc.label, colorHex);
|
|
1891
|
+
const color = hexToRGB(colorHex);
|
|
1892
|
+
const normValue = loc.totalValue / maxVal;
|
|
1893
|
+
patches.push({ lat: loc.lat, lng: loc.lng, value: loc.totalValue, normValue, color, si: 0, di: locIdx, name: loc.label, label: loc.label });
|
|
1894
|
+
locIdx++;
|
|
1895
|
+
}
|
|
1878
1896
|
const baseColor = [0.03, 0.05, 0.12];
|
|
1879
1897
|
const patchRadius = 0.8;
|
|
1880
1898
|
const gratLatStep = 30, gratLngStep = 30;
|
|
1881
1899
|
const gratWidth = 0.015;
|
|
1882
1900
|
const gratColor = [0.08, 0.12, 0.22];
|
|
1883
|
-
console.log(`[Globe3D] Building sphere ${SEGMENTS}x${RINGS}, ${patches.length} data patches`);
|
|
1884
1901
|
const verts = [];
|
|
1885
1902
|
const indices = [];
|
|
1886
|
-
let patchedVerts = 0;
|
|
1887
1903
|
for (let ring = 0; ring <= RINGS; ring++) {
|
|
1888
1904
|
const phi = ring / RINGS * Math.PI;
|
|
1889
1905
|
const lat = 90 - ring / RINGS * 180;
|
|
@@ -1917,7 +1933,6 @@ function createGlobe3DPlugin() {
|
|
|
1917
1933
|
}
|
|
1918
1934
|
}
|
|
1919
1935
|
if (ar > 0.01 || ag > 0.01 || ab > 0.01) {
|
|
1920
|
-
patchedVerts++;
|
|
1921
1936
|
r = Math.min(1, r + ar);
|
|
1922
1937
|
g = Math.min(1, g + ag);
|
|
1923
1938
|
b = Math.min(1, b + ab);
|
|
@@ -1935,12 +1950,11 @@ function createGlobe3DPlugin() {
|
|
|
1935
1950
|
);
|
|
1936
1951
|
}
|
|
1937
1952
|
}
|
|
1938
|
-
console.log(`[Globe3D] ${patchedVerts} / ${(RINGS + 1) * (SEGMENTS + 1)} vertices colored by data`);
|
|
1939
1953
|
for (let ring = 0; ring < RINGS; ring++) {
|
|
1940
1954
|
for (let seg = 0; seg < SEGMENTS; seg++) {
|
|
1941
1955
|
const a = ring * (SEGMENTS + 1) + seg;
|
|
1942
1956
|
const b = a + SEGMENTS + 1;
|
|
1943
|
-
indices.push(a,
|
|
1957
|
+
indices.push(a, a + 1, b, a + 1, b + 1, b);
|
|
1944
1958
|
}
|
|
1945
1959
|
}
|
|
1946
1960
|
const vertArr = new Float32Array(verts);
|
|
@@ -1965,6 +1979,7 @@ function createGlobe3DPlugin() {
|
|
|
1965
1979
|
setLightUniforms(prog, defaultLightConfig(), camera.position);
|
|
1966
1980
|
prog.setFloat("u_opacity", progress);
|
|
1967
1981
|
if (sphereVBO && sphereIBO) {
|
|
1982
|
+
gl.disable(gl.CULL_FACE);
|
|
1968
1983
|
sphereVBO.bind();
|
|
1969
1984
|
const layout = createVertexLayout([
|
|
1970
1985
|
{ location: prog.attributes["a_position"], size: 3 },
|
|
@@ -1976,6 +1991,7 @@ function createGlobe3DPlugin() {
|
|
|
1976
1991
|
const indexType = gl.UNSIGNED_SHORT;
|
|
1977
1992
|
gl.drawElements(gl.TRIANGLES, sphereIndexCount, indexType, 0);
|
|
1978
1993
|
disableVertexLayout(gl, layout);
|
|
1994
|
+
gl.enable(gl.CULL_FACE);
|
|
1979
1995
|
}
|
|
1980
1996
|
},
|
|
1981
1997
|
renderOverlay(ctx, ctx2d) {
|
|
@@ -1995,38 +2011,17 @@ function createGlobe3DPlugin() {
|
|
|
1995
2011
|
);
|
|
1996
2012
|
if (!screen || screen.z < -1 || screen.z > 1 || screen.z > 0.97) continue;
|
|
1997
2013
|
seenLabels.add(sp.label);
|
|
1998
|
-
|
|
1999
|
-
ctx2d.
|
|
2014
|
+
const locColor = locationColors.get(sp.label) ?? theme.textColor;
|
|
2015
|
+
ctx2d.fillStyle = locColor;
|
|
2016
|
+
ctx2d.globalAlpha = 0.9;
|
|
2000
2017
|
ctx2d.beginPath();
|
|
2001
|
-
ctx2d.arc(screen.x, screen.y,
|
|
2018
|
+
ctx2d.arc(screen.x, screen.y, 3, 0, Math.PI * 2);
|
|
2002
2019
|
ctx2d.fill();
|
|
2003
2020
|
ctx2d.fillStyle = theme.textColor;
|
|
2004
2021
|
ctx2d.globalAlpha = 0.85;
|
|
2005
2022
|
ctx2d.textAlign = "left";
|
|
2006
2023
|
ctx2d.fillText(sp.label, screen.x + 8, screen.y);
|
|
2007
2024
|
}
|
|
2008
|
-
if (seriesInfo.length > 1) {
|
|
2009
|
-
const lx = 12, ly = height - 14 - seriesInfo.length * 18;
|
|
2010
|
-
ctx2d.fillStyle = "rgba(0,0,0,0.45)";
|
|
2011
|
-
ctx2d.globalAlpha = 1;
|
|
2012
|
-
ctx2d.beginPath();
|
|
2013
|
-
ctx2d.roundRect(lx - 6, ly - 8, 120, seriesInfo.length * 18 + 12, 6);
|
|
2014
|
-
ctx2d.fill();
|
|
2015
|
-
ctx2d.textAlign = "left";
|
|
2016
|
-
ctx2d.textBaseline = "top";
|
|
2017
|
-
ctx2d.font = `${theme.fontSize - 1}px ${theme.fontFamily}`;
|
|
2018
|
-
for (let i = 0; i < seriesInfo.length; i++) {
|
|
2019
|
-
const s = seriesInfo[i];
|
|
2020
|
-
const y = ly + i * 18;
|
|
2021
|
-
ctx2d.fillStyle = s.color;
|
|
2022
|
-
ctx2d.globalAlpha = 0.9;
|
|
2023
|
-
ctx2d.beginPath();
|
|
2024
|
-
ctx2d.arc(lx + 4, y + 6, 4, 0, Math.PI * 2);
|
|
2025
|
-
ctx2d.fill();
|
|
2026
|
-
ctx2d.fillStyle = "rgba(255,255,255,0.8)";
|
|
2027
|
-
ctx2d.fillText(s.name, lx + 14, y);
|
|
2028
|
-
}
|
|
2029
|
-
}
|
|
2030
2025
|
ctx2d.restore();
|
|
2031
2026
|
},
|
|
2032
2027
|
needsLoop() {
|
|
@@ -3495,6 +3490,230 @@ function createGraphGLPlugin() {
|
|
|
3495
3490
|
};
|
|
3496
3491
|
}
|
|
3497
3492
|
|
|
3493
|
+
// src/charts/torus3d/torus3d-type.ts
|
|
3494
|
+
var RADIAL_SEGMENTS = 64;
|
|
3495
|
+
var HEIGHT_STEPS = 200;
|
|
3496
|
+
var TOTAL_HEIGHT = 6;
|
|
3497
|
+
var MIN_RADIUS = 0.6;
|
|
3498
|
+
var MAX_RADIUS = 2;
|
|
3499
|
+
function createTorus3DPlugin() {
|
|
3500
|
+
let vbo = null;
|
|
3501
|
+
let ibo = null;
|
|
3502
|
+
let indexCount = 0;
|
|
3503
|
+
let use32bit = false;
|
|
3504
|
+
const modelMatrix = mat4();
|
|
3505
|
+
const normalMatrix = new Float32Array(9);
|
|
3506
|
+
let labelPoints = [];
|
|
3507
|
+
return {
|
|
3508
|
+
type: "torus3d",
|
|
3509
|
+
prepare(ctx) {
|
|
3510
|
+
const { renderer, data, options, theme } = ctx;
|
|
3511
|
+
const gl = renderer.gl;
|
|
3512
|
+
const series = data.series;
|
|
3513
|
+
renderer.registerProgram(
|
|
3514
|
+
"mesh",
|
|
3515
|
+
MESH_VERT,
|
|
3516
|
+
MESH_FRAG,
|
|
3517
|
+
[...MESH_VERT_UNIFORMS, ...MESH_FRAG_UNIFORMS],
|
|
3518
|
+
MESH_VERT_ATTRIBUTES
|
|
3519
|
+
);
|
|
3520
|
+
const s = series[0];
|
|
3521
|
+
if (!s || s.values.length === 0) return;
|
|
3522
|
+
const opts = options;
|
|
3523
|
+
const intensity = opts.intensity ?? 1;
|
|
3524
|
+
const numRings = s.values.length;
|
|
3525
|
+
let maxVal = 0;
|
|
3526
|
+
for (const v of s.values) if (Math.abs(v) > maxVal) maxVal = Math.abs(v);
|
|
3527
|
+
if (maxVal === 0) maxVal = 1;
|
|
3528
|
+
const ringRadii = [];
|
|
3529
|
+
for (let i = 0; i < numRings; i++) {
|
|
3530
|
+
const norm = Math.abs(s.values[i]) / maxVal;
|
|
3531
|
+
ringRadii.push((MIN_RADIUS + norm * (MAX_RADIUS - MIN_RADIUS)) * intensity);
|
|
3532
|
+
}
|
|
3533
|
+
const ringColors = [];
|
|
3534
|
+
const ringHexColors = [];
|
|
3535
|
+
for (let i = 0; i < numRings; i++) {
|
|
3536
|
+
const hex = theme.colors[i % theme.colors.length];
|
|
3537
|
+
ringHexColors.push(hex);
|
|
3538
|
+
ringColors.push(hexToRGB(hex));
|
|
3539
|
+
}
|
|
3540
|
+
function catmullRom(p0, p1, p2, p3, t) {
|
|
3541
|
+
return 0.5 * (2 * p1 + (-p0 + p2) * t + (2 * p0 - 5 * p1 + 4 * p2 - p3) * t * t + (-p0 + 3 * p1 - 3 * p2 + p3) * t * t * t);
|
|
3542
|
+
}
|
|
3543
|
+
function radiusAt(t) {
|
|
3544
|
+
const f = t * (numRings - 1);
|
|
3545
|
+
const i = Math.max(0, Math.min(Math.floor(f), numRings - 2));
|
|
3546
|
+
const frac = f - i;
|
|
3547
|
+
const p0 = ringRadii[Math.max(0, i - 1)];
|
|
3548
|
+
const p1 = ringRadii[i];
|
|
3549
|
+
const p2 = ringRadii[Math.min(numRings - 1, i + 1)];
|
|
3550
|
+
const p3 = ringRadii[Math.min(numRings - 1, i + 2)];
|
|
3551
|
+
return Math.max(MIN_RADIUS * 0.5, catmullRom(p0, p1, p2, p3, frac));
|
|
3552
|
+
}
|
|
3553
|
+
function colorAt(t) {
|
|
3554
|
+
const f = t * (numRings - 1);
|
|
3555
|
+
const i = Math.max(0, Math.min(Math.floor(f), numRings - 2));
|
|
3556
|
+
const frac = f - i;
|
|
3557
|
+
const c0 = ringColors[Math.max(0, i - 1)];
|
|
3558
|
+
const c1 = ringColors[i];
|
|
3559
|
+
const c2 = ringColors[Math.min(numRings - 1, i + 1)];
|
|
3560
|
+
const c3 = ringColors[Math.min(numRings - 1, i + 2)];
|
|
3561
|
+
return [
|
|
3562
|
+
Math.max(0, Math.min(1, catmullRom(c0[0], c1[0], c2[0], c3[0], frac))),
|
|
3563
|
+
Math.max(0, Math.min(1, catmullRom(c0[1], c1[1], c2[1], c3[1], frac))),
|
|
3564
|
+
Math.max(0, Math.min(1, catmullRom(c0[2], c1[2], c2[2], c3[2], frac)))
|
|
3565
|
+
];
|
|
3566
|
+
}
|
|
3567
|
+
const verts = [];
|
|
3568
|
+
const indices = [];
|
|
3569
|
+
labelPoints = [];
|
|
3570
|
+
for (let h = 0; h <= HEIGHT_STEPS; h++) {
|
|
3571
|
+
const t = h / HEIGHT_STEPS;
|
|
3572
|
+
const y = (t - 0.5) * TOTAL_HEIGHT;
|
|
3573
|
+
const radius = radiusAt(t);
|
|
3574
|
+
const color = colorAt(t);
|
|
3575
|
+
const eps = 2e-3;
|
|
3576
|
+
const rPrev = radiusAt(Math.max(0, t - eps));
|
|
3577
|
+
const rNext = radiusAt(Math.min(1, t + eps));
|
|
3578
|
+
const drdy = (rNext - rPrev) / (2 * eps * TOTAL_HEIGHT);
|
|
3579
|
+
for (let seg = 0; seg <= RADIAL_SEGMENTS; seg++) {
|
|
3580
|
+
const theta = seg / RADIAL_SEGMENTS * Math.PI * 2;
|
|
3581
|
+
const cosT = Math.cos(theta);
|
|
3582
|
+
const sinT = Math.sin(theta);
|
|
3583
|
+
const nx = cosT;
|
|
3584
|
+
const ny = -drdy;
|
|
3585
|
+
const nz = sinT;
|
|
3586
|
+
const nlen = Math.sqrt(nx * nx + ny * ny + nz * nz) || 1;
|
|
3587
|
+
verts.push(
|
|
3588
|
+
radius * cosT,
|
|
3589
|
+
y,
|
|
3590
|
+
radius * sinT,
|
|
3591
|
+
nx / nlen,
|
|
3592
|
+
ny / nlen,
|
|
3593
|
+
nz / nlen,
|
|
3594
|
+
color[0],
|
|
3595
|
+
color[1],
|
|
3596
|
+
color[2]
|
|
3597
|
+
);
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
for (let i = 0; i < numRings; i++) {
|
|
3601
|
+
const t = (i + 0.5) / numRings;
|
|
3602
|
+
const y = (t - 0.5) * TOTAL_HEIGHT;
|
|
3603
|
+
const r = ringRadii[i];
|
|
3604
|
+
labelPoints.push({
|
|
3605
|
+
si: 0,
|
|
3606
|
+
di: i,
|
|
3607
|
+
wx: r + 0.4,
|
|
3608
|
+
wy: y,
|
|
3609
|
+
wz: 0,
|
|
3610
|
+
value: s.values[i],
|
|
3611
|
+
label: data.categories?.[i] ?? `${i + 1}`,
|
|
3612
|
+
color: ringHexColors[i]
|
|
3613
|
+
});
|
|
3614
|
+
}
|
|
3615
|
+
for (let h = 0; h < HEIGHT_STEPS; h++) {
|
|
3616
|
+
for (let seg = 0; seg < RADIAL_SEGMENTS; seg++) {
|
|
3617
|
+
const a = h * (RADIAL_SEGMENTS + 1) + seg;
|
|
3618
|
+
const b = a + RADIAL_SEGMENTS + 1;
|
|
3619
|
+
indices.push(a, a + 1, b, a + 1, b + 1, b);
|
|
3620
|
+
}
|
|
3621
|
+
}
|
|
3622
|
+
const capStart = verts.length / 9;
|
|
3623
|
+
const bottomColor = colorAt(0);
|
|
3624
|
+
verts.push(0, -0.5 * TOTAL_HEIGHT, 0, 0, -1, 0, bottomColor[0], bottomColor[1], bottomColor[2]);
|
|
3625
|
+
const topColor = colorAt(1);
|
|
3626
|
+
verts.push(0, 0.5 * TOTAL_HEIGHT, 0, 0, 1, 0, topColor[0], topColor[1], topColor[2]);
|
|
3627
|
+
for (let seg = 0; seg < RADIAL_SEGMENTS; seg++) {
|
|
3628
|
+
indices.push(capStart, seg + 1, seg);
|
|
3629
|
+
const topRow = HEIGHT_STEPS * (RADIAL_SEGMENTS + 1);
|
|
3630
|
+
indices.push(capStart + 1, topRow + seg, topRow + seg + 1);
|
|
3631
|
+
}
|
|
3632
|
+
const vertArr = new Float32Array(verts);
|
|
3633
|
+
use32bit = verts.length / 9 > 65535;
|
|
3634
|
+
const idxArr = use32bit ? new Uint32Array(indices) : new Uint16Array(indices);
|
|
3635
|
+
if (vbo) vbo.update(vertArr);
|
|
3636
|
+
else vbo = createVertexBuffer(gl, vertArr, gl.DYNAMIC_DRAW);
|
|
3637
|
+
if (ibo) ibo.update(idxArr);
|
|
3638
|
+
else ibo = createIndexBuffer(gl, idxArr, gl.DYNAMIC_DRAW);
|
|
3639
|
+
indexCount = indices.length;
|
|
3640
|
+
mat4Identity(modelMatrix);
|
|
3641
|
+
},
|
|
3642
|
+
render(ctx) {
|
|
3643
|
+
const { renderer, camera } = ctx;
|
|
3644
|
+
const gl = renderer.gl;
|
|
3645
|
+
const prog = renderer.getProgram("mesh");
|
|
3646
|
+
prog.use();
|
|
3647
|
+
prog.setMat4("u_projView", camera.projViewMatrix);
|
|
3648
|
+
prog.setMat4("u_model", modelMatrix);
|
|
3649
|
+
mat3NormalFromMat4(normalMatrix, modelMatrix);
|
|
3650
|
+
prog.setMat3("u_normalMatrix", normalMatrix);
|
|
3651
|
+
setLightUniforms(prog, defaultLightConfig(), camera.position);
|
|
3652
|
+
prog.setFloat("u_opacity", ctx.animationProgress);
|
|
3653
|
+
if (vbo && ibo) {
|
|
3654
|
+
gl.disable(gl.CULL_FACE);
|
|
3655
|
+
vbo.bind();
|
|
3656
|
+
const layout = createVertexLayout([
|
|
3657
|
+
{ location: prog.attributes["a_position"], size: 3 },
|
|
3658
|
+
{ location: prog.attributes["a_normal"], size: 3 },
|
|
3659
|
+
{ location: prog.attributes["a_color"], size: 3 }
|
|
3660
|
+
]);
|
|
3661
|
+
applyVertexLayout(gl, layout);
|
|
3662
|
+
ibo.bind();
|
|
3663
|
+
gl.drawElements(gl.TRIANGLES, indexCount, use32bit ? gl.UNSIGNED_INT : gl.UNSIGNED_SHORT, 0);
|
|
3664
|
+
disableVertexLayout(gl, layout);
|
|
3665
|
+
gl.enable(gl.CULL_FACE);
|
|
3666
|
+
}
|
|
3667
|
+
},
|
|
3668
|
+
renderOverlay(ctx, ctx2d) {
|
|
3669
|
+
const { camera, width, height, theme, animationProgress } = ctx;
|
|
3670
|
+
if (animationProgress < 0.3) return;
|
|
3671
|
+
ctx2d.save();
|
|
3672
|
+
ctx2d.font = `bold ${theme.fontSize}px ${theme.fontFamily}`;
|
|
3673
|
+
ctx2d.textBaseline = "middle";
|
|
3674
|
+
for (const lp of labelPoints) {
|
|
3675
|
+
const screen = projectToScreen(new Float32Array([lp.wx, lp.wy, lp.wz]), camera.projViewMatrix, width, height);
|
|
3676
|
+
if (!screen || screen.z < -1 || screen.z > 1) continue;
|
|
3677
|
+
ctx2d.fillStyle = lp.color;
|
|
3678
|
+
ctx2d.globalAlpha = 0.9;
|
|
3679
|
+
ctx2d.beginPath();
|
|
3680
|
+
ctx2d.arc(screen.x, screen.y, 4, 0, Math.PI * 2);
|
|
3681
|
+
ctx2d.fill();
|
|
3682
|
+
ctx2d.fillStyle = theme.textColor;
|
|
3683
|
+
ctx2d.globalAlpha = 0.85;
|
|
3684
|
+
ctx2d.textAlign = "left";
|
|
3685
|
+
ctx2d.fillText(`${lp.label}: ${lp.value}`, screen.x + 10, screen.y);
|
|
3686
|
+
}
|
|
3687
|
+
ctx2d.restore();
|
|
3688
|
+
},
|
|
3689
|
+
needsLoop() {
|
|
3690
|
+
return false;
|
|
3691
|
+
},
|
|
3692
|
+
hitTest(ctx, x, y) {
|
|
3693
|
+
const { camera, width, height } = ctx;
|
|
3694
|
+
let closest = null;
|
|
3695
|
+
let closestDist = 30;
|
|
3696
|
+
for (const lp of labelPoints) {
|
|
3697
|
+
const screen = projectToScreen(new Float32Array([lp.wx, lp.wy, lp.wz]), camera.projViewMatrix, width, height);
|
|
3698
|
+
if (!screen || screen.z < -1 || screen.z > 1) continue;
|
|
3699
|
+
const dist = Math.sqrt((screen.x - x) ** 2 + (screen.y - y) ** 2);
|
|
3700
|
+
if (dist < closestDist) {
|
|
3701
|
+
closestDist = dist;
|
|
3702
|
+
closest = { seriesIndex: lp.si, dataIndex: lp.di, value: lp.value, x: screen.x, y: screen.y, seriesName: lp.label };
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
return closest;
|
|
3706
|
+
},
|
|
3707
|
+
dispose() {
|
|
3708
|
+
vbo?.destroy();
|
|
3709
|
+
vbo = null;
|
|
3710
|
+
ibo?.destroy();
|
|
3711
|
+
ibo = null;
|
|
3712
|
+
labelPoints = [];
|
|
3713
|
+
}
|
|
3714
|
+
};
|
|
3715
|
+
}
|
|
3716
|
+
|
|
3498
3717
|
// src/api/factory.ts
|
|
3499
3718
|
function Scatter3D(container, opts) {
|
|
3500
3719
|
const { data, ...options } = opts;
|
|
@@ -3571,6 +3790,11 @@ function GraphGL(container, opts) {
|
|
|
3571
3790
|
const { data, ...options } = opts;
|
|
3572
3791
|
return createGLChart(container, createGraphGLPlugin(), data, options);
|
|
3573
3792
|
}
|
|
3793
|
+
function Torus3D(container, opts) {
|
|
3794
|
+
const { data, ...options } = opts;
|
|
3795
|
+
if (!options.camera) options.camera = { position: [4, 2, 6], target: [0, 0, 0] };
|
|
3796
|
+
return createGLChart(container, createTorus3DPlugin(), data, options);
|
|
3797
|
+
}
|
|
3574
3798
|
|
|
3575
3799
|
exports.Bar3D = Bar3D;
|
|
3576
3800
|
exports.DEFAULT_GL_THEME = DEFAULT_GL_THEME;
|
|
@@ -3585,6 +3809,7 @@ exports.Map3D = Map3D;
|
|
|
3585
3809
|
exports.Scatter3D = Scatter3D;
|
|
3586
3810
|
exports.ScatterGL = ScatterGL;
|
|
3587
3811
|
exports.Surface3D = Surface3D;
|
|
3812
|
+
exports.Torus3D = Torus3D;
|
|
3588
3813
|
exports.applyVertexLayout = applyVertexLayout;
|
|
3589
3814
|
exports.compileShader = compileShader;
|
|
3590
3815
|
exports.createBar3DPlugin = createBar3DPlugin;
|
|
@@ -3606,6 +3831,7 @@ exports.createScatter3DPlugin = createScatter3DPlugin;
|
|
|
3606
3831
|
exports.createScatterGLPlugin = createScatterGLPlugin;
|
|
3607
3832
|
exports.createShaderProgram = createShaderProgram;
|
|
3608
3833
|
exports.createSurface3DPlugin = createSurface3DPlugin;
|
|
3834
|
+
exports.createTorus3DPlugin = createTorus3DPlugin;
|
|
3609
3835
|
exports.createVertexBuffer = createVertexBuffer;
|
|
3610
3836
|
exports.createVertexLayout = createVertexLayout;
|
|
3611
3837
|
exports.defaultLightConfig = defaultLightConfig;
|
|
@@ -3623,5 +3849,5 @@ exports.toRad = toRad;
|
|
|
3623
3849
|
exports.updateCamera = updateCamera;
|
|
3624
3850
|
exports.updateOrbitControls = updateOrbitControls;
|
|
3625
3851
|
exports.vec3 = vec3;
|
|
3626
|
-
//# sourceMappingURL=chunk-
|
|
3627
|
-
//# sourceMappingURL=chunk-
|
|
3852
|
+
//# sourceMappingURL=chunk-OTQKQDB6.cjs.map
|
|
3853
|
+
//# sourceMappingURL=chunk-OTQKQDB6.cjs.map
|