pptx-react-viewer 4.10.1 → 4.11.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/{AiChatPanel-AR2K2XN2.mjs → AiChatPanel-3IKRPPUX.mjs} +3 -3
  3. package/dist/AiChatPanel-3IKRPPUX.mjs.br +0 -0
  4. package/dist/AiChatPanel-3IKRPPUX.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-X6E22UAR.js → AiChatPanel-537JJCV4.js} +27 -27
  6. package/dist/AiChatPanel-537JJCV4.js.br +0 -0
  7. package/dist/AiChatPanel-537JJCV4.js.gz +0 -0
  8. package/dist/{Model3DScene-ZSCVKXZE.js → Model3DScene-3XT5SBU4.js} +2 -2
  9. package/dist/Model3DScene-3XT5SBU4.js.br +0 -0
  10. package/dist/Model3DScene-3XT5SBU4.js.gz +0 -0
  11. package/dist/{Model3DScene-FF4RCG4O.mjs → Model3DScene-WBJV27OR.mjs} +1 -1
  12. package/dist/Model3DScene-WBJV27OR.mjs.br +0 -0
  13. package/dist/Model3DScene-WBJV27OR.mjs.gz +0 -0
  14. package/dist/{chunk-VOD4C7OS.mjs → chunk-4MI3PMQT.mjs} +1 -1
  15. package/dist/chunk-4MI3PMQT.mjs.br +0 -0
  16. package/dist/chunk-4MI3PMQT.mjs.gz +0 -0
  17. package/dist/{chunk-NE4USMMB.mjs → chunk-BR4GXQSN.mjs} +1 -1
  18. package/dist/chunk-BR4GXQSN.mjs.br +0 -0
  19. package/dist/chunk-BR4GXQSN.mjs.gz +0 -0
  20. package/dist/{chunk-22ODJ4CT.mjs → chunk-G353KKQX.mjs} +3 -3
  21. package/dist/chunk-G353KKQX.mjs.br +0 -0
  22. package/dist/chunk-G353KKQX.mjs.gz +0 -0
  23. package/dist/{chunk-VYJFYRT4.js → chunk-GLFTASJH.js} +806 -806
  24. package/dist/chunk-GLFTASJH.js.br +0 -0
  25. package/dist/chunk-GLFTASJH.js.gz +0 -0
  26. package/dist/{chunk-WLEFW2F4.js → chunk-LVWMKZPS.js} +5 -5
  27. package/dist/chunk-LVWMKZPS.js.br +0 -0
  28. package/dist/chunk-LVWMKZPS.js.gz +0 -0
  29. package/dist/{chunk-ICOJBMRC.js → chunk-NCUM2X4H.js} +1182 -1183
  30. package/dist/chunk-NCUM2X4H.js.br +0 -0
  31. package/dist/chunk-NCUM2X4H.js.gz +0 -0
  32. package/dist/{chunk-QPWNFTU5.mjs → chunk-SDEBL4LY.mjs} +9 -10
  33. package/dist/chunk-SDEBL4LY.mjs.br +0 -0
  34. package/dist/chunk-SDEBL4LY.mjs.gz +0 -0
  35. package/dist/{chunk-JJE4AACM.js → chunk-TLKFCZWS.js} +163 -2863
  36. package/dist/chunk-TLKFCZWS.js.br +0 -0
  37. package/dist/chunk-TLKFCZWS.js.gz +0 -0
  38. package/dist/{chunk-7EP22XCS.js → chunk-XGDCECDK.js} +187 -187
  39. package/dist/chunk-XGDCECDK.js.br +0 -0
  40. package/dist/chunk-XGDCECDK.js.gz +0 -0
  41. package/dist/{chunk-LDRA5LJT.mjs → chunk-ZVBB3CC5.mjs} +163 -2863
  42. package/dist/chunk-ZVBB3CC5.mjs.br +0 -0
  43. package/dist/chunk-ZVBB3CC5.mjs.gz +0 -0
  44. package/dist/index.js +61 -61
  45. package/dist/index.js.br +0 -0
  46. package/dist/index.js.gz +0 -0
  47. package/dist/index.mjs +5 -5
  48. package/dist/index.mjs.br +0 -0
  49. package/dist/index.mjs.gz +0 -0
  50. package/dist/internals.js +104 -104
  51. package/dist/internals.js.br +0 -0
  52. package/dist/internals.js.gz +0 -0
  53. package/dist/internals.mjs +3 -3
  54. package/dist/internals.mjs.br +0 -0
  55. package/dist/internals.mjs.gz +0 -0
  56. package/dist/viewer/index.js +26 -26
  57. package/dist/viewer/index.js.br +0 -0
  58. package/dist/viewer/index.js.gz +0 -0
  59. package/dist/viewer/index.mjs +5 -5
  60. package/dist/viewer/index.mjs.br +0 -0
  61. package/dist/viewer/index.mjs.gz +0 -0
  62. package/package.json +1 -1
  63. package/dist/AiChatPanel-AR2K2XN2.mjs.br +0 -0
  64. package/dist/AiChatPanel-AR2K2XN2.mjs.gz +0 -0
  65. package/dist/AiChatPanel-X6E22UAR.js.br +0 -0
  66. package/dist/AiChatPanel-X6E22UAR.js.gz +0 -0
  67. package/dist/Model3DScene-FF4RCG4O.mjs.br +0 -0
  68. package/dist/Model3DScene-FF4RCG4O.mjs.gz +0 -0
  69. package/dist/Model3DScene-ZSCVKXZE.js.br +0 -0
  70. package/dist/Model3DScene-ZSCVKXZE.js.gz +0 -0
  71. package/dist/chunk-22ODJ4CT.mjs.br +0 -0
  72. package/dist/chunk-22ODJ4CT.mjs.gz +0 -0
  73. package/dist/chunk-7EP22XCS.js.br +0 -0
  74. package/dist/chunk-7EP22XCS.js.gz +0 -0
  75. package/dist/chunk-ICOJBMRC.js.br +0 -0
  76. package/dist/chunk-ICOJBMRC.js.gz +0 -0
  77. package/dist/chunk-JJE4AACM.js.br +0 -0
  78. package/dist/chunk-JJE4AACM.js.gz +0 -0
  79. package/dist/chunk-LDRA5LJT.mjs.br +0 -0
  80. package/dist/chunk-LDRA5LJT.mjs.gz +0 -0
  81. package/dist/chunk-NE4USMMB.mjs.br +0 -0
  82. package/dist/chunk-NE4USMMB.mjs.gz +0 -0
  83. package/dist/chunk-QPWNFTU5.mjs.br +0 -0
  84. package/dist/chunk-QPWNFTU5.mjs.gz +0 -0
  85. package/dist/chunk-VOD4C7OS.mjs.br +0 -0
  86. package/dist/chunk-VOD4C7OS.mjs.gz +0 -0
  87. package/dist/chunk-VYJFYRT4.js.br +0 -0
  88. package/dist/chunk-VYJFYRT4.js.gz +0 -0
  89. package/dist/chunk-WLEFW2F4.js.br +0 -0
  90. package/dist/chunk-WLEFW2F4.js.gz +0 -0
@@ -27265,6 +27265,19 @@ var init_element_xml_builders = __esm({
27265
27265
  init_stroke_utils();
27266
27266
  }
27267
27267
  });
27268
+ function srgb255ToLinear(channel) {
27269
+ const c = clampUnitInterval(channel / 255);
27270
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
27271
+ }
27272
+ function linearToSrgb255(linear) {
27273
+ const c = clampUnitInterval(linear);
27274
+ return 255 * (c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055);
27275
+ }
27276
+ var init_color_linear = __esm({
27277
+ "src/core/color/color-linear.ts"() {
27278
+ init_color_primitives();
27279
+ }
27280
+ });
27268
27281
  function applyDrawingColorTransforms(baseColor, colorNode) {
27269
27282
  const rgb2 = hexToRgbChannels(baseColor);
27270
27283
  if (!rgb2) {
@@ -27307,15 +27320,15 @@ function applyDrawingColorTransforms(baseColor, colorNode) {
27307
27320
  }
27308
27321
  const shade3 = parseDrawingPercent(getVal("a:shade"));
27309
27322
  if (shade3 !== void 0) {
27310
- r *= shade3;
27311
- g2 *= shade3;
27312
- b *= shade3;
27323
+ r = linearToSrgb255(srgb255ToLinear(r) * shade3);
27324
+ g2 = linearToSrgb255(srgb255ToLinear(g2) * shade3);
27325
+ b = linearToSrgb255(srgb255ToLinear(b) * shade3);
27313
27326
  }
27314
27327
  const tint3 = parseDrawingPercent(getVal("a:tint"));
27315
27328
  if (tint3 !== void 0) {
27316
- r = 255 - (255 - r) * tint3;
27317
- g2 = 255 - (255 - g2) * tint3;
27318
- b = 255 - (255 - b) * tint3;
27329
+ r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) * tint3);
27330
+ g2 = linearToSrgb255(1 - (1 - srgb255ToLinear(g2)) * tint3);
27331
+ b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) * tint3);
27319
27332
  }
27320
27333
  const hslKeys = [
27321
27334
  "a:hue",
@@ -27428,6 +27441,7 @@ function applySrgbGammaDecode(r, g2, b) {
27428
27441
  }
27429
27442
  var init_color_transforms = __esm({
27430
27443
  "src/core/color/color-transforms.ts"() {
27444
+ init_color_linear();
27431
27445
  init_color_primitives();
27432
27446
  }
27433
27447
  });
@@ -169320,8 +169334,8 @@ function hexToRgb2(hex22) {
169320
169334
  ];
169321
169335
  }
169322
169336
  function rgbToHex(r, g2, b) {
169323
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169324
- return `#${clamp13(r).toString(16).padStart(2, "0")}${clamp13(g2).toString(16).padStart(2, "0")}${clamp13(b).toString(16).padStart(2, "0")}`;
169337
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169338
+ return `#${clamp12(r).toString(16).padStart(2, "0")}${clamp12(g2).toString(16).padStart(2, "0")}${clamp12(b).toString(16).padStart(2, "0")}`;
169325
169339
  }
169326
169340
  function tint(hex22, amount) {
169327
169341
  const [r, g2, b] = hexToRgb2(hex22);
@@ -169821,8 +169835,8 @@ function hexToRgb3(hex22) {
169821
169835
  ];
169822
169836
  }
169823
169837
  function rgbToHex2(r, g2, b) {
169824
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169825
- return `#${clamp13(r).toString(16).padStart(2, "0")}${clamp13(g2).toString(16).padStart(2, "0")}${clamp13(b).toString(16).padStart(2, "0")}`;
169838
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169839
+ return `#${clamp12(r).toString(16).padStart(2, "0")}${clamp12(g2).toString(16).padStart(2, "0")}${clamp12(b).toString(16).padStart(2, "0")}`;
169826
169840
  }
169827
169841
  function tint2(hex22, amount) {
169828
169842
  const [r, g2, b] = hexToRgb3(hex22);
@@ -170687,15 +170701,6 @@ var init_chart_view_model_bars = __esm2({
170687
170701
  init_chart_view_model_scale();
170688
170702
  }
170689
170703
  });
170690
- function resolveChart3DWallColors(surfaces) {
170691
- const floor = surfaces.floor?.spPr?.fillColor;
170692
- const sideWall = surfaces.sideWall?.spPr?.fillColor;
170693
- const backWall = surfaces.backWall?.spPr?.fillColor;
170694
- if (!floor && !sideWall && !backWall) {
170695
- return void 0;
170696
- }
170697
- return { floor, sideWall, backWall };
170698
- }
170699
170704
  function primitivesBounds(prims) {
170700
170705
  let minX = Number.POSITIVE_INFINITY;
170701
170706
  let maxX = Number.NEGATIVE_INFINITY;
@@ -178412,7 +178417,7 @@ function formatRegionMapValue(value, cultureLanguage) {
178412
178417
  }
178413
178418
  }
178414
178419
  function lerpColor(a, b, t) {
178415
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v))), ha = a.replace("#", ""), hb = b.replace("#", ""), r1 = parseInt(ha.substring(0, 2), 16), g1 = parseInt(ha.substring(2, 4), 16), b1 = parseInt(ha.substring(4, 6), 16), r22 = parseInt(hb.substring(0, 2), 16), g2 = parseInt(hb.substring(2, 4), 16), b2 = parseInt(hb.substring(4, 6), 16), r = clamp13(r1 + (r22 - r1) * t), g3 = clamp13(g1 + (g2 - g1) * t), bl = clamp13(b1 + (b2 - b1) * t), toHex23 = (n) => n.toString(16).padStart(2, "0");
178420
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v))), ha = a.replace("#", ""), hb = b.replace("#", ""), r1 = parseInt(ha.substring(0, 2), 16), g1 = parseInt(ha.substring(2, 4), 16), b1 = parseInt(ha.substring(4, 6), 16), r22 = parseInt(hb.substring(0, 2), 16), g2 = parseInt(hb.substring(2, 4), 16), b2 = parseInt(hb.substring(4, 6), 16), r = clamp12(r1 + (r22 - r1) * t), g3 = clamp12(g1 + (g2 - g1) * t), bl = clamp12(b1 + (b2 - b1) * t), toHex23 = (n) => n.toString(16).padStart(2, "0");
178416
178421
  return `#${toHex23(r)}${toHex23(g3)}${toHex23(bl)}`;
178417
178422
  }
178418
178423
  function resolveValueColorStops(valueColors, valueColorPositions, minVal, maxVal) {
@@ -181140,173 +181145,6 @@ var init_smartart_3d_drawing_solid = __esm2({
181140
181145
  DEG_PER_UNIT2 = 6e4;
181141
181146
  }
181142
181147
  });
