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
@@ -27272,6 +27272,19 @@ var init_element_xml_builders = __esm({
27272
27272
  init_stroke_utils();
27273
27273
  }
27274
27274
  });
27275
+ function srgb255ToLinear(channel) {
27276
+ const c = clampUnitInterval(channel / 255);
27277
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
27278
+ }
27279
+ function linearToSrgb255(linear) {
27280
+ const c = clampUnitInterval(linear);
27281
+ return 255 * (c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055);
27282
+ }
27283
+ var init_color_linear = __esm({
27284
+ "src/core/color/color-linear.ts"() {
27285
+ init_color_primitives();
27286
+ }
27287
+ });
27275
27288
  function applyDrawingColorTransforms(baseColor, colorNode) {
27276
27289
  const rgb2 = hexToRgbChannels(baseColor);
27277
27290
  if (!rgb2) {
@@ -27314,15 +27327,15 @@ function applyDrawingColorTransforms(baseColor, colorNode) {
27314
27327
  }
27315
27328
  const shade3 = parseDrawingPercent(getVal("a:shade"));
27316
27329
  if (shade3 !== void 0) {
27317
- r *= shade3;
27318
- g2 *= shade3;
27319
- b *= shade3;
27330
+ r = linearToSrgb255(srgb255ToLinear(r) * shade3);
27331
+ g2 = linearToSrgb255(srgb255ToLinear(g2) * shade3);
27332
+ b = linearToSrgb255(srgb255ToLinear(b) * shade3);
27320
27333
  }
27321
27334
  const tint3 = parseDrawingPercent(getVal("a:tint"));
27322
27335
  if (tint3 !== void 0) {
27323
- r = 255 - (255 - r) * tint3;
27324
- g2 = 255 - (255 - g2) * tint3;
27325
- b = 255 - (255 - b) * tint3;
27336
+ r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) * tint3);
27337
+ g2 = linearToSrgb255(1 - (1 - srgb255ToLinear(g2)) * tint3);
27338
+ b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) * tint3);
27326
27339
  }
27327
27340
  const hslKeys = [
27328
27341
  "a:hue",
@@ -27435,6 +27448,7 @@ function applySrgbGammaDecode(r, g2, b) {
27435
27448
  }
27436
27449
  var init_color_transforms = __esm({
27437
27450
  "src/core/color/color-transforms.ts"() {
27451
+ init_color_linear();
27438
27452
  init_color_primitives();
27439
27453
  }
27440
27454
  });
@@ -169327,8 +169341,8 @@ function hexToRgb2(hex22) {
169327
169341
  ];
169328
169342
  }
169329
169343
  function rgbToHex(r, g2, b) {
169330
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169331
- return `#${clamp13(r).toString(16).padStart(2, "0")}${clamp13(g2).toString(16).padStart(2, "0")}${clamp13(b).toString(16).padStart(2, "0")}`;
169344
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169345
+ return `#${clamp12(r).toString(16).padStart(2, "0")}${clamp12(g2).toString(16).padStart(2, "0")}${clamp12(b).toString(16).padStart(2, "0")}`;
169332
169346
  }
169333
169347
  function tint(hex22, amount) {
169334
169348
  const [r, g2, b] = hexToRgb2(hex22);
@@ -169828,8 +169842,8 @@ function hexToRgb3(hex22) {
169828
169842
  ];
169829
169843
  }
169830
169844
  function rgbToHex2(r, g2, b) {
169831
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169832
- return `#${clamp13(r).toString(16).padStart(2, "0")}${clamp13(g2).toString(16).padStart(2, "0")}${clamp13(b).toString(16).padStart(2, "0")}`;
169845
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
169846
+ return `#${clamp12(r).toString(16).padStart(2, "0")}${clamp12(g2).toString(16).padStart(2, "0")}${clamp12(b).toString(16).padStart(2, "0")}`;
169833
169847
  }
169834
169848
  function tint2(hex22, amount) {
169835
169849
  const [r, g2, b] = hexToRgb3(hex22);
@@ -170694,15 +170708,6 @@ var init_chart_view_model_bars = __esm2({
170694
170708
  init_chart_view_model_scale();
170695
170709
  }
170696
170710
  });
170697
- function resolveChart3DWallColors(surfaces) {
170698
- const floor = surfaces.floor?.spPr?.fillColor;
170699
- const sideWall = surfaces.sideWall?.spPr?.fillColor;
170700
- const backWall = surfaces.backWall?.spPr?.fillColor;
170701
- if (!floor && !sideWall && !backWall) {
170702
- return void 0;
170703
- }
170704
- return { floor, sideWall, backWall };
170705
- }
170706
170711
  function primitivesBounds(prims) {
170707
170712
  let minX = Number.POSITIVE_INFINITY;
170708
170713
  let maxX = Number.NEGATIVE_INFINITY;
@@ -178419,7 +178424,7 @@ function formatRegionMapValue(value, cultureLanguage) {
178419
178424
  }
178420
178425
  }
178421
178426
  function lerpColor(a, b, t) {
178422
- 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");
178427
+ 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");
178423
178428
  return `#${toHex23(r)}${toHex23(g3)}${toHex23(bl)}`;
178424
178429
  }
178425
178430
  function resolveValueColorStops(valueColors, valueColorPositions, minVal, maxVal) {
@@ -181147,173 +181152,6 @@ var init_smartart_3d_drawing_solid = __esm2({
181147
181152
  DEG_PER_UNIT2 = 6e4;
181148
181153
  }
181149
181154
  });
