@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.
Files changed (65) hide show
  1. package/dist/bar3d.cjs +4 -4
  2. package/dist/bar3d.d.cts +2 -2
  3. package/dist/bar3d.d.ts +2 -2
  4. package/dist/bar3d.js +1 -1
  5. package/dist/{chunk-XGQDO4VO.js → chunk-AGG2KSBO.js} +265 -41
  6. package/dist/chunk-AGG2KSBO.js.map +1 -0
  7. package/dist/{chunk-JCECG2KY.cjs → chunk-OTQKQDB6.cjs} +266 -40
  8. package/dist/chunk-OTQKQDB6.cjs.map +1 -0
  9. package/dist/{factory-Cp9Kr7aa.d.cts → factory-jQSzXhK4.d.cts} +4 -1
  10. package/dist/{factory-Cp9Kr7aa.d.ts → factory-jQSzXhK4.d.ts} +4 -1
  11. package/dist/flow-gl.cjs +4 -4
  12. package/dist/flow-gl.d.cts +2 -2
  13. package/dist/flow-gl.d.ts +2 -2
  14. package/dist/flow-gl.js +1 -1
  15. package/dist/globe3d.cjs +4 -4
  16. package/dist/globe3d.d.cts +2 -2
  17. package/dist/globe3d.d.ts +2 -2
  18. package/dist/globe3d.js +1 -1
  19. package/dist/graph-gl.cjs +4 -4
  20. package/dist/graph-gl.d.cts +2 -2
  21. package/dist/graph-gl.d.ts +2 -2
  22. package/dist/graph-gl.js +1 -1
  23. package/dist/index.cjs +60 -52
  24. package/dist/index.d.cts +3 -2
  25. package/dist/index.d.ts +3 -2
  26. package/dist/index.js +1 -1
  27. package/dist/line3d.cjs +4 -4
  28. package/dist/line3d.d.cts +2 -2
  29. package/dist/line3d.d.ts +2 -2
  30. package/dist/line3d.js +1 -1
  31. package/dist/lines-gl.cjs +4 -4
  32. package/dist/lines-gl.d.cts +2 -2
  33. package/dist/lines-gl.d.ts +2 -2
  34. package/dist/lines-gl.js +1 -1
  35. package/dist/lines3d.cjs +4 -4
  36. package/dist/lines3d.d.cts +2 -2
  37. package/dist/lines3d.d.ts +2 -2
  38. package/dist/lines3d.js +1 -1
  39. package/dist/map3d.cjs +4 -4
  40. package/dist/map3d.d.cts +2 -2
  41. package/dist/map3d.d.ts +2 -2
  42. package/dist/map3d.js +1 -1
  43. package/dist/scatter-gl.cjs +4 -4
  44. package/dist/scatter-gl.d.cts +2 -2
  45. package/dist/scatter-gl.d.ts +2 -2
  46. package/dist/scatter-gl.js +1 -1
  47. package/dist/scatter3d.cjs +4 -4
  48. package/dist/scatter3d.d.cts +2 -2
  49. package/dist/scatter3d.d.ts +2 -2
  50. package/dist/scatter3d.js +1 -1
  51. package/dist/surface3d.cjs +4 -4
  52. package/dist/surface3d.d.cts +2 -2
  53. package/dist/surface3d.d.ts +2 -2
  54. package/dist/surface3d.js +1 -1
  55. package/dist/torus3d-NpDo5Nb5.d.ts +15 -0
  56. package/dist/torus3d-fgZpxxQZ.d.cts +15 -0
  57. package/dist/torus3d.cjs +20 -0
  58. package/dist/torus3d.cjs.map +1 -0
  59. package/dist/torus3d.d.cts +2 -0
  60. package/dist/torus3d.d.ts +2 -0
  61. package/dist/torus3d.js +3 -0
  62. package/dist/torus3d.js.map +1 -0
  63. package/package.json +7 -2
  64. package/dist/chunk-JCECG2KY.cjs.map +0 -1
  65. 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 patches = [];
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 normValue = Math.abs(value) / maxVal;
1873
- patches.push({ lat, lng, value, normValue, color, si: sIdx, di, name: s.name, label: data.categories?.[di] ?? "" });
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: data.categories?.[di] ?? "" });
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, b, a + 1, a + 1, b, b + 1);
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
- ctx2d.fillStyle = theme.textColor;
1999
- ctx2d.globalAlpha = 0.7;
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, 2.5, 0, Math.PI * 2);
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-JCECG2KY.cjs.map
3627
- //# sourceMappingURL=chunk-JCECG2KY.cjs.map
3852
+ //# sourceMappingURL=chunk-OTQKQDB6.cjs.map
3853
+ //# sourceMappingURL=chunk-OTQKQDB6.cjs.map