181143
- function transposeForHorizontalBar3D(point) {
181144
- return [point[1], -point[0], point[2]];
181145
- }
181146
- function computeCartesianGridExtent(cols, rows, depthPercent) {
181147
- const gridWidth = Math.max(cols - 1, 1) * GRID_SPACING;
181148
- const depthScale = Math.min(Math.max((depthPercent ?? 100) / 100, 0.05), 3);
181149
- const gridDepth = Math.max(gridWidth * depthScale, rows > 1 ? GRID_SPACING : GRID_SPACING * 0.5);
181150
- return { gridWidth, gridDepth };
181151
- }
181152
- function clamp7(value, min, max) {
181153
- return Math.min(Math.max(value, min), max);
181154
- }
181155
- function normalizeAzimuth(deg3) {
181156
- const wrapped = deg3 % 360;
181157
- return wrapped < 0 ? wrapped + 360 : wrapped;
181158
- }
181159
- function resolveCartesianCameraFov(view3D) {
181160
- if (view3D?.rAngAx) {
181161
- return RIGHT_ANGLE_FOV;
181162
- }
181163
- const perspective2 = clamp7(
181164
- view3D?.rperspective ?? DEFAULT_PERSPECTIVE_DEG,
181165
- 0,
181166
- PERSPECTIVE_MAX_DEG
181167
- );
181168
- return FOV_MIN + perspective2 / PERSPECTIVE_MAX_DEG * (FOV_MAX - FOV_MIN);
181169
- }
181170
- function computeSphericalCameraPlacement(maxExtent, targetY, view3D) {
181171
- const fov = resolveCartesianCameraFov(view3D);
181172
- const halfFovRad = fov * Math.PI / 360;
181173
- const radius = Math.max(maxExtent, 0.01) / Math.tan(halfFovRad) * 0.75;
181174
- const target = [0, targetY, 0];
181175
- const elevationDeg = clamp7(view3D?.rotX ?? DEFAULT_ELEVATION_DEG, -89, 89);
181176
- const azimuthDeg = normalizeAzimuth(view3D?.rotY ?? DEFAULT_AZIMUTH_DEG);
181177
- const phi = (90 - elevationDeg) * Math.PI / 180;
181178
- const theta = azimuthDeg * Math.PI / 180;
181179
- const sinPhi = Math.sin(phi);
181180
- return {
181181
- position: [
181182
- radius * sinPhi * Math.sin(theta),
181183
- radius * Math.cos(phi) + target[1],
181184
- radius * sinPhi * Math.cos(theta)
181185
- ],
181186
- target,
181187
- fov
181188
- };
181189
- }
181190
- function computeCartesianCameraPlacement(cols, rows, view3D, horizontal = false) {
181191
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, view3D?.depthPercent);
181192
- const maxExtent = Math.max(gridWidth, gridDepth, MAX_VALUE_HEIGHT);
181193
- const placement = computeSphericalCameraPlacement(maxExtent, MAX_VALUE_HEIGHT * 0.2, view3D);
181194
- if (!horizontal) {
181195
- return placement;
181196
- }
181197
- return {
181198
- ...placement,
181199
- position: transposeForHorizontalBar3D(placement.position),
181200
- target: transposeForHorizontalBar3D(placement.target)
181201
- };
181202
- }
181203
- function buildCartesianChart3DLabels(cols, rows, categoryLabels, seriesNames, depthPercent, maxCat = 8, maxSer = 6, horizontal = false) {
181204
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
181205
- const labels = [];
181206
- const remap = (anchor) => horizontal ? transposeForHorizontalBar3D(anchor) : anchor;
181207
- const catStep = Math.max(1, Math.ceil(categoryLabels.length / maxCat));
181208
- for (let i2 = 0; i2 < categoryLabels.length; i2 += catStep) {
181209
- const x = -gridWidth / 2 + i2 / Math.max(cols - 1, 1) * gridWidth;
181210
- labels.push({
181211
- key: `cat-${i2}`,
181212
- text: categoryLabels[i2],
181213
- anchor: remap([x, -0.15, gridDepth / 2 + 0.25]),
181214
- axis: "category"
181215
- });
181216
- }
181217
- const serStep = Math.max(1, Math.ceil(seriesNames.length / maxSer));
181218
- for (let i2 = 0; i2 < seriesNames.length; i2 += serStep) {
181219
- const z = -gridDepth / 2 + i2 / Math.max(rows - 1, 1) * gridDepth;
181220
- labels.push({
181221
- key: `ser-${i2}`,
181222
- text: seriesNames[i2],
181223
- anchor: remap([gridWidth / 2 + 0.3, -0.15, z]),
181224
- axis: "series"
181225
- });
181226
- }
181227
- return labels;
181228
- }
181229
- var GRID_SPACING;
181230
- var MAX_VALUE_HEIGHT;
181231
- var DEFAULT_ELEVATION_DEG;
181232
- var DEFAULT_AZIMUTH_DEG;
181233
- var DEFAULT_PERSPECTIVE_DEG;
181234
- var FOV_MIN;
181235
- var FOV_MAX;
181236
- var RIGHT_ANGLE_FOV;
181237
- var PERSPECTIVE_MAX_DEG;
181238
- var init_cartesian_chart_3d_geom = __esm2({
181239
- "src/render/cartesian-chart-3d-geom.ts"() {
181240
- GRID_SPACING = 0.5;
181241
- MAX_VALUE_HEIGHT = 1.5;
181242
- DEFAULT_ELEVATION_DEG = 15;
181243
- DEFAULT_AZIMUTH_DEG = 20;
181244
- DEFAULT_PERSPECTIVE_DEG = 30;
181245
- FOV_MIN = 15;
181246
- FOV_MAX = 75;
181247
- RIGHT_ANGLE_FOV = 20;
181248
- PERSPECTIVE_MAX_DEG = 120;
181249
- }
181250
- });
181251
- function normalizeToHeight(value, range) {
181252
- if (range.span <= 0) {
181253
- return 0;
181254
- }
181255
- return (value - range.min) / range.span * MAX_VALUE_HEIGHT;
181256
- }
181257
- function layoutCartesianLine3DSeries(points4, cols, rows, range, depthPercent) {
181258
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
181259
- const rowStep = gridDepth / Math.max(rows, 1);
181260
- const baselineY = normalizeToHeight(0, range);
181261
- const bySeries = /* @__PURE__ */ new Map();
181262
- for (const p of points4) {
181263
- const list2 = bySeries.get(p.seriesIndex);
181264
- if (list2) {
181265
- list2.push(p);
181266
- } else {
181267
- bySeries.set(p.seriesIndex, [p]);
181268
- }
181269
- }
181270
- const paths = [];
181271
- for (const [seriesIndex, seriesPoints] of bySeries) {
181272
- const sorted = [...seriesPoints].sort((a, b) => a.categoryIndex - b.categoryIndex);
181273
- const z = -gridDepth / 2 + rowStep * (seriesIndex + 0.5);
181274
- const vertices = sorted.map((p) => {
181275
- const x = -gridWidth / 2 + p.categoryIndex / Math.max(cols - 1, 1) * gridWidth;
181276
- const y = normalizeToHeight(p.value, range);
181277
- return {
181278
- seriesIndex,
181279
- categoryIndex: p.categoryIndex,
181280
- value: p.value,
181281
- position: [x, y, z]
181282
- };
181283
- });
181284
- paths.push({
181285
- seriesIndex,
181286
- color: sorted[0]?.color ?? "#4472C4",
181287
- vertices,
181288
- depthZ: z,
181289
- baselineY
181290
- });
181291
- }
181292
- return paths.sort((a, b) => a.seriesIndex - b.seriesIndex);
181293
- }
181294
- function buildAreaRibbonTriangles(path) {
181295
- const { vertices, baselineY } = path;
181296
- const out = [];
181297
- for (let i2 = 0; i2 < vertices.length - 1; i2++) {
181298
- const [x1, y1, z1] = vertices[i2].position;
181299
- const [x2, y2, z2] = vertices[i2 + 1].position;
181300
- out.push(x1, y1, z1, x1, baselineY, z1, x2, baselineY, z2);
181301
- out.push(x1, y1, z1, x2, baselineY, z2, x2, y2, z2);
181302
- }
181303
- return out;
181304
- }
181305
- var init_cartesian_line_chart_3d_layout = __esm2({
181306
- "src/render/cartesian-line-chart-3d-layout.ts"() {
181307
- init_cartesian_chart_3d_geom();
181308
- }
181309
- });
181310
181148
  function formatValueLabel(chartData, grouping, v) {
181311
181149
  if (grouping === "percentStacked") {
181312
181150
  return `${Math.round(v * 100)}%`;
@@ -181709,1197 +181547,6 @@ var init_chart_3d_pie_layout = __esm2({
181709
181547
  RIM_SAMPLES = 96;
181710
181548
  }
181711
181549
  });
181712
- function computePieChart3DThickness(view3D) {
181713
- const scale2 = Math.min(
181714
- Math.max((view3D?.hPercent ?? 100) / 100, MIN_THICKNESS_SCALE),
181715
- MAX_THICKNESS_SCALE
181716
- );
181717
- return PIE_RADIUS * BASE_THICKNESS_RATIO * scale2;
181718
- }
181719
- function computePieChart3DCameraPlacement(view3D) {
181720
- const thickness = computePieChart3DThickness(view3D);
181721
- const maxExtent = PIE_RADIUS * CAMERA_EXTENT_MARGIN;
181722
- return computeSphericalCameraPlacement(maxExtent, thickness / 2, view3D);
181723
- }
181724
- function computePieChart3DSliceAngles(values, explosions, firstSliceAngleDeg, outerRadius) {
181725
- const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
181726
- let cumAngle = -Math.PI / 2 + (firstSliceAngleDeg ?? 0) * Math.PI / 180;
181727
- return values.map((value, pointIndex) => {
181728
- const sliceAngle = Math.abs(value) / total * Math.PI * 2;
181729
- const startAngle = cumAngle;
181730
- cumAngle += sliceAngle;
181731
- const explosion = explosions?.[pointIndex] ?? 0;
181732
- let explodeOffset = [0, 0];
181733
- if (explosion > 0) {
181734
- const mid = (startAngle + cumAngle) / 2;
181735
- const offset = outerRadius * (explosion / 100);
181736
- explodeOffset = [Math.cos(mid) * offset, Math.sin(mid) * offset];
181737
- }
181738
- return { pointIndex, value, startAngle, thetaLength: sliceAngle, explodeOffset };
181739
- });
181740
- }
181741
- var PIE_RADIUS;
181742
- var BASE_THICKNESS_RATIO;
181743
- var MIN_THICKNESS_SCALE;
181744
- var MAX_THICKNESS_SCALE;
181745
- var CAMERA_EXTENT_MARGIN;
181746
- var init_pie_chart_3d_geom = __esm2({
181747
- "src/render/pie-chart-3d-geom.ts"() {
181748
- init_cartesian_chart_3d_geom();
181749
- PIE_RADIUS = 1;
181750
- BASE_THICKNESS_RATIO = 0.3;
181751
- MIN_THICKNESS_SCALE = 0.05;
181752
- MAX_THICKNESS_SCALE = 3;
181753
- CAMERA_EXTENT_MARGIN = 1.35;
181754
- }
181755
- });
181756
- function computeGridExtent(cols, rows) {
181757
- return {
181758
- gridWidth: Math.max(cols - 1, 1) * GRID_SPACING2,
181759
- gridDepth: Math.max(rows - 1, 1) * GRID_SPACING2
181760
- };
181761
- }
181762
- function buildSurfaceGeometry(three, cols, rows, heightMap, colorMap) {
181763
- const widthSegs = Math.max(cols - 1, 0);
181764
- const depthSegs = Math.max(rows - 1, 0);
181765
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181766
- const geo = new three.PlaneGeometry(gridWidth, gridDepth, widthSegs, depthSegs);
181767
- geo.rotateX(-Math.PI / 2);
181768
- const pos2 = geo.attributes.position;
181769
- const vertexCount = pos2.count;
181770
- const colors = new Float32Array(vertexCount * 3);
181771
- for (let i2 = 0; i2 < vertexCount; i2++) {
181772
- const row = Math.floor(i2 / cols);
181773
- const col = i2 % cols;
181774
- const idx = row * cols + col;
181775
- const h2 = idx < heightMap.length ? heightMap[idx] : 0;
181776
- pos2.setY(i2, h2 * MAX_HEIGHT);
181777
- const ci = idx * 3;
181778
- colors[i2 * 3] = ci < colorMap.length ? colorMap[ci] : 0.5;
181779
- colors[i2 * 3 + 1] = ci + 1 < colorMap.length ? colorMap[ci + 1] : 0.5;
181780
- colors[i2 * 3 + 2] = ci + 2 < colorMap.length ? colorMap[ci + 2] : 0.5;
181781
- }
181782
- geo.setAttribute("color", new three.BufferAttribute(colors, 3));
181783
- geo.computeVertexNormals();
181784
- pos2.needsUpdate = true;
181785
- const wireGeometry = new three.WireframeGeometry(geo);
181786
- return { geometry: geo, wireGeometry };
181787
- }
181788
- function surfaceVertexWorldPosition(cols, rows, row, col, heightMap) {
181789
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181790
- const x = col * GRID_SPACING2 - gridWidth / 2;
181791
- const z = row * GRID_SPACING2 - gridDepth / 2;
181792
- const idx = row * cols + col;
181793
- const h2 = idx >= 0 && idx < heightMap.length ? heightMap[idx] : 0;
181794
- return [x, h2 * MAX_HEIGHT, z];
181795
- }
181796
- function buildSurfaceLabels(cols, rows, categoryLabels, seriesNames, maxCat = 8, maxSer = 6) {
181797
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181798
- const labels = [];
181799
- const catStep = Math.max(1, Math.ceil(categoryLabels.length / maxCat));
181800
- for (let i2 = 0; i2 < categoryLabels.length; i2 += catStep) {
181801
- const x = -gridWidth / 2 + i2 / Math.max(cols - 1, 1) * gridWidth;
181802
- labels.push({
181803
- key: `cat-${i2}`,
181804
- text: categoryLabels[i2],
181805
- anchor: [x, -0.15, gridDepth / 2 + 0.25],
181806
- axis: "category"
181807
- });
181808
- }
181809
- const serStep = Math.max(1, Math.ceil(seriesNames.length / maxSer));
181810
- for (let i2 = 0; i2 < seriesNames.length; i2 += serStep) {
181811
- const z = -gridDepth / 2 + i2 / Math.max(rows - 1, 1) * gridDepth;
181812
- labels.push({
181813
- key: `ser-${i2}`,
181814
- text: seriesNames[i2],
181815
- anchor: [gridWidth / 2 + 0.3, -0.15, z],
181816
- axis: "series"
181817
- });
181818
- }
181819
- labels.push({
181820
- key: "value-axis",
181821
- text: "Value",
181822
- anchor: [-gridWidth / 2 - 0.35, 0.75, -gridDepth / 2],
181823
- axis: "value"
181824
- });
181825
- return labels;
181826
- }
181827
- function clamp9(value, min, max) {
181828
- return Math.min(Math.max(value, min), max);
181829
- }
181830
- function normalizeAzimuth2(deg3) {
181831
- const wrapped = deg3 % 360;
181832
- return wrapped < 0 ? wrapped + 360 : wrapped;
181833
- }
181834
- function computeCameraPlacement(cols, rows, view3D) {
181835
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181836
- const maxExtent = Math.max(gridWidth, gridDepth, MAX_HEIGHT);
181837
- const dist2 = maxExtent * 1.8;
181838
- const target = [0, 0.3, 0];
181839
- if (!view3D || view3D.rotX === void 0 && view3D.rotY === void 0) {
181840
- return { position: [dist2 * 0.8, dist2 * 0.7, dist2 * 0.8], target };
181841
- }
181842
- const radius = dist2 * RADIUS_FACTOR;
181843
- const elevationDeg = clamp9(view3D.rotX ?? DEFAULT_ELEVATION_DEG2, -89, 89);
181844
- const azimuthDeg = normalizeAzimuth2(view3D.rotY ?? DEFAULT_AZIMUTH_DEG2);
181845
- const phi = (90 - elevationDeg) * Math.PI / 180;
181846
- const theta = azimuthDeg * Math.PI / 180;
181847
- const sinPhi = Math.sin(phi);
181848
- return {
181849
- position: [
181850
- radius * sinPhi * Math.sin(theta),
181851
- radius * Math.cos(phi),
181852
- radius * sinPhi * Math.cos(theta)
181853
- ],
181854
- target
181855
- };
181856
- }
181857
- var GRID_SPACING2;
181858
- var MAX_HEIGHT;
181859
- var DEFAULT_ELEVATION_DEG2;
181860
- var DEFAULT_AZIMUTH_DEG2;
181861
- var RADIUS_FACTOR;
181862
- var init_surface_chart_3d_geom = __esm2({
181863
- "src/render/surface-chart-3d-geom.ts"() {
181864
- GRID_SPACING2 = 0.5;
181865
- MAX_HEIGHT = 1.5;
181866
- DEFAULT_ELEVATION_DEG2 = 15;
181867
- DEFAULT_AZIMUTH_DEG2 = 20;
181868
- RADIUS_FACTOR = Math.sqrt(0.8 ** 2 + 0.7 ** 2 + 0.8 ** 2);
181869
- }
181870
- });
181871
- function createHostedChart3DStage(ctx, placement, limits, ambientIntensity = 0.6) {
181872
- const three = ctx.three;
181873
- const width = Math.max(1, ctx.size.width);
181874
- const height = Math.max(1, ctx.size.height);
181875
- const scene = new three.Scene();
181876
- scene.add(new three.AmbientLight(16777215, ambientIntensity));
181877
- const key2 = new three.DirectionalLight(16777215, 0.8);
181878
- key2.position.set(5, 8, 5);
181879
- scene.add(key2);
181880
- const fill = new three.DirectionalLight(16777215, 0.3);
181881
- fill.position.set(-3, 4, -2);
181882
- scene.add(fill);
181883
- const camera = new three.PerspectiveCamera(placement.fov, width / height, 0.1, 1e3);
181884
- camera.position.set(...placement.position);
181885
- const target = new three.Vector3(...placement.target);
181886
- camera.lookAt(target);
181887
- let orbit = null;
181888
- if (ctx.OrbitControls) {
181889
- orbit = new ctx.OrbitControls(camera, ctx.eventTarget);
181890
- const limited = orbit;
181891
- limited.enablePan = true;
181892
- limited.enableZoom = true;
181893
- limited.enableRotate = true;
181894
- limited.minDistance = limits.minDistance;
181895
- limited.maxDistance = limits.maxDistance;
181896
- limited.maxPolarAngle = Math.PI / 2 + 0.3;
181897
- limited.target.copy(target);
181898
- limited.enabled = ctx.interactive;
181899
- limited.update();
181900
- }
181901
- return {
181902
- three,
181903
- canvas: ctx.eventTarget,
181904
- scene,
181905
- camera,
181906
- controls: orbit ?? { enabled: false },
181907
- orbit,
181908
- width,
181909
- height
181910
- };
181911
- }
181912
- function hostedChart3DInteraction(ctx) {
181913
- let interactive = ctx.interactive;
181914
- return {
181915
- onSelect: (part) => {
181916
- if (interactive) {
181917
- ctx.emit({ type: "select", part });
181918
- }
181919
- },
181920
- onValueDragPreview: (part, value) => {
181921
- if (interactive) {
181922
- ctx.emit({ type: "drag", detail: { part, value, phase: "move" } });
181923
- }
181924
- },
181925
- onValueDragCommit: (part, value) => {
181926
- if (interactive) {
181927
- ctx.emit({ type: "drag", detail: { part, value, phase: "commit" } });
181928
- }
181929
- },
181930
- set: (on) => {
181931
- interactive = on;
181932
- }
181933
- };
181934
- }
181935
- function finishHostedChart3DScene(ctx, stage, parts, interactive) {
181936
- let width = stage.width;
181937
- let height = stage.height;
181938
- const requestRender = () => ctx.requestRender();
181939
- stage.orbit?.addEventListener("change", requestRender);
181940
- for (const type of REDRAW_EVENTS) {
181941
- ctx.eventTarget.addEventListener(type, requestRender);
181942
- }
181943
- let disposed = false;
181944
- return {
181945
- render(renderer) {
181946
- stage.orbit?.update();
181947
- renderer.render(stage.scene, stage.camera);
181948
- parts.afterRender?.(stage.camera, width, height);
181949
- },
181950
- resize(size) {
181951
- width = Math.max(1, size.width);
181952
- height = Math.max(1, size.height);
181953
- stage.camera.aspect = width / height;
181954
- stage.camera.updateProjectionMatrix();
181955
- parts.resize?.(width, height);
181956
- },
181957
- isAnimating: () => false,
181958
- setInteractive(on) {
181959
- interactive.set(on);
181960
- if (stage.orbit) {
181961
- stage.orbit.enabled = on;
181962
- }
181963
- },
181964
- setSelectedPart(part) {
181965
- parts.setSelectedPart?.(part);
181966
- },
181967
- setTextStyle(style) {
181968
- parts.setTextStyle?.(style);
181969
- },
181970
- dispose() {
181971
- if (disposed) {
181972
- return;
181973
- }
181974
- disposed = true;
181975
- stage.orbit?.removeEventListener("change", requestRender);
181976
- for (const type of REDRAW_EVENTS) {
181977
- ctx.eventTarget.removeEventListener(type, requestRender);
181978
- }
181979
- stage.orbit?.dispose();
181980
- parts.dispose();
181981
- stage.scene.clear();
181982
- }
181983
- };
181984
- }
181985
- var REDRAW_EVENTS;
181986
- var init_chart_3d_hosted_stage = __esm2({
181987
- "src/render/chart-3d-hosted-stage.ts"() {
181988
- REDRAW_EVENTS = ["pointermove", "pointerdown", "pointerup", "pointerleave", "wheel"];
181989
- }
181990
- });
181991
- function attachChart3DHoverTooltip(options) {
181992
- const raycaster = new options.three.Raycaster();
181993
- const ndc = new options.three.Vector2();
181994
- let hoveredTooltip;
181995
- const updateHoverTooltip = (clientX, clientY) => {
181996
- const rect22 = options.canvas.getBoundingClientRect();
181997
- if (rect22.width <= 0 || rect22.height <= 0) {
181998
- return;
181999
- }
182000
- ndc.x = (clientX - rect22.left) / rect22.width * 2 - 1;
182001
- ndc.y = -((clientY - rect22.top) / rect22.height) * 2 + 1;
182002
- raycaster.setFromCamera(ndc, options.camera);
182003
- const hit = raycaster.intersectObjects(options.meshes, false)[0];
182004
- const tooltip = options.buildTooltip(hit);
182005
- if (tooltip !== hoveredTooltip) {
182006
- hoveredTooltip = tooltip;
182007
- options.canvas.title = tooltip ?? "";
182008
- }
182009
- };
182010
- const onPointerMove = (event) => {
182011
- updateHoverTooltip(event.clientX, event.clientY);
182012
- };
182013
- const onPointerLeave = () => {
182014
- if (hoveredTooltip !== void 0) {
182015
- hoveredTooltip = void 0;
182016
- options.canvas.title = "";
182017
- }
182018
- };
182019
- options.canvas.addEventListener("pointermove", onPointerMove);
182020
- options.canvas.addEventListener("pointerleave", onPointerLeave);
182021
- return {
182022
- dispose() {
182023
- options.canvas.removeEventListener("pointermove", onPointerMove);
182024
- options.canvas.removeEventListener("pointerleave", onPointerLeave);
182025
- }
182026
- };
182027
- }
182028
- var init_chart_3d_hover_tooltip = __esm2({
182029
- "src/render/chart-3d-hover-tooltip.ts"() {
182030
- }
182031
- });
182032
- function createLabelOverlay(doc, labels) {
182033
- const layer = doc.createElement("div");
182034
- Object.assign(layer.style, {
182035
- position: "absolute",
182036
- inset: "0",
182037
- pointerEvents: "none",
182038
- overflow: "hidden"
182039
- });
182040
- const entries2 = labels.map((label) => {
182041
- const node = doc.createElement("div");
182042
- node.textContent = label.text;
182043
- const baseColor = label.axis === "value" ? "#999" : "#666";
182044
- Object.assign(node.style, {
182045
- position: "absolute",
182046
- fontSize: `${BASE_FONT_SIZE_PX}px`,
182047
- color: baseColor,
182048
- whiteSpace: "nowrap",
182049
- userSelect: "none",
182050
- transform: "translate(-50%, -50%)",
182051
- willChange: "left, top"
182052
- });
182053
- if (label.axis === "value") {
182054
- node.style.writingMode = "vertical-rl";
182055
- }
182056
- layer.appendChild(node);
182057
- return { node, baseColor };
182058
- });
182059
- function applyTextStyle(style) {
182060
- for (const { node, baseColor } of entries2) {
182061
- node.style.fontWeight = style?.bold === void 0 ? "" : style.bold ? "bold" : "normal";
182062
- node.style.fontStyle = style?.italic === void 0 ? "" : style.italic ? "italic" : "normal";
182063
- node.style.textDecorationLine = style?.underline === void 0 ? "" : style.underline ? "underline" : "none";
182064
- const scale2 = typeof style?.fontScale === "number" && Number.isFinite(style.fontScale) && style.fontScale > 0 ? style.fontScale : 1;
182065
- node.style.fontSize = `${BASE_FONT_SIZE_PX * scale2}px`;
182066
- node.style.color = style?.color ?? baseColor;
182067
- }
182068
- }
182069
- return { layer, nodes: entries2.map((e) => e.node), applyTextStyle };
182070
- }
182071
- var BASE_FONT_SIZE_PX;
182072
- var init_surface_chart_3d_label_overlay = __esm2({
182073
- "src/render/surface-chart-3d-label-overlay.ts"() {
182074
- BASE_FONT_SIZE_PX = 9;
182075
- }
182076
- });
182077
- function createChart3DLabelProjector(three, doc, labels) {
182078
- const overlay = createLabelOverlay(doc, labels);
182079
- const anchors = labels.map((l) => new three.Vector3(...l.anchor));
182080
- const projected = new three.Vector3();
182081
- return {
182082
- layer: overlay.layer,
182083
- applyTextStyle: overlay.applyTextStyle,
182084
- update(camera, width, height) {
182085
- for (let i2 = 0; i2 < overlay.nodes.length; i2++) {
182086
- projected.copy(anchors[i2]).project(camera);
182087
- const node = overlay.nodes[i2];
182088
- if (projected.z > 1) {
182089
- node.style.display = "none";
182090
- continue;
182091
- }
182092
- node.style.display = "";
182093
- node.style.left = `${(projected.x + 1) / 2 * width}px`;
182094
- node.style.top = `${(-projected.y + 1) / 2 * height}px`;
182095
- }
182096
- }
182097
- };
182098
- }
182099
- var init_chart_3d_label_projection = __esm2({
182100
- "src/render/chart-3d-label-projection.ts"() {
182101
- init_surface_chart_3d_label_overlay();
182102
- }
182103
- });
182104
- function surfaceFaceIndexToCell(faceIndex, cols, rows) {
182105
- const quadsPerRow = cols - 1;
182106
- const quadsPerCol = rows - 1;
182107
- if (!Number.isFinite(faceIndex) || faceIndex < 0 || quadsPerRow <= 0 || quadsPerCol <= 0) {
182108
- return null;
182109
- }
182110
- const quadIndex = Math.floor(faceIndex / 2);
182111
- const row = Math.floor(quadIndex / quadsPerRow);
182112
- const col = quadIndex % quadsPerRow;
182113
- if (row < 0 || row >= quadsPerCol || col < 0 || col >= quadsPerRow) {
182114
- return null;
182115
- }
182116
- return { row, col };
182117
- }
182118
- function buildSurfaceHoverTooltip(faceIndex, data) {
182119
- if (faceIndex === void 0 || faceIndex === null || !data.values) {
182120
- return void 0;
182121
- }
182122
- const cell = surfaceFaceIndexToCell(faceIndex, data.cols, data.rows);
182123
- if (!cell) {
182124
- return void 0;
182125
- }
182126
- const idx = cell.row * data.cols + cell.col;
182127
- const value = data.values[idx];
182128
- if (value === void 0) {
182129
- return void 0;
182130
- }
182131
- return buildMarkTooltip(
182132
- data.seriesNames[cell.row],
182133
- data.categoryLabels[cell.col],
182134
- value,
182135
- data.numberFormats?.[cell.row]
182136
- );
182137
- }
182138
- var init_surface_chart_3d_hit_test = __esm2({
182139
- "src/render/surface-chart-3d-hit-test.ts"() {
182140
- init_chart_view_model();
182141
- }
182142
- });
182143
- function chart3DHitToPartRef(hit) {
182144
- if (!hit) {
182145
- return null;
182146
- }
182147
- return { role: "dataPoint", seriesIndex: hit.seriesIndex, pointIndex: hit.pointIndex };
182148
- }
182149
- function chart3DMarkMatchesPart(mark, part) {
182150
- return part !== null && part !== void 0 && part.role === "dataPoint" && part.seriesIndex === mark.seriesIndex && part.pointIndex === mark.pointIndex;
182151
- }
182152
- function calibrateChart3DValueAxis(screenAtValue0, value0, screenAtValue1, value1) {
182153
- const valueSpan = value1 - value0;
182154
- const dx = screenAtValue1.x - screenAtValue0.x;
182155
- const dy = screenAtValue1.y - screenAtValue0.y;
182156
- const pixelSpan = Math.hypot(dx, dy);
182157
- if (valueSpan === 0 || pixelSpan < 1e-6 || !Number.isFinite(valueSpan)) {
182158
- return null;
182159
- }
182160
- return {
182161
- directionScreen: { x: dx / pixelSpan, y: dy / pixelSpan },
182162
- pixelsPerUnit: pixelSpan / valueSpan
182163
- };
182164
- }
182165
- function chart3DPointerDeltaToValueDelta(calibration, pointerDeltaScreen) {
182166
- const dot2 = pointerDeltaScreen.x * calibration.directionScreen.x + pointerDeltaScreen.y * calibration.directionScreen.y;
182167
- return dot2 / calibration.pixelsPerUnit;
182168
- }
182169
- var CHART_3D_DRAG_THRESHOLD_PX;
182170
- var CHART_3D_SELECTED_EMISSIVE;
182171
- var CHART_3D_SELECTED_EMISSIVE_INTENSITY;
182172
- var init_chart_3d_interaction = __esm2({
182173
- "src/render/chart-3d-interaction.ts"() {
182174
- CHART_3D_DRAG_THRESHOLD_PX = 3;
182175
- CHART_3D_SELECTED_EMISSIVE = "#3b82f6";
182176
- CHART_3D_SELECTED_EMISSIVE_INTENSITY = 0.55;
182177
- }
182178
- });
182179
- function projectToScreen(three, camera, point, width, height) {
182180
- const v = new three.Vector3(point[0], point[1], point[2]);
182181
- v.project(camera);
182182
- return { x: (v.x + 1) / 2 * width, y: (-v.y + 1) / 2 * height };
182183
- }
182184
- function attachChart3DPointerInteraction(options) {
182185
- let width = options.width;
182186
- let height = options.height;
182187
- const raycaster = new options.three.Raycaster();
182188
- const ndc = new options.three.Vector2();
182189
- let dragState = null;
182190
- function raycastAt(clientX, clientY) {
182191
- const rect22 = options.canvas.getBoundingClientRect();
182192
- if (rect22.width <= 0 || rect22.height <= 0) {
182193
- return void 0;
182194
- }
182195
- ndc.x = (clientX - rect22.left) / rect22.width * 2 - 1;
182196
- ndc.y = -((clientY - rect22.top) / rect22.height) * 2 + 1;
182197
- raycaster.setFromCamera(ndc, options.camera);
182198
- return raycaster.intersectObjects(options.meshes, false)[0];
182199
- }
182200
- function setSelectedPart(part) {
182201
- options.applyHighlight?.(part);
182202
- }
182203
- function currentDelta(clientX, clientY, state) {
182204
- return { x: clientX - state.startClientX, y: clientY - state.startClientY };
182205
- }
182206
- const onPointerDown = (event) => {
182207
- options.canvas.setPointerCapture?.(
182208
- event.pointerId
182209
- );
182210
- const hit = raycastAt(event.clientX, event.clientY);
182211
- const part = hit ? options.resolveHit(hit) : null;
182212
- const armed = part !== null && isChartInteractionArmed(options.canvas);
182213
- if (armed) {
182214
- event.stopPropagation();
182215
- }
182216
- let calibration = null;
182217
- let startValue = 0;
182218
- if (hit && part && armed && options.calibrateDrag) {
182219
- const input = options.calibrateDrag(hit, part);
182220
- if (input) {
182221
- const s0 = projectToScreen(
182222
- options.three,
182223
- options.camera,
182224
- input.worldAtValue0,
182225
- width,
182226
- height
182227
- );
182228
- const s1 = projectToScreen(
182229
- options.three,
182230
- options.camera,
182231
- input.worldAtValue1,
182232
- width,
182233
- height
182234
- );
182235
- calibration = calibrateChart3DValueAxis(s0, input.value0, s1, input.value1);
182236
- startValue = input.value1;
182237
- }
182238
- }
182239
- dragState = {
182240
- part,
182241
- calibration,
182242
- startValue,
182243
- startClientX: event.clientX,
182244
- startClientY: event.clientY,
182245
- moved: false
182246
- };
182247
- if (calibration) {
182248
- event.preventDefault();
182249
- options.setControlsEnabled?.(false);
182250
- }
182251
- };
182252
- const onPointerMove = (event) => {
182253
- if (!dragState || !dragState.part || !dragState.calibration) {
182254
- return;
182255
- }
182256
- const delta = currentDelta(event.clientX, event.clientY, dragState);
182257
- if (!dragState.moved && Math.hypot(delta.x, delta.y) < CHART_3D_DRAG_THRESHOLD_PX) {
182258
- return;
182259
- }
182260
- dragState.moved = true;
182261
- const value = dragState.startValue + chart3DPointerDeltaToValueDelta(dragState.calibration, delta);
182262
- options.onValueDragPreview?.(dragState.part, value);
182263
- };
182264
- const onPointerUp = (event) => {
182265
- if (!dragState) {
182266
- return;
182267
- }
182268
- const state = dragState;
182269
- dragState = null;
182270
- options.canvas.releasePointerCapture?.(event.pointerId);
182271
- if (state.calibration) {
182272
- options.setControlsEnabled?.(true);
182273
- }
182274
- if (state.moved && state.part && state.calibration) {
182275
- const delta = currentDelta(event.clientX, event.clientY, state);
182276
- const value = state.startValue + chart3DPointerDeltaToValueDelta(state.calibration, delta);
182277
- options.onValueDragCommit?.(state.part, value);
182278
- return;
182279
- }
182280
- setSelectedPart(state.part);
182281
- options.onSelect?.(state.part);
182282
- };
182283
- options.canvas.addEventListener("pointerdown", onPointerDown);
182284
- options.canvas.addEventListener("pointermove", onPointerMove);
182285
- options.canvas.addEventListener("pointerup", onPointerUp);
182286
- options.canvas.addEventListener("pointercancel", onPointerUp);
182287
- return {
182288
- setSelectedPart,
182289
- updateSize(w, h2) {
182290
- width = w;
182291
- height = h2;
182292
- },
182293
- dispose() {
182294
- options.canvas.removeEventListener("pointerdown", onPointerDown);
182295
- options.canvas.removeEventListener("pointermove", onPointerMove);
182296
- options.canvas.removeEventListener("pointerup", onPointerUp);
182297
- options.canvas.removeEventListener("pointercancel", onPointerUp);
182298
- }
182299
- };
182300
- }
182301
- var init_chart_3d_pointer_interaction = __esm2({
182302
- "src/render/chart-3d-pointer-interaction.ts"() {
182303
- init_chart_3d_interaction();
182304
- init_chart_canvas_drag();
182305
- }
182306
- });
182307
- function calibrateSurfaceChart3DDrag(position2, value, values) {
182308
- let min = Infinity;
182309
- let max = -Infinity;
182310
- for (const v of values) {
182311
- if (v < min) {
182312
- min = v;
182313
- }
182314
- if (v > max) {
182315
- max = v;
182316
- }
182317
- }
182318
- if (!(max > min)) {
182319
- return null;
182320
- }
182321
- const [x, , z] = position2;
182322
- const atMin = value === min;
182323
- return {
182324
- worldAtValue0: [x, atMin ? MAX_HEIGHT : 0, z],
182325
- value0: atMin ? max : min,
182326
- worldAtValue1: position2,
182327
- value1: value
182328
- };
182329
- }
182330
- var init_surface_chart_3d_drag = __esm2({
182331
- "src/render/surface-chart-3d-drag.ts"() {
182332
- init_surface_chart_3d_geom();
182333
- }
182334
- });
182335
- function createSurfaceHighlightMarker(three, cols, rows, heightMap) {
182336
- const geometry = new three.SphereGeometry(MARKER_RADIUS, 12, 8);
182337
- const material = new three.MeshPhongMaterial({
182338
- color: CHART_3D_SELECTED_EMISSIVE,
182339
- emissive: CHART_3D_SELECTED_EMISSIVE,
182340
- emissiveIntensity: CHART_3D_SELECTED_EMISSIVE_INTENSITY,
182341
- shininess: 30
182342
- });
182343
- const mesh = new three.Mesh(geometry, material);
182344
- mesh.visible = false;
182345
- return {
182346
- mesh,
182347
- setSelected(cell) {
182348
- if (!cell) {
182349
- mesh.visible = false;
182350
- return;
182351
- }
182352
- const [x, y, z] = surfaceVertexWorldPosition(cols, rows, cell.row, cell.col, heightMap);
182353
- mesh.position.set(x, y + MARKER_Y_OFFSET, z);
182354
- mesh.visible = true;
182355
- },
182356
- dispose() {
182357
- geometry.dispose();
182358
- material.dispose();
182359
- }
182360
- };
182361
- }
182362
- function cellFromIntersection(intersection, cols, rows) {
182363
- return intersection.faceIndex === void 0 || intersection.faceIndex === null ? null : surfaceFaceIndexToCell(intersection.faceIndex, cols, rows);
182364
- }
182365
- function attachSurfaceChart3DInteraction(params) {
182366
- return attachChart3DPointerInteraction({
182367
- three: params.three,
182368
- canvas: params.canvas,
182369
- camera: params.camera,
182370
- width: params.width,
182371
- height: params.height,
182372
- meshes: [params.surfaceMesh],
182373
- resolveHit: (intersection) => {
182374
- const cell = cellFromIntersection(intersection, params.cols, params.rows);
182375
- return chart3DHitToPartRef(cell ? { seriesIndex: cell.row, pointIndex: cell.col } : null);
182376
- },
182377
- calibrateDrag: (intersection) => {
182378
- const cell = cellFromIntersection(intersection, params.cols, params.rows);
182379
- if (!cell || !params.values) {
182380
- return null;
182381
- }
182382
- const idx = cell.row * params.cols + cell.col;
182383
- const value = params.values[idx];
182384
- if (value === void 0) {
182385
- return null;
182386
- }
182387
- const position2 = surfaceVertexWorldPosition(
182388
- params.cols,
182389
- params.rows,
182390
- cell.row,
182391
- cell.col,
182392
- params.heightMap
182393
- );
182394
- return calibrateSurfaceChart3DDrag(position2, value, params.values);
182395
- },
182396
- applyHighlight: (part) => {
182397
- const cell = part && part.role === "dataPoint" && part.pointIndex !== void 0 ? { row: part.seriesIndex, col: part.pointIndex } : null;
182398
- params.highlightMarker.setSelected(cell);
182399
- },
182400
- setControlsEnabled: (enabled) => {
182401
- params.controls.enabled = enabled;
182402
- },
182403
- onSelect: params.interaction?.onSelect,
182404
- onValueDragPreview: params.interaction?.onValueDragPreview,
182405
- onValueDragCommit: params.interaction?.onValueDragCommit
182406
- });
182407
- }
182408
- var MARKER_RADIUS;
182409
- var MARKER_Y_OFFSET;
182410
- var init_surface_chart_3d_interaction_wiring = __esm2({
182411
- "src/render/surface-chart-3d-interaction-wiring.ts"() {
182412
- init_chart_3d_interaction();
182413
- init_chart_3d_pointer_interaction();
182414
- init_surface_chart_3d_drag();
182415
- init_surface_chart_3d_geom();
182416
- init_surface_chart_3d_hit_test();
182417
- MARKER_RADIUS = 0.07;
182418
- MARKER_Y_OFFSET = 0.03;
182419
- }
182420
- });
182421
- function buildSurfaceWallMeshes(three, cols, rows, wallHeight, colors, extent) {
182422
- const { gridWidth, gridDepth } = extent ?? computeGridExtent(cols, rows);
182423
- const meshes = [];
182424
- const disposables = [];
182425
- const addPlane = (width, height, color2, position2, rotation) => {
182426
- const geometry = new three.PlaneGeometry(width, height);
182427
- const material = new three.MeshBasicMaterial({
182428
- color: color2,
182429
- transparent: true,
182430
- opacity: PANEL_OPACITY,
182431
- side: three.DoubleSide,
182432
- depthWrite: false
182433
- });
182434
- const mesh = new three.Mesh(geometry, material);
182435
- mesh.position.set(...position2);
182436
- mesh.rotation.set(...rotation);
182437
- meshes.push(mesh);
182438
- disposables.push(geometry, material);
182439
- };
182440
- if (colors.floor) {
182441
- addPlane(gridWidth, gridDepth, colors.floor, [0, -0.01, 0], [-Math.PI / 2, 0, 0]);
182442
- }
182443
- if (colors.backWall) {
182444
- addPlane(
182445
- gridWidth,
182446
- wallHeight,
182447
- colors.backWall,
182448
- [0, wallHeight / 2, -gridDepth / 2],
182449
- [0, 0, 0]
182450
- );
182451
- }
182452
- if (colors.sideWall) {
182453
- addPlane(
182454
- gridDepth,
182455
- wallHeight,
182456
- colors.sideWall,
182457
- [gridWidth / 2, wallHeight / 2, 0],
182458
- [0, Math.PI / 2, 0]
182459
- );
182460
- }
182461
- return {
182462
- meshes,
182463
- dispose: () => {
182464
- for (const d of disposables) {
182465
- d.dispose();
182466
- }
182467
- }
182468
- };
182469
- }
182470
- var PANEL_OPACITY;
182471
- var init_surface_chart_3d_walls = __esm2({
182472
- "src/render/surface-chart-3d-walls.ts"() {
182473
- init_surface_chart_3d_geom();
182474
- PANEL_OPACITY = 0.35;
182475
- }
182476
- });
182477
- function createSurfaceChart3DScene(ctx, options) {
182478
- const { cols, rows } = options;
182479
- const placement = computeCameraPlacement(cols, rows, options.view3D);
182480
- const stage = createHostedChart3DStage(
182481
- ctx,
182482
- { fov: FOV2, ...placement },
182483
- { minDistance: 1, maxDistance: 20 },
182484
- 0.6
182485
- );
182486
- const { three, scene, camera, canvas, controls, width, height } = stage;
182487
- const interaction = hostedChart3DInteraction(ctx);
182488
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
182489
- const floorSize = Math.max(gridWidth, gridDepth) * 1.2;
182490
- const gridFloor = new three.GridHelper(floorSize, Math.max(cols, rows), 13421772, 15263976);
182491
- gridFloor.position.y = -0.02;
182492
- scene.add(gridFloor);
182493
- const walls = options.surfaceColors ? buildSurfaceWallMeshes(three, cols, rows, MAX_HEIGHT, options.surfaceColors) : null;
182494
- for (const mesh of walls?.meshes ?? []) {
182495
- scene.add(mesh);
182496
- }
182497
- const { heightMap, colorMap } = options;
182498
- const { geometry, wireGeometry } = buildSurfaceGeometry(three, cols, rows, heightMap, colorMap);
182499
- const surfaceMaterial = new three.MeshPhongMaterial({
182500
- vertexColors: true,
182501
- side: three.DoubleSide,
182502
- shininess: 30,
182503
- transparent: true,
182504
- opacity: 0.92
182505
- });
182506
- const surfaceMesh = new three.Mesh(geometry, surfaceMaterial);
182507
- scene.add(surfaceMesh);
182508
- const highlightMarker = createSurfaceHighlightMarker(three, cols, rows, heightMap);
182509
- scene.add(highlightMarker.mesh);
182510
- let wireMaterial = null;
182511
- if (options.wireframe) {
182512
- wireMaterial = new three.LineBasicMaterial({
182513
- color: 3355443,
182514
- transparent: true,
182515
- opacity: 0.25
182516
- });
182517
- scene.add(new three.LineSegments(wireGeometry, wireMaterial));
182518
- }
182519
- const hoverTooltip = attachChart3DHoverTooltip({
182520
- three,
182521
- canvas,
182522
- camera,
182523
- meshes: [surfaceMesh],
182524
- buildTooltip: (intersection) => buildSurfaceHoverTooltip(intersection?.faceIndex, {
182525
- cols,
182526
- rows,
182527
- categoryLabels: options.categoryLabels,
182528
- seriesNames: options.seriesNames,
182529
- values: options.values,
182530
- numberFormats: options.numberFormats
182531
- })
182532
- });
182533
- const pointerInteraction = attachSurfaceChart3DInteraction({
182534
- three,
182535
- canvas,
182536
- camera,
182537
- controls,
182538
- width,
182539
- height,
182540
- surfaceMesh,
182541
- cols,
182542
- rows,
182543
- heightMap,
182544
- values: options.values,
182545
- highlightMarker,
182546
- interaction
182547
- });
182548
- const labels = buildSurfaceLabels(cols, rows, options.categoryLabels, options.seriesNames);
182549
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
182550
- labelProjector.applyTextStyle(options.textStyle);
182551
- ctx.overlay.appendChild(labelProjector.layer);
182552
- return finishHostedChart3DScene(
182553
- ctx,
182554
- stage,
182555
- {
182556
- afterRender: (cam, w, h2) => labelProjector.update(cam, w, h2),
182557
- resize: (w, h2) => pointerInteraction.updateSize(w, h2),
182558
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
182559
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
182560
- dispose() {
182561
- hoverTooltip.dispose();
182562
- pointerInteraction.dispose();
182563
- geometry.dispose();
182564
- wireGeometry.dispose();
182565
- surfaceMaterial.dispose();
182566
- wireMaterial?.dispose();
182567
- highlightMarker.dispose();
182568
- gridFloor.dispose();
182569
- walls?.dispose();
182570
- labelProjector.layer.remove();
182571
- }
182572
- },
182573
- interaction
182574
- );
182575
- }
182576
- var FOV2;
182577
- var init_surface_chart_3d_scene = __esm2({
182578
- "src/render/surface-chart-3d-scene.ts"() {
182579
- init_chart_3d_hosted_stage();
182580
- init_chart_3d_hover_tooltip();
182581
- init_chart_3d_label_projection();
182582
- init_surface_chart_3d_geom();
182583
- init_surface_chart_3d_hit_test();
182584
- init_surface_chart_3d_interaction_wiring();
182585
- init_surface_chart_3d_walls();
182586
- FOV2 = 45;
182587
- }
182588
- });
182589
- function colorFace(color2) {
182590
- return { kind: "color", color: color2 };
182591
- }
182592
- function worldHeightPerValueUnit(box) {
182593
- return box.value !== 0 ? box.size[1] / box.value : void 0;
182594
- }
182595
- function faceRepeat(format2, pictureStackUnit, faceWorldSize, box) {
182596
- if (format2 === "stretch" || pictureStackUnit === void 0 || pictureStackUnit <= 0) {
182597
- return 1;
182598
- }
182599
- const perValueUnit = worldHeightPerValueUnit(box);
182600
- if (!perValueUnit) {
182601
- return 1;
182602
- }
182603
- const tileWorldSize = pictureStackUnit * perValueUnit;
182604
- return tileWorldSize > 0 ? Math.max(1, faceWorldSize / tileWorldSize) : 1;
182605
- }
182606
- function resolveTargetedFace(series, box, face, faceWorldSize, untargetedFallback) {
182607
- const resolved = resolveDataPointPictureFill(series, box.categoryIndex, box.seriesIndex, face);
182608
- if (!resolved) {
182609
- return colorFace(untargetedFallback);
182610
- }
182611
- const pictureStackUnit = resolveActiveDataPointPicture(
182612
- series,
182613
- box.categoryIndex
182614
- )?.pictureStackUnit;
182615
- return {
182616
- kind: "picture",
182617
- imageUrl: resolved.imageUrl,
182618
- repeatX: 1,
182619
- repeatY: faceRepeat(resolved.format, pictureStackUnit, faceWorldSize, box)
182620
- };
182621
- }
182622
- function allSameColor(fills) {
182623
- const first = fills[0];
182624
- if (!first || first.kind !== "color") {
182625
- return void 0;
182626
- }
182627
- return fills.every((fill) => fill.kind === "color" && fill.color === first.color) ? first.color : void 0;
182628
- }
182629
- function resolveBarBoxFaceFills(box, series) {
182630
- const plain = {
182631
- posX: colorFace(box.color),
182632
- negX: colorFace(box.color),
182633
- posY: colorFace(box.color),
182634
- negY: colorFace(box.color),
182635
- posZ: colorFace(box.color),
182636
- negZ: colorFace(box.color)
182637
- };
182638
- if (box.shape !== void 0 && box.shape !== "box") {
182639
- return plain;
182640
- }
182641
- const seriesData = series[box.seriesIndex];
182642
- if (!seriesData) {
182643
- return plain;
182644
- }
182645
- const active2 = resolveActiveDataPointPicture(seriesData, box.categoryIndex);
182646
- if (!active2?.imageUrl) {
182647
- return plain;
182648
- }
182649
- const [, height, depth] = box.size;
182650
- const frontFill = resolveTargetedFace(seriesData, box, "front", height, box.color);
182651
- const sideFill = resolveTargetedFace(
182652
- seriesData,
182653
- box,
182654
- "side",
182655
- height,
182656
- resolveUntargetedBarFaceFill("side", box.color)
182657
- );
182658
- const endFill = resolveTargetedFace(
182659
- seriesData,
182660
- box,
182661
- "end",
182662
- depth,
182663
- resolveUntargetedBarFaceFill("end", box.color)
182664
- );
182665
- return {
182666
- posX: sideFill,
182667
- negX: sideFill,
182668
- posY: endFill,
182669
- negY: colorFace(box.color),
182670
- posZ: frontFill,
182671
- negZ: colorFace(box.color)
182672
- };
182673
- }
182674
- function resolveBarRoundFaceFills(box, series) {
182675
- const plain = {
182676
- side: colorFace(box.color),
182677
- end: colorFace(box.color),
182678
- bottom: colorFace(box.color)
182679
- };
182680
- const seriesData = series[box.seriesIndex];
182681
- if (!seriesData) {
182682
- return plain;
182683
- }
182684
- const active2 = resolveActiveDataPointPicture(seriesData, box.categoryIndex);
182685
- if (!active2?.imageUrl) {
182686
- return plain;
182687
- }
182688
- const [, height, depth] = box.size;
182689
- const sideFill = resolveTargetedFace(
182690
- seriesData,
182691
- box,
182692
- "side",
182693
- height,
182694
- resolveUntargetedBarFaceFill("side", box.color)
182695
- );
182696
- const endFill = resolveTargetedFace(
182697
- seriesData,
182698
- box,
182699
- "end",
182700
- depth,
182701
- resolveUntargetedBarFaceFill("end", box.color)
182702
- );
182703
- return { side: sideFill, end: endFill, bottom: colorFace(box.color) };
182704
- }
182705
- function uniformBoxColor(fills) {
182706
- return allSameColor([fills.posX, fills.negX, fills.posY, fills.negY, fills.posZ, fills.negZ]);
182707
- }
182708
- function uniformRoundColor(fills) {
182709
- return allSameColor([fills.side, fills.end, fills.bottom]);
182710
- }
182711
- var init_bar_chart_3d_face_fill = __esm2({
182712
- "src/render/bar-chart-3d-face-fill.ts"() {
182713
- init_chart_bar3d_face_picture();
182714
- init_chart_datapoint_picture_resolve();
182715
- }
182716
- });
182717
- function createBarChart3DTextureManager(three) {
182718
- const loader = new three.TextureLoader();
182719
- const cache2 = /* @__PURE__ */ new Map();
182720
- const loaded = [];
182721
- return {
182722
- load(url) {
182723
- const cached = cache2.get(url);
182724
- if (cached) {
182725
- return cached;
182726
- }
182727
- const pending = new Promise((resolve3, reject) => {
182728
- loader.load(
182729
- url,
182730
- (texture) => {
182731
- loaded.push(texture);
182732
- resolve3(texture);
182733
- },
182734
- void 0,
182735
- reject
182736
- );
182737
- });
182738
- cache2.set(url, pending);
182739
- return pending;
182740
- },
182741
- disposeAll() {
182742
- for (const texture of loaded) {
182743
- texture.dispose();
182744
- }
182745
- loaded.length = 0;
182746
- cache2.clear();
182747
- }
182748
- };
182749
- }
182750
- function buildColorMaterial(three, color2) {
182751
- return new three.MeshPhongMaterial({ color: color2, shininess: 30 });
182752
- }
182753
- function buildFaceMaterial(three, fill, textures, ownedTextures, isDisposed) {
182754
- if (fill.kind === "color") {
182755
- return buildColorMaterial(three, fill.color);
182756
- }
182757
- const material = buildColorMaterial(three, "#ffffff");
182758
- textures.load(fill.imageUrl).then((base) => {
182759
- const texture = base.clone();
182760
- texture.wrapS = three.RepeatWrapping;
182761
- texture.wrapT = three.RepeatWrapping;
182762
- texture.repeat.set(fill.repeatX, fill.repeatY);
182763
- texture.needsUpdate = true;
182764
- if (isDisposed()) {
182765
- texture.dispose();
182766
- return void 0;
182767
- }
182768
- ownedTextures.push(texture);
182769
- material.map = texture;
182770
- material.needsUpdate = true;
182771
- return void 0;
182772
- }).catch(() => {
182773
- });
182774
- return material;
182775
- }
182776
- function buildMaterialArrayResult(three, fills, textures) {
182777
- let disposed = false;
182778
- const ownedTextures = [];
182779
- const materials = fills.map(
182780
- (fill) => buildFaceMaterial(three, fill, textures, ownedTextures, () => disposed)
182781
- );
182782
- return {
182783
- material: materials,
182784
- dispose: () => {
182785
- disposed = true;
182786
- for (const material of materials) {
182787
- material.dispose();
182788
- }
182789
- for (const texture of ownedTextures) {
182790
- texture.dispose();
182791
- }
182792
- }
182793
- };
182794
- }
182795
- function buildBarBoxMaterial(three, box, assets) {
182796
- if (!assets) {
182797
- const material = buildColorMaterial(three, box.color);
182798
- return { material, dispose: () => material.dispose() };
182799
- }
182800
- const isRound = box.shape !== void 0 && box.shape !== "box";
182801
- if (isRound) {
182802
- const roundFills = resolveBarRoundFaceFills(box, assets.context.series);
182803
- const solid2 = uniformRoundColor(roundFills);
182804
- if (solid2 !== void 0) {
182805
- const material = buildColorMaterial(three, solid2);
182806
- return { material, dispose: () => material.dispose() };
182807
- }
182808
- return buildMaterialArrayResult(
182809
- three,
182810
- [roundFills.side, roundFills.end, roundFills.bottom],
182811
- assets.textures
182812
- );
182813
- }
182814
- const fills = resolveBarBoxFaceFills(box, assets.context.series);
182815
- const solid = uniformBoxColor(fills);
182816
- if (solid !== void 0) {
182817
- const material = buildColorMaterial(three, solid);
182818
- return { material, dispose: () => material.dispose() };
182819
- }
182820
- return buildMaterialArrayResult(
182821
- three,
182822
- FACE_ORDER.map((face) => fills[face]),
182823
- assets.textures
182824
- );
182825
- }
182826
- var FACE_ORDER;
182827
- var init_bar_chart_3d_materials = __esm2({
182828
- "src/render/bar-chart-3d-materials.ts"() {
182829
- init_bar_chart_3d_face_fill();
182830
- FACE_ORDER = [
182831
- "posX",
182832
- "negX",
182833
- "posY",
182834
- "negY",
182835
- "posZ",
182836
- "negZ"
182837
- ];
182838
- }
182839
- });
182840
- function buildBar3DGeometry(three, shape, coneToMaxTopRadiusFactor2) {
182841
- switch (shape) {
182842
- case "cylinder":
182843
- return new three.CylinderGeometry(0.5, 0.5, 1, ROUND_SEGMENTS);
182844
- case "cone":
182845
- return new three.ConeGeometry(0.5, 1, ROUND_SEGMENTS);
182846
- case "pyramid":
182847
- return new three.ConeGeometry(0.5, 1, PYRAMID_SEGMENTS);
182848
- case "coneToMax":
182849
- return new three.CylinderGeometry(
182850
- 0.5 * (coneToMaxTopRadiusFactor2 ?? 0),
182851
- 0.5,
182852
- 1,
182853
- ROUND_SEGMENTS
182854
- );
182855
- case "pyramidToMax":
182856
- return new three.CylinderGeometry(
182857
- 0.5 * (coneToMaxTopRadiusFactor2 ?? 0),
182858
- 0.5,
182859
- 1,
182860
- PYRAMID_SEGMENTS
182861
- );
182862
- case "box":
182863
- default:
182864
- return new three.BoxGeometry(1, 1, 1);
182865
- }
182866
- }
182867
- function buildBar3DMeshGroup(three, scene, boxes, horizontal = false, picture) {
182868
- const meshes = [];
182869
- const materials = [];
182870
- const materialDisposers = [];
182871
- const geometries = [];
182872
- for (const box of boxes) {
182873
- const geometry = buildBar3DGeometry(three, box.shape, box.coneToMaxTopRadiusFactor);
182874
- const { material, dispose } = buildBarBoxMaterial(three, box, picture);
182875
- const mesh = new three.Mesh(geometry, material);
182876
- mesh.position.set(...box.center);
182877
- mesh.scale.set(...box.size);
182878
- if (horizontal) {
182879
- mesh.rotation.z = -Math.PI / 2;
182880
- }
182881
- mesh.userData = {
182882
- seriesIndex: box.seriesIndex,
182883
- categoryIndex: box.categoryIndex,
182884
- value: box.value
182885
- };
182886
- scene.add(mesh);
182887
- meshes.push(mesh);
182888
- materials.push(material);
182889
- materialDisposers.push(dispose);
182890
- geometries.push(geometry);
182891
- }
182892
- return { meshes, materials, geometries, materialDisposers };
182893
- }
182894
- var ROUND_SEGMENTS;
182895
- var PYRAMID_SEGMENTS;
182896
- var init_bar_chart_3d_geometry = __esm2({
182897
- "src/render/bar-chart-3d-geometry.ts"() {
182898
- init_bar_chart_3d_materials();
182899
- ROUND_SEGMENTS = 32;
182900
- PYRAMID_SEGMENTS = 4;
182901
- }
182902
- });
182903
181550
  function buildBarChart3DHoverTooltip(hit, data) {
182904
181551
  if (!hit) {
182905
181552
  return void 0;
@@ -182916,984 +181563,6 @@ var init_bar_chart_3d_hit_test = __esm2({
182916
181563
  init_chart_view_model();
182917
181564
  }
182918
181565
  });
182919
- function valueAxisIndex(horizontal) {
182920
- return horizontal ? 0 : 1;
182921
- }
182922
- function calibrateBarChart3DDrag(boxes, hit, grouping, horizontal) {
182923
- if (grouping !== "clustered") {
182924
- return null;
182925
- }
182926
- const box = boxes.find(
182927
- (b) => b.seriesIndex === hit.seriesIndex && b.categoryIndex === hit.categoryIndex
182928
- );
182929
- if (!box) {
182930
- return null;
182931
- }
182932
- const axis = valueAxisIndex(horizontal);
182933
- const half = box.size[axis] / 2;
182934
- const center = box.center[axis];
182935
- const lo = center - half;
182936
- const hi = center + half;
182937
- const zeroIsLo = Math.abs(lo) <= Math.abs(hi);
182938
- const zeroCoord = zeroIsLo ? lo : hi;
182939
- const valueCoord = zeroIsLo ? hi : lo;
182940
- if (Math.abs(valueCoord - zeroCoord) < 1e-9) {
182941
- return null;
182942
- }
182943
- const at = (coord) => axis === 0 ? [coord, box.center[1], box.center[2]] : [box.center[0], coord, box.center[2]];
182944
- return {
182945
- worldAtValue0: at(zeroCoord),
182946
- value0: 0,
182947
- worldAtValue1: at(valueCoord),
182948
- value1: hit.value
182949
- };
182950
- }
182951
- var init_bar_chart_3d_drag = __esm2({
182952
- "src/render/bar-chart-3d-drag.ts"() {
182953
- }
182954
- });
182955
- function applyChart3DMeshHighlight(entries2, part) {
182956
- for (const { mark, material } of entries2) {
182957
- const selected = chart3DMarkMatchesPart(mark, part);
182958
- const materials = Array.isArray(material) ? material : [material];
182959
- for (const one of materials) {
182960
- one.emissive.set(selected ? CHART_3D_SELECTED_EMISSIVE : CLEAR_EMISSIVE);
182961
- one.emissiveIntensity = selected ? CHART_3D_SELECTED_EMISSIVE_INTENSITY : 0;
182962
- }
182963
- }
182964
- }
182965
- var CLEAR_EMISSIVE;
182966
- var init_chart_3d_mesh_highlight = __esm2({
182967
- "src/render/chart-3d-mesh-highlight.ts"() {
182968
- init_chart_3d_interaction();
182969
- CLEAR_EMISSIVE = "#000000";
182970
- }
182971
- });
182972
- function attachBarChart3DInteraction(params) {
182973
- const highlightEntries = params.boxMeshes.map((mesh, i2) => {
182974
- const hit = mesh.userData;
182975
- return {
182976
- mark: { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex },
182977
- material: params.boxMaterials[i2]
182978
- };
182979
- });
182980
- return attachChart3DPointerInteraction({
182981
- three: params.three,
182982
- canvas: params.canvas,
182983
- camera: params.camera,
182984
- width: params.width,
182985
- height: params.height,
182986
- meshes: params.boxMeshes,
182987
- resolveHit: (intersection) => {
182988
- const hit = intersection.object.userData;
182989
- return chart3DHitToPartRef(
182990
- hit ? { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex } : null
182991
- );
182992
- },
182993
- calibrateDrag: (intersection) => {
182994
- const hit = intersection.object.userData;
182995
- return calibrateBarChart3DDrag(params.boxes, hit, params.grouping, params.horizontal);
182996
- },
182997
- applyHighlight: (part) => applyChart3DMeshHighlight(highlightEntries, part),
182998
- setControlsEnabled: (enabled) => {
182999
- params.controls.enabled = enabled;
183000
- },
183001
- onSelect: params.interaction?.onSelect,
183002
- onValueDragPreview: params.interaction?.onValueDragPreview,
183003
- onValueDragCommit: params.interaction?.onValueDragCommit
183004
- });
183005
- }
183006
- var init_bar_chart_3d_interaction_wiring = __esm2({
183007
- "src/render/bar-chart-3d-interaction-wiring.ts"() {
183008
- init_bar_chart_3d_drag();
183009
- init_chart_3d_interaction();
183010
- init_chart_3d_mesh_highlight();
183011
- init_chart_3d_pointer_interaction();
183012
- }
183013
- });
183014
- function createBarChart3DScene(ctx, options) {
183015
- const placement = computeCartesianCameraPlacement(
183016
- options.cols,
183017
- options.rows,
183018
- options.view3D,
183019
- options.horizontal
183020
- );
183021
- const stage = createHostedChart3DStage(ctx, placement, { minDistance: 0.5, maxDistance: 30 });
183022
- const { three, scene, camera, canvas } = stage;
183023
- const extent = computeCartesianGridExtent(
183024
- options.cols,
183025
- options.rows,
183026
- options.view3D?.depthPercent
183027
- );
183028
- const floorSize = Math.max(extent.gridWidth, extent.gridDepth, MAX_VALUE_HEIGHT * 2) * 1.2;
183029
- const gridFloor = new three.GridHelper(
183030
- floorSize,
183031
- Math.max(options.cols, options.rows),
183032
- 13421772,
183033
- 15263976
183034
- );
183035
- gridFloor.position.y = -0.02;
183036
- scene.add(gridFloor);
183037
- const walls = options.wallColors ? buildSurfaceWallMeshes(
183038
- three,
183039
- options.cols,
183040
- options.rows,
183041
- MAX_VALUE_HEIGHT,
183042
- options.wallColors,
183043
- extent
183044
- ) : null;
183045
- for (const mesh of walls?.meshes ?? []) {
183046
- scene.add(mesh);
183047
- }
183048
- const baseTextures = createBarChart3DTextureManager(three);
183049
- const textures = {
183050
- load: (url) => baseTextures.load(url).then((texture) => {
183051
- setTimeout(ctx.requestRender, 0);
183052
- return texture;
183053
- }),
183054
- disposeAll: () => baseTextures.disposeAll()
183055
- };
183056
- const {
183057
- meshes: boxMeshes,
183058
- materials: boxMaterials,
183059
- geometries: boxGeometries,
183060
- materialDisposers: boxMaterialDisposers
183061
- } = buildBar3DMeshGroup(
183062
- three,
183063
- scene,
183064
- options.boxes,
183065
- options.horizontal,
183066
- options.picture ? { context: options.picture, textures } : void 0
183067
- );
183068
- const hoverTooltip = attachChart3DHoverTooltip({
183069
- three,
183070
- canvas,
183071
- camera,
183072
- meshes: boxMeshes,
183073
- buildTooltip: (intersection) => buildBarChart3DHoverTooltip(intersection?.object.userData, {
183074
- categoryLabels: options.categoryLabels,
183075
- seriesNames: options.seriesNames,
183076
- numberFormats: options.numberFormats
183077
- })
183078
- });
183079
- const interaction = hostedChart3DInteraction(ctx);
183080
- const pointerInteraction = attachBarChart3DInteraction({
183081
- three,
183082
- canvas,
183083
- camera,
183084
- controls: stage.controls,
183085
- width: stage.width,
183086
- height: stage.height,
183087
- boxMeshes,
183088
- boxMaterials,
183089
- boxes: options.boxes,
183090
- grouping: options.grouping,
183091
- horizontal: Boolean(options.horizontal),
183092
- interaction
183093
- });
183094
- const labels = buildCartesianChart3DLabels(
183095
- options.cols,
183096
- options.rows,
183097
- options.categoryLabels,
183098
- options.seriesNames,
183099
- options.view3D?.depthPercent,
183100
- void 0,
183101
- void 0,
183102
- options.horizontal
183103
- );
183104
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
183105
- labelProjector.applyTextStyle(options.textStyle);
183106
- ctx.overlay.appendChild(labelProjector.layer);
183107
- return finishHostedChart3DScene(
183108
- ctx,
183109
- stage,
183110
- {
183111
- afterRender: (cam, width, height) => labelProjector.update(cam, width, height),
183112
- resize: (width, height) => pointerInteraction.updateSize(width, height),
183113
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183114
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
183115
- dispose() {
183116
- hoverTooltip.dispose();
183117
- pointerInteraction.dispose();
183118
- for (const g2 of boxGeometries) {
183119
- g2.dispose();
183120
- }
183121
- for (const disposeMaterial of boxMaterialDisposers) {
183122
- disposeMaterial();
183123
- }
183124
- textures.disposeAll();
183125
- gridFloor.dispose();
183126
- walls?.dispose();
183127
- labelProjector.layer.remove();
183128
- }
183129
- },
183130
- interaction
183131
- );
183132
- }
183133
- var init_bar_chart_3d_scene = __esm2({
183134
- "src/render/bar-chart-3d-scene.ts"() {
183135
- init_bar_chart_3d_geometry();
183136
- init_bar_chart_3d_hit_test();
183137
- init_bar_chart_3d_interaction_wiring();
183138
- init_bar_chart_3d_materials();
183139
- init_cartesian_chart_3d_geom();
183140
- init_chart_3d_hosted_stage();
183141
- init_chart_3d_hover_tooltip();
183142
- init_chart_3d_label_projection();
183143
- init_surface_chart_3d_walls();
183144
- }
183145
- });
183146
- function buildCartesianChart3DHoverTooltip(hit, data) {
183147
- if (!hit) {
183148
- return void 0;
183149
- }
183150
- return buildMarkTooltip(
183151
- data.seriesNames[hit.seriesIndex],
183152
- data.categoryLabels[hit.categoryIndex],
183153
- hit.value,
183154
- data.numberFormats?.[hit.seriesIndex]
183155
- );
183156
- }
183157
- var init_cartesian_chart_3d_hit_test = __esm2({
183158
- "src/render/cartesian-chart-3d-hit-test.ts"() {
183159
- init_chart_view_model();
183160
- }
183161
- });
183162
- function calibrateCartesianChart3DDrag(markerPosition, value) {
183163
- if (Math.abs(value) < 1e-9) {
183164
- return null;
183165
- }
183166
- return {
183167
- worldAtValue0: [markerPosition[0], 0, markerPosition[2]],
183168
- value0: 0,
183169
- worldAtValue1: markerPosition,
183170
- value1: value
183171
- };
183172
- }
183173
- var init_cartesian_chart_3d_drag = __esm2({
183174
- "src/render/cartesian-chart-3d-drag.ts"() {
183175
- }
183176
- });
183177
- function attachCartesianChart3DInteraction(params) {
183178
- const highlightEntries = params.markerMeshes.map((mesh, i2) => {
183179
- const hit = mesh.userData;
183180
- return {
183181
- mark: { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex },
183182
- material: params.markerMaterials[i2]
183183
- };
183184
- });
183185
- return attachChart3DPointerInteraction({
183186
- three: params.three,
183187
- canvas: params.canvas,
183188
- camera: params.camera,
183189
- width: params.width,
183190
- height: params.height,
183191
- meshes: params.markerMeshes,
183192
- resolveHit: (intersection) => {
183193
- const hit = intersection.object.userData;
183194
- return chart3DHitToPartRef(
183195
- hit ? { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex } : null
183196
- );
183197
- },
183198
- calibrateDrag: (intersection) => {
183199
- const hit = intersection.object.userData;
183200
- const vertex = params.series[hit.seriesIndex]?.vertices.find(
183201
- (v) => v.categoryIndex === hit.categoryIndex
183202
- );
183203
- return vertex ? calibrateCartesianChart3DDrag(vertex.position, hit.value) : null;
183204
- },
183205
- applyHighlight: (part) => applyChart3DMeshHighlight(highlightEntries, part),
183206
- setControlsEnabled: (enabled) => {
183207
- params.controls.enabled = enabled;
183208
- },
183209
- onSelect: params.interaction?.onSelect,
183210
- onValueDragPreview: params.interaction?.onValueDragPreview,
183211
- onValueDragCommit: params.interaction?.onValueDragCommit
183212
- });
183213
- }
183214
- var init_cartesian_chart_3d_interaction_wiring = __esm2({
183215
- "src/render/cartesian-chart-3d-interaction-wiring.ts"() {
183216
- init_cartesian_chart_3d_drag();
183217
- init_chart_3d_interaction();
183218
- init_chart_3d_mesh_highlight();
183219
- init_chart_3d_pointer_interaction();
183220
- }
183221
- });
183222
- function createLineChart3DScene(ctx, options) {
183223
- const placement = computeCartesianCameraPlacement(options.cols, options.rows, options.view3D);
183224
- const stage = createHostedChart3DStage(
183225
- ctx,
183226
- placement,
183227
- { minDistance: 0.5, maxDistance: 30 },
183228
- 0.6
183229
- );
183230
- const { three, scene, camera, canvas, controls, width, height } = stage;
183231
- const interaction = hostedChart3DInteraction(ctx);
183232
- const extent = computeCartesianGridExtent(
183233
- options.cols,
183234
- options.rows,
183235
- options.view3D?.depthPercent
183236
- );
183237
- const floorSize = Math.max(extent.gridWidth, extent.gridDepth) * 1.2;
183238
- const gridFloor = new three.GridHelper(
183239
- floorSize,
183240
- Math.max(options.cols, options.rows),
183241
- 13421772,
183242
- 15263976
183243
- );
183244
- gridFloor.position.y = -0.02;
183245
- scene.add(gridFloor);
183246
- const walls = options.wallColors ? buildSurfaceWallMeshes(
183247
- three,
183248
- options.cols,
183249
- options.rows,
183250
- MAX_VALUE_HEIGHT,
183251
- options.wallColors,
183252
- extent
183253
- ) : null;
183254
- for (const mesh of walls?.meshes ?? []) {
183255
- scene.add(mesh);
183256
- }
183257
- const markerGeometry = new three.SphereGeometry(MARKER_RADIUS2, 8, 6);
183258
- const tubeGeometries = [];
183259
- const tubeMaterials = [];
183260
- const markerMeshes = [];
183261
- const markerMaterials = [];
183262
- for (const path of options.series) {
183263
- if (path.vertices.length >= 2) {
183264
- const curve = new three.CatmullRomCurve3(
183265
- path.vertices.map((v) => new three.Vector3(...v.position))
183266
- );
183267
- const tubeGeometry = new three.TubeGeometry(
183268
- curve,
183269
- Math.max(path.vertices.length * 8, 16),
183270
- TUBE_RADIUS,
183271
- 8,
183272
- false
183273
- );
183274
- const tubeMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183275
- const tube = new three.Mesh(tubeGeometry, tubeMaterial);
183276
- scene.add(tube);
183277
- tubeGeometries.push(tubeGeometry);
183278
- tubeMaterials.push(tubeMaterial);
183279
- }
183280
- for (const v of path.vertices) {
183281
- const markerMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183282
- const marker = new three.Mesh(markerGeometry, markerMaterial);
183283
- marker.position.set(...v.position);
183284
- marker.userData = {
183285
- seriesIndex: v.seriesIndex,
183286
- categoryIndex: v.categoryIndex,
183287
- value: v.value
183288
- };
183289
- scene.add(marker);
183290
- markerMeshes.push(marker);
183291
- markerMaterials.push(markerMaterial);
183292
- }
183293
- }
183294
- const tooltipData = {
183295
- categoryLabels: options.categoryLabels,
183296
- seriesNames: options.seriesNames,
183297
- numberFormats: options.numberFormats
183298
- };
183299
- const hoverTooltip = attachChart3DHoverTooltip({
183300
- three,
183301
- canvas,
183302
- camera,
183303
- meshes: markerMeshes,
183304
- buildTooltip: (intersection) => buildCartesianChart3DHoverTooltip(
183305
- intersection?.object.userData,
183306
- tooltipData
183307
- )
183308
- });
183309
- const pointerInteraction = attachCartesianChart3DInteraction({
183310
- three,
183311
- canvas,
183312
- camera,
183313
- controls,
183314
- width,
183315
- height,
183316
- markerMeshes,
183317
- markerMaterials,
183318
- series: options.series,
183319
- interaction
183320
- });
183321
- const labels = buildCartesianChart3DLabels(
183322
- options.cols,
183323
- options.rows,
183324
- options.categoryLabels,
183325
- options.seriesNames,
183326
- options.view3D?.depthPercent
183327
- );
183328
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
183329
- labelProjector.applyTextStyle(options.textStyle);
183330
- ctx.overlay.appendChild(labelProjector.layer);
183331
- return finishHostedChart3DScene(
183332
- ctx,
183333
- stage,
183334
- {
183335
- afterRender: (cam, w, h2) => labelProjector.update(cam, w, h2),
183336
- resize: (w, h2) => pointerInteraction.updateSize(w, h2),
183337
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183338
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
183339
- dispose() {
183340
- hoverTooltip.dispose();
183341
- pointerInteraction.dispose();
183342
- markerGeometry.dispose();
183343
- for (const g2 of tubeGeometries) {
183344
- g2.dispose();
183345
- }
183346
- for (const m of [...tubeMaterials, ...markerMaterials]) {
183347
- m.dispose();
183348
- }
183349
- gridFloor.dispose();
183350
- walls?.dispose();
183351
- labelProjector.layer.remove();
183352
- }
183353
- },
183354
- interaction
183355
- );
183356
- }
183357
- var TUBE_RADIUS;
183358
- var MARKER_RADIUS2;
183359
- var init_line_chart_3d_scene = __esm2({
183360
- "src/render/line-chart-3d-scene.ts"() {
183361
- init_cartesian_chart_3d_geom();
183362
- init_cartesian_chart_3d_hit_test();
183363
- init_cartesian_chart_3d_interaction_wiring();
183364
- init_chart_3d_hosted_stage();
183365
- init_chart_3d_hover_tooltip();
183366
- init_chart_3d_label_projection();
183367
- init_surface_chart_3d_walls();
183368
- TUBE_RADIUS = 0.025;
183369
- MARKER_RADIUS2 = 0.045;
183370
- }
183371
- });
183372
- function buildAreaRibbonGeometry(three, path) {
183373
- const triangles = buildAreaRibbonTriangles(path);
183374
- if (triangles.length === 0) {
183375
- return null;
183376
- }
183377
- const geometry = new three.BufferGeometry();
183378
- geometry.setAttribute("position", new three.Float32BufferAttribute(triangles, 3));
183379
- geometry.computeVertexNormals();
183380
- return geometry;
183381
- }
183382
- var init_area_chart_3d_ribbon_geometry = __esm2({
183383
- "src/render/area-chart-3d-ribbon-geometry.ts"() {
183384
- init_cartesian_line_chart_3d_layout();
183385
- }
183386
- });
183387
- function createAreaChart3DScene(ctx, options) {
183388
- const placement = computeCartesianCameraPlacement(options.cols, options.rows, options.view3D);
183389
- const stage = createHostedChart3DStage(
183390
- ctx,
183391
- placement,
183392
- { minDistance: 0.5, maxDistance: 30 },
183393
- 0.6
183394
- );
183395
- const { three, scene, camera, canvas, controls, width, height } = stage;
183396
- const interaction = hostedChart3DInteraction(ctx);
183397
- const extent = computeCartesianGridExtent(
183398
- options.cols,
183399
- options.rows,
183400
- options.view3D?.depthPercent
183401
- );
183402
- const floorSize = Math.max(extent.gridWidth, extent.gridDepth) * 1.2;
183403
- const gridSegs = Math.max(options.cols, options.rows);
183404
- const gridFloor = new three.GridHelper(floorSize, gridSegs, 13421772, 15263976);
183405
- gridFloor.position.y = -0.02;
183406
- scene.add(gridFloor);
183407
- const walls = options.wallColors ? buildSurfaceWallMeshes(
183408
- three,
183409
- options.cols,
183410
- options.rows,
183411
- MAX_VALUE_HEIGHT,
183412
- options.wallColors,
183413
- extent
183414
- ) : null;
183415
- for (const mesh of walls?.meshes ?? []) {
183416
- scene.add(mesh);
183417
- }
183418
- const markerGeometry = new three.SphereGeometry(MARKER_RADIUS3, 8, 6);
183419
- const tubeGeometries = [];
183420
- const ribbonGeometries = [];
183421
- const otherMaterials = [];
183422
- const markerMeshes = [];
183423
- const markerMaterials = [];
183424
- for (const path of options.series) {
183425
- const ribbonGeometry = buildAreaRibbonGeometry(three, path);
183426
- if (ribbonGeometry) {
183427
- const ribbonMaterial = new three.MeshPhongMaterial({
183428
- color: path.color,
183429
- side: three.DoubleSide,
183430
- transparent: true,
183431
- opacity: RIBBON_OPACITY,
183432
- shininess: 10
183433
- });
183434
- scene.add(new three.Mesh(ribbonGeometry, ribbonMaterial));
183435
- ribbonGeometries.push(ribbonGeometry);
183436
- otherMaterials.push(ribbonMaterial);
183437
- }
183438
- if (path.vertices.length >= 2) {
183439
- const curve = new three.CatmullRomCurve3(
183440
- path.vertices.map((v) => new three.Vector3(...v.position))
183441
- );
183442
- const tubeGeometry = new three.TubeGeometry(
183443
- curve,
183444
- Math.max(path.vertices.length * 8, 16),
183445
- TUBE_RADIUS2,
183446
- 8,
183447
- false
183448
- );
183449
- const tubeMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183450
- scene.add(new three.Mesh(tubeGeometry, tubeMaterial));
183451
- tubeGeometries.push(tubeGeometry);
183452
- otherMaterials.push(tubeMaterial);
183453
- }
183454
- for (const v of path.vertices) {
183455
- const markerMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183456
- const marker = new three.Mesh(markerGeometry, markerMaterial);
183457
- marker.position.set(...v.position);
183458
- marker.userData = {
183459
- seriesIndex: v.seriesIndex,
183460
- categoryIndex: v.categoryIndex,
183461
- value: v.value
183462
- };
183463
- scene.add(marker);
183464
- markerMeshes.push(marker);
183465
- markerMaterials.push(markerMaterial);
183466
- otherMaterials.push(markerMaterial);
183467
- }
183468
- }
183469
- const tooltipData = {
183470
- categoryLabels: options.categoryLabels,
183471
- seriesNames: options.seriesNames,
183472
- numberFormats: options.numberFormats
183473
- };
183474
- const hoverTooltip = attachChart3DHoverTooltip({
183475
- three,
183476
- canvas,
183477
- camera,
183478
- meshes: markerMeshes,
183479
- buildTooltip: (intersection) => buildCartesianChart3DHoverTooltip(
183480
- intersection?.object.userData,
183481
- tooltipData
183482
- )
183483
- });
183484
- const pointerInteraction = attachCartesianChart3DInteraction({
183485
- three,
183486
- canvas,
183487
- camera,
183488
- controls,
183489
- width,
183490
- height,
183491
- markerMeshes,
183492
- markerMaterials,
183493
- series: options.series,
183494
- interaction
183495
- });
183496
- const labels = buildCartesianChart3DLabels(
183497
- options.cols,
183498
- options.rows,
183499
- options.categoryLabels,
183500
- options.seriesNames,
183501
- options.view3D?.depthPercent
183502
- );
183503
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
183504
- labelProjector.applyTextStyle(options.textStyle);
183505
- ctx.overlay.appendChild(labelProjector.layer);
183506
- return finishHostedChart3DScene(
183507
- ctx,
183508
- stage,
183509
- {
183510
- afterRender: (cam, w, h2) => labelProjector.update(cam, w, h2),
183511
- resize: (w, h2) => pointerInteraction.updateSize(w, h2),
183512
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183513
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
183514
- dispose() {
183515
- hoverTooltip.dispose();
183516
- pointerInteraction.dispose();
183517
- markerGeometry.dispose();
183518
- for (const g2 of [...tubeGeometries, ...ribbonGeometries]) {
183519
- g2.dispose();
183520
- }
183521
- for (const m of otherMaterials) {
183522
- m.dispose();
183523
- }
183524
- gridFloor.dispose();
183525
- walls?.dispose();
183526
- labelProjector.layer.remove();
183527
- }
183528
- },
183529
- interaction
183530
- );
183531
- }
183532
- var TUBE_RADIUS2;
183533
- var MARKER_RADIUS3;
183534
- var RIBBON_OPACITY;
183535
- var init_area_chart_3d_scene = __esm2({
183536
- "src/render/area-chart-3d-scene.ts"() {
183537
- init_area_chart_3d_ribbon_geometry();
183538
- init_cartesian_chart_3d_geom();
183539
- init_cartesian_chart_3d_hit_test();
183540
- init_cartesian_chart_3d_interaction_wiring();
183541
- init_chart_3d_hosted_stage();
183542
- init_chart_3d_hover_tooltip();
183543
- init_chart_3d_label_projection();
183544
- init_surface_chart_3d_walls();
183545
- TUBE_RADIUS2 = 0.02;
183546
- MARKER_RADIUS3 = 0.045;
183547
- RIBBON_OPACITY = 0.75;
183548
- }
183549
- });
183550
- function buildPieChart3DHoverTooltip(hit, data) {
183551
- if (!hit) {
183552
- return void 0;
183553
- }
183554
- return buildMarkTooltip(
183555
- data.seriesName,
183556
- data.categoryLabels[hit.pointIndex],
183557
- hit.value,
183558
- data.numberFormat
183559
- );
183560
- }
183561
- var init_pie_chart_3d_hit_test = __esm2({
183562
- "src/render/pie-chart-3d-hit-test.ts"() {
183563
- init_chart_view_model();
183564
- }
183565
- });
183566
- function pieChart3DPointerAngle(x, z) {
183567
- return Math.atan2(x, z);
183568
- }
183569
- function resolvePieChart3DDragValue(geometry, pointerAngle) {
183570
- return resolvePieSliceShareValue(
183571
- pointerAngle,
183572
- geometry.leadingAngle,
183573
- geometry.values,
183574
- geometry.pointIndex
183575
- );
183576
- }
183577
- var init_pie_chart_3d_drag = __esm2({
183578
- "src/render/pie-chart-3d-drag.ts"() {
183579
- init_chart_interaction_pie();
183580
- }
183581
- });
183582
- function attachPieChart3DInteraction(params) {
183583
- const raycaster = new params.three.Raycaster();
183584
- const ndc = new params.three.Vector2();
183585
- const plane = new params.three.Plane(new params.three.Vector3(0, 1, 0), 0);
183586
- const planeHit = new params.three.Vector3();
183587
- let dragState = null;
183588
- const highlightEntries = params.wedgeMeshes.map((mesh, i2) => {
183589
- const hit = mesh.userData;
183590
- return {
183591
- mark: { seriesIndex: 0, pointIndex: hit.pointIndex },
183592
- material: params.wedgeMaterials[i2]
183593
- };
183594
- });
183595
- function setNdc(clientX, clientY) {
183596
- const rect22 = params.canvas.getBoundingClientRect();
183597
- if (rect22.width <= 0 || rect22.height <= 0) {
183598
- return false;
183599
- }
183600
- ndc.x = (clientX - rect22.left) / rect22.width * 2 - 1;
183601
- ndc.y = -((clientY - rect22.top) / rect22.height) * 2 + 1;
183602
- return true;
183603
- }
183604
- function raycastWedge(clientX, clientY) {
183605
- if (!setNdc(clientX, clientY)) {
183606
- return void 0;
183607
- }
183608
- raycaster.setFromCamera(ndc, params.camera);
183609
- return raycaster.intersectObjects(params.wedgeMeshes, false)[0];
183610
- }
183611
- function planeAngleAt(clientX, clientY) {
183612
- if (!setNdc(clientX, clientY)) {
183613
- return null;
183614
- }
183615
- raycaster.setFromCamera(ndc, params.camera);
183616
- const hit = raycaster.ray.intersectPlane(plane, planeHit);
183617
- return hit ? pieChart3DPointerAngle(hit.x, hit.z) : null;
183618
- }
183619
- function setSelectedPart(part) {
183620
- applyChart3DMeshHighlight(highlightEntries, part);
183621
- }
183622
- function travelBelowThreshold(clientX, clientY, state) {
183623
- const dx = clientX - state.startClientX;
183624
- const dy = clientY - state.startClientY;
183625
- return Math.hypot(dx, dy) < CHART_3D_DRAG_THRESHOLD_PX;
183626
- }
183627
- const onPointerDown = (event) => {
183628
- params.canvas.setPointerCapture?.(
183629
- event.pointerId
183630
- );
183631
- const hit = raycastWedge(event.clientX, event.clientY);
183632
- const hitData = hit?.object.userData;
183633
- const part = chart3DHitToPartRef(
183634
- hitData ? { seriesIndex: 0, pointIndex: hitData.pointIndex } : null
183635
- );
183636
- const armed = part !== null && isChartInteractionArmed(params.canvas);
183637
- if (armed) {
183638
- event.stopPropagation();
183639
- }
183640
- let geometry = null;
183641
- if (part && hitData && armed) {
183642
- const wedges = params.getWedges();
183643
- const wedge = wedges.find((w) => w.pointIndex === hitData.pointIndex);
183644
- if (wedge) {
183645
- geometry = {
183646
- values: wedges.map((w) => w.value),
183647
- pointIndex: hitData.pointIndex,
183648
- leadingAngle: wedge.startAngle
183649
- };
183650
- }
183651
- }
183652
- dragState = {
183653
- part,
183654
- geometry,
183655
- moved: false,
183656
- startClientX: event.clientX,
183657
- startClientY: event.clientY,
183658
- lastAngle: null
183659
- };
183660
- if (geometry) {
183661
- event.preventDefault();
183662
- params.controls.enabled = false;
183663
- }
183664
- };
183665
- const onPointerMove = (event) => {
183666
- const state = dragState;
183667
- if (!state || !state.part || !state.geometry) {
183668
- return;
183669
- }
183670
- if (!state.moved && travelBelowThreshold(event.clientX, event.clientY, state)) {
183671
- return;
183672
- }
183673
- state.moved = true;
183674
- const angle = planeAngleAt(event.clientX, event.clientY);
183675
- if (angle === null) {
183676
- return;
183677
- }
183678
- state.lastAngle = angle;
183679
- const value = resolvePieChart3DDragValue(state.geometry, angle);
183680
- params.interaction?.onValueDragPreview?.(state.part, value);
183681
- };
183682
- const onPointerUp = (event) => {
183683
- if (!dragState) {
183684
- return;
183685
- }
183686
- const state = dragState;
183687
- dragState = null;
183688
- params.canvas.releasePointerCapture?.(event.pointerId);
183689
- if (state.geometry) {
183690
- params.controls.enabled = true;
183691
- }
183692
- if (state.moved && state.part && state.geometry) {
183693
- const angle = planeAngleAt(event.clientX, event.clientY) ?? state.lastAngle;
183694
- if (angle !== null) {
183695
- const value = resolvePieChart3DDragValue(state.geometry, angle);
183696
- params.interaction?.onValueDragCommit?.(state.part, value);
183697
- }
183698
- return;
183699
- }
183700
- setSelectedPart(state.part);
183701
- params.interaction?.onSelect?.(state.part);
183702
- };
183703
- params.canvas.addEventListener("pointerdown", onPointerDown);
183704
- params.canvas.addEventListener("pointermove", onPointerMove);
183705
- params.canvas.addEventListener("pointerup", onPointerUp);
183706
- params.canvas.addEventListener("pointercancel", onPointerUp);
183707
- return {
183708
- setSelectedPart,
183709
- dispose() {
183710
- params.canvas.removeEventListener("pointerdown", onPointerDown);
183711
- params.canvas.removeEventListener("pointermove", onPointerMove);
183712
- params.canvas.removeEventListener("pointerup", onPointerUp);
183713
- params.canvas.removeEventListener("pointercancel", onPointerUp);
183714
- }
183715
- };
183716
- }
183717
- var init_pie_chart_3d_interaction_wiring = __esm2({
183718
- "src/render/pie-chart-3d-interaction-wiring.ts"() {
183719
- init_chart_3d_interaction();
183720
- init_chart_3d_mesh_highlight();
183721
- init_chart_canvas_drag();
183722
- init_pie_chart_3d_drag();
183723
- }
183724
- });
183725
- function wedgeSegments(thetaLength) {
183726
- return Math.max(
183727
- MIN_RADIAL_SEGMENTS,
183728
- Math.round(thetaLength / (Math.PI * 2) * FULL_CIRCLE_SEGMENTS)
183729
- );
183730
- }
183731
- function buildPieChart3DWedgeMeshes(three, scene, wedges, outerRadius, thickness) {
183732
- const meshes = [];
183733
- const geometries = [];
183734
- const materials = [];
183735
- for (const wedge of wedges) {
183736
- const geometry = new three.CylinderGeometry(
183737
- outerRadius,
183738
- outerRadius,
183739
- thickness,
183740
- wedgeSegments(wedge.thetaLength),
183741
- 1,
183742
- false,
183743
- wedge.startAngle,
183744
- wedge.thetaLength
183745
- );
183746
- const material = new three.MeshPhongMaterial({ color: wedge.color, shininess: 30 });
183747
- const mesh = new three.Mesh(geometry, material);
183748
- mesh.position.set(wedge.explodeOffset[0], 0, wedge.explodeOffset[1]);
183749
- mesh.userData = { pointIndex: wedge.pointIndex, value: wedge.value };
183750
- scene.add(mesh);
183751
- meshes.push(mesh);
183752
- geometries.push(geometry);
183753
- materials.push(material);
183754
- }
183755
- return { meshes, geometries, materials };
183756
- }
183757
- function applyPieChart3DWedgeAngles(three, meshes, geometries, outerRadius, thickness, angles) {
183758
- for (const angle of angles) {
183759
- const mesh = meshes[angle.pointIndex];
183760
- const oldGeometry = geometries[angle.pointIndex];
183761
- if (!mesh || !oldGeometry) {
183762
- continue;
183763
- }
183764
- const geometry = new three.CylinderGeometry(
183765
- outerRadius,
183766
- outerRadius,
183767
- thickness,
183768
- wedgeSegments(angle.thetaLength),
183769
- 1,
183770
- false,
183771
- angle.startAngle,
183772
- angle.thetaLength
183773
- );
183774
- mesh.geometry = geometry;
183775
- oldGeometry.dispose();
183776
- geometries[angle.pointIndex] = geometry;
183777
- mesh.position.set(angle.explodeOffset[0], 0, angle.explodeOffset[1]);
183778
- mesh.userData = { pointIndex: angle.pointIndex, value: angle.value };
183779
- }
183780
- }
183781
- var MIN_RADIAL_SEGMENTS;
183782
- var FULL_CIRCLE_SEGMENTS;
183783
- var init_pie_chart_3d_mesh = __esm2({
183784
- "src/render/pie-chart-3d-mesh.ts"() {
183785
- MIN_RADIAL_SEGMENTS = 3;
183786
- FULL_CIRCLE_SEGMENTS = 64;
183787
- }
183788
- });
183789
- function createPieChart3DScene(ctx, options) {
183790
- const placement = computePieChart3DCameraPlacement(options.view3D);
183791
- const stage = createHostedChart3DStage(
183792
- ctx,
183793
- placement,
183794
- { minDistance: 0.5, maxDistance: 30 },
183795
- 0.65
183796
- );
183797
- const { three, scene, camera, canvas, controls } = stage;
183798
- const interaction = hostedChart3DInteraction(ctx);
183799
- const {
183800
- meshes: wedgeMeshes,
183801
- geometries: wedgeGeometries,
183802
- materials: wedgeMaterials
183803
- } = buildPieChart3DWedgeMeshes(
183804
- three,
183805
- scene,
183806
- options.wedges,
183807
- options.outerRadius,
183808
- options.thickness
183809
- );
183810
- const hoverTooltip = attachChart3DHoverTooltip({
183811
- three,
183812
- canvas,
183813
- camera,
183814
- meshes: wedgeMeshes,
183815
- buildTooltip: (intersection) => buildPieChart3DHoverTooltip(intersection?.object.userData, {
183816
- categoryLabels: options.categoryLabels,
183817
- seriesName: options.seriesName,
183818
- numberFormat: options.numberFormat
183819
- })
183820
- });
183821
- let currentAngles = options.wedges;
183822
- let liveValues = options.values.slice();
183823
- function recomputeLiveAngles() {
183824
- const angles = computePieChart3DSliceAngles(
183825
- liveValues,
183826
- options.explosions,
183827
- options.firstSliceAngleDeg,
183828
- options.outerRadius
183829
- );
183830
- currentAngles = angles;
183831
- applyPieChart3DWedgeAngles(
183832
- three,
183833
- wedgeMeshes,
183834
- wedgeGeometries,
183835
- options.outerRadius,
183836
- options.thickness,
183837
- angles
183838
- );
183839
- }
183840
- const pointerInteraction = attachPieChart3DInteraction({
183841
- three,
183842
- canvas,
183843
- camera,
183844
- controls,
183845
- wedgeMeshes,
183846
- wedgeMaterials,
183847
- getWedges: () => currentAngles,
183848
- interaction: {
183849
- onSelect: interaction?.onSelect,
183850
- onValueDragPreview: (part, value) => {
183851
- if (part.pointIndex !== void 0) {
183852
- liveValues = liveValues.map((v, i2) => i2 === part.pointIndex ? value : v);
183853
- recomputeLiveAngles();
183854
- }
183855
- interaction?.onValueDragPreview?.(part, value);
183856
- },
183857
- onValueDragCommit: (part, value) => {
183858
- if (part.pointIndex !== void 0) {
183859
- liveValues = liveValues.map((v, i2) => i2 === part.pointIndex ? value : v);
183860
- recomputeLiveAngles();
183861
- }
183862
- interaction?.onValueDragCommit?.(part, value);
183863
- }
183864
- }
183865
- });
183866
- return finishHostedChart3DScene(
183867
- ctx,
183868
- stage,
183869
- {
183870
- // No `resize`: this scene's own wiring re-derives the pointer's NDC
183871
- // position from `canvas.getBoundingClientRect()` on every raycast.
183872
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183873
- dispose() {
183874
- hoverTooltip.dispose();
183875
- pointerInteraction.dispose();
183876
- for (const g2 of wedgeGeometries) {
183877
- g2.dispose();
183878
- }
183879
- for (const m of wedgeMaterials) {
183880
- m.dispose();
183881
- }
183882
- }
183883
- },
183884
- interaction
183885
- );
183886
- }
183887
- var init_pie_chart_3d_scene = __esm2({
183888
- "src/render/pie-chart-3d-scene.ts"() {
183889
- init_chart_3d_hosted_stage();
183890
- init_chart_3d_hover_tooltip();
183891
- init_pie_chart_3d_geom();
183892
- init_pie_chart_3d_hit_test();
183893
- init_pie_chart_3d_interaction_wiring();
183894
- init_pie_chart_3d_mesh();
183895
- }
183896
- });
183897
181566
  function createRenderer(three, state) {
183898
181567
  try {
183899
181568
  const renderer = new three.WebGLRenderer({
@@ -184141,7 +181810,7 @@ function buildObliqueShapeGeometry(three, bar, horizontal) {
184141
181810
  0.5 * bar.taper.top,
184142
181811
  0.5 * bar.taper.bottom,
184143
181812
  1,
184144
- ROUND_SEGMENTS2
181813
+ ROUND_SEGMENTS
184145
181814
  );
184146
181815
  }
184147
181816
  if (horizontal) {
@@ -184182,11 +181851,11 @@ function shadeObliqueShapeGeometry(three, geometry, bar, scale2, viewYaw) {
184182
181851
  }
184183
181852
  colors.needsUpdate = true;
184184
181853
  }
184185
- var ROUND_SEGMENTS2;
181854
+ var ROUND_SEGMENTS;
184186
181855
  var init_chart_3d_oblique_shape_mesh = __esm2({
184187
181856
  "src/render/chart-3d-oblique-shape-mesh.ts"() {
184188
181857
  init_chart_3d_shading();
184189
- ROUND_SEGMENTS2 = 48;
181858
+ ROUND_SEGMENTS = 48;
184190
181859
  }
184191
181860
  });
184192
181861
  function obliqueToScene(layout, svgWidth, svgHeight, p) {
@@ -184392,6 +182061,12 @@ var init_chart_3d_chrome_overlay = __esm2({
184392
182061
  OBLIQUE_LEGEND_BASELINE = 14 * PT6;
184393
182062
  }
184394
182063
  });
182064
+ var CHART_3D_DRAG_THRESHOLD_PX;
182065
+ var init_chart_3d_interaction = __esm2({
182066
+ "src/render/chart-3d-interaction.ts"() {
182067
+ CHART_3D_DRAG_THRESHOLD_PX = 3;
182068
+ }
182069
+ });
184395
182070
  function partOf(point) {
184396
182071
  return point ? { role: "dataPoint", seriesIndex: point.seriesIndex, pointIndex: point.pointIndex } : null;
184397
182072
  }
@@ -184547,9 +182222,9 @@ function obliqueDragValue(layout, startValue, dx, dy) {
184547
182222
  function obliqueDraggedExtent(layout, value) {
184548
182223
  const { min, max } = layout.range;
184549
182224
  const base = Math.min(Math.max(0, min), max);
184550
- const clamp13 = (v) => Math.min(Math.max(v, min), max);
184551
- const lo = (clamp13(Math.min(base, value)) - min) * layout.valueScale;
184552
- const hi = (clamp13(Math.max(base, value)) - min) * layout.valueScale;
182225
+ const clamp12 = (v) => Math.min(Math.max(v, min), max);
182226
+ const lo = (clamp12(Math.min(base, value)) - min) * layout.valueScale;
182227
+ const hi = (clamp12(Math.max(base, value)) - min) * layout.valueScale;
184553
182228
  return { from: lo, length: hi - lo };
184554
182229
  }
184555
182230
  function obliqueBarAtValue(layout, bar, value) {
@@ -184689,6 +182364,7 @@ function buildPerspBarPrisms(chartData, layout, override) {
184689
182364
  neg = to;
184690
182365
  }
184691
182366
  }
182367
+ const shape = chartData.series[s]?.shape ?? chartData.barShape ?? "box";
184692
182368
  const slotIndex = layout.grouping === "clustered" ? s : 0;
184693
182369
  const row = layout.grouping === "standard" ? s : 0;
184694
182370
  const c0 = c * slot + gapWidth * barW / 2 + slotIndex * barW;
@@ -184707,7 +182383,16 @@ function buildPerspBarPrisms(chartData, layout, override) {
184707
182383
  [x0, y1]
184708
182384
  ],
184709
182385
  z0,
184710
- z1: z0 + depth
182386
+ z1: z0 + depth,
182387
+ shape,
182388
+ taper: obliqueBarTaper(
182389
+ shape,
182390
+ v0,
182391
+ v1,
182392
+ (layout.range.max - layout.range.min) * layout.valueScale,
182393
+ raw
182394
+ ),
182395
+ horizontal: layout.horizontal
184711
182396
  });
184712
182397
  }
184713
182398
  }
@@ -184716,6 +182401,7 @@ function buildPerspBarPrisms(chartData, layout, override) {
184716
182401
  var DEFAULT_GAP_WIDTH2;
184717
182402
  var init_chart_3d_persp_bars = __esm2({
184718
182403
  "src/render/chart-3d-persp-bars.ts"() {
182404
+ init_chart_3d_oblique_bars();
184719
182405
  DEFAULT_GAP_WIDTH2 = 150;
184720
182406
  }
184721
182407
  });
@@ -184807,6 +182493,55 @@ var init_chart_3d_persp_marks = __esm2({
184807
182493
  RIBBON_THICKNESS = 0.012;
184808
182494
  }
184809
182495
  });
182496
+ function isShapedPerspPrism(prism) {
182497
+ return prism.shape !== void 0 && prism.shape !== "box";
182498
+ }
182499
+ function outlineBounds2(prism) {
182500
+ const xs = prism.outline.map(([x]) => x);
182501
+ const ys = prism.outline.map(([, y]) => y);
182502
+ return [Math.min(...xs), Math.max(...xs), Math.min(...ys), Math.max(...ys)];
182503
+ }
182504
+ function buildShapedPrismGeometry(three, prism) {
182505
+ const shape = prism.shape ?? "box";
182506
+ const unit2 = buildObliqueShapeGeometry(
182507
+ three,
182508
+ { shape, taper: prism.taper ?? { bottom: 1, top: 1 } },
182509
+ Boolean(prism.horizontal)
182510
+ );
182511
+ const geometry = unit2.index ? unit2.toNonIndexed() : unit2;
182512
+ if (geometry !== unit2) {
182513
+ unit2.dispose();
182514
+ }
182515
+ const [x0, x1, y0, y1] = outlineBounds2(prism);
182516
+ const sx = Math.max(x1 - x0, 1e-6);
182517
+ const sy = Math.max(y1 - y0, 1e-6);
182518
+ const sz = Math.max(prism.z1 - prism.z0, 1e-6);
182519
+ geometry.scale(sx, sy, sz);
182520
+ geometry.translate((x0 + x1) / 2, (y0 + y1) / 2, (prism.z0 + prism.z1) / 2);
182521
+ geometry.computeVertexNormals();
182522
+ const normals = geometry.getAttribute("normal");
182523
+ const colors = new Float32Array(normals.count * 3);
182524
+ const base = new three.Color(prism.color).getRGB(new three.Color(), three.SRGBColorSpace);
182525
+ const out = new three.Color();
182526
+ for (let i2 = 0; i2 < normals.count; i2++) {
182527
+ const f6 = chart3DNormalShade(shape, normals.getX(i2), normals.getY(i2), -normals.getZ(i2));
182528
+ out.setRGB(
182529
+ Math.min(1, base.r * f6),
182530
+ Math.min(1, base.g * f6),
182531
+ Math.min(1, base.b * f6),
182532
+ three.SRGBColorSpace
182533
+ );
182534
+ colors.set([out.r, out.g, out.b], i2 * 3);
182535
+ }
182536
+ geometry.setAttribute("color", new three.Float32BufferAttribute(colors, 3));
182537
+ return geometry;
182538
+ }
182539
+ var init_chart_3d_persp_shape_mesh = __esm2({
182540
+ "src/render/chart-3d-persp-shape-mesh.ts"() {
182541
+ init_chart_3d_oblique_shape_mesh();
182542
+ init_chart_3d_shading();
182543
+ }
182544
+ });
184810
182545
  function shadePerspGeometry(three, geometry, color2) {
184811
182546
  const normals = geometry.getAttribute("normal");
184812
182547
  const colors = new Float32Array(normals.count * 3);
@@ -184827,6 +182562,9 @@ function shadePerspGeometry(three, geometry, color2) {
184827
182562
  geometry.setAttribute("color", new three.Float32BufferAttribute(colors, 3));
184828
182563
  }
184829
182564
  function buildPrismGeometry(three, prism) {
182565
+ if (isShapedPerspPrism(prism)) {
182566
+ return buildShapedPrismGeometry(three, prism);
182567
+ }
184830
182568
  const shape = new three.Shape(prism.outline.map(([x, y]) => new three.Vector2(x, y)));
184831
182569
  const extruded = new three.ExtrudeGeometry(shape, {
184832
182570
  depth: Math.max(prism.z1 - prism.z0, 1e-6),
@@ -184889,6 +182627,7 @@ function buildPerspMeshes(three, layout, prisms) {
184889
182627
  var GRIDLINE_COLOR5;
184890
182628
  var init_chart_3d_persp_mesh = __esm2({
184891
182629
  "src/render/chart-3d-persp-mesh.ts"() {
182630
+ init_chart_3d_persp_shape_mesh();
184892
182631
  init_chart_3d_persp_view();
184893
182632
  init_chart_3d_shading();
184894
182633
  GRIDLINE_COLOR5 = 14277081;
@@ -185666,24 +183405,6 @@ function buildObliqueCamera(three, svgWidth, svgHeight, shearX, shearY) {
185666
183405
  camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
185667
183406
  return camera;
185668
183407
  }
185669
- function mountPerspectiveScene(perspective2, ctx) {
185670
- switch (perspective2.kind) {
185671
- case "bar":
185672
- return createBarChart3DScene(ctx, perspective2.options);
185673
- case "line":
185674
- return createLineChart3DScene(ctx, perspective2.options);
185675
- case "area":
185676
- return createAreaChart3DScene(ctx, perspective2.options);
185677
- case "pie":
185678
- return createPieChart3DScene(ctx, perspective2.options);
185679
- case "surface":
185680
- return createSurfaceChart3DScene(ctx, perspective2.options);
185681
- default: {
185682
- const exhaustive2 = perspective2;
185683
- return exhaustive2;
185684
- }
185685
- }
185686
- }
185687
183408
  async function mountChart3DView(spec2, ctx) {
185688
183409
  if (spec2.geometry?.kind === "pie") {
185689
183410
  const chartData2 = spec2.element.chartData;
@@ -185712,9 +183433,6 @@ async function mountChart3DView(spec2, ctx) {
185712
183433
  );
185713
183434
  }
185714
183435
  if (spec2.projection.mode !== "oblique" || spec2.geometry?.kind !== "oblique") {
185715
- if (spec2.perspective) {
185716
- return mountPerspectiveScene(spec2.perspective, ctx);
185717
- }
185718
183436
  throw new Error(`no 3D chart scene for chartType=${spec2.chartType}`);
185719
183437
  }
185720
183438
  const three = ctx.three;
@@ -185776,17 +183494,12 @@ async function mountChart3DView(spec2, ctx) {
185776
183494
  }
185777
183495
  var init_chart_3d_view_scene = __esm2({
185778
183496
  "src/render/chart-3d-view-scene.ts"() {
185779
- init_area_chart_3d_scene();
185780
- init_bar_chart_3d_scene();
185781
183497
  init_chart_3d_bar_mesh();
185782
183498
  init_chart_3d_chrome_overlay();
185783
183499
  init_chart_3d_oblique_interaction();
185784
183500
  init_chart_3d_persp_scene();
185785
183501
  init_chart_3d_pie_layout();
185786
183502
  init_chart_3d_pie_scene();
185787
- init_line_chart_3d_scene();
185788
- init_pie_chart_3d_scene();
185789
- init_surface_chart_3d_scene();
185790
183503
  }
185791
183504
  });
185792
183505
  function isSmartArt3DGlassMaterial(material) {
@@ -186596,10 +184309,10 @@ function threeViewOverflowChanged(a, b) {
186596
184309
  return a.top !== b.top || a.right !== b.right || a.bottom !== b.bottom || a.left !== b.left;
186597
184310
  }
186598
184311
  function overflowPixelSize(size, overflow) {
186599
- const clamp13 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
184312
+ const clamp12 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
186600
184313
  return {
186601
- width: clamp13(size.pixelWidth * (1 + overflow.left + overflow.right)),
186602
- height: clamp13(size.pixelHeight * (1 + overflow.top + overflow.bottom))
184314
+ width: clamp12(size.pixelWidth * (1 + overflow.left + overflow.right)),
184315
+ height: clamp12(size.pixelHeight * (1 + overflow.top + overflow.bottom))
186603
184316
  };
186604
184317
  }
186605
184318
  function overflowViewOffset(size, overflow) {
@@ -187137,10 +184850,20 @@ function renderSelectMenu(menu, choices2, value) {
187137
184850
  }
187138
184851
  function positionSelectMenu(menu, trigger) {
187139
184852
  const rect22 = trigger.getBoundingClientRect();
187140
- menu.style.minWidth = `${rect22.width}px`;
187141
- menu.style.maxHeight = `${Math.min(240, Math.max(0, window.innerHeight - rect22.bottom - 8))}px`;
187142
- menu.style.top = `${rect22.bottom + 4}px`;
187143
- menu.style.left = `${Math.max(0, Math.min(rect22.left, window.innerWidth - menu.offsetWidth))}px`;
184853
+ const margin = 8;
184854
+ const gap = 4;
184855
+ const width = Math.max(0, window.innerWidth - margin * 2);
184856
+ const below = Math.max(0, window.innerHeight - rect22.bottom - gap - margin);
184857
+ const above = Math.max(0, rect22.top - gap - margin);
184858
+ menu.style.minWidth = `${Math.min(rect22.width, width)}px`;
184859
+ menu.style.maxWidth = `${width}px`;
184860
+ menu.style.maxHeight = "240px";
184861
+ const preferredHeight = menu.getBoundingClientRect().height;
184862
+ const flip = below < preferredHeight && above > below;
184863
+ menu.style.maxHeight = `${Math.min(240, flip ? above : below)}px`;
184864
+ const { height, width: menuWidth } = menu.getBoundingClientRect();
184865
+ menu.style.top = `${Math.max(margin, flip ? rect22.top - gap - height : rect22.bottom + gap)}px`;
184866
+ menu.style.left = `${Math.max(margin, Math.min(rect22.left, window.innerWidth - menuWidth - margin))}px`;
187144
184867
  }
187145
184868
  function markSelectActive(menu, trigger, active2, open) {
187146
184869
  for (const item3 of menu.querySelectorAll("[data-index]")) {
@@ -187418,6 +185141,9 @@ function definePptxSelect(registry) {
187418
185141
  }
187419
185142
  this.text.textContent = this.choices.find((choice) => choice.value === this.value)?.label ?? "";
187420
185143
  this.trigger.disabled = this.disabled;
185144
+ if (this.disabled) {
185145
+ this.close();
185146
+ }
187421
185147
  this.trigger.setAttribute("aria-label", this.getAttribute("aria-label") ?? "");
187422
185148
  this.internals?.setFormValue?.(this.disabled ? null : this.value);
187423
185149
  if (this.open || this.menu.childElementCount) {
@@ -187426,16 +185152,12 @@ function definePptxSelect(registry) {
187426
185152
  }
187427
185153
  renderMenu() {
187428
185154
  renderSelectMenu(this.menu, this.choices, this.value);
187429
- this.markActive();
185155
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187430
185156
  }
187431
185157
  show() {
187432
185158
  if (this.disabled || !this.choices.some((choice) => !choice.disabled && !choice.hidden) || this.open) {
187433
185159
  return;
187434
185160
  }
187435
- const availableBelow = window.innerHeight - this.trigger.getBoundingClientRect().bottom;
187436
- if (availableBelow < Math.min(this.choices.length * 32 + 12, 160)) {
187437
- this.trigger.scrollIntoView?.({ block: "center" });
187438
- }
187439
185161
  this.open = true;
187440
185162
  this.setAttribute("open", "");
187441
185163
  const selected = this.choices.findIndex(
@@ -187450,7 +185172,7 @@ function definePptxSelect(registry) {
187450
185172
  }
187451
185173
  this.trigger.setAttribute("aria-expanded", "true");
187452
185174
  this.position();
187453
- this.markActive();
185175
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187454
185176
  document.addEventListener("pointerdown", this.onOutside, true);
187455
185177
  window.addEventListener("resize", this.position);
187456
185178
  window.addEventListener("scroll", this.position, true);
@@ -187460,6 +185182,8 @@ function definePptxSelect(registry) {
187460
185182
  return;
187461
185183
  }
187462
185184
  this.open = false;
185185
+ window.clearTimeout(this.searchTimer);
185186
+ this.search = "";
187463
185187
  this.removeAttribute("open");
187464
185188
  if (this.menu.matches(":popover-open")) {
187465
185189
  this.menu.hidePopover();
@@ -187482,9 +185206,6 @@ function definePptxSelect(registry) {
187482
185206
  }
187483
185207
  positionSelectMenu(this.menu, this.trigger);
187484
185208
  };
187485
- markActive() {
187486
- markSelectActive(this.menu, this.trigger, this.active, this.open);
187487
- }
187488
185209
  move(step) {
187489
185210
  if (!this.open) {
187490
185211
  this.show();
@@ -187493,7 +185214,7 @@ function definePptxSelect(registry) {
187493
185214
  return;
187494
185215
  }
187495
185216
  this.active = nextSelectActive(this.choices, this.active, step);
187496
- this.markActive();
185217
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187497
185218
  }
187498
185219
  commit(index) {
187499
185220
  const choice = this.choices[index];
@@ -187521,8 +185242,8 @@ function definePptxSelect(registry) {
187521
185242
  event.preventDefault();
187522
185243
  event.stopPropagation();
187523
185244
  this.show();
187524
- this.active = event.key === "Home" ? this.choices.findIndex((choice) => !choice.disabled && !choice.hidden) : this.choices.length - 1 - [...this.choices].reverse().findIndex((choice) => !choice.disabled && !choice.hidden);
187525
- this.markActive();
185245
+ this.active = event.key === "Home" ? nextSelectActive(this.choices, -1, 1) : nextSelectActive(this.choices, 0, -1);
185246
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187526
185247
  } else if (event.key === "Enter" || event.key === " ") {
187527
185248
  event.preventDefault();
187528
185249
  event.stopPropagation();
@@ -187536,6 +185257,8 @@ function definePptxSelect(registry) {
187536
185257
  event.stopPropagation();
187537
185258
  this.close();
187538
185259
  this.trigger.focus();
185260
+ } else if (event.key === "Tab") {
185261
+ this.close();
187539
185262
  } else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
187540
185263
  event.stopPropagation();
187541
185264
  this.search += event.key.toLocaleLowerCase();
@@ -187549,7 +185272,7 @@ function definePptxSelect(registry) {
187549
185272
  );
187550
185273
  if (index >= 0) {
187551
185274
  this.active = index;
187552
- this.markActive();
185275
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187553
185276
  }
187554
185277
  }
187555
185278
  }
@@ -200609,8 +198332,8 @@ function hexToRgb4(hex22) {
200609
198332
  };
200610
198333
  }
200611
198334
  function rgbToHex3(r, g2, b) {
200612
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
200613
- return `#${clamp13(r).toString(16).padStart(2, "0")}${clamp13(g2).toString(16).padStart(2, "0")}${clamp13(b).toString(16).padStart(2, "0")}`;
198335
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
198336
+ return `#${clamp12(r).toString(16).padStart(2, "0")}${clamp12(g2).toString(16).padStart(2, "0")}${clamp12(b).toString(16).padStart(2, "0")}`;
200614
198337
  }
200615
198338
  function rgbToHsl2(r, g2, b) {
200616
198339
  const rn = r / 255;
@@ -207984,8 +205707,8 @@ function hexToRgb5(hex22) {
207984
205707
  };
207985
205708
  }
207986
205709
  function rgbToHex4(r, g2, b) {
207987
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
207988
- return `#${clamp13(r).toString(16).padStart(2, "0").toUpperCase()}${clamp13(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp13(b).toString(16).padStart(2, "0").toUpperCase()}`;
205710
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
205711
+ return `#${clamp12(r).toString(16).padStart(2, "0").toUpperCase()}${clamp12(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp12(b).toString(16).padStart(2, "0").toUpperCase()}`;
207989
205712
  }
207990
205713
  function tintColor(hex22, tintFactor) {
207991
205714
  const { r, g: g2, b } = hexToRgb5(hex22);
@@ -223160,8 +220883,8 @@ function hexToRgb6(hex22) {
223160
220883
  };
223161
220884
  }
223162
220885
  function rgbToHex5(r, g2, b) {
223163
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
223164
- return `#${clamp13(r).toString(16).padStart(2, "0").toUpperCase()}${clamp13(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp13(b).toString(16).padStart(2, "0").toUpperCase()}`;
220886
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
220887
+ return `#${clamp12(r).toString(16).padStart(2, "0").toUpperCase()}${clamp12(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp12(b).toString(16).padStart(2, "0").toUpperCase()}`;
223165
220888
  }
223166
220889
  function tintColor2(hex22, tintFactor) {
223167
220890
  const { r, g: g2, b } = hexToRgb6(hex22);
@@ -232654,242 +230377,6 @@ function buildSmartArt3DSpecForElement(element, options = {}) {
232654
230377
  });
232655
230378
  return model.meshes.length > 0 ? model : null;
232656
230379
  }
232657
- init_cartesian_line_chart_3d_layout();
232658
- init_chart_3d_surfaces();
232659
- init_chart_datapoint_style();
232660
- init_chart_view_model();
232661
- function buildPoints(chartData, catCount) {
232662
- const series = chartData.series;
232663
- const palette = chartData.colorPalette;
232664
- const points4 = [];
232665
- for (let si = 0; si < series.length; si++) {
232666
- const baseColor = seriesColor22(series[si], si, palette);
232667
- for (let ci = 0; ci < catCount; ci++) {
232668
- const value = series[si].values[ci] ?? 0;
232669
- const color2 = resolveDataPointFill(series[si], ci, paletteColor2(si, palette)) ?? baseColor;
232670
- points4.push({ seriesIndex: si, categoryIndex: ci, value, color: color2 });
232671
- }
232672
- }
232673
- return points4;
232674
- }
232675
- function buildCartesianLine3DSceneData(chartData, categoryLabels, options) {
232676
- const rows = chartData.series.length;
232677
- const cols = categoryLabels.length;
232678
- if (rows === 0 || cols === 0) {
232679
- return null;
232680
- }
232681
- const points4 = buildPoints(chartData, cols);
232682
- const range = computeValueRange2(chartData.series, options.height);
232683
- const depthPercent = chartData.view3D?.depthPercent;
232684
- const series = layoutCartesianLine3DSeries(points4, cols, rows, range, depthPercent);
232685
- return {
232686
- cols,
232687
- rows,
232688
- series,
232689
- categoryLabels,
232690
- seriesNames: chartData.series.map((s) => s.name),
232691
- numberFormats: chartData.series.map((s) => s.numberFormat),
232692
- width: options.width,
232693
- height: options.height,
232694
- view3D: chartData.view3D ? {
232695
- rotX: chartData.view3D.rotX,
232696
- rotY: chartData.view3D.rotY,
232697
- rperspective: chartData.view3D.perspective,
232698
- depthPercent: chartData.view3D.depthPercent,
232699
- rAngAx: chartData.view3D.rAngAx
232700
- } : void 0,
232701
- wallColors: resolveChart3DWallColors(chartData)
232702
- };
232703
- }
232704
- function buildAreaChart3DDataForElement(element, options) {
232705
- if (element.type !== "chart") {
232706
- return null;
232707
- }
232708
- const chartEl = element;
232709
- const chartData = chartEl.chartData;
232710
- if (!chartData || chartData.series.length === 0) {
232711
- return null;
232712
- }
232713
- if (chartData.chartType !== "area3D") {
232714
- return null;
232715
- }
232716
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
232717
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
232718
- return buildCartesianLine3DSceneData(chartData, categoryLabels, options);
232719
- }
232720
- init_cartesian_chart_3d_geom();
232721
- function coneToMaxTopRadiusFactor(shape, value, max) {
232722
- if (shape !== "coneToMax" && shape !== "pyramidToMax") {
232723
- return void 0;
232724
- }
232725
- if (!(max > 0)) {
232726
- return 0;
232727
- }
232728
- return Math.max(0, Math.min(1, 1 - Math.abs(value) / max));
232729
- }
232730
- var MIN_BOX_HEIGHT = 0.02;
232731
- var BOX_GAP = 0.15;
232732
- function normalizeToHeight2(value, range) {
232733
- if (range.span <= 0) {
232734
- return 0;
232735
- }
232736
- return (value - range.min) / range.span * MAX_VALUE_HEIGHT;
232737
- }
232738
- function layoutClustered(points4, cols, rows, range, depthPercent) {
232739
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
232740
- const colStep = gridWidth / cols;
232741
- const rowStep = gridDepth / Math.max(rows, 1);
232742
- const boxW = colStep * (1 - BOX_GAP);
232743
- const boxD = rowStep * (1 - BOX_GAP);
232744
- const zeroH = normalizeToHeight2(0, range);
232745
- return points4.map((p) => {
232746
- const valueH = normalizeToHeight2(p.plotValue, range);
232747
- const top = Math.max(valueH, zeroH);
232748
- const bottom = Math.min(valueH, zeroH);
232749
- const h2 = Math.max(top - bottom, MIN_BOX_HEIGHT);
232750
- const x = -gridWidth / 2 + colStep * (p.categoryIndex + 0.5);
232751
- const z = -gridDepth / 2 + rowStep * (p.seriesIndex + 0.5);
232752
- return {
232753
- seriesIndex: p.seriesIndex,
232754
- categoryIndex: p.categoryIndex,
232755
- value: p.value,
232756
- color: p.color,
232757
- center: [x, bottom + h2 / 2, z],
232758
- size: [boxW, h2, boxD],
232759
- shape: p.shape,
232760
- coneToMaxTopRadiusFactor: coneToMaxTopRadiusFactor(p.shape, p.value, range.max)
232761
- };
232762
- });
232763
- }
232764
- function layoutStacked(points4, cols, rows, range, depthPercent) {
232765
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
232766
- const colStep = gridWidth / cols;
232767
- const boxW = colStep * (1 - BOX_GAP);
232768
- const boxD = gridDepth * (1 - BOX_GAP);
232769
- const boxes = [];
232770
- for (let ci = 0; ci < cols; ci++) {
232771
- const x = -gridWidth / 2 + colStep * (ci + 0.5);
232772
- let posRunning = 0;
232773
- let negRunning = 0;
232774
- const catPoints = points4.filter((p) => p.categoryIndex === ci).sort((a, b) => a.seriesIndex - b.seriesIndex);
232775
- for (const p of catPoints) {
232776
- const isNeg = p.plotValue < 0;
232777
- const base = isNeg ? negRunning : posRunning;
232778
- const top = base + p.plotValue;
232779
- if (isNeg) {
232780
- negRunning = top;
232781
- } else {
232782
- posRunning = top;
232783
- }
232784
- const baseH = normalizeToHeight2(base, range);
232785
- const topH = normalizeToHeight2(top, range);
232786
- const h2 = Math.max(Math.abs(topH - baseH), MIN_BOX_HEIGHT);
232787
- boxes.push({
232788
- seriesIndex: p.seriesIndex,
232789
- categoryIndex: p.categoryIndex,
232790
- value: p.value,
232791
- color: p.color,
232792
- center: [x, Math.min(baseH, topH) + h2 / 2, 0],
232793
- size: [boxW, h2, boxD],
232794
- shape: p.shape,
232795
- coneToMaxTopRadiusFactor: coneToMaxTopRadiusFactor(p.shape, p.value, range.max)
232796
- });
232797
- }
232798
- }
232799
- return boxes;
232800
- }
232801
- function layoutBarChart3D(points4, cols, rows, range, grouping, depthPercent, horizontal = false) {
232802
- const boxes = grouping === "clustered" ? layoutClustered(points4, cols, rows, range, depthPercent) : layoutStacked(points4, cols, rows, range, depthPercent);
232803
- if (!horizontal) {
232804
- return boxes;
232805
- }
232806
- return boxes.map((box) => ({ ...box, center: transposeForHorizontalBar3D(box.center) }));
232807
- }
232808
- init_chart_3d_surfaces();
232809
- init_chart_datapoint_style();
232810
- init_chart_view_model();
232811
- function categoryTotals3(series, catCount) {
232812
- return Array.from(
232813
- { length: catCount },
232814
- (_, ci) => series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0)
232815
- );
232816
- }
232817
- function buildPoints2(chartData, catCount, isPercent) {
232818
- const series = chartData.series;
232819
- const palette = chartData.colorPalette;
232820
- const totals = isPercent ? categoryTotals3(series, catCount) : void 0;
232821
- const points4 = [];
232822
- for (let si = 0; si < series.length; si++) {
232823
- const baseColor = seriesColor22(series[si], si, palette);
232824
- for (let ci = 0; ci < catCount; ci++) {
232825
- const value = series[si].values[ci] ?? 0;
232826
- const color2 = resolveDataPointFill(series[si], ci, paletteColor2(si, palette)) ?? baseColor;
232827
- const catTotal = totals?.[ci];
232828
- const plotValue = isPercent && catTotal !== void 0 && catTotal > 0 ? value / catTotal * 100 : value;
232829
- points4.push({
232830
- seriesIndex: si,
232831
- categoryIndex: ci,
232832
- value,
232833
- plotValue,
232834
- color: color2,
232835
- // Per-series `c:ser/c:shape` wins over the chart-level `c:bar3DChart/c:shape`.
232836
- shape: series[si].shape ?? chartData.barShape
232837
- });
232838
- }
232839
- }
232840
- return points4;
232841
- }
232842
- function buildBarChart3DData(chartData, categoryLabels, options) {
232843
- const rows = chartData.series.length;
232844
- const cols = categoryLabels.length;
232845
- if (rows === 0 || cols === 0) {
232846
- return null;
232847
- }
232848
- const grouping = chartData.grouping === "stacked" || chartData.grouping === "percentStacked" ? chartData.grouping : "clustered";
232849
- const isPercent = grouping === "percentStacked";
232850
- const horizontal = chartData.barDirection === "bar";
232851
- const points4 = buildPoints2(chartData, cols, isPercent);
232852
- const range = isPercent ? { min: 0, max: 100, span: 100 } : grouping === "stacked" ? computeStackedValueRange(chartData.series, cols, options.height) : computeValueRange2(chartData.series, options.height);
232853
- const depthPercent = chartData.view3D?.depthPercent;
232854
- const boxes = layoutBarChart3D(points4, cols, rows, range, grouping, depthPercent, horizontal);
232855
- return {
232856
- cols,
232857
- rows,
232858
- boxes,
232859
- categoryLabels,
232860
- seriesNames: chartData.series.map((s) => s.name),
232861
- numberFormats: chartData.series.map((s) => s.numberFormat),
232862
- grouping,
232863
- width: options.width,
232864
- height: options.height,
232865
- view3D: chartData.view3D ? {
232866
- rotX: chartData.view3D.rotX,
232867
- rotY: chartData.view3D.rotY,
232868
- rperspective: chartData.view3D.perspective,
232869
- depthPercent: chartData.view3D.depthPercent,
232870
- rAngAx: chartData.view3D.rAngAx
232871
- } : void 0,
232872
- wallColors: resolveChart3DWallColors(chartData),
232873
- picture: { series: chartData.series },
232874
- ...horizontal ? { horizontal: true } : {}
232875
- };
232876
- }
232877
- function buildBarChart3DDataForElement(element, options) {
232878
- if (element.type !== "chart") {
232879
- return null;
232880
- }
232881
- const chartEl = element;
232882
- const chartData = chartEl.chartData;
232883
- if (!chartData || chartData.series.length === 0) {
232884
- return null;
232885
- }
232886
- if (chartData.chartType !== "bar3D") {
232887
- return null;
232888
- }
232889
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
232890
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
232891
- return buildBarChart3DData(chartData, categoryLabels, options);
232892
- }
232893
230380
  init_chart_3d_oblique_bars();
232894
230381
  init_chart_view_model_chrome();
232895
230382
  var PT = 4 / 3;
@@ -233378,16 +230865,16 @@ var DEFAULT_ROT_X3 = 15;
233378
230865
  var DEFAULT_ROT_Y2 = 20;
233379
230866
  var DEFAULT_PIE_ROT_X = 30;
233380
230867
  var DEFAULT_PIE_ROT_Y = 0;
233381
- var DEFAULT_PERSPECTIVE_DEG2 = 30;
233382
- var PERSPECTIVE_MAX_DEG2 = 120;
233383
- var FOV_MIN2 = 15;
233384
- var FOV_MAX2 = 75;
233385
- function clamp82(value, min, max) {
230868
+ var DEFAULT_PERSPECTIVE_DEG = 30;
230869
+ var PERSPECTIVE_MAX_DEG = 120;
230870
+ var FOV_MIN = 15;
230871
+ var FOV_MAX = 75;
230872
+ function clamp7(value, min, max) {
233386
230873
  return Math.min(Math.max(value, min), max);
233387
230874
  }
233388
230875
  function resolvePerspectiveFov(perspectiveDeg) {
233389
- const perspective2 = clamp82(perspectiveDeg ?? DEFAULT_PERSPECTIVE_DEG2, 0, PERSPECTIVE_MAX_DEG2);
233390
- return FOV_MIN2 + perspective2 / PERSPECTIVE_MAX_DEG2 * (FOV_MAX2 - FOV_MIN2);
230876
+ const perspective2 = clamp7(perspectiveDeg ?? DEFAULT_PERSPECTIVE_DEG, 0, PERSPECTIVE_MAX_DEG);
230877
+ return FOV_MIN + perspective2 / PERSPECTIVE_MAX_DEG * (FOV_MAX - FOV_MIN);
233391
230878
  }
233392
230879
  function resolveChart3DProjection(chartType, view3D) {
233393
230880
  const isPie = chartType === "pie3D";
@@ -233413,149 +230900,6 @@ function resolveChart3DProjection(chartType, view3D) {
233413
230900
  };
233414
230901
  }
233415
230902
  init_chart_view_model_build();
233416
- function buildLineChart3DDataForElement(element, options) {
233417
- if (element.type !== "chart") {
233418
- return null;
233419
- }
233420
- const chartEl = element;
233421
- const chartData = chartEl.chartData;
233422
- if (!chartData || chartData.series.length === 0) {
233423
- return null;
233424
- }
233425
- if (chartData.chartType !== "line3D") {
233426
- return null;
233427
- }
233428
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
233429
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
233430
- return buildCartesianLine3DSceneData(chartData, categoryLabels, options);
233431
- }
233432
- init_chart_datapoint_style();
233433
- init_chart_view_model();
233434
- init_pie_chart_3d_geom();
233435
- function buildPieChart3DData(chartData, categoryLabels, options) {
233436
- const pieSeries = chartData.series[0];
233437
- if (!pieSeries || pieSeries.values.length === 0) {
233438
- return null;
233439
- }
233440
- const values = pieSeries.values;
233441
- const explosions = values.map((_v, i2) => resolveDataPointExplosion(pieSeries, i2));
233442
- const outerRadius = PIE_RADIUS;
233443
- const angles = computePieChart3DSliceAngles(
233444
- values,
233445
- explosions,
233446
- chartData.firstSliceAngle,
233447
- outerRadius
233448
- );
233449
- const wedges = angles.map((angle) => ({
233450
- ...angle,
233451
- color: resolveVaryColorFill(
233452
- pieSeries,
233453
- angle.pointIndex,
233454
- paletteColor2(angle.pointIndex, chartData.colorPalette)
233455
- )
233456
- }));
233457
- const view3D = chartData.view3D ? {
233458
- rotX: chartData.view3D.rotX,
233459
- rotY: chartData.view3D.rotY,
233460
- rperspective: chartData.view3D.perspective,
233461
- rAngAx: chartData.view3D.rAngAx,
233462
- hPercent: chartData.view3D.hPercent
233463
- } : void 0;
233464
- return {
233465
- wedges,
233466
- categoryLabels,
233467
- seriesName: pieSeries.name,
233468
- numberFormat: pieSeries.numberFormat,
233469
- outerRadius,
233470
- thickness: computePieChart3DThickness(view3D),
233471
- width: options.width,
233472
- height: options.height,
233473
- view3D,
233474
- values,
233475
- explosions,
233476
- firstSliceAngleDeg: chartData.firstSliceAngle
233477
- };
233478
- }
233479
- function buildPieChart3DDataForElement(element, options) {
233480
- if (element.type !== "chart") {
233481
- return null;
233482
- }
233483
- const chartEl = element;
233484
- const chartData = chartEl.chartData;
233485
- if (!chartData || chartData.series.length === 0) {
233486
- return null;
233487
- }
233488
- if (chartData.chartType !== "pie3D") {
233489
- return null;
233490
- }
233491
- const pieSeries = chartData.series[0];
233492
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: pieSeries.values.length }, (_, i2) => String(i2 + 1));
233493
- return buildPieChart3DData(chartData, categoryLabels, options);
233494
- }
233495
- init_chart_3d_surfaces();
233496
- init_chart_surface_bands();
233497
- init_chart_surface_treemap();
233498
- init_chart_view_model();
233499
- function resolveSurfaceColors(chartData) {
233500
- return resolveChart3DWallColors(chartData);
233501
- }
233502
- function buildSurfaceChart3DData(chartData, categoryLabels, options) {
233503
- const seriesCount = chartData.series.length;
233504
- const catCount = categoryLabels.length;
233505
- if (seriesCount === 0 || catCount === 0) {
233506
- return null;
233507
- }
233508
- const range = computeValueRange2(chartData.series, options.height);
233509
- const heightMap = new Float32Array(seriesCount * catCount);
233510
- const colorMap = new Float32Array(seriesCount * catCount * 3);
233511
- const values = new Float32Array(seriesCount * catCount);
233512
- for (let row = 0; row < seriesCount; row++) {
233513
- for (let col = 0; col < catCount; col++) {
233514
- const idx = row * catCount + col;
233515
- const val2 = chartData.series[row]?.values[col] ?? 0;
233516
- values[idx] = val2;
233517
- const t = range.span > 0 ? (val2 - range.min) / range.span : 0;
233518
- heightMap[idx] = t;
233519
- const bandFill = resolveSurfaceBandFill(t, chartData.bandFmts);
233520
- const { r, g: g2, b } = bandFill ? hexToRgb4(bandFill) : surfaceColor(t);
233521
- const ci = idx * 3;
233522
- colorMap[ci] = r / 255;
233523
- colorMap[ci + 1] = g2 / 255;
233524
- colorMap[ci + 2] = b / 255;
233525
- }
233526
- }
233527
- return {
233528
- cols: catCount,
233529
- rows: seriesCount,
233530
- heightMap,
233531
- colorMap,
233532
- values,
233533
- numberFormats: chartData.series.map((s) => s.numberFormat),
233534
- wireframe: options.wireframe ?? chartData.wireframe ?? true,
233535
- categoryLabels,
233536
- seriesNames: chartData.series.map((s) => s.name),
233537
- width: options.width,
233538
- height: options.height,
233539
- view3D: chartData.view3D ? { rotX: chartData.view3D.rotX, rotY: chartData.view3D.rotY } : void 0,
233540
- surfaceColors: resolveSurfaceColors(chartData)
233541
- };
233542
- }
233543
- function buildSurfaceChart3DDataForElement(element, options) {
233544
- if (element.type !== "chart") {
233545
- return null;
233546
- }
233547
- const chartEl = element;
233548
- const chartData = chartEl.chartData;
233549
- if (!chartData || chartData.series.length === 0) {
233550
- return null;
233551
- }
233552
- if (resolveChartKind(chartData.chartType ?? "bar") !== "surface") {
233553
- return null;
233554
- }
233555
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
233556
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
233557
- return buildSurfaceChart3DData(chartData, categoryLabels, options);
233558
- }
233559
230903
  var CHART_3D_TYPES = /* @__PURE__ */ new Set([
233560
230904
  "bar3D",
233561
230905
  "line3D",
@@ -233592,6 +230936,9 @@ function buildChart3DSpecForElement(element) {
233592
230936
  const vm = buildChartViewModel(element);
233593
230937
  const projection = resolveChart3DProjection(chartType, chartData.view3D);
233594
230938
  const geometry = chartType === "bar3D" && projection.mode === "oblique" ? buildBarGeometry(element, vm) : PERSP_BOX_TYPES.has(chartType) && (projection.mode === "perspective" || chartType !== "bar3D") ? buildPerspGeometry(element, vm, projection.mode === "oblique") : chartType === "pie3D" ? buildPieGeometry(element, vm) : null;
230939
+ if (!geometry) {
230940
+ return null;
230941
+ }
233595
230942
  const longest = chartData.series.reduce((m, series) => Math.max(m, series.values.length), 0);
233596
230943
  const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longest }, (_, i2) => String(i2 + 1));
233597
230944
  return {
@@ -233602,37 +230949,9 @@ function buildChart3DSpecForElement(element) {
233602
230949
  projection,
233603
230950
  vm,
233604
230951
  geometry,
233605
- categoryLabels,
233606
- perspective: geometry ? null : buildPerspectiveScene(element)
230952
+ categoryLabels
233607
230953
  };
233608
230954
  }
233609
- function buildPerspectiveScene(element) {
233610
- const size = { width: element.width, height: element.height };
233611
- switch (element.chartData?.chartType) {
233612
- case "bar3D": {
233613
- const options = buildBarChart3DDataForElement(element, size);
233614
- return options ? { kind: "bar", options } : null;
233615
- }
233616
- case "line3D": {
233617
- const options = buildLineChart3DDataForElement(element, size);
233618
- return options ? { kind: "line", options } : null;
233619
- }
233620
- case "area3D": {
233621
- const options = buildAreaChart3DDataForElement(element, size);
233622
- return options ? { kind: "area", options } : null;
233623
- }
233624
- case "pie3D": {
233625
- const options = buildPieChart3DDataForElement(element, size);
233626
- return options ? { kind: "pie", options } : null;
233627
- }
233628
- case "surface": {
233629
- const options = buildSurfaceChart3DDataForElement(element, size);
233630
- return options ? { kind: "surface", options } : null;
233631
- }
233632
- default:
233633
- return null;
233634
- }
233635
- }
233636
230955
  function observeElementHeight(el, onHeight) {
233637
230956
  onHeight(el.getBoundingClientRect().height);
233638
230957
  if (typeof ResizeObserver === "undefined") {
@@ -233993,19 +231312,7 @@ async function mountModel3D(container, modelUrl, options) {
233993
231312
  }
233994
231313
  };
233995
231314
  }
233996
- init_surface_chart_3d_geom();
233997
- init_surface_chart_3d_scene();
233998
- init_surface_chart_3d_hit_test();
233999
- init_cartesian_chart_3d_geom();
234000
- init_bar_chart_3d_scene();
234001
231315
  init_bar_chart_3d_hit_test();
234002
- init_cartesian_line_chart_3d_layout();
234003
- init_cartesian_chart_3d_hit_test();
234004
- init_line_chart_3d_scene();
234005
- init_area_chart_3d_scene();
234006
- init_pie_chart_3d_geom();
234007
- init_pie_chart_3d_scene();
234008
- init_pie_chart_3d_hit_test();
234009
231316
  init_text_wrap_estimate();
234010
231317
  function collectFontsFromElement(element, fonts) {
234011
231318
  if (hasTextProperties(element)) {
@@ -240447,16 +237754,16 @@ function trimmedMediaDurationMs(trimStartMs, trimEndMs, durationMs) {
240447
237754
  }
240448
237755
  return effectiveEnd - trimStartMs;
240449
237756
  }
240450
- function clamp12(value, minimum, maximum) {
237757
+ function clamp11(value, minimum, maximum) {
240451
237758
  return Math.min(maximum, Math.max(minimum, value));
240452
237759
  }
240453
237760
  function mediaTrimEndSeconds(durationSeconds, trimEndMs) {
240454
237761
  const duration = Math.max(0, durationSeconds);
240455
- return trimEndMs > 0 ? clamp12(duration - trimEndMs / 1e3, 0, duration) : duration;
237762
+ return trimEndMs > 0 ? clamp11(duration - trimEndMs / 1e3, 0, duration) : duration;
240456
237763
  }
240457
237764
  function mediaTrimEndMsFromSeconds(durationSeconds, endSeconds) {
240458
237765
  const duration = Math.max(0, durationSeconds);
240459
- return Math.max(0, duration - clamp12(endSeconds, 0, duration)) * 1e3;
237766
+ return Math.max(0, duration - clamp11(endSeconds, 0, duration)) * 1e3;
240460
237767
  }
240461
237768
  function buildSummaryZoomView(element, lookup, translate) {
240462
237769
  if (element.zoomType !== "summary" || !element.summaryTargets?.length) {
@@ -243308,9 +240615,9 @@ function resolveAuthoredSlideRange(selection, slideCount) {
243308
240615
  if (typeof from !== "number" || typeof to !== "number" || !Number.isFinite(from) || !Number.isFinite(to)) {
243309
240616
  return void 0;
243310
240617
  }
243311
- const clamp13 = (value) => Math.min(Math.max(Math.round(value), 1), slideCount);
243312
- const clampedFrom = clamp13(from);
243313
- const clampedTo = clamp13(to);
240618
+ const clamp12 = (value) => Math.min(Math.max(Math.round(value), 1), slideCount);
240619
+ const clampedFrom = clamp12(from);
240620
+ const clampedTo = clamp12(to);
243314
240621
  return {
243315
240622
  fromIndex: Math.min(clampedFrom, clampedTo) - 1,
243316
240623
  toIndex: Math.max(clampedFrom, clampedTo) - 1
@@ -247727,14 +245034,14 @@ function shadowMatches(style, spec2) {
247727
245034
  }
247728
245035
  function tileEffects(spec2) {
247729
245036
  const { x, y } = shadowOffsets(spec2.distEmu, spec2.dir);
247730
- const clamp13 = (v) => Math.max(-4, Math.min(4, v * 0.6));
245037
+ const clamp12 = (v) => Math.max(-4, Math.min(4, v * 0.6));
247731
245038
  return {
247732
245039
  shadow: {
247733
245040
  color: "#000000",
247734
245041
  opacity: Math.min(0.8, (spec2.alpha ?? 1e5) / 1e5 + 0.25),
247735
245042
  blur: Math.min(6, spec2.blurEmu / EMU_PER_PX62 / 1.5),
247736
- dx: clamp13(x),
247737
- dy: clamp13(y) + (spec2.sy !== void 0 && spec2.sy < 0 ? 3 : 0),
245043
+ dx: clamp12(x),
245044
+ dy: clamp12(y) + (spec2.sy !== void 0 && spec2.sy < 0 ? 3 : 0),
247738
245045
  inner: spec2.kind === "inner"
247739
245046
  }
247740
245047
  };
@@ -249147,9 +246454,9 @@ function effectFilter(style, id) {
249147
246454
  merge.push('<feMergeNode in="glow"/>');
249148
246455
  }
249149
246456
  if (style.textShadowColor) {
249150
- const clamp13 = (v) => Math.max(-2, Math.min(2, (v ?? 0) / 2));
246457
+ const clamp12 = (v) => Math.max(-2, Math.min(2, (v ?? 0) / 2));
249151
246458
  parts.push(
249152
- `<feDropShadow dx="${num7(clamp13(style.textShadowOffsetX))}" dy="${num7(clamp13(style.textShadowOffsetY))}" stdDeviation="${num7(Math.min(1.5, (style.textShadowBlur ?? 2) / 4))}" flood-color="${safeColor(style.textShadowColor, "#000000")}" flood-opacity="${num7(style.textShadowOpacity ?? 1)}" result="shadow"/>`
246459
+ `<feDropShadow dx="${num7(clamp12(style.textShadowOffsetX))}" dy="${num7(clamp12(style.textShadowOffsetY))}" stdDeviation="${num7(Math.min(1.5, (style.textShadowBlur ?? 2) / 4))}" flood-color="${safeColor(style.textShadowColor, "#000000")}" flood-opacity="${num7(style.textShadowOpacity ?? 1)}" result="shadow"/>`
249153
246460
  );
249154
246461
  merge.push('<feMergeNode in="shadow"/>');
249155
246462
  } else {
@@ -250826,9 +248133,6 @@ function getActiveXControlOverlayView(control, slideSize, index = 0, resolveFall
250826
248133
  className: imageUrl ? "image" : "placeholder"
250827
248134
  };
250828
248135
  }
250829
- init_bar_chart_3d_geometry();
250830
- init_bar_chart_3d_face_fill();
250831
- init_bar_chart_3d_materials();
250832
248136
  init_chart_bar3d_face_picture_sample();
250833
248137
  var BAR3D_SHAPE_OPTIONS = [
250834
248138
  { value: "box", labelKey: "pptx.chart.bar3DShapeBox" },
@@ -251494,10 +248798,6 @@ var ThreeViewController = class {
251494
248798
  spec2.spec,
251495
248799
  {
251496
248800
  three,
251497
- // No camera orbit: PowerPoint never rotates a chart or SmartArt
251498
- // under the pointer, and an orbit would turn the scene while the
251499
- // user drags the element to move it on the slide.
251500
- OrbitControls: null,
251501
248801
  size: this.size,
251502
248802
  eventTarget: this.opts.eventTarget,
251503
248803
  overlay,
@@ -251626,12 +248926,12 @@ function computeThreeViewSize(layoutWidth, layoutHeight, screenWidth, screenHeig
251626
248926
  const dpr = Math.min(MAX_DEVICE_PIXEL_RATIO, Math.max(1, devicePixelRatio || 1));
251627
248927
  const onScreenW = screenWidth > 0 ? screenWidth : width;
251628
248928
  const onScreenH = screenHeight > 0 ? screenHeight : height;
251629
- const clamp13 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
248929
+ const clamp12 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
251630
248930
  return {
251631
248931
  width,
251632
248932
  height,
251633
- pixelWidth: clamp13(onScreenW * dpr),
251634
- pixelHeight: clamp13(onScreenH * dpr)
248933
+ pixelWidth: clamp12(onScreenW * dpr),
248934
+ pixelHeight: clamp12(onScreenH * dpr)
251635
248935
  };
251636
248936
  }
251637
248937
  function measureThreeViewSize(element) {