181150
- function transposeForHorizontalBar3D(point) {
181151
- return [point[1], -point[0], point[2]];
181152
- }
181153
- function computeCartesianGridExtent(cols, rows, depthPercent) {
181154
- const gridWidth = Math.max(cols - 1, 1) * GRID_SPACING;
181155
- const depthScale = Math.min(Math.max((depthPercent ?? 100) / 100, 0.05), 3);
181156
- const gridDepth = Math.max(gridWidth * depthScale, rows > 1 ? GRID_SPACING : GRID_SPACING * 0.5);
181157
- return { gridWidth, gridDepth };
181158
- }
181159
- function clamp7(value, min, max) {
181160
- return Math.min(Math.max(value, min), max);
181161
- }
181162
- function normalizeAzimuth(deg3) {
181163
- const wrapped = deg3 % 360;
181164
- return wrapped < 0 ? wrapped + 360 : wrapped;
181165
- }
181166
- function resolveCartesianCameraFov(view3D) {
181167
- if (view3D?.rAngAx) {
181168
- return RIGHT_ANGLE_FOV;
181169
- }
181170
- const perspective2 = clamp7(
181171
- view3D?.rperspective ?? DEFAULT_PERSPECTIVE_DEG,
181172
- 0,
181173
- PERSPECTIVE_MAX_DEG
181174
- );
181175
- return FOV_MIN + perspective2 / PERSPECTIVE_MAX_DEG * (FOV_MAX - FOV_MIN);
181176
- }
181177
- function computeSphericalCameraPlacement(maxExtent, targetY, view3D) {
181178
- const fov = resolveCartesianCameraFov(view3D);
181179
- const halfFovRad = fov * Math.PI / 360;
181180
- const radius = Math.max(maxExtent, 0.01) / Math.tan(halfFovRad) * 0.75;
181181
- const target = [0, targetY, 0];
181182
- const elevationDeg = clamp7(view3D?.rotX ?? DEFAULT_ELEVATION_DEG, -89, 89);
181183
- const azimuthDeg = normalizeAzimuth(view3D?.rotY ?? DEFAULT_AZIMUTH_DEG);
181184
- const phi = (90 - elevationDeg) * Math.PI / 180;
181185
- const theta = azimuthDeg * Math.PI / 180;
181186
- const sinPhi = Math.sin(phi);
181187
- return {
181188
- position: [
181189
- radius * sinPhi * Math.sin(theta),
181190
- radius * Math.cos(phi) + target[1],
181191
- radius * sinPhi * Math.cos(theta)
181192
- ],
181193
- target,
181194
- fov
181195
- };
181196
- }
181197
- function computeCartesianCameraPlacement(cols, rows, view3D, horizontal = false) {
181198
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, view3D?.depthPercent);
181199
- const maxExtent = Math.max(gridWidth, gridDepth, MAX_VALUE_HEIGHT);
181200
- const placement = computeSphericalCameraPlacement(maxExtent, MAX_VALUE_HEIGHT * 0.2, view3D);
181201
- if (!horizontal) {
181202
- return placement;
181203
- }
181204
- return {
181205
- ...placement,
181206
- position: transposeForHorizontalBar3D(placement.position),
181207
- target: transposeForHorizontalBar3D(placement.target)
181208
- };
181209
- }
181210
- function buildCartesianChart3DLabels(cols, rows, categoryLabels, seriesNames, depthPercent, maxCat = 8, maxSer = 6, horizontal = false) {
181211
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
181212
- const labels = [];
181213
- const remap = (anchor) => horizontal ? transposeForHorizontalBar3D(anchor) : anchor;
181214
- const catStep = Math.max(1, Math.ceil(categoryLabels.length / maxCat));
181215
- for (let i2 = 0; i2 < categoryLabels.length; i2 += catStep) {
181216
- const x = -gridWidth / 2 + i2 / Math.max(cols - 1, 1) * gridWidth;
181217
- labels.push({
181218
- key: `cat-${i2}`,
181219
- text: categoryLabels[i2],
181220
- anchor: remap([x, -0.15, gridDepth / 2 + 0.25]),
181221
- axis: "category"
181222
- });
181223
- }
181224
- const serStep = Math.max(1, Math.ceil(seriesNames.length / maxSer));
181225
- for (let i2 = 0; i2 < seriesNames.length; i2 += serStep) {
181226
- const z = -gridDepth / 2 + i2 / Math.max(rows - 1, 1) * gridDepth;
181227
- labels.push({
181228
- key: `ser-${i2}`,
181229
- text: seriesNames[i2],
181230
- anchor: remap([gridWidth / 2 + 0.3, -0.15, z]),
181231
- axis: "series"
181232
- });
181233
- }
181234
- return labels;
181235
- }
181236
- var GRID_SPACING;
181237
- var MAX_VALUE_HEIGHT;
181238
- var DEFAULT_ELEVATION_DEG;
181239
- var DEFAULT_AZIMUTH_DEG;
181240
- var DEFAULT_PERSPECTIVE_DEG;
181241
- var FOV_MIN;
181242
- var FOV_MAX;
181243
- var RIGHT_ANGLE_FOV;
181244
- var PERSPECTIVE_MAX_DEG;
181245
- var init_cartesian_chart_3d_geom = __esm2({
181246
- "src/render/cartesian-chart-3d-geom.ts"() {
181247
- GRID_SPACING = 0.5;
181248
- MAX_VALUE_HEIGHT = 1.5;
181249
- DEFAULT_ELEVATION_DEG = 15;
181250
- DEFAULT_AZIMUTH_DEG = 20;
181251
- DEFAULT_PERSPECTIVE_DEG = 30;
181252
- FOV_MIN = 15;
181253
- FOV_MAX = 75;
181254
- RIGHT_ANGLE_FOV = 20;
181255
- PERSPECTIVE_MAX_DEG = 120;
181256
- }
181257
- });
181258
- function normalizeToHeight(value, range) {
181259
- if (range.span <= 0) {
181260
- return 0;
181261
- }
181262
- return (value - range.min) / range.span * MAX_VALUE_HEIGHT;
181263
- }
181264
- function layoutCartesianLine3DSeries(points4, cols, rows, range, depthPercent) {
181265
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
181266
- const rowStep = gridDepth / Math.max(rows, 1);
181267
- const baselineY = normalizeToHeight(0, range);
181268
- const bySeries = /* @__PURE__ */ new Map();
181269
- for (const p of points4) {
181270
- const list2 = bySeries.get(p.seriesIndex);
181271
- if (list2) {
181272
- list2.push(p);
181273
- } else {
181274
- bySeries.set(p.seriesIndex, [p]);
181275
- }
181276
- }
181277
- const paths = [];
181278
- for (const [seriesIndex, seriesPoints] of bySeries) {
181279
- const sorted = [...seriesPoints].sort((a, b) => a.categoryIndex - b.categoryIndex);
181280
- const z = -gridDepth / 2 + rowStep * (seriesIndex + 0.5);
181281
- const vertices = sorted.map((p) => {
181282
- const x = -gridWidth / 2 + p.categoryIndex / Math.max(cols - 1, 1) * gridWidth;
181283
- const y = normalizeToHeight(p.value, range);
181284
- return {
181285
- seriesIndex,
181286
- categoryIndex: p.categoryIndex,
181287
- value: p.value,
181288
- position: [x, y, z]
181289
- };
181290
- });
181291
- paths.push({
181292
- seriesIndex,
181293
- color: sorted[0]?.color ?? "#4472C4",
181294
- vertices,
181295
- depthZ: z,
181296
- baselineY
181297
- });
181298
- }
181299
- return paths.sort((a, b) => a.seriesIndex - b.seriesIndex);
181300
- }
181301
- function buildAreaRibbonTriangles(path) {
181302
- const { vertices, baselineY } = path;
181303
- const out = [];
181304
- for (let i2 = 0; i2 < vertices.length - 1; i2++) {
181305
- const [x1, y1, z1] = vertices[i2].position;
181306
- const [x2, y2, z2] = vertices[i2 + 1].position;
181307
- out.push(x1, y1, z1, x1, baselineY, z1, x2, baselineY, z2);
181308
- out.push(x1, y1, z1, x2, baselineY, z2, x2, y2, z2);
181309
- }
181310
- return out;
181311
- }
181312
- var init_cartesian_line_chart_3d_layout = __esm2({
181313
- "src/render/cartesian-line-chart-3d-layout.ts"() {
181314
- init_cartesian_chart_3d_geom();
181315
- }
181316
- });
181317
181155
  function formatValueLabel(chartData, grouping, v) {
181318
181156
  if (grouping === "percentStacked") {
181319
181157
  return `${Math.round(v * 100)}%`;
@@ -181716,1197 +181554,6 @@ var init_chart_3d_pie_layout = __esm2({
181716
181554
  RIM_SAMPLES = 96;
181717
181555
  }
181718
181556
  });
181719
- function computePieChart3DThickness(view3D) {
181720
- const scale2 = Math.min(
181721
- Math.max((view3D?.hPercent ?? 100) / 100, MIN_THICKNESS_SCALE),
181722
- MAX_THICKNESS_SCALE
181723
- );
181724
- return PIE_RADIUS * BASE_THICKNESS_RATIO * scale2;
181725
- }
181726
- function computePieChart3DCameraPlacement(view3D) {
181727
- const thickness = computePieChart3DThickness(view3D);
181728
- const maxExtent = PIE_RADIUS * CAMERA_EXTENT_MARGIN;
181729
- return computeSphericalCameraPlacement(maxExtent, thickness / 2, view3D);
181730
- }
181731
- function computePieChart3DSliceAngles(values, explosions, firstSliceAngleDeg, outerRadius) {
181732
- const total = values.reduce((s, v) => s + Math.abs(v), 0) || 1;
181733
- let cumAngle = -Math.PI / 2 + (firstSliceAngleDeg ?? 0) * Math.PI / 180;
181734
- return values.map((value, pointIndex) => {
181735
- const sliceAngle = Math.abs(value) / total * Math.PI * 2;
181736
- const startAngle = cumAngle;
181737
- cumAngle += sliceAngle;
181738
- const explosion = explosions?.[pointIndex] ?? 0;
181739
- let explodeOffset = [0, 0];
181740
- if (explosion > 0) {
181741
- const mid = (startAngle + cumAngle) / 2;
181742
- const offset = outerRadius * (explosion / 100);
181743
- explodeOffset = [Math.cos(mid) * offset, Math.sin(mid) * offset];
181744
- }
181745
- return { pointIndex, value, startAngle, thetaLength: sliceAngle, explodeOffset };
181746
- });
181747
- }
181748
- var PIE_RADIUS;
181749
- var BASE_THICKNESS_RATIO;
181750
- var MIN_THICKNESS_SCALE;
181751
- var MAX_THICKNESS_SCALE;
181752
- var CAMERA_EXTENT_MARGIN;
181753
- var init_pie_chart_3d_geom = __esm2({
181754
- "src/render/pie-chart-3d-geom.ts"() {
181755
- init_cartesian_chart_3d_geom();
181756
- PIE_RADIUS = 1;
181757
- BASE_THICKNESS_RATIO = 0.3;
181758
- MIN_THICKNESS_SCALE = 0.05;
181759
- MAX_THICKNESS_SCALE = 3;
181760
- CAMERA_EXTENT_MARGIN = 1.35;
181761
- }
181762
- });
181763
- function computeGridExtent(cols, rows) {
181764
- return {
181765
- gridWidth: Math.max(cols - 1, 1) * GRID_SPACING2,
181766
- gridDepth: Math.max(rows - 1, 1) * GRID_SPACING2
181767
- };
181768
- }
181769
- function buildSurfaceGeometry(three, cols, rows, heightMap, colorMap) {
181770
- const widthSegs = Math.max(cols - 1, 0);
181771
- const depthSegs = Math.max(rows - 1, 0);
181772
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181773
- const geo = new three.PlaneGeometry(gridWidth, gridDepth, widthSegs, depthSegs);
181774
- geo.rotateX(-Math.PI / 2);
181775
- const pos2 = geo.attributes.position;
181776
- const vertexCount = pos2.count;
181777
- const colors = new Float32Array(vertexCount * 3);
181778
- for (let i2 = 0; i2 < vertexCount; i2++) {
181779
- const row = Math.floor(i2 / cols);
181780
- const col = i2 % cols;
181781
- const idx = row * cols + col;
181782
- const h2 = idx < heightMap.length ? heightMap[idx] : 0;
181783
- pos2.setY(i2, h2 * MAX_HEIGHT);
181784
- const ci = idx * 3;
181785
- colors[i2 * 3] = ci < colorMap.length ? colorMap[ci] : 0.5;
181786
- colors[i2 * 3 + 1] = ci + 1 < colorMap.length ? colorMap[ci + 1] : 0.5;
181787
- colors[i2 * 3 + 2] = ci + 2 < colorMap.length ? colorMap[ci + 2] : 0.5;
181788
- }
181789
- geo.setAttribute("color", new three.BufferAttribute(colors, 3));
181790
- geo.computeVertexNormals();
181791
- pos2.needsUpdate = true;
181792
- const wireGeometry = new three.WireframeGeometry(geo);
181793
- return { geometry: geo, wireGeometry };
181794
- }
181795
- function surfaceVertexWorldPosition(cols, rows, row, col, heightMap) {
181796
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181797
- const x = col * GRID_SPACING2 - gridWidth / 2;
181798
- const z = row * GRID_SPACING2 - gridDepth / 2;
181799
- const idx = row * cols + col;
181800
- const h2 = idx >= 0 && idx < heightMap.length ? heightMap[idx] : 0;
181801
- return [x, h2 * MAX_HEIGHT, z];
181802
- }
181803
- function buildSurfaceLabels(cols, rows, categoryLabels, seriesNames, maxCat = 8, maxSer = 6) {
181804
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181805
- const labels = [];
181806
- const catStep = Math.max(1, Math.ceil(categoryLabels.length / maxCat));
181807
- for (let i2 = 0; i2 < categoryLabels.length; i2 += catStep) {
181808
- const x = -gridWidth / 2 + i2 / Math.max(cols - 1, 1) * gridWidth;
181809
- labels.push({
181810
- key: `cat-${i2}`,
181811
- text: categoryLabels[i2],
181812
- anchor: [x, -0.15, gridDepth / 2 + 0.25],
181813
- axis: "category"
181814
- });
181815
- }
181816
- const serStep = Math.max(1, Math.ceil(seriesNames.length / maxSer));
181817
- for (let i2 = 0; i2 < seriesNames.length; i2 += serStep) {
181818
- const z = -gridDepth / 2 + i2 / Math.max(rows - 1, 1) * gridDepth;
181819
- labels.push({
181820
- key: `ser-${i2}`,
181821
- text: seriesNames[i2],
181822
- anchor: [gridWidth / 2 + 0.3, -0.15, z],
181823
- axis: "series"
181824
- });
181825
- }
181826
- labels.push({
181827
- key: "value-axis",
181828
- text: "Value",
181829
- anchor: [-gridWidth / 2 - 0.35, 0.75, -gridDepth / 2],
181830
- axis: "value"
181831
- });
181832
- return labels;
181833
- }
181834
- function clamp9(value, min, max) {
181835
- return Math.min(Math.max(value, min), max);
181836
- }
181837
- function normalizeAzimuth2(deg3) {
181838
- const wrapped = deg3 % 360;
181839
- return wrapped < 0 ? wrapped + 360 : wrapped;
181840
- }
181841
- function computeCameraPlacement(cols, rows, view3D) {
181842
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
181843
- const maxExtent = Math.max(gridWidth, gridDepth, MAX_HEIGHT);
181844
- const dist2 = maxExtent * 1.8;
181845
- const target = [0, 0.3, 0];
181846
- if (!view3D || view3D.rotX === void 0 && view3D.rotY === void 0) {
181847
- return { position: [dist2 * 0.8, dist2 * 0.7, dist2 * 0.8], target };
181848
- }
181849
- const radius = dist2 * RADIUS_FACTOR;
181850
- const elevationDeg = clamp9(view3D.rotX ?? DEFAULT_ELEVATION_DEG2, -89, 89);
181851
- const azimuthDeg = normalizeAzimuth2(view3D.rotY ?? DEFAULT_AZIMUTH_DEG2);
181852
- const phi = (90 - elevationDeg) * Math.PI / 180;
181853
- const theta = azimuthDeg * Math.PI / 180;
181854
- const sinPhi = Math.sin(phi);
181855
- return {
181856
- position: [
181857
- radius * sinPhi * Math.sin(theta),
181858
- radius * Math.cos(phi),
181859
- radius * sinPhi * Math.cos(theta)
181860
- ],
181861
- target
181862
- };
181863
- }
181864
- var GRID_SPACING2;
181865
- var MAX_HEIGHT;
181866
- var DEFAULT_ELEVATION_DEG2;
181867
- var DEFAULT_AZIMUTH_DEG2;
181868
- var RADIUS_FACTOR;
181869
- var init_surface_chart_3d_geom = __esm2({
181870
- "src/render/surface-chart-3d-geom.ts"() {
181871
- GRID_SPACING2 = 0.5;
181872
- MAX_HEIGHT = 1.5;
181873
- DEFAULT_ELEVATION_DEG2 = 15;
181874
- DEFAULT_AZIMUTH_DEG2 = 20;
181875
- RADIUS_FACTOR = Math.sqrt(0.8 ** 2 + 0.7 ** 2 + 0.8 ** 2);
181876
- }
181877
- });
181878
- function createHostedChart3DStage(ctx, placement, limits, ambientIntensity = 0.6) {
181879
- const three = ctx.three;
181880
- const width = Math.max(1, ctx.size.width);
181881
- const height = Math.max(1, ctx.size.height);
181882
- const scene = new three.Scene();
181883
- scene.add(new three.AmbientLight(16777215, ambientIntensity));
181884
- const key2 = new three.DirectionalLight(16777215, 0.8);
181885
- key2.position.set(5, 8, 5);
181886
- scene.add(key2);
181887
- const fill = new three.DirectionalLight(16777215, 0.3);
181888
- fill.position.set(-3, 4, -2);
181889
- scene.add(fill);
181890
- const camera = new three.PerspectiveCamera(placement.fov, width / height, 0.1, 1e3);
181891
- camera.position.set(...placement.position);
181892
- const target = new three.Vector3(...placement.target);
181893
- camera.lookAt(target);
181894
- let orbit = null;
181895
- if (ctx.OrbitControls) {
181896
- orbit = new ctx.OrbitControls(camera, ctx.eventTarget);
181897
- const limited = orbit;
181898
- limited.enablePan = true;
181899
- limited.enableZoom = true;
181900
- limited.enableRotate = true;
181901
- limited.minDistance = limits.minDistance;
181902
- limited.maxDistance = limits.maxDistance;
181903
- limited.maxPolarAngle = Math.PI / 2 + 0.3;
181904
- limited.target.copy(target);
181905
- limited.enabled = ctx.interactive;
181906
- limited.update();
181907
- }
181908
- return {
181909
- three,
181910
- canvas: ctx.eventTarget,
181911
- scene,
181912
- camera,
181913
- controls: orbit ?? { enabled: false },
181914
- orbit,
181915
- width,
181916
- height
181917
- };
181918
- }
181919
- function hostedChart3DInteraction(ctx) {
181920
- let interactive = ctx.interactive;
181921
- return {
181922
- onSelect: (part) => {
181923
- if (interactive) {
181924
- ctx.emit({ type: "select", part });
181925
- }
181926
- },
181927
- onValueDragPreview: (part, value) => {
181928
- if (interactive) {
181929
- ctx.emit({ type: "drag", detail: { part, value, phase: "move" } });
181930
- }
181931
- },
181932
- onValueDragCommit: (part, value) => {
181933
- if (interactive) {
181934
- ctx.emit({ type: "drag", detail: { part, value, phase: "commit" } });
181935
- }
181936
- },
181937
- set: (on) => {
181938
- interactive = on;
181939
- }
181940
- };
181941
- }
181942
- function finishHostedChart3DScene(ctx, stage, parts, interactive) {
181943
- let width = stage.width;
181944
- let height = stage.height;
181945
- const requestRender = () => ctx.requestRender();
181946
- stage.orbit?.addEventListener("change", requestRender);
181947
- for (const type of REDRAW_EVENTS) {
181948
- ctx.eventTarget.addEventListener(type, requestRender);
181949
- }
181950
- let disposed = false;
181951
- return {
181952
- render(renderer) {
181953
- stage.orbit?.update();
181954
- renderer.render(stage.scene, stage.camera);
181955
- parts.afterRender?.(stage.camera, width, height);
181956
- },
181957
- resize(size) {
181958
- width = Math.max(1, size.width);
181959
- height = Math.max(1, size.height);
181960
- stage.camera.aspect = width / height;
181961
- stage.camera.updateProjectionMatrix();
181962
- parts.resize?.(width, height);
181963
- },
181964
- isAnimating: () => false,
181965
- setInteractive(on) {
181966
- interactive.set(on);
181967
- if (stage.orbit) {
181968
- stage.orbit.enabled = on;
181969
- }
181970
- },
181971
- setSelectedPart(part) {
181972
- parts.setSelectedPart?.(part);
181973
- },
181974
- setTextStyle(style) {
181975
- parts.setTextStyle?.(style);
181976
- },
181977
- dispose() {
181978
- if (disposed) {
181979
- return;
181980
- }
181981
- disposed = true;
181982
- stage.orbit?.removeEventListener("change", requestRender);
181983
- for (const type of REDRAW_EVENTS) {
181984
- ctx.eventTarget.removeEventListener(type, requestRender);
181985
- }
181986
- stage.orbit?.dispose();
181987
- parts.dispose();
181988
- stage.scene.clear();
181989
- }
181990
- };
181991
- }
181992
- var REDRAW_EVENTS;
181993
- var init_chart_3d_hosted_stage = __esm2({
181994
- "src/render/chart-3d-hosted-stage.ts"() {
181995
- REDRAW_EVENTS = ["pointermove", "pointerdown", "pointerup", "pointerleave", "wheel"];
181996
- }
181997
- });
181998
- function attachChart3DHoverTooltip(options) {
181999
- const raycaster = new options.three.Raycaster();
182000
- const ndc = new options.three.Vector2();
182001
- let hoveredTooltip;
182002
- const updateHoverTooltip = (clientX, clientY) => {
182003
- const rect22 = options.canvas.getBoundingClientRect();
182004
- if (rect22.width <= 0 || rect22.height <= 0) {
182005
- return;
182006
- }
182007
- ndc.x = (clientX - rect22.left) / rect22.width * 2 - 1;
182008
- ndc.y = -((clientY - rect22.top) / rect22.height) * 2 + 1;
182009
- raycaster.setFromCamera(ndc, options.camera);
182010
- const hit = raycaster.intersectObjects(options.meshes, false)[0];
182011
- const tooltip = options.buildTooltip(hit);
182012
- if (tooltip !== hoveredTooltip) {
182013
- hoveredTooltip = tooltip;
182014
- options.canvas.title = tooltip ?? "";
182015
- }
182016
- };
182017
- const onPointerMove = (event) => {
182018
- updateHoverTooltip(event.clientX, event.clientY);
182019
- };
182020
- const onPointerLeave = () => {
182021
- if (hoveredTooltip !== void 0) {
182022
- hoveredTooltip = void 0;
182023
- options.canvas.title = "";
182024
- }
182025
- };
182026
- options.canvas.addEventListener("pointermove", onPointerMove);
182027
- options.canvas.addEventListener("pointerleave", onPointerLeave);
182028
- return {
182029
- dispose() {
182030
- options.canvas.removeEventListener("pointermove", onPointerMove);
182031
- options.canvas.removeEventListener("pointerleave", onPointerLeave);
182032
- }
182033
- };
182034
- }
182035
- var init_chart_3d_hover_tooltip = __esm2({
182036
- "src/render/chart-3d-hover-tooltip.ts"() {
182037
- }
182038
- });
182039
- function createLabelOverlay(doc, labels) {
182040
- const layer = doc.createElement("div");
182041
- Object.assign(layer.style, {
182042
- position: "absolute",
182043
- inset: "0",
182044
- pointerEvents: "none",
182045
- overflow: "hidden"
182046
- });
182047
- const entries2 = labels.map((label) => {
182048
- const node = doc.createElement("div");
182049
- node.textContent = label.text;
182050
- const baseColor = label.axis === "value" ? "#999" : "#666";
182051
- Object.assign(node.style, {
182052
- position: "absolute",
182053
- fontSize: `${BASE_FONT_SIZE_PX}px`,
182054
- color: baseColor,
182055
- whiteSpace: "nowrap",
182056
- userSelect: "none",
182057
- transform: "translate(-50%, -50%)",
182058
- willChange: "left, top"
182059
- });
182060
- if (label.axis === "value") {
182061
- node.style.writingMode = "vertical-rl";
182062
- }
182063
- layer.appendChild(node);
182064
- return { node, baseColor };
182065
- });
182066
- function applyTextStyle(style) {
182067
- for (const { node, baseColor } of entries2) {
182068
- node.style.fontWeight = style?.bold === void 0 ? "" : style.bold ? "bold" : "normal";
182069
- node.style.fontStyle = style?.italic === void 0 ? "" : style.italic ? "italic" : "normal";
182070
- node.style.textDecorationLine = style?.underline === void 0 ? "" : style.underline ? "underline" : "none";
182071
- const scale2 = typeof style?.fontScale === "number" && Number.isFinite(style.fontScale) && style.fontScale > 0 ? style.fontScale : 1;
182072
- node.style.fontSize = `${BASE_FONT_SIZE_PX * scale2}px`;
182073
- node.style.color = style?.color ?? baseColor;
182074
- }
182075
- }
182076
- return { layer, nodes: entries2.map((e) => e.node), applyTextStyle };
182077
- }
182078
- var BASE_FONT_SIZE_PX;
182079
- var init_surface_chart_3d_label_overlay = __esm2({
182080
- "src/render/surface-chart-3d-label-overlay.ts"() {
182081
- BASE_FONT_SIZE_PX = 9;
182082
- }
182083
- });
182084
- function createChart3DLabelProjector(three, doc, labels) {
182085
- const overlay = createLabelOverlay(doc, labels);
182086
- const anchors = labels.map((l) => new three.Vector3(...l.anchor));
182087
- const projected = new three.Vector3();
182088
- return {
182089
- layer: overlay.layer,
182090
- applyTextStyle: overlay.applyTextStyle,
182091
- update(camera, width, height) {
182092
- for (let i2 = 0; i2 < overlay.nodes.length; i2++) {
182093
- projected.copy(anchors[i2]).project(camera);
182094
- const node = overlay.nodes[i2];
182095
- if (projected.z > 1) {
182096
- node.style.display = "none";
182097
- continue;
182098
- }
182099
- node.style.display = "";
182100
- node.style.left = `${(projected.x + 1) / 2 * width}px`;
182101
- node.style.top = `${(-projected.y + 1) / 2 * height}px`;
182102
- }
182103
- }
182104
- };
182105
- }
182106
- var init_chart_3d_label_projection = __esm2({
182107
- "src/render/chart-3d-label-projection.ts"() {
182108
- init_surface_chart_3d_label_overlay();
182109
- }
182110
- });
182111
- function surfaceFaceIndexToCell(faceIndex, cols, rows) {
182112
- const quadsPerRow = cols - 1;
182113
- const quadsPerCol = rows - 1;
182114
- if (!Number.isFinite(faceIndex) || faceIndex < 0 || quadsPerRow <= 0 || quadsPerCol <= 0) {
182115
- return null;
182116
- }
182117
- const quadIndex = Math.floor(faceIndex / 2);
182118
- const row = Math.floor(quadIndex / quadsPerRow);
182119
- const col = quadIndex % quadsPerRow;
182120
- if (row < 0 || row >= quadsPerCol || col < 0 || col >= quadsPerRow) {
182121
- return null;
182122
- }
182123
- return { row, col };
182124
- }
182125
- function buildSurfaceHoverTooltip(faceIndex, data) {
182126
- if (faceIndex === void 0 || faceIndex === null || !data.values) {
182127
- return void 0;
182128
- }
182129
- const cell = surfaceFaceIndexToCell(faceIndex, data.cols, data.rows);
182130
- if (!cell) {
182131
- return void 0;
182132
- }
182133
- const idx = cell.row * data.cols + cell.col;
182134
- const value = data.values[idx];
182135
- if (value === void 0) {
182136
- return void 0;
182137
- }
182138
- return buildMarkTooltip(
182139
- data.seriesNames[cell.row],
182140
- data.categoryLabels[cell.col],
182141
- value,
182142
- data.numberFormats?.[cell.row]
182143
- );
182144
- }
182145
- var init_surface_chart_3d_hit_test = __esm2({
182146
- "src/render/surface-chart-3d-hit-test.ts"() {
182147
- init_chart_view_model();
182148
- }
182149
- });
182150
- function chart3DHitToPartRef(hit) {
182151
- if (!hit) {
182152
- return null;
182153
- }
182154
- return { role: "dataPoint", seriesIndex: hit.seriesIndex, pointIndex: hit.pointIndex };
182155
- }
182156
- function chart3DMarkMatchesPart(mark, part) {
182157
- return part !== null && part !== void 0 && part.role === "dataPoint" && part.seriesIndex === mark.seriesIndex && part.pointIndex === mark.pointIndex;
182158
- }
182159
- function calibrateChart3DValueAxis(screenAtValue0, value0, screenAtValue1, value1) {
182160
- const valueSpan = value1 - value0;
182161
- const dx = screenAtValue1.x - screenAtValue0.x;
182162
- const dy = screenAtValue1.y - screenAtValue0.y;
182163
- const pixelSpan = Math.hypot(dx, dy);
182164
- if (valueSpan === 0 || pixelSpan < 1e-6 || !Number.isFinite(valueSpan)) {
182165
- return null;
182166
- }
182167
- return {
182168
- directionScreen: { x: dx / pixelSpan, y: dy / pixelSpan },
182169
- pixelsPerUnit: pixelSpan / valueSpan
182170
- };
182171
- }
182172
- function chart3DPointerDeltaToValueDelta(calibration, pointerDeltaScreen) {
182173
- const dot2 = pointerDeltaScreen.x * calibration.directionScreen.x + pointerDeltaScreen.y * calibration.directionScreen.y;
182174
- return dot2 / calibration.pixelsPerUnit;
182175
- }
182176
- var CHART_3D_DRAG_THRESHOLD_PX;
182177
- var CHART_3D_SELECTED_EMISSIVE;
182178
- var CHART_3D_SELECTED_EMISSIVE_INTENSITY;
182179
- var init_chart_3d_interaction = __esm2({
182180
- "src/render/chart-3d-interaction.ts"() {
182181
- CHART_3D_DRAG_THRESHOLD_PX = 3;
182182
- CHART_3D_SELECTED_EMISSIVE = "#3b82f6";
182183
- CHART_3D_SELECTED_EMISSIVE_INTENSITY = 0.55;
182184
- }
182185
- });
182186
- function projectToScreen(three, camera, point, width, height) {
182187
- const v = new three.Vector3(point[0], point[1], point[2]);
182188
- v.project(camera);
182189
- return { x: (v.x + 1) / 2 * width, y: (-v.y + 1) / 2 * height };
182190
- }
182191
- function attachChart3DPointerInteraction(options) {
182192
- let width = options.width;
182193
- let height = options.height;
182194
- const raycaster = new options.three.Raycaster();
182195
- const ndc = new options.three.Vector2();
182196
- let dragState = null;
182197
- function raycastAt(clientX, clientY) {
182198
- const rect22 = options.canvas.getBoundingClientRect();
182199
- if (rect22.width <= 0 || rect22.height <= 0) {
182200
- return void 0;
182201
- }
182202
- ndc.x = (clientX - rect22.left) / rect22.width * 2 - 1;
182203
- ndc.y = -((clientY - rect22.top) / rect22.height) * 2 + 1;
182204
- raycaster.setFromCamera(ndc, options.camera);
182205
- return raycaster.intersectObjects(options.meshes, false)[0];
182206
- }
182207
- function setSelectedPart(part) {
182208
- options.applyHighlight?.(part);
182209
- }
182210
- function currentDelta(clientX, clientY, state) {
182211
- return { x: clientX - state.startClientX, y: clientY - state.startClientY };
182212
- }
182213
- const onPointerDown = (event) => {
182214
- options.canvas.setPointerCapture?.(
182215
- event.pointerId
182216
- );
182217
- const hit = raycastAt(event.clientX, event.clientY);
182218
- const part = hit ? options.resolveHit(hit) : null;
182219
- const armed = part !== null && isChartInteractionArmed(options.canvas);
182220
- if (armed) {
182221
- event.stopPropagation();
182222
- }
182223
- let calibration = null;
182224
- let startValue = 0;
182225
- if (hit && part && armed && options.calibrateDrag) {
182226
- const input = options.calibrateDrag(hit, part);
182227
- if (input) {
182228
- const s0 = projectToScreen(
182229
- options.three,
182230
- options.camera,
182231
- input.worldAtValue0,
182232
- width,
182233
- height
182234
- );
182235
- const s1 = projectToScreen(
182236
- options.three,
182237
- options.camera,
182238
- input.worldAtValue1,
182239
- width,
182240
- height
182241
- );
182242
- calibration = calibrateChart3DValueAxis(s0, input.value0, s1, input.value1);
182243
- startValue = input.value1;
182244
- }
182245
- }
182246
- dragState = {
182247
- part,
182248
- calibration,
182249
- startValue,
182250
- startClientX: event.clientX,
182251
- startClientY: event.clientY,
182252
- moved: false
182253
- };
182254
- if (calibration) {
182255
- event.preventDefault();
182256
- options.setControlsEnabled?.(false);
182257
- }
182258
- };
182259
- const onPointerMove = (event) => {
182260
- if (!dragState || !dragState.part || !dragState.calibration) {
182261
- return;
182262
- }
182263
- const delta = currentDelta(event.clientX, event.clientY, dragState);
182264
- if (!dragState.moved && Math.hypot(delta.x, delta.y) < CHART_3D_DRAG_THRESHOLD_PX) {
182265
- return;
182266
- }
182267
- dragState.moved = true;
182268
- const value = dragState.startValue + chart3DPointerDeltaToValueDelta(dragState.calibration, delta);
182269
- options.onValueDragPreview?.(dragState.part, value);
182270
- };
182271
- const onPointerUp = (event) => {
182272
- if (!dragState) {
182273
- return;
182274
- }
182275
- const state = dragState;
182276
- dragState = null;
182277
- options.canvas.releasePointerCapture?.(event.pointerId);
182278
- if (state.calibration) {
182279
- options.setControlsEnabled?.(true);
182280
- }
182281
- if (state.moved && state.part && state.calibration) {
182282
- const delta = currentDelta(event.clientX, event.clientY, state);
182283
- const value = state.startValue + chart3DPointerDeltaToValueDelta(state.calibration, delta);
182284
- options.onValueDragCommit?.(state.part, value);
182285
- return;
182286
- }
182287
- setSelectedPart(state.part);
182288
- options.onSelect?.(state.part);
182289
- };
182290
- options.canvas.addEventListener("pointerdown", onPointerDown);
182291
- options.canvas.addEventListener("pointermove", onPointerMove);
182292
- options.canvas.addEventListener("pointerup", onPointerUp);
182293
- options.canvas.addEventListener("pointercancel", onPointerUp);
182294
- return {
182295
- setSelectedPart,
182296
- updateSize(w, h2) {
182297
- width = w;
182298
- height = h2;
182299
- },
182300
- dispose() {
182301
- options.canvas.removeEventListener("pointerdown", onPointerDown);
182302
- options.canvas.removeEventListener("pointermove", onPointerMove);
182303
- options.canvas.removeEventListener("pointerup", onPointerUp);
182304
- options.canvas.removeEventListener("pointercancel", onPointerUp);
182305
- }
182306
- };
182307
- }
182308
- var init_chart_3d_pointer_interaction = __esm2({
182309
- "src/render/chart-3d-pointer-interaction.ts"() {
182310
- init_chart_3d_interaction();
182311
- init_chart_canvas_drag();
182312
- }
182313
- });
182314
- function calibrateSurfaceChart3DDrag(position2, value, values) {
182315
- let min = Infinity;
182316
- let max = -Infinity;
182317
- for (const v of values) {
182318
- if (v < min) {
182319
- min = v;
182320
- }
182321
- if (v > max) {
182322
- max = v;
182323
- }
182324
- }
182325
- if (!(max > min)) {
182326
- return null;
182327
- }
182328
- const [x, , z] = position2;
182329
- const atMin = value === min;
182330
- return {
182331
- worldAtValue0: [x, atMin ? MAX_HEIGHT : 0, z],
182332
- value0: atMin ? max : min,
182333
- worldAtValue1: position2,
182334
- value1: value
182335
- };
182336
- }
182337
- var init_surface_chart_3d_drag = __esm2({
182338
- "src/render/surface-chart-3d-drag.ts"() {
182339
- init_surface_chart_3d_geom();
182340
- }
182341
- });
182342
- function createSurfaceHighlightMarker(three, cols, rows, heightMap) {
182343
- const geometry = new three.SphereGeometry(MARKER_RADIUS, 12, 8);
182344
- const material = new three.MeshPhongMaterial({
182345
- color: CHART_3D_SELECTED_EMISSIVE,
182346
- emissive: CHART_3D_SELECTED_EMISSIVE,
182347
- emissiveIntensity: CHART_3D_SELECTED_EMISSIVE_INTENSITY,
182348
- shininess: 30
182349
- });
182350
- const mesh = new three.Mesh(geometry, material);
182351
- mesh.visible = false;
182352
- return {
182353
- mesh,
182354
- setSelected(cell) {
182355
- if (!cell) {
182356
- mesh.visible = false;
182357
- return;
182358
- }
182359
- const [x, y, z] = surfaceVertexWorldPosition(cols, rows, cell.row, cell.col, heightMap);
182360
- mesh.position.set(x, y + MARKER_Y_OFFSET, z);
182361
- mesh.visible = true;
182362
- },
182363
- dispose() {
182364
- geometry.dispose();
182365
- material.dispose();
182366
- }
182367
- };
182368
- }
182369
- function cellFromIntersection(intersection, cols, rows) {
182370
- return intersection.faceIndex === void 0 || intersection.faceIndex === null ? null : surfaceFaceIndexToCell(intersection.faceIndex, cols, rows);
182371
- }
182372
- function attachSurfaceChart3DInteraction(params) {
182373
- return attachChart3DPointerInteraction({
182374
- three: params.three,
182375
- canvas: params.canvas,
182376
- camera: params.camera,
182377
- width: params.width,
182378
- height: params.height,
182379
- meshes: [params.surfaceMesh],
182380
- resolveHit: (intersection) => {
182381
- const cell = cellFromIntersection(intersection, params.cols, params.rows);
182382
- return chart3DHitToPartRef(cell ? { seriesIndex: cell.row, pointIndex: cell.col } : null);
182383
- },
182384
- calibrateDrag: (intersection) => {
182385
- const cell = cellFromIntersection(intersection, params.cols, params.rows);
182386
- if (!cell || !params.values) {
182387
- return null;
182388
- }
182389
- const idx = cell.row * params.cols + cell.col;
182390
- const value = params.values[idx];
182391
- if (value === void 0) {
182392
- return null;
182393
- }
182394
- const position2 = surfaceVertexWorldPosition(
182395
- params.cols,
182396
- params.rows,
182397
- cell.row,
182398
- cell.col,
182399
- params.heightMap
182400
- );
182401
- return calibrateSurfaceChart3DDrag(position2, value, params.values);
182402
- },
182403
- applyHighlight: (part) => {
182404
- const cell = part && part.role === "dataPoint" && part.pointIndex !== void 0 ? { row: part.seriesIndex, col: part.pointIndex } : null;
182405
- params.highlightMarker.setSelected(cell);
182406
- },
182407
- setControlsEnabled: (enabled) => {
182408
- params.controls.enabled = enabled;
182409
- },
182410
- onSelect: params.interaction?.onSelect,
182411
- onValueDragPreview: params.interaction?.onValueDragPreview,
182412
- onValueDragCommit: params.interaction?.onValueDragCommit
182413
- });
182414
- }
182415
- var MARKER_RADIUS;
182416
- var MARKER_Y_OFFSET;
182417
- var init_surface_chart_3d_interaction_wiring = __esm2({
182418
- "src/render/surface-chart-3d-interaction-wiring.ts"() {
182419
- init_chart_3d_interaction();
182420
- init_chart_3d_pointer_interaction();
182421
- init_surface_chart_3d_drag();
182422
- init_surface_chart_3d_geom();
182423
- init_surface_chart_3d_hit_test();
182424
- MARKER_RADIUS = 0.07;
182425
- MARKER_Y_OFFSET = 0.03;
182426
- }
182427
- });
182428
- function buildSurfaceWallMeshes(three, cols, rows, wallHeight, colors, extent) {
182429
- const { gridWidth, gridDepth } = extent ?? computeGridExtent(cols, rows);
182430
- const meshes = [];
182431
- const disposables = [];
182432
- const addPlane = (width, height, color2, position2, rotation) => {
182433
- const geometry = new three.PlaneGeometry(width, height);
182434
- const material = new three.MeshBasicMaterial({
182435
- color: color2,
182436
- transparent: true,
182437
- opacity: PANEL_OPACITY,
182438
- side: three.DoubleSide,
182439
- depthWrite: false
182440
- });
182441
- const mesh = new three.Mesh(geometry, material);
182442
- mesh.position.set(...position2);
182443
- mesh.rotation.set(...rotation);
182444
- meshes.push(mesh);
182445
- disposables.push(geometry, material);
182446
- };
182447
- if (colors.floor) {
182448
- addPlane(gridWidth, gridDepth, colors.floor, [0, -0.01, 0], [-Math.PI / 2, 0, 0]);
182449
- }
182450
- if (colors.backWall) {
182451
- addPlane(
182452
- gridWidth,
182453
- wallHeight,
182454
- colors.backWall,
182455
- [0, wallHeight / 2, -gridDepth / 2],
182456
- [0, 0, 0]
182457
- );
182458
- }
182459
- if (colors.sideWall) {
182460
- addPlane(
182461
- gridDepth,
182462
- wallHeight,
182463
- colors.sideWall,
182464
- [gridWidth / 2, wallHeight / 2, 0],
182465
- [0, Math.PI / 2, 0]
182466
- );
182467
- }
182468
- return {
182469
- meshes,
182470
- dispose: () => {
182471
- for (const d of disposables) {
182472
- d.dispose();
182473
- }
182474
- }
182475
- };
182476
- }
182477
- var PANEL_OPACITY;
182478
- var init_surface_chart_3d_walls = __esm2({
182479
- "src/render/surface-chart-3d-walls.ts"() {
182480
- init_surface_chart_3d_geom();
182481
- PANEL_OPACITY = 0.35;
182482
- }
182483
- });
182484
- function createSurfaceChart3DScene(ctx, options) {
182485
- const { cols, rows } = options;
182486
- const placement = computeCameraPlacement(cols, rows, options.view3D);
182487
- const stage = createHostedChart3DStage(
182488
- ctx,
182489
- { fov: FOV2, ...placement },
182490
- { minDistance: 1, maxDistance: 20 },
182491
- 0.6
182492
- );
182493
- const { three, scene, camera, canvas, controls, width, height } = stage;
182494
- const interaction = hostedChart3DInteraction(ctx);
182495
- const { gridWidth, gridDepth } = computeGridExtent(cols, rows);
182496
- const floorSize = Math.max(gridWidth, gridDepth) * 1.2;
182497
- const gridFloor = new three.GridHelper(floorSize, Math.max(cols, rows), 13421772, 15263976);
182498
- gridFloor.position.y = -0.02;
182499
- scene.add(gridFloor);
182500
- const walls = options.surfaceColors ? buildSurfaceWallMeshes(three, cols, rows, MAX_HEIGHT, options.surfaceColors) : null;
182501
- for (const mesh of walls?.meshes ?? []) {
182502
- scene.add(mesh);
182503
- }
182504
- const { heightMap, colorMap } = options;
182505
- const { geometry, wireGeometry } = buildSurfaceGeometry(three, cols, rows, heightMap, colorMap);
182506
- const surfaceMaterial = new three.MeshPhongMaterial({
182507
- vertexColors: true,
182508
- side: three.DoubleSide,
182509
- shininess: 30,
182510
- transparent: true,
182511
- opacity: 0.92
182512
- });
182513
- const surfaceMesh = new three.Mesh(geometry, surfaceMaterial);
182514
- scene.add(surfaceMesh);
182515
- const highlightMarker = createSurfaceHighlightMarker(three, cols, rows, heightMap);
182516
- scene.add(highlightMarker.mesh);
182517
- let wireMaterial = null;
182518
- if (options.wireframe) {
182519
- wireMaterial = new three.LineBasicMaterial({
182520
- color: 3355443,
182521
- transparent: true,
182522
- opacity: 0.25
182523
- });
182524
- scene.add(new three.LineSegments(wireGeometry, wireMaterial));
182525
- }
182526
- const hoverTooltip = attachChart3DHoverTooltip({
182527
- three,
182528
- canvas,
182529
- camera,
182530
- meshes: [surfaceMesh],
182531
- buildTooltip: (intersection) => buildSurfaceHoverTooltip(intersection?.faceIndex, {
182532
- cols,
182533
- rows,
182534
- categoryLabels: options.categoryLabels,
182535
- seriesNames: options.seriesNames,
182536
- values: options.values,
182537
- numberFormats: options.numberFormats
182538
- })
182539
- });
182540
- const pointerInteraction = attachSurfaceChart3DInteraction({
182541
- three,
182542
- canvas,
182543
- camera,
182544
- controls,
182545
- width,
182546
- height,
182547
- surfaceMesh,
182548
- cols,
182549
- rows,
182550
- heightMap,
182551
- values: options.values,
182552
- highlightMarker,
182553
- interaction
182554
- });
182555
- const labels = buildSurfaceLabels(cols, rows, options.categoryLabels, options.seriesNames);
182556
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
182557
- labelProjector.applyTextStyle(options.textStyle);
182558
- ctx.overlay.appendChild(labelProjector.layer);
182559
- return finishHostedChart3DScene(
182560
- ctx,
182561
- stage,
182562
- {
182563
- afterRender: (cam, w, h2) => labelProjector.update(cam, w, h2),
182564
- resize: (w, h2) => pointerInteraction.updateSize(w, h2),
182565
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
182566
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
182567
- dispose() {
182568
- hoverTooltip.dispose();
182569
- pointerInteraction.dispose();
182570
- geometry.dispose();
182571
- wireGeometry.dispose();
182572
- surfaceMaterial.dispose();
182573
- wireMaterial?.dispose();
182574
- highlightMarker.dispose();
182575
- gridFloor.dispose();
182576
- walls?.dispose();
182577
- labelProjector.layer.remove();
182578
- }
182579
- },
182580
- interaction
182581
- );
182582
- }
182583
- var FOV2;
182584
- var init_surface_chart_3d_scene = __esm2({
182585
- "src/render/surface-chart-3d-scene.ts"() {
182586
- init_chart_3d_hosted_stage();
182587
- init_chart_3d_hover_tooltip();
182588
- init_chart_3d_label_projection();
182589
- init_surface_chart_3d_geom();
182590
- init_surface_chart_3d_hit_test();
182591
- init_surface_chart_3d_interaction_wiring();
182592
- init_surface_chart_3d_walls();
182593
- FOV2 = 45;
182594
- }
182595
- });
182596
- function colorFace(color2) {
182597
- return { kind: "color", color: color2 };
182598
- }
182599
- function worldHeightPerValueUnit(box) {
182600
- return box.value !== 0 ? box.size[1] / box.value : void 0;
182601
- }
182602
- function faceRepeat(format2, pictureStackUnit, faceWorldSize, box) {
182603
- if (format2 === "stretch" || pictureStackUnit === void 0 || pictureStackUnit <= 0) {
182604
- return 1;
182605
- }
182606
- const perValueUnit = worldHeightPerValueUnit(box);
182607
- if (!perValueUnit) {
182608
- return 1;
182609
- }
182610
- const tileWorldSize = pictureStackUnit * perValueUnit;
182611
- return tileWorldSize > 0 ? Math.max(1, faceWorldSize / tileWorldSize) : 1;
182612
- }
182613
- function resolveTargetedFace(series, box, face, faceWorldSize, untargetedFallback) {
182614
- const resolved = resolveDataPointPictureFill(series, box.categoryIndex, box.seriesIndex, face);
182615
- if (!resolved) {
182616
- return colorFace(untargetedFallback);
182617
- }
182618
- const pictureStackUnit = resolveActiveDataPointPicture(
182619
- series,
182620
- box.categoryIndex
182621
- )?.pictureStackUnit;
182622
- return {
182623
- kind: "picture",
182624
- imageUrl: resolved.imageUrl,
182625
- repeatX: 1,
182626
- repeatY: faceRepeat(resolved.format, pictureStackUnit, faceWorldSize, box)
182627
- };
182628
- }
182629
- function allSameColor(fills) {
182630
- const first = fills[0];
182631
- if (!first || first.kind !== "color") {
182632
- return void 0;
182633
- }
182634
- return fills.every((fill) => fill.kind === "color" && fill.color === first.color) ? first.color : void 0;
182635
- }
182636
- function resolveBarBoxFaceFills(box, series) {
182637
- const plain = {
182638
- posX: colorFace(box.color),
182639
- negX: colorFace(box.color),
182640
- posY: colorFace(box.color),
182641
- negY: colorFace(box.color),
182642
- posZ: colorFace(box.color),
182643
- negZ: colorFace(box.color)
182644
- };
182645
- if (box.shape !== void 0 && box.shape !== "box") {
182646
- return plain;
182647
- }
182648
- const seriesData = series[box.seriesIndex];
182649
- if (!seriesData) {
182650
- return plain;
182651
- }
182652
- const active2 = resolveActiveDataPointPicture(seriesData, box.categoryIndex);
182653
- if (!active2?.imageUrl) {
182654
- return plain;
182655
- }
182656
- const [, height, depth] = box.size;
182657
- const frontFill = resolveTargetedFace(seriesData, box, "front", height, box.color);
182658
- const sideFill = resolveTargetedFace(
182659
- seriesData,
182660
- box,
182661
- "side",
182662
- height,
182663
- resolveUntargetedBarFaceFill("side", box.color)
182664
- );
182665
- const endFill = resolveTargetedFace(
182666
- seriesData,
182667
- box,
182668
- "end",
182669
- depth,
182670
- resolveUntargetedBarFaceFill("end", box.color)
182671
- );
182672
- return {
182673
- posX: sideFill,
182674
- negX: sideFill,
182675
- posY: endFill,
182676
- negY: colorFace(box.color),
182677
- posZ: frontFill,
182678
- negZ: colorFace(box.color)
182679
- };
182680
- }
182681
- function resolveBarRoundFaceFills(box, series) {
182682
- const plain = {
182683
- side: colorFace(box.color),
182684
- end: colorFace(box.color),
182685
- bottom: colorFace(box.color)
182686
- };
182687
- const seriesData = series[box.seriesIndex];
182688
- if (!seriesData) {
182689
- return plain;
182690
- }
182691
- const active2 = resolveActiveDataPointPicture(seriesData, box.categoryIndex);
182692
- if (!active2?.imageUrl) {
182693
- return plain;
182694
- }
182695
- const [, height, depth] = box.size;
182696
- const sideFill = resolveTargetedFace(
182697
- seriesData,
182698
- box,
182699
- "side",
182700
- height,
182701
- resolveUntargetedBarFaceFill("side", box.color)
182702
- );
182703
- const endFill = resolveTargetedFace(
182704
- seriesData,
182705
- box,
182706
- "end",
182707
- depth,
182708
- resolveUntargetedBarFaceFill("end", box.color)
182709
- );
182710
- return { side: sideFill, end: endFill, bottom: colorFace(box.color) };
182711
- }
182712
- function uniformBoxColor(fills) {
182713
- return allSameColor([fills.posX, fills.negX, fills.posY, fills.negY, fills.posZ, fills.negZ]);
182714
- }
182715
- function uniformRoundColor(fills) {
182716
- return allSameColor([fills.side, fills.end, fills.bottom]);
182717
- }
182718
- var init_bar_chart_3d_face_fill = __esm2({
182719
- "src/render/bar-chart-3d-face-fill.ts"() {
182720
- init_chart_bar3d_face_picture();
182721
- init_chart_datapoint_picture_resolve();
182722
- }
182723
- });
182724
- function createBarChart3DTextureManager(three) {
182725
- const loader = new three.TextureLoader();
182726
- const cache2 = /* @__PURE__ */ new Map();
182727
- const loaded = [];
182728
- return {
182729
- load(url) {
182730
- const cached = cache2.get(url);
182731
- if (cached) {
182732
- return cached;
182733
- }
182734
- const pending = new Promise((resolve3, reject) => {
182735
- loader.load(
182736
- url,
182737
- (texture) => {
182738
- loaded.push(texture);
182739
- resolve3(texture);
182740
- },
182741
- void 0,
182742
- reject
182743
- );
182744
- });
182745
- cache2.set(url, pending);
182746
- return pending;
182747
- },
182748
- disposeAll() {
182749
- for (const texture of loaded) {
182750
- texture.dispose();
182751
- }
182752
- loaded.length = 0;
182753
- cache2.clear();
182754
- }
182755
- };
182756
- }
182757
- function buildColorMaterial(three, color2) {
182758
- return new three.MeshPhongMaterial({ color: color2, shininess: 30 });
182759
- }
182760
- function buildFaceMaterial(three, fill, textures, ownedTextures, isDisposed) {
182761
- if (fill.kind === "color") {
182762
- return buildColorMaterial(three, fill.color);
182763
- }
182764
- const material = buildColorMaterial(three, "#ffffff");
182765
- textures.load(fill.imageUrl).then((base) => {
182766
- const texture = base.clone();
182767
- texture.wrapS = three.RepeatWrapping;
182768
- texture.wrapT = three.RepeatWrapping;
182769
- texture.repeat.set(fill.repeatX, fill.repeatY);
182770
- texture.needsUpdate = true;
182771
- if (isDisposed()) {
182772
- texture.dispose();
182773
- return void 0;
182774
- }
182775
- ownedTextures.push(texture);
182776
- material.map = texture;
182777
- material.needsUpdate = true;
182778
- return void 0;
182779
- }).catch(() => {
182780
- });
182781
- return material;
182782
- }
182783
- function buildMaterialArrayResult(three, fills, textures) {
182784
- let disposed = false;
182785
- const ownedTextures = [];
182786
- const materials = fills.map(
182787
- (fill) => buildFaceMaterial(three, fill, textures, ownedTextures, () => disposed)
182788
- );
182789
- return {
182790
- material: materials,
182791
- dispose: () => {
182792
- disposed = true;
182793
- for (const material of materials) {
182794
- material.dispose();
182795
- }
182796
- for (const texture of ownedTextures) {
182797
- texture.dispose();
182798
- }
182799
- }
182800
- };
182801
- }
182802
- function buildBarBoxMaterial(three, box, assets) {
182803
- if (!assets) {
182804
- const material = buildColorMaterial(three, box.color);
182805
- return { material, dispose: () => material.dispose() };
182806
- }
182807
- const isRound = box.shape !== void 0 && box.shape !== "box";
182808
- if (isRound) {
182809
- const roundFills = resolveBarRoundFaceFills(box, assets.context.series);
182810
- const solid2 = uniformRoundColor(roundFills);
182811
- if (solid2 !== void 0) {
182812
- const material = buildColorMaterial(three, solid2);
182813
- return { material, dispose: () => material.dispose() };
182814
- }
182815
- return buildMaterialArrayResult(
182816
- three,
182817
- [roundFills.side, roundFills.end, roundFills.bottom],
182818
- assets.textures
182819
- );
182820
- }
182821
- const fills = resolveBarBoxFaceFills(box, assets.context.series);
182822
- const solid = uniformBoxColor(fills);
182823
- if (solid !== void 0) {
182824
- const material = buildColorMaterial(three, solid);
182825
- return { material, dispose: () => material.dispose() };
182826
- }
182827
- return buildMaterialArrayResult(
182828
- three,
182829
- FACE_ORDER.map((face) => fills[face]),
182830
- assets.textures
182831
- );
182832
- }
182833
- var FACE_ORDER;
182834
- var init_bar_chart_3d_materials = __esm2({
182835
- "src/render/bar-chart-3d-materials.ts"() {
182836
- init_bar_chart_3d_face_fill();
182837
- FACE_ORDER = [
182838
- "posX",
182839
- "negX",
182840
- "posY",
182841
- "negY",
182842
- "posZ",
182843
- "negZ"
182844
- ];
182845
- }
182846
- });
182847
- function buildBar3DGeometry(three, shape, coneToMaxTopRadiusFactor2) {
182848
- switch (shape) {
182849
- case "cylinder":
182850
- return new three.CylinderGeometry(0.5, 0.5, 1, ROUND_SEGMENTS);
182851
- case "cone":
182852
- return new three.ConeGeometry(0.5, 1, ROUND_SEGMENTS);
182853
- case "pyramid":
182854
- return new three.ConeGeometry(0.5, 1, PYRAMID_SEGMENTS);
182855
- case "coneToMax":
182856
- return new three.CylinderGeometry(
182857
- 0.5 * (coneToMaxTopRadiusFactor2 ?? 0),
182858
- 0.5,
182859
- 1,
182860
- ROUND_SEGMENTS
182861
- );
182862
- case "pyramidToMax":
182863
- return new three.CylinderGeometry(
182864
- 0.5 * (coneToMaxTopRadiusFactor2 ?? 0),
182865
- 0.5,
182866
- 1,
182867
- PYRAMID_SEGMENTS
182868
- );
182869
- case "box":
182870
- default:
182871
- return new three.BoxGeometry(1, 1, 1);
182872
- }
182873
- }
182874
- function buildBar3DMeshGroup(three, scene, boxes, horizontal = false, picture) {
182875
- const meshes = [];
182876
- const materials = [];
182877
- const materialDisposers = [];
182878
- const geometries = [];
182879
- for (const box of boxes) {
182880
- const geometry = buildBar3DGeometry(three, box.shape, box.coneToMaxTopRadiusFactor);
182881
- const { material, dispose } = buildBarBoxMaterial(three, box, picture);
182882
- const mesh = new three.Mesh(geometry, material);
182883
- mesh.position.set(...box.center);
182884
- mesh.scale.set(...box.size);
182885
- if (horizontal) {
182886
- mesh.rotation.z = -Math.PI / 2;
182887
- }
182888
- mesh.userData = {
182889
- seriesIndex: box.seriesIndex,
182890
- categoryIndex: box.categoryIndex,
182891
- value: box.value
182892
- };
182893
- scene.add(mesh);
182894
- meshes.push(mesh);
182895
- materials.push(material);
182896
- materialDisposers.push(dispose);
182897
- geometries.push(geometry);
182898
- }
182899
- return { meshes, materials, geometries, materialDisposers };
182900
- }
182901
- var ROUND_SEGMENTS;
182902
- var PYRAMID_SEGMENTS;
182903
- var init_bar_chart_3d_geometry = __esm2({
182904
- "src/render/bar-chart-3d-geometry.ts"() {
182905
- init_bar_chart_3d_materials();
182906
- ROUND_SEGMENTS = 32;
182907
- PYRAMID_SEGMENTS = 4;
182908
- }
182909
- });
182910
181557
  function buildBarChart3DHoverTooltip(hit, data) {
182911
181558
  if (!hit) {
182912
181559
  return void 0;
@@ -182923,984 +181570,6 @@ var init_bar_chart_3d_hit_test = __esm2({
182923
181570
  init_chart_view_model();
182924
181571
  }
182925
181572
  });
182926
- function valueAxisIndex(horizontal) {
182927
- return horizontal ? 0 : 1;
182928
- }
182929
- function calibrateBarChart3DDrag(boxes, hit, grouping, horizontal) {
182930
- if (grouping !== "clustered") {
182931
- return null;
182932
- }
182933
- const box = boxes.find(
182934
- (b) => b.seriesIndex === hit.seriesIndex && b.categoryIndex === hit.categoryIndex
182935
- );
182936
- if (!box) {
182937
- return null;
182938
- }
182939
- const axis = valueAxisIndex(horizontal);
182940
- const half = box.size[axis] / 2;
182941
- const center = box.center[axis];
182942
- const lo = center - half;
182943
- const hi = center + half;
182944
- const zeroIsLo = Math.abs(lo) <= Math.abs(hi);
182945
- const zeroCoord = zeroIsLo ? lo : hi;
182946
- const valueCoord = zeroIsLo ? hi : lo;
182947
- if (Math.abs(valueCoord - zeroCoord) < 1e-9) {
182948
- return null;
182949
- }
182950
- const at = (coord) => axis === 0 ? [coord, box.center[1], box.center[2]] : [box.center[0], coord, box.center[2]];
182951
- return {
182952
- worldAtValue0: at(zeroCoord),
182953
- value0: 0,
182954
- worldAtValue1: at(valueCoord),
182955
- value1: hit.value
182956
- };
182957
- }
182958
- var init_bar_chart_3d_drag = __esm2({
182959
- "src/render/bar-chart-3d-drag.ts"() {
182960
- }
182961
- });
182962
- function applyChart3DMeshHighlight(entries2, part) {
182963
- for (const { mark, material } of entries2) {
182964
- const selected = chart3DMarkMatchesPart(mark, part);
182965
- const materials = Array.isArray(material) ? material : [material];
182966
- for (const one of materials) {
182967
- one.emissive.set(selected ? CHART_3D_SELECTED_EMISSIVE : CLEAR_EMISSIVE);
182968
- one.emissiveIntensity = selected ? CHART_3D_SELECTED_EMISSIVE_INTENSITY : 0;
182969
- }
182970
- }
182971
- }
182972
- var CLEAR_EMISSIVE;
182973
- var init_chart_3d_mesh_highlight = __esm2({
182974
- "src/render/chart-3d-mesh-highlight.ts"() {
182975
- init_chart_3d_interaction();
182976
- CLEAR_EMISSIVE = "#000000";
182977
- }
182978
- });
182979
- function attachBarChart3DInteraction(params) {
182980
- const highlightEntries = params.boxMeshes.map((mesh, i2) => {
182981
- const hit = mesh.userData;
182982
- return {
182983
- mark: { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex },
182984
- material: params.boxMaterials[i2]
182985
- };
182986
- });
182987
- return attachChart3DPointerInteraction({
182988
- three: params.three,
182989
- canvas: params.canvas,
182990
- camera: params.camera,
182991
- width: params.width,
182992
- height: params.height,
182993
- meshes: params.boxMeshes,
182994
- resolveHit: (intersection) => {
182995
- const hit = intersection.object.userData;
182996
- return chart3DHitToPartRef(
182997
- hit ? { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex } : null
182998
- );
182999
- },
183000
- calibrateDrag: (intersection) => {
183001
- const hit = intersection.object.userData;
183002
- return calibrateBarChart3DDrag(params.boxes, hit, params.grouping, params.horizontal);
183003
- },
183004
- applyHighlight: (part) => applyChart3DMeshHighlight(highlightEntries, part),
183005
- setControlsEnabled: (enabled) => {
183006
- params.controls.enabled = enabled;
183007
- },
183008
- onSelect: params.interaction?.onSelect,
183009
- onValueDragPreview: params.interaction?.onValueDragPreview,
183010
- onValueDragCommit: params.interaction?.onValueDragCommit
183011
- });
183012
- }
183013
- var init_bar_chart_3d_interaction_wiring = __esm2({
183014
- "src/render/bar-chart-3d-interaction-wiring.ts"() {
183015
- init_bar_chart_3d_drag();
183016
- init_chart_3d_interaction();
183017
- init_chart_3d_mesh_highlight();
183018
- init_chart_3d_pointer_interaction();
183019
- }
183020
- });
183021
- function createBarChart3DScene(ctx, options) {
183022
- const placement = computeCartesianCameraPlacement(
183023
- options.cols,
183024
- options.rows,
183025
- options.view3D,
183026
- options.horizontal
183027
- );
183028
- const stage = createHostedChart3DStage(ctx, placement, { minDistance: 0.5, maxDistance: 30 });
183029
- const { three, scene, camera, canvas } = stage;
183030
- const extent = computeCartesianGridExtent(
183031
- options.cols,
183032
- options.rows,
183033
- options.view3D?.depthPercent
183034
- );
183035
- const floorSize = Math.max(extent.gridWidth, extent.gridDepth, MAX_VALUE_HEIGHT * 2) * 1.2;
183036
- const gridFloor = new three.GridHelper(
183037
- floorSize,
183038
- Math.max(options.cols, options.rows),
183039
- 13421772,
183040
- 15263976
183041
- );
183042
- gridFloor.position.y = -0.02;
183043
- scene.add(gridFloor);
183044
- const walls = options.wallColors ? buildSurfaceWallMeshes(
183045
- three,
183046
- options.cols,
183047
- options.rows,
183048
- MAX_VALUE_HEIGHT,
183049
- options.wallColors,
183050
- extent
183051
- ) : null;
183052
- for (const mesh of walls?.meshes ?? []) {
183053
- scene.add(mesh);
183054
- }
183055
- const baseTextures = createBarChart3DTextureManager(three);
183056
- const textures = {
183057
- load: (url) => baseTextures.load(url).then((texture) => {
183058
- setTimeout(ctx.requestRender, 0);
183059
- return texture;
183060
- }),
183061
- disposeAll: () => baseTextures.disposeAll()
183062
- };
183063
- const {
183064
- meshes: boxMeshes,
183065
- materials: boxMaterials,
183066
- geometries: boxGeometries,
183067
- materialDisposers: boxMaterialDisposers
183068
- } = buildBar3DMeshGroup(
183069
- three,
183070
- scene,
183071
- options.boxes,
183072
- options.horizontal,
183073
- options.picture ? { context: options.picture, textures } : void 0
183074
- );
183075
- const hoverTooltip = attachChart3DHoverTooltip({
183076
- three,
183077
- canvas,
183078
- camera,
183079
- meshes: boxMeshes,
183080
- buildTooltip: (intersection) => buildBarChart3DHoverTooltip(intersection?.object.userData, {
183081
- categoryLabels: options.categoryLabels,
183082
- seriesNames: options.seriesNames,
183083
- numberFormats: options.numberFormats
183084
- })
183085
- });
183086
- const interaction = hostedChart3DInteraction(ctx);
183087
- const pointerInteraction = attachBarChart3DInteraction({
183088
- three,
183089
- canvas,
183090
- camera,
183091
- controls: stage.controls,
183092
- width: stage.width,
183093
- height: stage.height,
183094
- boxMeshes,
183095
- boxMaterials,
183096
- boxes: options.boxes,
183097
- grouping: options.grouping,
183098
- horizontal: Boolean(options.horizontal),
183099
- interaction
183100
- });
183101
- const labels = buildCartesianChart3DLabels(
183102
- options.cols,
183103
- options.rows,
183104
- options.categoryLabels,
183105
- options.seriesNames,
183106
- options.view3D?.depthPercent,
183107
- void 0,
183108
- void 0,
183109
- options.horizontal
183110
- );
183111
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
183112
- labelProjector.applyTextStyle(options.textStyle);
183113
- ctx.overlay.appendChild(labelProjector.layer);
183114
- return finishHostedChart3DScene(
183115
- ctx,
183116
- stage,
183117
- {
183118
- afterRender: (cam, width, height) => labelProjector.update(cam, width, height),
183119
- resize: (width, height) => pointerInteraction.updateSize(width, height),
183120
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183121
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
183122
- dispose() {
183123
- hoverTooltip.dispose();
183124
- pointerInteraction.dispose();
183125
- for (const g2 of boxGeometries) {
183126
- g2.dispose();
183127
- }
183128
- for (const disposeMaterial of boxMaterialDisposers) {
183129
- disposeMaterial();
183130
- }
183131
- textures.disposeAll();
183132
- gridFloor.dispose();
183133
- walls?.dispose();
183134
- labelProjector.layer.remove();
183135
- }
183136
- },
183137
- interaction
183138
- );
183139
- }
183140
- var init_bar_chart_3d_scene = __esm2({
183141
- "src/render/bar-chart-3d-scene.ts"() {
183142
- init_bar_chart_3d_geometry();
183143
- init_bar_chart_3d_hit_test();
183144
- init_bar_chart_3d_interaction_wiring();
183145
- init_bar_chart_3d_materials();
183146
- init_cartesian_chart_3d_geom();
183147
- init_chart_3d_hosted_stage();
183148
- init_chart_3d_hover_tooltip();
183149
- init_chart_3d_label_projection();
183150
- init_surface_chart_3d_walls();
183151
- }
183152
- });
183153
- function buildCartesianChart3DHoverTooltip(hit, data) {
183154
- if (!hit) {
183155
- return void 0;
183156
- }
183157
- return buildMarkTooltip(
183158
- data.seriesNames[hit.seriesIndex],
183159
- data.categoryLabels[hit.categoryIndex],
183160
- hit.value,
183161
- data.numberFormats?.[hit.seriesIndex]
183162
- );
183163
- }
183164
- var init_cartesian_chart_3d_hit_test = __esm2({
183165
- "src/render/cartesian-chart-3d-hit-test.ts"() {
183166
- init_chart_view_model();
183167
- }
183168
- });
183169
- function calibrateCartesianChart3DDrag(markerPosition, value) {
183170
- if (Math.abs(value) < 1e-9) {
183171
- return null;
183172
- }
183173
- return {
183174
- worldAtValue0: [markerPosition[0], 0, markerPosition[2]],
183175
- value0: 0,
183176
- worldAtValue1: markerPosition,
183177
- value1: value
183178
- };
183179
- }
183180
- var init_cartesian_chart_3d_drag = __esm2({
183181
- "src/render/cartesian-chart-3d-drag.ts"() {
183182
- }
183183
- });
183184
- function attachCartesianChart3DInteraction(params) {
183185
- const highlightEntries = params.markerMeshes.map((mesh, i2) => {
183186
- const hit = mesh.userData;
183187
- return {
183188
- mark: { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex },
183189
- material: params.markerMaterials[i2]
183190
- };
183191
- });
183192
- return attachChart3DPointerInteraction({
183193
- three: params.three,
183194
- canvas: params.canvas,
183195
- camera: params.camera,
183196
- width: params.width,
183197
- height: params.height,
183198
- meshes: params.markerMeshes,
183199
- resolveHit: (intersection) => {
183200
- const hit = intersection.object.userData;
183201
- return chart3DHitToPartRef(
183202
- hit ? { seriesIndex: hit.seriesIndex, pointIndex: hit.categoryIndex } : null
183203
- );
183204
- },
183205
- calibrateDrag: (intersection) => {
183206
- const hit = intersection.object.userData;
183207
- const vertex = params.series[hit.seriesIndex]?.vertices.find(
183208
- (v) => v.categoryIndex === hit.categoryIndex
183209
- );
183210
- return vertex ? calibrateCartesianChart3DDrag(vertex.position, hit.value) : null;
183211
- },
183212
- applyHighlight: (part) => applyChart3DMeshHighlight(highlightEntries, part),
183213
- setControlsEnabled: (enabled) => {
183214
- params.controls.enabled = enabled;
183215
- },
183216
- onSelect: params.interaction?.onSelect,
183217
- onValueDragPreview: params.interaction?.onValueDragPreview,
183218
- onValueDragCommit: params.interaction?.onValueDragCommit
183219
- });
183220
- }
183221
- var init_cartesian_chart_3d_interaction_wiring = __esm2({
183222
- "src/render/cartesian-chart-3d-interaction-wiring.ts"() {
183223
- init_cartesian_chart_3d_drag();
183224
- init_chart_3d_interaction();
183225
- init_chart_3d_mesh_highlight();
183226
- init_chart_3d_pointer_interaction();
183227
- }
183228
- });
183229
- function createLineChart3DScene(ctx, options) {
183230
- const placement = computeCartesianCameraPlacement(options.cols, options.rows, options.view3D);
183231
- const stage = createHostedChart3DStage(
183232
- ctx,
183233
- placement,
183234
- { minDistance: 0.5, maxDistance: 30 },
183235
- 0.6
183236
- );
183237
- const { three, scene, camera, canvas, controls, width, height } = stage;
183238
- const interaction = hostedChart3DInteraction(ctx);
183239
- const extent = computeCartesianGridExtent(
183240
- options.cols,
183241
- options.rows,
183242
- options.view3D?.depthPercent
183243
- );
183244
- const floorSize = Math.max(extent.gridWidth, extent.gridDepth) * 1.2;
183245
- const gridFloor = new three.GridHelper(
183246
- floorSize,
183247
- Math.max(options.cols, options.rows),
183248
- 13421772,
183249
- 15263976
183250
- );
183251
- gridFloor.position.y = -0.02;
183252
- scene.add(gridFloor);
183253
- const walls = options.wallColors ? buildSurfaceWallMeshes(
183254
- three,
183255
- options.cols,
183256
- options.rows,
183257
- MAX_VALUE_HEIGHT,
183258
- options.wallColors,
183259
- extent
183260
- ) : null;
183261
- for (const mesh of walls?.meshes ?? []) {
183262
- scene.add(mesh);
183263
- }
183264
- const markerGeometry = new three.SphereGeometry(MARKER_RADIUS2, 8, 6);
183265
- const tubeGeometries = [];
183266
- const tubeMaterials = [];
183267
- const markerMeshes = [];
183268
- const markerMaterials = [];
183269
- for (const path of options.series) {
183270
- if (path.vertices.length >= 2) {
183271
- const curve = new three.CatmullRomCurve3(
183272
- path.vertices.map((v) => new three.Vector3(...v.position))
183273
- );
183274
- const tubeGeometry = new three.TubeGeometry(
183275
- curve,
183276
- Math.max(path.vertices.length * 8, 16),
183277
- TUBE_RADIUS,
183278
- 8,
183279
- false
183280
- );
183281
- const tubeMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183282
- const tube = new three.Mesh(tubeGeometry, tubeMaterial);
183283
- scene.add(tube);
183284
- tubeGeometries.push(tubeGeometry);
183285
- tubeMaterials.push(tubeMaterial);
183286
- }
183287
- for (const v of path.vertices) {
183288
- const markerMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183289
- const marker = new three.Mesh(markerGeometry, markerMaterial);
183290
- marker.position.set(...v.position);
183291
- marker.userData = {
183292
- seriesIndex: v.seriesIndex,
183293
- categoryIndex: v.categoryIndex,
183294
- value: v.value
183295
- };
183296
- scene.add(marker);
183297
- markerMeshes.push(marker);
183298
- markerMaterials.push(markerMaterial);
183299
- }
183300
- }
183301
- const tooltipData = {
183302
- categoryLabels: options.categoryLabels,
183303
- seriesNames: options.seriesNames,
183304
- numberFormats: options.numberFormats
183305
- };
183306
- const hoverTooltip = attachChart3DHoverTooltip({
183307
- three,
183308
- canvas,
183309
- camera,
183310
- meshes: markerMeshes,
183311
- buildTooltip: (intersection) => buildCartesianChart3DHoverTooltip(
183312
- intersection?.object.userData,
183313
- tooltipData
183314
- )
183315
- });
183316
- const pointerInteraction = attachCartesianChart3DInteraction({
183317
- three,
183318
- canvas,
183319
- camera,
183320
- controls,
183321
- width,
183322
- height,
183323
- markerMeshes,
183324
- markerMaterials,
183325
- series: options.series,
183326
- interaction
183327
- });
183328
- const labels = buildCartesianChart3DLabels(
183329
- options.cols,
183330
- options.rows,
183331
- options.categoryLabels,
183332
- options.seriesNames,
183333
- options.view3D?.depthPercent
183334
- );
183335
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
183336
- labelProjector.applyTextStyle(options.textStyle);
183337
- ctx.overlay.appendChild(labelProjector.layer);
183338
- return finishHostedChart3DScene(
183339
- ctx,
183340
- stage,
183341
- {
183342
- afterRender: (cam, w, h2) => labelProjector.update(cam, w, h2),
183343
- resize: (w, h2) => pointerInteraction.updateSize(w, h2),
183344
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183345
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
183346
- dispose() {
183347
- hoverTooltip.dispose();
183348
- pointerInteraction.dispose();
183349
- markerGeometry.dispose();
183350
- for (const g2 of tubeGeometries) {
183351
- g2.dispose();
183352
- }
183353
- for (const m of [...tubeMaterials, ...markerMaterials]) {
183354
- m.dispose();
183355
- }
183356
- gridFloor.dispose();
183357
- walls?.dispose();
183358
- labelProjector.layer.remove();
183359
- }
183360
- },
183361
- interaction
183362
- );
183363
- }
183364
- var TUBE_RADIUS;
183365
- var MARKER_RADIUS2;
183366
- var init_line_chart_3d_scene = __esm2({
183367
- "src/render/line-chart-3d-scene.ts"() {
183368
- init_cartesian_chart_3d_geom();
183369
- init_cartesian_chart_3d_hit_test();
183370
- init_cartesian_chart_3d_interaction_wiring();
183371
- init_chart_3d_hosted_stage();
183372
- init_chart_3d_hover_tooltip();
183373
- init_chart_3d_label_projection();
183374
- init_surface_chart_3d_walls();
183375
- TUBE_RADIUS = 0.025;
183376
- MARKER_RADIUS2 = 0.045;
183377
- }
183378
- });
183379
- function buildAreaRibbonGeometry(three, path) {
183380
- const triangles = buildAreaRibbonTriangles(path);
183381
- if (triangles.length === 0) {
183382
- return null;
183383
- }
183384
- const geometry = new three.BufferGeometry();
183385
- geometry.setAttribute("position", new three.Float32BufferAttribute(triangles, 3));
183386
- geometry.computeVertexNormals();
183387
- return geometry;
183388
- }
183389
- var init_area_chart_3d_ribbon_geometry = __esm2({
183390
- "src/render/area-chart-3d-ribbon-geometry.ts"() {
183391
- init_cartesian_line_chart_3d_layout();
183392
- }
183393
- });
183394
- function createAreaChart3DScene(ctx, options) {
183395
- const placement = computeCartesianCameraPlacement(options.cols, options.rows, options.view3D);
183396
- const stage = createHostedChart3DStage(
183397
- ctx,
183398
- placement,
183399
- { minDistance: 0.5, maxDistance: 30 },
183400
- 0.6
183401
- );
183402
- const { three, scene, camera, canvas, controls, width, height } = stage;
183403
- const interaction = hostedChart3DInteraction(ctx);
183404
- const extent = computeCartesianGridExtent(
183405
- options.cols,
183406
- options.rows,
183407
- options.view3D?.depthPercent
183408
- );
183409
- const floorSize = Math.max(extent.gridWidth, extent.gridDepth) * 1.2;
183410
- const gridSegs = Math.max(options.cols, options.rows);
183411
- const gridFloor = new three.GridHelper(floorSize, gridSegs, 13421772, 15263976);
183412
- gridFloor.position.y = -0.02;
183413
- scene.add(gridFloor);
183414
- const walls = options.wallColors ? buildSurfaceWallMeshes(
183415
- three,
183416
- options.cols,
183417
- options.rows,
183418
- MAX_VALUE_HEIGHT,
183419
- options.wallColors,
183420
- extent
183421
- ) : null;
183422
- for (const mesh of walls?.meshes ?? []) {
183423
- scene.add(mesh);
183424
- }
183425
- const markerGeometry = new three.SphereGeometry(MARKER_RADIUS3, 8, 6);
183426
- const tubeGeometries = [];
183427
- const ribbonGeometries = [];
183428
- const otherMaterials = [];
183429
- const markerMeshes = [];
183430
- const markerMaterials = [];
183431
- for (const path of options.series) {
183432
- const ribbonGeometry = buildAreaRibbonGeometry(three, path);
183433
- if (ribbonGeometry) {
183434
- const ribbonMaterial = new three.MeshPhongMaterial({
183435
- color: path.color,
183436
- side: three.DoubleSide,
183437
- transparent: true,
183438
- opacity: RIBBON_OPACITY,
183439
- shininess: 10
183440
- });
183441
- scene.add(new three.Mesh(ribbonGeometry, ribbonMaterial));
183442
- ribbonGeometries.push(ribbonGeometry);
183443
- otherMaterials.push(ribbonMaterial);
183444
- }
183445
- if (path.vertices.length >= 2) {
183446
- const curve = new three.CatmullRomCurve3(
183447
- path.vertices.map((v) => new three.Vector3(...v.position))
183448
- );
183449
- const tubeGeometry = new three.TubeGeometry(
183450
- curve,
183451
- Math.max(path.vertices.length * 8, 16),
183452
- TUBE_RADIUS2,
183453
- 8,
183454
- false
183455
- );
183456
- const tubeMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183457
- scene.add(new three.Mesh(tubeGeometry, tubeMaterial));
183458
- tubeGeometries.push(tubeGeometry);
183459
- otherMaterials.push(tubeMaterial);
183460
- }
183461
- for (const v of path.vertices) {
183462
- const markerMaterial = new three.MeshPhongMaterial({ color: path.color, shininess: 30 });
183463
- const marker = new three.Mesh(markerGeometry, markerMaterial);
183464
- marker.position.set(...v.position);
183465
- marker.userData = {
183466
- seriesIndex: v.seriesIndex,
183467
- categoryIndex: v.categoryIndex,
183468
- value: v.value
183469
- };
183470
- scene.add(marker);
183471
- markerMeshes.push(marker);
183472
- markerMaterials.push(markerMaterial);
183473
- otherMaterials.push(markerMaterial);
183474
- }
183475
- }
183476
- const tooltipData = {
183477
- categoryLabels: options.categoryLabels,
183478
- seriesNames: options.seriesNames,
183479
- numberFormats: options.numberFormats
183480
- };
183481
- const hoverTooltip = attachChart3DHoverTooltip({
183482
- three,
183483
- canvas,
183484
- camera,
183485
- meshes: markerMeshes,
183486
- buildTooltip: (intersection) => buildCartesianChart3DHoverTooltip(
183487
- intersection?.object.userData,
183488
- tooltipData
183489
- )
183490
- });
183491
- const pointerInteraction = attachCartesianChart3DInteraction({
183492
- three,
183493
- canvas,
183494
- camera,
183495
- controls,
183496
- width,
183497
- height,
183498
- markerMeshes,
183499
- markerMaterials,
183500
- series: options.series,
183501
- interaction
183502
- });
183503
- const labels = buildCartesianChart3DLabels(
183504
- options.cols,
183505
- options.rows,
183506
- options.categoryLabels,
183507
- options.seriesNames,
183508
- options.view3D?.depthPercent
183509
- );
183510
- const labelProjector = createChart3DLabelProjector(three, ctx.document, labels);
183511
- labelProjector.applyTextStyle(options.textStyle);
183512
- ctx.overlay.appendChild(labelProjector.layer);
183513
- return finishHostedChart3DScene(
183514
- ctx,
183515
- stage,
183516
- {
183517
- afterRender: (cam, w, h2) => labelProjector.update(cam, w, h2),
183518
- resize: (w, h2) => pointerInteraction.updateSize(w, h2),
183519
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183520
- setTextStyle: (style) => labelProjector.applyTextStyle(style),
183521
- dispose() {
183522
- hoverTooltip.dispose();
183523
- pointerInteraction.dispose();
183524
- markerGeometry.dispose();
183525
- for (const g2 of [...tubeGeometries, ...ribbonGeometries]) {
183526
- g2.dispose();
183527
- }
183528
- for (const m of otherMaterials) {
183529
- m.dispose();
183530
- }
183531
- gridFloor.dispose();
183532
- walls?.dispose();
183533
- labelProjector.layer.remove();
183534
- }
183535
- },
183536
- interaction
183537
- );
183538
- }
183539
- var TUBE_RADIUS2;
183540
- var MARKER_RADIUS3;
183541
- var RIBBON_OPACITY;
183542
- var init_area_chart_3d_scene = __esm2({
183543
- "src/render/area-chart-3d-scene.ts"() {
183544
- init_area_chart_3d_ribbon_geometry();
183545
- init_cartesian_chart_3d_geom();
183546
- init_cartesian_chart_3d_hit_test();
183547
- init_cartesian_chart_3d_interaction_wiring();
183548
- init_chart_3d_hosted_stage();
183549
- init_chart_3d_hover_tooltip();
183550
- init_chart_3d_label_projection();
183551
- init_surface_chart_3d_walls();
183552
- TUBE_RADIUS2 = 0.02;
183553
- MARKER_RADIUS3 = 0.045;
183554
- RIBBON_OPACITY = 0.75;
183555
- }
183556
- });
183557
- function buildPieChart3DHoverTooltip(hit, data) {
183558
- if (!hit) {
183559
- return void 0;
183560
- }
183561
- return buildMarkTooltip(
183562
- data.seriesName,
183563
- data.categoryLabels[hit.pointIndex],
183564
- hit.value,
183565
- data.numberFormat
183566
- );
183567
- }
183568
- var init_pie_chart_3d_hit_test = __esm2({
183569
- "src/render/pie-chart-3d-hit-test.ts"() {
183570
- init_chart_view_model();
183571
- }
183572
- });
183573
- function pieChart3DPointerAngle(x, z) {
183574
- return Math.atan2(x, z);
183575
- }
183576
- function resolvePieChart3DDragValue(geometry, pointerAngle) {
183577
- return resolvePieSliceShareValue(
183578
- pointerAngle,
183579
- geometry.leadingAngle,
183580
- geometry.values,
183581
- geometry.pointIndex
183582
- );
183583
- }
183584
- var init_pie_chart_3d_drag = __esm2({
183585
- "src/render/pie-chart-3d-drag.ts"() {
183586
- init_chart_interaction_pie();
183587
- }
183588
- });
183589
- function attachPieChart3DInteraction(params) {
183590
- const raycaster = new params.three.Raycaster();
183591
- const ndc = new params.three.Vector2();
183592
- const plane = new params.three.Plane(new params.three.Vector3(0, 1, 0), 0);
183593
- const planeHit = new params.three.Vector3();
183594
- let dragState = null;
183595
- const highlightEntries = params.wedgeMeshes.map((mesh, i2) => {
183596
- const hit = mesh.userData;
183597
- return {
183598
- mark: { seriesIndex: 0, pointIndex: hit.pointIndex },
183599
- material: params.wedgeMaterials[i2]
183600
- };
183601
- });
183602
- function setNdc(clientX, clientY) {
183603
- const rect22 = params.canvas.getBoundingClientRect();
183604
- if (rect22.width <= 0 || rect22.height <= 0) {
183605
- return false;
183606
- }
183607
- ndc.x = (clientX - rect22.left) / rect22.width * 2 - 1;
183608
- ndc.y = -((clientY - rect22.top) / rect22.height) * 2 + 1;
183609
- return true;
183610
- }
183611
- function raycastWedge(clientX, clientY) {
183612
- if (!setNdc(clientX, clientY)) {
183613
- return void 0;
183614
- }
183615
- raycaster.setFromCamera(ndc, params.camera);
183616
- return raycaster.intersectObjects(params.wedgeMeshes, false)[0];
183617
- }
183618
- function planeAngleAt(clientX, clientY) {
183619
- if (!setNdc(clientX, clientY)) {
183620
- return null;
183621
- }
183622
- raycaster.setFromCamera(ndc, params.camera);
183623
- const hit = raycaster.ray.intersectPlane(plane, planeHit);
183624
- return hit ? pieChart3DPointerAngle(hit.x, hit.z) : null;
183625
- }
183626
- function setSelectedPart(part) {
183627
- applyChart3DMeshHighlight(highlightEntries, part);
183628
- }
183629
- function travelBelowThreshold(clientX, clientY, state) {
183630
- const dx = clientX - state.startClientX;
183631
- const dy = clientY - state.startClientY;
183632
- return Math.hypot(dx, dy) < CHART_3D_DRAG_THRESHOLD_PX;
183633
- }
183634
- const onPointerDown = (event) => {
183635
- params.canvas.setPointerCapture?.(
183636
- event.pointerId
183637
- );
183638
- const hit = raycastWedge(event.clientX, event.clientY);
183639
- const hitData = hit?.object.userData;
183640
- const part = chart3DHitToPartRef(
183641
- hitData ? { seriesIndex: 0, pointIndex: hitData.pointIndex } : null
183642
- );
183643
- const armed = part !== null && isChartInteractionArmed(params.canvas);
183644
- if (armed) {
183645
- event.stopPropagation();
183646
- }
183647
- let geometry = null;
183648
- if (part && hitData && armed) {
183649
- const wedges = params.getWedges();
183650
- const wedge = wedges.find((w) => w.pointIndex === hitData.pointIndex);
183651
- if (wedge) {
183652
- geometry = {
183653
- values: wedges.map((w) => w.value),
183654
- pointIndex: hitData.pointIndex,
183655
- leadingAngle: wedge.startAngle
183656
- };
183657
- }
183658
- }
183659
- dragState = {
183660
- part,
183661
- geometry,
183662
- moved: false,
183663
- startClientX: event.clientX,
183664
- startClientY: event.clientY,
183665
- lastAngle: null
183666
- };
183667
- if (geometry) {
183668
- event.preventDefault();
183669
- params.controls.enabled = false;
183670
- }
183671
- };
183672
- const onPointerMove = (event) => {
183673
- const state = dragState;
183674
- if (!state || !state.part || !state.geometry) {
183675
- return;
183676
- }
183677
- if (!state.moved && travelBelowThreshold(event.clientX, event.clientY, state)) {
183678
- return;
183679
- }
183680
- state.moved = true;
183681
- const angle = planeAngleAt(event.clientX, event.clientY);
183682
- if (angle === null) {
183683
- return;
183684
- }
183685
- state.lastAngle = angle;
183686
- const value = resolvePieChart3DDragValue(state.geometry, angle);
183687
- params.interaction?.onValueDragPreview?.(state.part, value);
183688
- };
183689
- const onPointerUp = (event) => {
183690
- if (!dragState) {
183691
- return;
183692
- }
183693
- const state = dragState;
183694
- dragState = null;
183695
- params.canvas.releasePointerCapture?.(event.pointerId);
183696
- if (state.geometry) {
183697
- params.controls.enabled = true;
183698
- }
183699
- if (state.moved && state.part && state.geometry) {
183700
- const angle = planeAngleAt(event.clientX, event.clientY) ?? state.lastAngle;
183701
- if (angle !== null) {
183702
- const value = resolvePieChart3DDragValue(state.geometry, angle);
183703
- params.interaction?.onValueDragCommit?.(state.part, value);
183704
- }
183705
- return;
183706
- }
183707
- setSelectedPart(state.part);
183708
- params.interaction?.onSelect?.(state.part);
183709
- };
183710
- params.canvas.addEventListener("pointerdown", onPointerDown);
183711
- params.canvas.addEventListener("pointermove", onPointerMove);
183712
- params.canvas.addEventListener("pointerup", onPointerUp);
183713
- params.canvas.addEventListener("pointercancel", onPointerUp);
183714
- return {
183715
- setSelectedPart,
183716
- dispose() {
183717
- params.canvas.removeEventListener("pointerdown", onPointerDown);
183718
- params.canvas.removeEventListener("pointermove", onPointerMove);
183719
- params.canvas.removeEventListener("pointerup", onPointerUp);
183720
- params.canvas.removeEventListener("pointercancel", onPointerUp);
183721
- }
183722
- };
183723
- }
183724
- var init_pie_chart_3d_interaction_wiring = __esm2({
183725
- "src/render/pie-chart-3d-interaction-wiring.ts"() {
183726
- init_chart_3d_interaction();
183727
- init_chart_3d_mesh_highlight();
183728
- init_chart_canvas_drag();
183729
- init_pie_chart_3d_drag();
183730
- }
183731
- });
183732
- function wedgeSegments(thetaLength) {
183733
- return Math.max(
183734
- MIN_RADIAL_SEGMENTS,
183735
- Math.round(thetaLength / (Math.PI * 2) * FULL_CIRCLE_SEGMENTS)
183736
- );
183737
- }
183738
- function buildPieChart3DWedgeMeshes(three, scene, wedges, outerRadius, thickness) {
183739
- const meshes = [];
183740
- const geometries = [];
183741
- const materials = [];
183742
- for (const wedge of wedges) {
183743
- const geometry = new three.CylinderGeometry(
183744
- outerRadius,
183745
- outerRadius,
183746
- thickness,
183747
- wedgeSegments(wedge.thetaLength),
183748
- 1,
183749
- false,
183750
- wedge.startAngle,
183751
- wedge.thetaLength
183752
- );
183753
- const material = new three.MeshPhongMaterial({ color: wedge.color, shininess: 30 });
183754
- const mesh = new three.Mesh(geometry, material);
183755
- mesh.position.set(wedge.explodeOffset[0], 0, wedge.explodeOffset[1]);
183756
- mesh.userData = { pointIndex: wedge.pointIndex, value: wedge.value };
183757
- scene.add(mesh);
183758
- meshes.push(mesh);
183759
- geometries.push(geometry);
183760
- materials.push(material);
183761
- }
183762
- return { meshes, geometries, materials };
183763
- }
183764
- function applyPieChart3DWedgeAngles(three, meshes, geometries, outerRadius, thickness, angles) {
183765
- for (const angle of angles) {
183766
- const mesh = meshes[angle.pointIndex];
183767
- const oldGeometry = geometries[angle.pointIndex];
183768
- if (!mesh || !oldGeometry) {
183769
- continue;
183770
- }
183771
- const geometry = new three.CylinderGeometry(
183772
- outerRadius,
183773
- outerRadius,
183774
- thickness,
183775
- wedgeSegments(angle.thetaLength),
183776
- 1,
183777
- false,
183778
- angle.startAngle,
183779
- angle.thetaLength
183780
- );
183781
- mesh.geometry = geometry;
183782
- oldGeometry.dispose();
183783
- geometries[angle.pointIndex] = geometry;
183784
- mesh.position.set(angle.explodeOffset[0], 0, angle.explodeOffset[1]);
183785
- mesh.userData = { pointIndex: angle.pointIndex, value: angle.value };
183786
- }
183787
- }
183788
- var MIN_RADIAL_SEGMENTS;
183789
- var FULL_CIRCLE_SEGMENTS;
183790
- var init_pie_chart_3d_mesh = __esm2({
183791
- "src/render/pie-chart-3d-mesh.ts"() {
183792
- MIN_RADIAL_SEGMENTS = 3;
183793
- FULL_CIRCLE_SEGMENTS = 64;
183794
- }
183795
- });
183796
- function createPieChart3DScene(ctx, options) {
183797
- const placement = computePieChart3DCameraPlacement(options.view3D);
183798
- const stage = createHostedChart3DStage(
183799
- ctx,
183800
- placement,
183801
- { minDistance: 0.5, maxDistance: 30 },
183802
- 0.65
183803
- );
183804
- const { three, scene, camera, canvas, controls } = stage;
183805
- const interaction = hostedChart3DInteraction(ctx);
183806
- const {
183807
- meshes: wedgeMeshes,
183808
- geometries: wedgeGeometries,
183809
- materials: wedgeMaterials
183810
- } = buildPieChart3DWedgeMeshes(
183811
- three,
183812
- scene,
183813
- options.wedges,
183814
- options.outerRadius,
183815
- options.thickness
183816
- );
183817
- const hoverTooltip = attachChart3DHoverTooltip({
183818
- three,
183819
- canvas,
183820
- camera,
183821
- meshes: wedgeMeshes,
183822
- buildTooltip: (intersection) => buildPieChart3DHoverTooltip(intersection?.object.userData, {
183823
- categoryLabels: options.categoryLabels,
183824
- seriesName: options.seriesName,
183825
- numberFormat: options.numberFormat
183826
- })
183827
- });
183828
- let currentAngles = options.wedges;
183829
- let liveValues = options.values.slice();
183830
- function recomputeLiveAngles() {
183831
- const angles = computePieChart3DSliceAngles(
183832
- liveValues,
183833
- options.explosions,
183834
- options.firstSliceAngleDeg,
183835
- options.outerRadius
183836
- );
183837
- currentAngles = angles;
183838
- applyPieChart3DWedgeAngles(
183839
- three,
183840
- wedgeMeshes,
183841
- wedgeGeometries,
183842
- options.outerRadius,
183843
- options.thickness,
183844
- angles
183845
- );
183846
- }
183847
- const pointerInteraction = attachPieChart3DInteraction({
183848
- three,
183849
- canvas,
183850
- camera,
183851
- controls,
183852
- wedgeMeshes,
183853
- wedgeMaterials,
183854
- getWedges: () => currentAngles,
183855
- interaction: {
183856
- onSelect: interaction?.onSelect,
183857
- onValueDragPreview: (part, value) => {
183858
- if (part.pointIndex !== void 0) {
183859
- liveValues = liveValues.map((v, i2) => i2 === part.pointIndex ? value : v);
183860
- recomputeLiveAngles();
183861
- }
183862
- interaction?.onValueDragPreview?.(part, value);
183863
- },
183864
- onValueDragCommit: (part, value) => {
183865
- if (part.pointIndex !== void 0) {
183866
- liveValues = liveValues.map((v, i2) => i2 === part.pointIndex ? value : v);
183867
- recomputeLiveAngles();
183868
- }
183869
- interaction?.onValueDragCommit?.(part, value);
183870
- }
183871
- }
183872
- });
183873
- return finishHostedChart3DScene(
183874
- ctx,
183875
- stage,
183876
- {
183877
- // No `resize`: this scene's own wiring re-derives the pointer's NDC
183878
- // position from `canvas.getBoundingClientRect()` on every raycast.
183879
- setSelectedPart: (part) => pointerInteraction.setSelectedPart(part),
183880
- dispose() {
183881
- hoverTooltip.dispose();
183882
- pointerInteraction.dispose();
183883
- for (const g2 of wedgeGeometries) {
183884
- g2.dispose();
183885
- }
183886
- for (const m of wedgeMaterials) {
183887
- m.dispose();
183888
- }
183889
- }
183890
- },
183891
- interaction
183892
- );
183893
- }
183894
- var init_pie_chart_3d_scene = __esm2({
183895
- "src/render/pie-chart-3d-scene.ts"() {
183896
- init_chart_3d_hosted_stage();
183897
- init_chart_3d_hover_tooltip();
183898
- init_pie_chart_3d_geom();
183899
- init_pie_chart_3d_hit_test();
183900
- init_pie_chart_3d_interaction_wiring();
183901
- init_pie_chart_3d_mesh();
183902
- }
183903
- });
183904
181573
  function createRenderer(three, state) {
183905
181574
  try {
183906
181575
  const renderer = new three.WebGLRenderer({
@@ -184148,7 +181817,7 @@ function buildObliqueShapeGeometry(three, bar, horizontal) {
184148
181817
  0.5 * bar.taper.top,
184149
181818
  0.5 * bar.taper.bottom,
184150
181819
  1,
184151
- ROUND_SEGMENTS2
181820
+ ROUND_SEGMENTS
184152
181821
  );
184153
181822
  }
184154
181823
  if (horizontal) {
@@ -184189,11 +181858,11 @@ function shadeObliqueShapeGeometry(three, geometry, bar, scale2, viewYaw) {
184189
181858
  }
184190
181859
  colors.needsUpdate = true;
184191
181860
  }
184192
- var ROUND_SEGMENTS2;
181861
+ var ROUND_SEGMENTS;
184193
181862
  var init_chart_3d_oblique_shape_mesh = __esm2({
184194
181863
  "src/render/chart-3d-oblique-shape-mesh.ts"() {
184195
181864
  init_chart_3d_shading();
184196
- ROUND_SEGMENTS2 = 48;
181865
+ ROUND_SEGMENTS = 48;
184197
181866
  }
184198
181867
  });
184199
181868
  function obliqueToScene(layout, svgWidth, svgHeight, p) {
@@ -184399,6 +182068,12 @@ var init_chart_3d_chrome_overlay = __esm2({
184399
182068
  OBLIQUE_LEGEND_BASELINE = 14 * PT6;
184400
182069
  }
184401
182070
  });
182071
+ var CHART_3D_DRAG_THRESHOLD_PX;
182072
+ var init_chart_3d_interaction = __esm2({
182073
+ "src/render/chart-3d-interaction.ts"() {
182074
+ CHART_3D_DRAG_THRESHOLD_PX = 3;
182075
+ }
182076
+ });
184402
182077
  function partOf(point) {
184403
182078
  return point ? { role: "dataPoint", seriesIndex: point.seriesIndex, pointIndex: point.pointIndex } : null;
184404
182079
  }
@@ -184554,9 +182229,9 @@ function obliqueDragValue(layout, startValue, dx, dy) {
184554
182229
  function obliqueDraggedExtent(layout, value) {
184555
182230
  const { min, max } = layout.range;
184556
182231
  const base = Math.min(Math.max(0, min), max);
184557
- const clamp13 = (v) => Math.min(Math.max(v, min), max);
184558
- const lo = (clamp13(Math.min(base, value)) - min) * layout.valueScale;
184559
- const hi = (clamp13(Math.max(base, value)) - min) * layout.valueScale;
182232
+ const clamp12 = (v) => Math.min(Math.max(v, min), max);
182233
+ const lo = (clamp12(Math.min(base, value)) - min) * layout.valueScale;
182234
+ const hi = (clamp12(Math.max(base, value)) - min) * layout.valueScale;
184560
182235
  return { from: lo, length: hi - lo };
184561
182236
  }
184562
182237
  function obliqueBarAtValue(layout, bar, value) {
@@ -184696,6 +182371,7 @@ function buildPerspBarPrisms(chartData, layout, override) {
184696
182371
  neg = to;
184697
182372
  }
184698
182373
  }
182374
+ const shape = chartData.series[s]?.shape ?? chartData.barShape ?? "box";
184699
182375
  const slotIndex = layout.grouping === "clustered" ? s : 0;
184700
182376
  const row = layout.grouping === "standard" ? s : 0;
184701
182377
  const c0 = c * slot + gapWidth * barW / 2 + slotIndex * barW;
@@ -184714,7 +182390,16 @@ function buildPerspBarPrisms(chartData, layout, override) {
184714
182390
  [x0, y1]
184715
182391
  ],
184716
182392
  z0,
184717
- z1: z0 + depth
182393
+ z1: z0 + depth,
182394
+ shape,
182395
+ taper: obliqueBarTaper(
182396
+ shape,
182397
+ v0,
182398
+ v1,
182399
+ (layout.range.max - layout.range.min) * layout.valueScale,
182400
+ raw
182401
+ ),
182402
+ horizontal: layout.horizontal
184718
182403
  });
184719
182404
  }
184720
182405
  }
@@ -184723,6 +182408,7 @@ function buildPerspBarPrisms(chartData, layout, override) {
184723
182408
  var DEFAULT_GAP_WIDTH2;
184724
182409
  var init_chart_3d_persp_bars = __esm2({
184725
182410
  "src/render/chart-3d-persp-bars.ts"() {
182411
+ init_chart_3d_oblique_bars();
184726
182412
  DEFAULT_GAP_WIDTH2 = 150;
184727
182413
  }
184728
182414
  });
@@ -184814,6 +182500,55 @@ var init_chart_3d_persp_marks = __esm2({
184814
182500
  RIBBON_THICKNESS = 0.012;
184815
182501
  }
184816
182502
  });
182503
+ function isShapedPerspPrism(prism) {
182504
+ return prism.shape !== void 0 && prism.shape !== "box";
182505
+ }
182506
+ function outlineBounds2(prism) {
182507
+ const xs = prism.outline.map(([x]) => x);
182508
+ const ys = prism.outline.map(([, y]) => y);
182509
+ return [Math.min(...xs), Math.max(...xs), Math.min(...ys), Math.max(...ys)];
182510
+ }
182511
+ function buildShapedPrismGeometry(three, prism) {
182512
+ const shape = prism.shape ?? "box";
182513
+ const unit2 = buildObliqueShapeGeometry(
182514
+ three,
182515
+ { shape, taper: prism.taper ?? { bottom: 1, top: 1 } },
182516
+ Boolean(prism.horizontal)
182517
+ );
182518
+ const geometry = unit2.index ? unit2.toNonIndexed() : unit2;
182519
+ if (geometry !== unit2) {
182520
+ unit2.dispose();
182521
+ }
182522
+ const [x0, x1, y0, y1] = outlineBounds2(prism);
182523
+ const sx = Math.max(x1 - x0, 1e-6);
182524
+ const sy = Math.max(y1 - y0, 1e-6);
182525
+ const sz = Math.max(prism.z1 - prism.z0, 1e-6);
182526
+ geometry.scale(sx, sy, sz);
182527
+ geometry.translate((x0 + x1) / 2, (y0 + y1) / 2, (prism.z0 + prism.z1) / 2);
182528
+ geometry.computeVertexNormals();
182529
+ const normals = geometry.getAttribute("normal");
182530
+ const colors = new Float32Array(normals.count * 3);
182531
+ const base = new three.Color(prism.color).getRGB(new three.Color(), three.SRGBColorSpace);
182532
+ const out = new three.Color();
182533
+ for (let i2 = 0; i2 < normals.count; i2++) {
182534
+ const f6 = chart3DNormalShade(shape, normals.getX(i2), normals.getY(i2), -normals.getZ(i2));
182535
+ out.setRGB(
182536
+ Math.min(1, base.r * f6),
182537
+ Math.min(1, base.g * f6),
182538
+ Math.min(1, base.b * f6),
182539
+ three.SRGBColorSpace
182540
+ );
182541
+ colors.set([out.r, out.g, out.b], i2 * 3);
182542
+ }
182543
+ geometry.setAttribute("color", new three.Float32BufferAttribute(colors, 3));
182544
+ return geometry;
182545
+ }
182546
+ var init_chart_3d_persp_shape_mesh = __esm2({
182547
+ "src/render/chart-3d-persp-shape-mesh.ts"() {
182548
+ init_chart_3d_oblique_shape_mesh();
182549
+ init_chart_3d_shading();
182550
+ }
182551
+ });
184817
182552
  function shadePerspGeometry(three, geometry, color2) {
184818
182553
  const normals = geometry.getAttribute("normal");
184819
182554
  const colors = new Float32Array(normals.count * 3);
@@ -184834,6 +182569,9 @@ function shadePerspGeometry(three, geometry, color2) {
184834
182569
  geometry.setAttribute("color", new three.Float32BufferAttribute(colors, 3));
184835
182570
  }
184836
182571
  function buildPrismGeometry(three, prism) {
182572
+ if (isShapedPerspPrism(prism)) {
182573
+ return buildShapedPrismGeometry(three, prism);
182574
+ }
184837
182575
  const shape = new three.Shape(prism.outline.map(([x, y]) => new three.Vector2(x, y)));
184838
182576
  const extruded = new three.ExtrudeGeometry(shape, {
184839
182577
  depth: Math.max(prism.z1 - prism.z0, 1e-6),
@@ -184896,6 +182634,7 @@ function buildPerspMeshes(three, layout, prisms) {
184896
182634
  var GRIDLINE_COLOR5;
184897
182635
  var init_chart_3d_persp_mesh = __esm2({
184898
182636
  "src/render/chart-3d-persp-mesh.ts"() {
182637
+ init_chart_3d_persp_shape_mesh();
184899
182638
  init_chart_3d_persp_view();
184900
182639
  init_chart_3d_shading();
184901
182640
  GRIDLINE_COLOR5 = 14277081;
@@ -185673,24 +183412,6 @@ function buildObliqueCamera(three, svgWidth, svgHeight, shearX, shearY) {
185673
183412
  camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
185674
183413
  return camera;
185675
183414
  }
185676
- function mountPerspectiveScene(perspective2, ctx) {
185677
- switch (perspective2.kind) {
185678
- case "bar":
185679
- return createBarChart3DScene(ctx, perspective2.options);
185680
- case "line":
185681
- return createLineChart3DScene(ctx, perspective2.options);
185682
- case "area":
185683
- return createAreaChart3DScene(ctx, perspective2.options);
185684
- case "pie":
185685
- return createPieChart3DScene(ctx, perspective2.options);
185686
- case "surface":
185687
- return createSurfaceChart3DScene(ctx, perspective2.options);
185688
- default: {
185689
- const exhaustive2 = perspective2;
185690
- return exhaustive2;
185691
- }
185692
- }
185693
- }
185694
183415
  async function mountChart3DView(spec2, ctx) {
185695
183416
  if (spec2.geometry?.kind === "pie") {
185696
183417
  const chartData2 = spec2.element.chartData;
@@ -185719,9 +183440,6 @@ async function mountChart3DView(spec2, ctx) {
185719
183440
  );
185720
183441
  }
185721
183442
  if (spec2.projection.mode !== "oblique" || spec2.geometry?.kind !== "oblique") {
185722
- if (spec2.perspective) {
185723
- return mountPerspectiveScene(spec2.perspective, ctx);
185724
- }
185725
183443
  throw new Error(`no 3D chart scene for chartType=${spec2.chartType}`);
185726
183444
  }
185727
183445
  const three = ctx.three;
@@ -185783,17 +183501,12 @@ async function mountChart3DView(spec2, ctx) {
185783
183501
  }
185784
183502
  var init_chart_3d_view_scene = __esm2({
185785
183503
  "src/render/chart-3d-view-scene.ts"() {
185786
- init_area_chart_3d_scene();
185787
- init_bar_chart_3d_scene();
185788
183504
  init_chart_3d_bar_mesh();
185789
183505
  init_chart_3d_chrome_overlay();
185790
183506
  init_chart_3d_oblique_interaction();
185791
183507
  init_chart_3d_persp_scene();
185792
183508
  init_chart_3d_pie_layout();
185793
183509
  init_chart_3d_pie_scene();
185794
- init_line_chart_3d_scene();
185795
- init_pie_chart_3d_scene();
185796
- init_surface_chart_3d_scene();
185797
183510
  }
185798
183511
  });
185799
183512
  function isSmartArt3DGlassMaterial(material) {
@@ -186603,10 +184316,10 @@ function threeViewOverflowChanged(a, b) {
186603
184316
  return a.top !== b.top || a.right !== b.right || a.bottom !== b.bottom || a.left !== b.left;
186604
184317
  }
186605
184318
  function overflowPixelSize(size, overflow) {
186606
- const clamp13 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
184319
+ const clamp12 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
186607
184320
  return {
186608
- width: clamp13(size.pixelWidth * (1 + overflow.left + overflow.right)),
186609
- height: clamp13(size.pixelHeight * (1 + overflow.top + overflow.bottom))
184321
+ width: clamp12(size.pixelWidth * (1 + overflow.left + overflow.right)),
184322
+ height: clamp12(size.pixelHeight * (1 + overflow.top + overflow.bottom))
186610
184323
  };
186611
184324
  }
186612
184325
  function overflowViewOffset(size, overflow) {
@@ -187144,10 +184857,20 @@ function renderSelectMenu(menu, choices2, value) {
187144
184857
  }
187145
184858
  function positionSelectMenu(menu, trigger) {
187146
184859
  const rect22 = trigger.getBoundingClientRect();
187147
- menu.style.minWidth = `${rect22.width}px`;
187148
- menu.style.maxHeight = `${Math.min(240, Math.max(0, window.innerHeight - rect22.bottom - 8))}px`;
187149
- menu.style.top = `${rect22.bottom + 4}px`;
187150
- menu.style.left = `${Math.max(0, Math.min(rect22.left, window.innerWidth - menu.offsetWidth))}px`;
184860
+ const margin = 8;
184861
+ const gap = 4;
184862
+ const width = Math.max(0, window.innerWidth - margin * 2);
184863
+ const below = Math.max(0, window.innerHeight - rect22.bottom - gap - margin);
184864
+ const above = Math.max(0, rect22.top - gap - margin);
184865
+ menu.style.minWidth = `${Math.min(rect22.width, width)}px`;
184866
+ menu.style.maxWidth = `${width}px`;
184867
+ menu.style.maxHeight = "240px";
184868
+ const preferredHeight = menu.getBoundingClientRect().height;
184869
+ const flip = below < preferredHeight && above > below;
184870
+ menu.style.maxHeight = `${Math.min(240, flip ? above : below)}px`;
184871
+ const { height, width: menuWidth } = menu.getBoundingClientRect();
184872
+ menu.style.top = `${Math.max(margin, flip ? rect22.top - gap - height : rect22.bottom + gap)}px`;
184873
+ menu.style.left = `${Math.max(margin, Math.min(rect22.left, window.innerWidth - menuWidth - margin))}px`;
187151
184874
  }
187152
184875
  function markSelectActive(menu, trigger, active2, open) {
187153
184876
  for (const item3 of menu.querySelectorAll("[data-index]")) {
@@ -187425,6 +185148,9 @@ function definePptxSelect(registry) {
187425
185148
  }
187426
185149
  this.text.textContent = this.choices.find((choice) => choice.value === this.value)?.label ?? "";
187427
185150
  this.trigger.disabled = this.disabled;
185151
+ if (this.disabled) {
185152
+ this.close();
185153
+ }
187428
185154
  this.trigger.setAttribute("aria-label", this.getAttribute("aria-label") ?? "");
187429
185155
  this.internals?.setFormValue?.(this.disabled ? null : this.value);
187430
185156
  if (this.open || this.menu.childElementCount) {
@@ -187433,16 +185159,12 @@ function definePptxSelect(registry) {
187433
185159
  }
187434
185160
  renderMenu() {
187435
185161
  renderSelectMenu(this.menu, this.choices, this.value);
187436
- this.markActive();
185162
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187437
185163
  }
187438
185164
  show() {
187439
185165
  if (this.disabled || !this.choices.some((choice) => !choice.disabled && !choice.hidden) || this.open) {
187440
185166
  return;
187441
185167
  }
187442
- const availableBelow = window.innerHeight - this.trigger.getBoundingClientRect().bottom;
187443
- if (availableBelow < Math.min(this.choices.length * 32 + 12, 160)) {
187444
- this.trigger.scrollIntoView?.({ block: "center" });
187445
- }
187446
185168
  this.open = true;
187447
185169
  this.setAttribute("open", "");
187448
185170
  const selected = this.choices.findIndex(
@@ -187457,7 +185179,7 @@ function definePptxSelect(registry) {
187457
185179
  }
187458
185180
  this.trigger.setAttribute("aria-expanded", "true");
187459
185181
  this.position();
187460
- this.markActive();
185182
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187461
185183
  document.addEventListener("pointerdown", this.onOutside, true);
187462
185184
  window.addEventListener("resize", this.position);
187463
185185
  window.addEventListener("scroll", this.position, true);
@@ -187467,6 +185189,8 @@ function definePptxSelect(registry) {
187467
185189
  return;
187468
185190
  }
187469
185191
  this.open = false;
185192
+ window.clearTimeout(this.searchTimer);
185193
+ this.search = "";
187470
185194
  this.removeAttribute("open");
187471
185195
  if (this.menu.matches(":popover-open")) {
187472
185196
  this.menu.hidePopover();
@@ -187489,9 +185213,6 @@ function definePptxSelect(registry) {
187489
185213
  }
187490
185214
  positionSelectMenu(this.menu, this.trigger);
187491
185215
  };
187492
- markActive() {
187493
- markSelectActive(this.menu, this.trigger, this.active, this.open);
187494
- }
187495
185216
  move(step) {
187496
185217
  if (!this.open) {
187497
185218
  this.show();
@@ -187500,7 +185221,7 @@ function definePptxSelect(registry) {
187500
185221
  return;
187501
185222
  }
187502
185223
  this.active = nextSelectActive(this.choices, this.active, step);
187503
- this.markActive();
185224
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187504
185225
  }
187505
185226
  commit(index) {
187506
185227
  const choice = this.choices[index];
@@ -187528,8 +185249,8 @@ function definePptxSelect(registry) {
187528
185249
  event.preventDefault();
187529
185250
  event.stopPropagation();
187530
185251
  this.show();
187531
- 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);
187532
- this.markActive();
185252
+ this.active = event.key === "Home" ? nextSelectActive(this.choices, -1, 1) : nextSelectActive(this.choices, 0, -1);
185253
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187533
185254
  } else if (event.key === "Enter" || event.key === " ") {
187534
185255
  event.preventDefault();
187535
185256
  event.stopPropagation();
@@ -187543,6 +185264,8 @@ function definePptxSelect(registry) {
187543
185264
  event.stopPropagation();
187544
185265
  this.close();
187545
185266
  this.trigger.focus();
185267
+ } else if (event.key === "Tab") {
185268
+ this.close();
187546
185269
  } else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
187547
185270
  event.stopPropagation();
187548
185271
  this.search += event.key.toLocaleLowerCase();
@@ -187556,7 +185279,7 @@ function definePptxSelect(registry) {
187556
185279
  );
187557
185280
  if (index >= 0) {
187558
185281
  this.active = index;
187559
- this.markActive();
185282
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
187560
185283
  }
187561
185284
  }
187562
185285
  }
@@ -200616,8 +198339,8 @@ function hexToRgb4(hex22) {
200616
198339
  };
200617
198340
  }
200618
198341
  function rgbToHex3(r, g2, b) {
200619
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
200620
- return `#${clamp13(r).toString(16).padStart(2, "0")}${clamp13(g2).toString(16).padStart(2, "0")}${clamp13(b).toString(16).padStart(2, "0")}`;
198342
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
198343
+ return `#${clamp12(r).toString(16).padStart(2, "0")}${clamp12(g2).toString(16).padStart(2, "0")}${clamp12(b).toString(16).padStart(2, "0")}`;
200621
198344
  }
200622
198345
  function rgbToHsl2(r, g2, b) {
200623
198346
  const rn = r / 255;
@@ -207991,8 +205714,8 @@ function hexToRgb5(hex22) {
207991
205714
  };
207992
205715
  }
207993
205716
  function rgbToHex4(r, g2, b) {
207994
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
207995
- 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()}`;
205717
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
205718
+ 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()}`;
207996
205719
  }
207997
205720
  function tintColor(hex22, tintFactor) {
207998
205721
  const { r, g: g2, b } = hexToRgb5(hex22);
@@ -223167,8 +220890,8 @@ function hexToRgb6(hex22) {
223167
220890
  };
223168
220891
  }
223169
220892
  function rgbToHex5(r, g2, b) {
223170
- const clamp13 = (v) => Math.max(0, Math.min(255, Math.round(v)));
223171
- 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()}`;
220893
+ const clamp12 = (v) => Math.max(0, Math.min(255, Math.round(v)));
220894
+ 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()}`;
223172
220895
  }
223173
220896
  function tintColor2(hex22, tintFactor) {
223174
220897
  const { r, g: g2, b } = hexToRgb6(hex22);
@@ -232661,242 +230384,6 @@ function buildSmartArt3DSpecForElement(element, options = {}) {
232661
230384
  });
232662
230385
  return model.meshes.length > 0 ? model : null;
232663
230386
  }
232664
- init_cartesian_line_chart_3d_layout();
232665
- init_chart_3d_surfaces();
232666
- init_chart_datapoint_style();
232667
- init_chart_view_model();
232668
- function buildPoints(chartData, catCount) {
232669
- const series = chartData.series;
232670
- const palette = chartData.colorPalette;
232671
- const points4 = [];
232672
- for (let si = 0; si < series.length; si++) {
232673
- const baseColor = seriesColor22(series[si], si, palette);
232674
- for (let ci = 0; ci < catCount; ci++) {
232675
- const value = series[si].values[ci] ?? 0;
232676
- const color2 = resolveDataPointFill(series[si], ci, paletteColor2(si, palette)) ?? baseColor;
232677
- points4.push({ seriesIndex: si, categoryIndex: ci, value, color: color2 });
232678
- }
232679
- }
232680
- return points4;
232681
- }
232682
- function buildCartesianLine3DSceneData(chartData, categoryLabels, options) {
232683
- const rows = chartData.series.length;
232684
- const cols = categoryLabels.length;
232685
- if (rows === 0 || cols === 0) {
232686
- return null;
232687
- }
232688
- const points4 = buildPoints(chartData, cols);
232689
- const range = computeValueRange2(chartData.series, options.height);
232690
- const depthPercent = chartData.view3D?.depthPercent;
232691
- const series = layoutCartesianLine3DSeries(points4, cols, rows, range, depthPercent);
232692
- return {
232693
- cols,
232694
- rows,
232695
- series,
232696
- categoryLabels,
232697
- seriesNames: chartData.series.map((s) => s.name),
232698
- numberFormats: chartData.series.map((s) => s.numberFormat),
232699
- width: options.width,
232700
- height: options.height,
232701
- view3D: chartData.view3D ? {
232702
- rotX: chartData.view3D.rotX,
232703
- rotY: chartData.view3D.rotY,
232704
- rperspective: chartData.view3D.perspective,
232705
- depthPercent: chartData.view3D.depthPercent,
232706
- rAngAx: chartData.view3D.rAngAx
232707
- } : void 0,
232708
- wallColors: resolveChart3DWallColors(chartData)
232709
- };
232710
- }
232711
- function buildAreaChart3DDataForElement(element, options) {
232712
- if (element.type !== "chart") {
232713
- return null;
232714
- }
232715
- const chartEl = element;
232716
- const chartData = chartEl.chartData;
232717
- if (!chartData || chartData.series.length === 0) {
232718
- return null;
232719
- }
232720
- if (chartData.chartType !== "area3D") {
232721
- return null;
232722
- }
232723
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
232724
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
232725
- return buildCartesianLine3DSceneData(chartData, categoryLabels, options);
232726
- }
232727
- init_cartesian_chart_3d_geom();
232728
- function coneToMaxTopRadiusFactor(shape, value, max) {
232729
- if (shape !== "coneToMax" && shape !== "pyramidToMax") {
232730
- return void 0;
232731
- }
232732
- if (!(max > 0)) {
232733
- return 0;
232734
- }
232735
- return Math.max(0, Math.min(1, 1 - Math.abs(value) / max));
232736
- }
232737
- var MIN_BOX_HEIGHT = 0.02;
232738
- var BOX_GAP = 0.15;
232739
- function normalizeToHeight2(value, range) {
232740
- if (range.span <= 0) {
232741
- return 0;
232742
- }
232743
- return (value - range.min) / range.span * MAX_VALUE_HEIGHT;
232744
- }
232745
- function layoutClustered(points4, cols, rows, range, depthPercent) {
232746
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
232747
- const colStep = gridWidth / cols;
232748
- const rowStep = gridDepth / Math.max(rows, 1);
232749
- const boxW = colStep * (1 - BOX_GAP);
232750
- const boxD = rowStep * (1 - BOX_GAP);
232751
- const zeroH = normalizeToHeight2(0, range);
232752
- return points4.map((p) => {
232753
- const valueH = normalizeToHeight2(p.plotValue, range);
232754
- const top = Math.max(valueH, zeroH);
232755
- const bottom = Math.min(valueH, zeroH);
232756
- const h2 = Math.max(top - bottom, MIN_BOX_HEIGHT);
232757
- const x = -gridWidth / 2 + colStep * (p.categoryIndex + 0.5);
232758
- const z = -gridDepth / 2 + rowStep * (p.seriesIndex + 0.5);
232759
- return {
232760
- seriesIndex: p.seriesIndex,
232761
- categoryIndex: p.categoryIndex,
232762
- value: p.value,
232763
- color: p.color,
232764
- center: [x, bottom + h2 / 2, z],
232765
- size: [boxW, h2, boxD],
232766
- shape: p.shape,
232767
- coneToMaxTopRadiusFactor: coneToMaxTopRadiusFactor(p.shape, p.value, range.max)
232768
- };
232769
- });
232770
- }
232771
- function layoutStacked(points4, cols, rows, range, depthPercent) {
232772
- const { gridWidth, gridDepth } = computeCartesianGridExtent(cols, rows, depthPercent);
232773
- const colStep = gridWidth / cols;
232774
- const boxW = colStep * (1 - BOX_GAP);
232775
- const boxD = gridDepth * (1 - BOX_GAP);
232776
- const boxes = [];
232777
- for (let ci = 0; ci < cols; ci++) {
232778
- const x = -gridWidth / 2 + colStep * (ci + 0.5);
232779
- let posRunning = 0;
232780
- let negRunning = 0;
232781
- const catPoints = points4.filter((p) => p.categoryIndex === ci).sort((a, b) => a.seriesIndex - b.seriesIndex);
232782
- for (const p of catPoints) {
232783
- const isNeg = p.plotValue < 0;
232784
- const base = isNeg ? negRunning : posRunning;
232785
- const top = base + p.plotValue;
232786
- if (isNeg) {
232787
- negRunning = top;
232788
- } else {
232789
- posRunning = top;
232790
- }
232791
- const baseH = normalizeToHeight2(base, range);
232792
- const topH = normalizeToHeight2(top, range);
232793
- const h2 = Math.max(Math.abs(topH - baseH), MIN_BOX_HEIGHT);
232794
- boxes.push({
232795
- seriesIndex: p.seriesIndex,
232796
- categoryIndex: p.categoryIndex,
232797
- value: p.value,
232798
- color: p.color,
232799
- center: [x, Math.min(baseH, topH) + h2 / 2, 0],
232800
- size: [boxW, h2, boxD],
232801
- shape: p.shape,
232802
- coneToMaxTopRadiusFactor: coneToMaxTopRadiusFactor(p.shape, p.value, range.max)
232803
- });
232804
- }
232805
- }
232806
- return boxes;
232807
- }
232808
- function layoutBarChart3D(points4, cols, rows, range, grouping, depthPercent, horizontal = false) {
232809
- const boxes = grouping === "clustered" ? layoutClustered(points4, cols, rows, range, depthPercent) : layoutStacked(points4, cols, rows, range, depthPercent);
232810
- if (!horizontal) {
232811
- return boxes;
232812
- }
232813
- return boxes.map((box) => ({ ...box, center: transposeForHorizontalBar3D(box.center) }));
232814
- }
232815
- init_chart_3d_surfaces();
232816
- init_chart_datapoint_style();
232817
- init_chart_view_model();
232818
- function categoryTotals3(series, catCount) {
232819
- return Array.from(
232820
- { length: catCount },
232821
- (_, ci) => series.reduce((sum, s) => sum + Math.abs(s.values[ci] ?? 0), 0)
232822
- );
232823
- }
232824
- function buildPoints2(chartData, catCount, isPercent) {
232825
- const series = chartData.series;
232826
- const palette = chartData.colorPalette;
232827
- const totals = isPercent ? categoryTotals3(series, catCount) : void 0;
232828
- const points4 = [];
232829
- for (let si = 0; si < series.length; si++) {
232830
- const baseColor = seriesColor22(series[si], si, palette);
232831
- for (let ci = 0; ci < catCount; ci++) {
232832
- const value = series[si].values[ci] ?? 0;
232833
- const color2 = resolveDataPointFill(series[si], ci, paletteColor2(si, palette)) ?? baseColor;
232834
- const catTotal = totals?.[ci];
232835
- const plotValue = isPercent && catTotal !== void 0 && catTotal > 0 ? value / catTotal * 100 : value;
232836
- points4.push({
232837
- seriesIndex: si,
232838
- categoryIndex: ci,
232839
- value,
232840
- plotValue,
232841
- color: color2,
232842
- // Per-series `c:ser/c:shape` wins over the chart-level `c:bar3DChart/c:shape`.
232843
- shape: series[si].shape ?? chartData.barShape
232844
- });
232845
- }
232846
- }
232847
- return points4;
232848
- }
232849
- function buildBarChart3DData(chartData, categoryLabels, options) {
232850
- const rows = chartData.series.length;
232851
- const cols = categoryLabels.length;
232852
- if (rows === 0 || cols === 0) {
232853
- return null;
232854
- }
232855
- const grouping = chartData.grouping === "stacked" || chartData.grouping === "percentStacked" ? chartData.grouping : "clustered";
232856
- const isPercent = grouping === "percentStacked";
232857
- const horizontal = chartData.barDirection === "bar";
232858
- const points4 = buildPoints2(chartData, cols, isPercent);
232859
- const range = isPercent ? { min: 0, max: 100, span: 100 } : grouping === "stacked" ? computeStackedValueRange(chartData.series, cols, options.height) : computeValueRange2(chartData.series, options.height);
232860
- const depthPercent = chartData.view3D?.depthPercent;
232861
- const boxes = layoutBarChart3D(points4, cols, rows, range, grouping, depthPercent, horizontal);
232862
- return {
232863
- cols,
232864
- rows,
232865
- boxes,
232866
- categoryLabels,
232867
- seriesNames: chartData.series.map((s) => s.name),
232868
- numberFormats: chartData.series.map((s) => s.numberFormat),
232869
- grouping,
232870
- width: options.width,
232871
- height: options.height,
232872
- view3D: chartData.view3D ? {
232873
- rotX: chartData.view3D.rotX,
232874
- rotY: chartData.view3D.rotY,
232875
- rperspective: chartData.view3D.perspective,
232876
- depthPercent: chartData.view3D.depthPercent,
232877
- rAngAx: chartData.view3D.rAngAx
232878
- } : void 0,
232879
- wallColors: resolveChart3DWallColors(chartData),
232880
- picture: { series: chartData.series },
232881
- ...horizontal ? { horizontal: true } : {}
232882
- };
232883
- }
232884
- function buildBarChart3DDataForElement(element, options) {
232885
- if (element.type !== "chart") {
232886
- return null;
232887
- }
232888
- const chartEl = element;
232889
- const chartData = chartEl.chartData;
232890
- if (!chartData || chartData.series.length === 0) {
232891
- return null;
232892
- }
232893
- if (chartData.chartType !== "bar3D") {
232894
- return null;
232895
- }
232896
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
232897
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
232898
- return buildBarChart3DData(chartData, categoryLabels, options);
232899
- }
232900
230387
  init_chart_3d_oblique_bars();
232901
230388
  init_chart_view_model_chrome();
232902
230389
  var PT = 4 / 3;
@@ -233385,16 +230872,16 @@ var DEFAULT_ROT_X3 = 15;
233385
230872
  var DEFAULT_ROT_Y2 = 20;
233386
230873
  var DEFAULT_PIE_ROT_X = 30;
233387
230874
  var DEFAULT_PIE_ROT_Y = 0;
233388
- var DEFAULT_PERSPECTIVE_DEG2 = 30;
233389
- var PERSPECTIVE_MAX_DEG2 = 120;
233390
- var FOV_MIN2 = 15;
233391
- var FOV_MAX2 = 75;
233392
- function clamp82(value, min, max) {
230875
+ var DEFAULT_PERSPECTIVE_DEG = 30;
230876
+ var PERSPECTIVE_MAX_DEG = 120;
230877
+ var FOV_MIN = 15;
230878
+ var FOV_MAX = 75;
230879
+ function clamp7(value, min, max) {
233393
230880
  return Math.min(Math.max(value, min), max);
233394
230881
  }
233395
230882
  function resolvePerspectiveFov(perspectiveDeg) {
233396
- const perspective2 = clamp82(perspectiveDeg ?? DEFAULT_PERSPECTIVE_DEG2, 0, PERSPECTIVE_MAX_DEG2);
233397
- return FOV_MIN2 + perspective2 / PERSPECTIVE_MAX_DEG2 * (FOV_MAX2 - FOV_MIN2);
230883
+ const perspective2 = clamp7(perspectiveDeg ?? DEFAULT_PERSPECTIVE_DEG, 0, PERSPECTIVE_MAX_DEG);
230884
+ return FOV_MIN + perspective2 / PERSPECTIVE_MAX_DEG * (FOV_MAX - FOV_MIN);
233398
230885
  }
233399
230886
  function resolveChart3DProjection(chartType, view3D) {
233400
230887
  const isPie = chartType === "pie3D";
@@ -233420,149 +230907,6 @@ function resolveChart3DProjection(chartType, view3D) {
233420
230907
  };
233421
230908
  }
233422
230909
  init_chart_view_model_build();
233423
- function buildLineChart3DDataForElement(element, options) {
233424
- if (element.type !== "chart") {
233425
- return null;
233426
- }
233427
- const chartEl = element;
233428
- const chartData = chartEl.chartData;
233429
- if (!chartData || chartData.series.length === 0) {
233430
- return null;
233431
- }
233432
- if (chartData.chartType !== "line3D") {
233433
- return null;
233434
- }
233435
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
233436
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
233437
- return buildCartesianLine3DSceneData(chartData, categoryLabels, options);
233438
- }
233439
- init_chart_datapoint_style();
233440
- init_chart_view_model();
233441
- init_pie_chart_3d_geom();
233442
- function buildPieChart3DData(chartData, categoryLabels, options) {
233443
- const pieSeries = chartData.series[0];
233444
- if (!pieSeries || pieSeries.values.length === 0) {
233445
- return null;
233446
- }
233447
- const values = pieSeries.values;
233448
- const explosions = values.map((_v, i2) => resolveDataPointExplosion(pieSeries, i2));
233449
- const outerRadius = PIE_RADIUS;
233450
- const angles = computePieChart3DSliceAngles(
233451
- values,
233452
- explosions,
233453
- chartData.firstSliceAngle,
233454
- outerRadius
233455
- );
233456
- const wedges = angles.map((angle) => ({
233457
- ...angle,
233458
- color: resolveVaryColorFill(
233459
- pieSeries,
233460
- angle.pointIndex,
233461
- paletteColor2(angle.pointIndex, chartData.colorPalette)
233462
- )
233463
- }));
233464
- const view3D = chartData.view3D ? {
233465
- rotX: chartData.view3D.rotX,
233466
- rotY: chartData.view3D.rotY,
233467
- rperspective: chartData.view3D.perspective,
233468
- rAngAx: chartData.view3D.rAngAx,
233469
- hPercent: chartData.view3D.hPercent
233470
- } : void 0;
233471
- return {
233472
- wedges,
233473
- categoryLabels,
233474
- seriesName: pieSeries.name,
233475
- numberFormat: pieSeries.numberFormat,
233476
- outerRadius,
233477
- thickness: computePieChart3DThickness(view3D),
233478
- width: options.width,
233479
- height: options.height,
233480
- view3D,
233481
- values,
233482
- explosions,
233483
- firstSliceAngleDeg: chartData.firstSliceAngle
233484
- };
233485
- }
233486
- function buildPieChart3DDataForElement(element, options) {
233487
- if (element.type !== "chart") {
233488
- return null;
233489
- }
233490
- const chartEl = element;
233491
- const chartData = chartEl.chartData;
233492
- if (!chartData || chartData.series.length === 0) {
233493
- return null;
233494
- }
233495
- if (chartData.chartType !== "pie3D") {
233496
- return null;
233497
- }
233498
- const pieSeries = chartData.series[0];
233499
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: pieSeries.values.length }, (_, i2) => String(i2 + 1));
233500
- return buildPieChart3DData(chartData, categoryLabels, options);
233501
- }
233502
- init_chart_3d_surfaces();
233503
- init_chart_surface_bands();
233504
- init_chart_surface_treemap();
233505
- init_chart_view_model();
233506
- function resolveSurfaceColors(chartData) {
233507
- return resolveChart3DWallColors(chartData);
233508
- }
233509
- function buildSurfaceChart3DData(chartData, categoryLabels, options) {
233510
- const seriesCount = chartData.series.length;
233511
- const catCount = categoryLabels.length;
233512
- if (seriesCount === 0 || catCount === 0) {
233513
- return null;
233514
- }
233515
- const range = computeValueRange2(chartData.series, options.height);
233516
- const heightMap = new Float32Array(seriesCount * catCount);
233517
- const colorMap = new Float32Array(seriesCount * catCount * 3);
233518
- const values = new Float32Array(seriesCount * catCount);
233519
- for (let row = 0; row < seriesCount; row++) {
233520
- for (let col = 0; col < catCount; col++) {
233521
- const idx = row * catCount + col;
233522
- const val2 = chartData.series[row]?.values[col] ?? 0;
233523
- values[idx] = val2;
233524
- const t = range.span > 0 ? (val2 - range.min) / range.span : 0;
233525
- heightMap[idx] = t;
233526
- const bandFill = resolveSurfaceBandFill(t, chartData.bandFmts);
233527
- const { r, g: g2, b } = bandFill ? hexToRgb4(bandFill) : surfaceColor(t);
233528
- const ci = idx * 3;
233529
- colorMap[ci] = r / 255;
233530
- colorMap[ci + 1] = g2 / 255;
233531
- colorMap[ci + 2] = b / 255;
233532
- }
233533
- }
233534
- return {
233535
- cols: catCount,
233536
- rows: seriesCount,
233537
- heightMap,
233538
- colorMap,
233539
- values,
233540
- numberFormats: chartData.series.map((s) => s.numberFormat),
233541
- wireframe: options.wireframe ?? chartData.wireframe ?? true,
233542
- categoryLabels,
233543
- seriesNames: chartData.series.map((s) => s.name),
233544
- width: options.width,
233545
- height: options.height,
233546
- view3D: chartData.view3D ? { rotX: chartData.view3D.rotX, rotY: chartData.view3D.rotY } : void 0,
233547
- surfaceColors: resolveSurfaceColors(chartData)
233548
- };
233549
- }
233550
- function buildSurfaceChart3DDataForElement(element, options) {
233551
- if (element.type !== "chart") {
233552
- return null;
233553
- }
233554
- const chartEl = element;
233555
- const chartData = chartEl.chartData;
233556
- if (!chartData || chartData.series.length === 0) {
233557
- return null;
233558
- }
233559
- if (resolveChartKind(chartData.chartType ?? "bar") !== "surface") {
233560
- return null;
233561
- }
233562
- const longestLen = chartData.series.reduce((m, s) => Math.max(m, s.values.length), 0);
233563
- const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longestLen }, (_, i2) => String(i2 + 1));
233564
- return buildSurfaceChart3DData(chartData, categoryLabels, options);
233565
- }
233566
230910
  var CHART_3D_TYPES = /* @__PURE__ */ new Set([
233567
230911
  "bar3D",
233568
230912
  "line3D",
@@ -233599,6 +230943,9 @@ function buildChart3DSpecForElement(element) {
233599
230943
  const vm = buildChartViewModel(element);
233600
230944
  const projection = resolveChart3DProjection(chartType, chartData.view3D);
233601
230945
  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;
230946
+ if (!geometry) {
230947
+ return null;
230948
+ }
233602
230949
  const longest = chartData.series.reduce((m, series) => Math.max(m, series.values.length), 0);
233603
230950
  const categoryLabels = chartData.categories.length > 0 ? chartData.categories : Array.from({ length: longest }, (_, i2) => String(i2 + 1));
233604
230951
  return {
@@ -233609,37 +230956,9 @@ function buildChart3DSpecForElement(element) {
233609
230956
  projection,
233610
230957
  vm,
233611
230958
  geometry,
233612
- categoryLabels,
233613
- perspective: geometry ? null : buildPerspectiveScene(element)
230959
+ categoryLabels
233614
230960
  };
233615
230961
  }
233616
- function buildPerspectiveScene(element) {
233617
- const size = { width: element.width, height: element.height };
233618
- switch (element.chartData?.chartType) {
233619
- case "bar3D": {
233620
- const options = buildBarChart3DDataForElement(element, size);
233621
- return options ? { kind: "bar", options } : null;
233622
- }
233623
- case "line3D": {
233624
- const options = buildLineChart3DDataForElement(element, size);
233625
- return options ? { kind: "line", options } : null;
233626
- }
233627
- case "area3D": {
233628
- const options = buildAreaChart3DDataForElement(element, size);
233629
- return options ? { kind: "area", options } : null;
233630
- }
233631
- case "pie3D": {
233632
- const options = buildPieChart3DDataForElement(element, size);
233633
- return options ? { kind: "pie", options } : null;
233634
- }
233635
- case "surface": {
233636
- const options = buildSurfaceChart3DDataForElement(element, size);
233637
- return options ? { kind: "surface", options } : null;
233638
- }
233639
- default:
233640
- return null;
233641
- }
233642
- }
233643
230962
  function observeElementHeight(el, onHeight) {
233644
230963
  onHeight(el.getBoundingClientRect().height);
233645
230964
  if (typeof ResizeObserver === "undefined") {
@@ -234000,19 +231319,7 @@ async function mountModel3D(container, modelUrl, options) {
234000
231319
  }
234001
231320
  };
234002
231321
  }
234003
- init_surface_chart_3d_geom();
234004
- init_surface_chart_3d_scene();
234005
- init_surface_chart_3d_hit_test();
234006
- init_cartesian_chart_3d_geom();
234007
- init_bar_chart_3d_scene();
234008
231322
  init_bar_chart_3d_hit_test();
234009
- init_cartesian_line_chart_3d_layout();
234010
- init_cartesian_chart_3d_hit_test();
234011
- init_line_chart_3d_scene();
234012
- init_area_chart_3d_scene();
234013
- init_pie_chart_3d_geom();
234014
- init_pie_chart_3d_scene();
234015
- init_pie_chart_3d_hit_test();
234016
231323
  init_text_wrap_estimate();
234017
231324
  function collectFontsFromElement(element, fonts) {
234018
231325
  if (hasTextProperties(element)) {
@@ -240454,16 +237761,16 @@ function trimmedMediaDurationMs(trimStartMs, trimEndMs, durationMs) {
240454
237761
  }
240455
237762
  return effectiveEnd - trimStartMs;
240456
237763
  }
240457
- function clamp12(value, minimum, maximum) {
237764
+ function clamp11(value, minimum, maximum) {
240458
237765
  return Math.min(maximum, Math.max(minimum, value));
240459
237766
  }
240460
237767
  function mediaTrimEndSeconds(durationSeconds, trimEndMs) {
240461
237768
  const duration = Math.max(0, durationSeconds);
240462
- return trimEndMs > 0 ? clamp12(duration - trimEndMs / 1e3, 0, duration) : duration;
237769
+ return trimEndMs > 0 ? clamp11(duration - trimEndMs / 1e3, 0, duration) : duration;
240463
237770
  }
240464
237771
  function mediaTrimEndMsFromSeconds(durationSeconds, endSeconds) {
240465
237772
  const duration = Math.max(0, durationSeconds);
240466
- return Math.max(0, duration - clamp12(endSeconds, 0, duration)) * 1e3;
237773
+ return Math.max(0, duration - clamp11(endSeconds, 0, duration)) * 1e3;
240467
237774
  }
240468
237775
  function buildSummaryZoomView(element, lookup, translate) {
240469
237776
  if (element.zoomType !== "summary" || !element.summaryTargets?.length) {
@@ -243315,9 +240622,9 @@ function resolveAuthoredSlideRange(selection, slideCount) {
243315
240622
  if (typeof from !== "number" || typeof to !== "number" || !Number.isFinite(from) || !Number.isFinite(to)) {
243316
240623
  return void 0;
243317
240624
  }
243318
- const clamp13 = (value) => Math.min(Math.max(Math.round(value), 1), slideCount);
243319
- const clampedFrom = clamp13(from);
243320
- const clampedTo = clamp13(to);
240625
+ const clamp12 = (value) => Math.min(Math.max(Math.round(value), 1), slideCount);
240626
+ const clampedFrom = clamp12(from);
240627
+ const clampedTo = clamp12(to);
243321
240628
  return {
243322
240629
  fromIndex: Math.min(clampedFrom, clampedTo) - 1,
243323
240630
  toIndex: Math.max(clampedFrom, clampedTo) - 1
@@ -247734,14 +245041,14 @@ function shadowMatches(style, spec2) {
247734
245041
  }
247735
245042
  function tileEffects(spec2) {
247736
245043
  const { x, y } = shadowOffsets(spec2.distEmu, spec2.dir);
247737
- const clamp13 = (v) => Math.max(-4, Math.min(4, v * 0.6));
245044
+ const clamp12 = (v) => Math.max(-4, Math.min(4, v * 0.6));
247738
245045
  return {
247739
245046
  shadow: {
247740
245047
  color: "#000000",
247741
245048
  opacity: Math.min(0.8, (spec2.alpha ?? 1e5) / 1e5 + 0.25),
247742
245049
  blur: Math.min(6, spec2.blurEmu / EMU_PER_PX62 / 1.5),
247743
- dx: clamp13(x),
247744
- dy: clamp13(y) + (spec2.sy !== void 0 && spec2.sy < 0 ? 3 : 0),
245050
+ dx: clamp12(x),
245051
+ dy: clamp12(y) + (spec2.sy !== void 0 && spec2.sy < 0 ? 3 : 0),
247745
245052
  inner: spec2.kind === "inner"
247746
245053
  }
247747
245054
  };
@@ -249154,9 +246461,9 @@ function effectFilter(style, id) {
249154
246461
  merge.push('<feMergeNode in="glow"/>');
249155
246462
  }
249156
246463
  if (style.textShadowColor) {
249157
- const clamp13 = (v) => Math.max(-2, Math.min(2, (v ?? 0) / 2));
246464
+ const clamp12 = (v) => Math.max(-2, Math.min(2, (v ?? 0) / 2));
249158
246465
  parts.push(
249159
- `<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"/>`
246466
+ `<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"/>`
249160
246467
  );
249161
246468
  merge.push('<feMergeNode in="shadow"/>');
249162
246469
  } else {
@@ -250833,9 +248140,6 @@ function getActiveXControlOverlayView(control, slideSize, index = 0, resolveFall
250833
248140
  className: imageUrl ? "image" : "placeholder"
250834
248141
  };
250835
248142
  }
250836
- init_bar_chart_3d_geometry();
250837
- init_bar_chart_3d_face_fill();
250838
- init_bar_chart_3d_materials();
250839
248143
  init_chart_bar3d_face_picture_sample();
250840
248144
  var BAR3D_SHAPE_OPTIONS = [
250841
248145
  { value: "box", labelKey: "pptx.chart.bar3DShapeBox" },
@@ -251501,10 +248805,6 @@ var ThreeViewController = class {
251501
248805
  spec2.spec,
251502
248806
  {
251503
248807
  three,
251504
- // No camera orbit: PowerPoint never rotates a chart or SmartArt
251505
- // under the pointer, and an orbit would turn the scene while the
251506
- // user drags the element to move it on the slide.
251507
- OrbitControls: null,
251508
248808
  size: this.size,
251509
248809
  eventTarget: this.opts.eventTarget,
251510
248810
  overlay,
@@ -251633,12 +248933,12 @@ function computeThreeViewSize(layoutWidth, layoutHeight, screenWidth, screenHeig
251633
248933
  const dpr = Math.min(MAX_DEVICE_PIXEL_RATIO, Math.max(1, devicePixelRatio || 1));
251634
248934
  const onScreenW = screenWidth > 0 ? screenWidth : width;
251635
248935
  const onScreenH = screenHeight > 0 ? screenHeight : height;
251636
- const clamp13 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
248936
+ const clamp12 = (px32) => Math.max(1, Math.min(MAX_VIEW_PIXELS, Math.round(px32)));
251637
248937
  return {
251638
248938
  width,
251639
248939
  height,
251640
- pixelWidth: clamp13(onScreenW * dpr),
251641
- pixelHeight: clamp13(onScreenH * dpr)
248940
+ pixelWidth: clamp12(onScreenW * dpr),
248941
+ pixelHeight: clamp12(onScreenH * dpr)
251642
248942
  };
251643
248943
  }
251644
248944
  function measureThreeViewSize(element) {