pptx-angular-viewer 4.7.0 → 4.8.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 (25) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/fesm2022/pptx-angular-viewer-chart-3d-view-scene-CM71j9A9.mjs +1703 -0
  3. package/fesm2022/pptx-angular-viewer-chart-3d-view-scene-CM71j9A9.mjs.map +1 -0
  4. package/fesm2022/{pptx-angular-viewer-chat-history-idb-D_SZnX0q.mjs → pptx-angular-viewer-chat-history-idb-7dyn_ZbD.mjs} +2 -2
  5. package/fesm2022/{pptx-angular-viewer-chat-history-idb-D_SZnX0q.mjs.map → pptx-angular-viewer-chat-history-idb-7dyn_ZbD.mjs.map} +1 -1
  6. package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-D3TADvW3.mjs → pptx-angular-viewer-pptx-angular-viewer-Cf08ueRA.mjs} +3769 -1247
  7. package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-D3TADvW3.mjs.map → pptx-angular-viewer-pptx-angular-viewer-Cf08ueRA.mjs.map} +1 -1
  8. package/fesm2022/pptx-angular-viewer-view-scene-Bn9SJZk9.mjs +862 -0
  9. package/fesm2022/pptx-angular-viewer-view-scene-Bn9SJZk9.mjs.map +1 -0
  10. package/fesm2022/pptx-angular-viewer.mjs +1 -1
  11. package/i18n/de.cjs +64 -96
  12. package/i18n/de.mjs +64 -96
  13. package/i18n/es.cjs +64 -96
  14. package/i18n/es.mjs +64 -96
  15. package/i18n/fr.cjs +64 -96
  16. package/i18n/fr.mjs +64 -96
  17. package/i18n/zh-CN.cjs +63 -95
  18. package/i18n/zh-CN.mjs +63 -95
  19. package/package.json +2 -2
  20. package/types/pptx-angular-viewer.d.ts +508 -77
  21. package/types/pptx-angular-viewer.d.ts.map +1 -1
  22. package/fesm2022/pptx-angular-viewer-chart-3d-view-scene-CFWKnfML.mjs +0 -470
  23. package/fesm2022/pptx-angular-viewer-chart-3d-view-scene-CFWKnfML.mjs.map +0 -1
  24. package/fesm2022/pptx-angular-viewer-view-scene-C5oUG9yl.mjs +0 -235
  25. package/fesm2022/pptx-angular-viewer-view-scene-C5oUG9yl.mjs.map +0 -1
@@ -1,470 +0,0 @@
1
- import { s as shade, c as createSvgEl, r as renderChartLineSvg, a as renderChartTextSvg, b as appendChartLegendSvg, d as dragAnchorViewY, e as advanceChartValueDrag, f as buildBarChart3DHoverTooltip, i as isChartInteractionArmed, g as beginChartValueDrag, C as CHART_3D_DRAG_THRESHOLD_PX, h as createSurfaceChart3DScene, j as createPieChart3DScene, k as createAreaChart3DScene, l as createLineChart3DScene, m as createBarChart3DScene } from './pptx-angular-viewer-pptx-angular-viewer-D3TADvW3.mjs';
2
-
3
- /**
4
- * chart-3d-shading.ts: PowerPoint's flat chart-space shading for a 3D chart's
5
- * box faces, as one colour multiplier per named face.
6
- *
7
- * PowerPoint's 3D charts (bar3D, pie3D, line3D ribbons, area3D slabs, surface
8
- * bands) are flat-shaded in "chart space": every face of a given orientation
9
- * gets the SAME multiplier applied to the mark's base colour, regardless of
10
- * the chart's `c:view3D` tilt. Measured directly off the pixels of
11
- * `gt/chart-01.webp` (a 3-D Clustered Column, series 1 = theme accent1
12
- * `#156082`): the front (camera-facing) rect samples the base colour exactly
13
- * (`front = base`), the top face samples ~0.75x, and the visible side face
14
- * ~0.64x. `back`/`left` (mirrors of `right`) and `bottom` (rarely visible)
15
- * are not independently measured; `back`/`left` reuse the measured side
16
- * multiplier and `bottom` is a reasonable approximation between side and a
17
- * fully unlit face.
18
- *
19
- * @module chart-3d-shading
20
- */
21
- /**
22
- * Darken amount (0-1, `chart-palette.ts#shade`'s `amount`) per face,
23
- * derived from the measured multipliers: `amount = 1 - multiplier`.
24
- */
25
- const FACE_SHADE_AMOUNT = {
26
- front: 0,
27
- top: 0.25,
28
- right: 0.36,
29
- left: 0.36,
30
- back: 0.36,
31
- bottom: 0.5,
32
- };
33
- /** Apply PowerPoint's measured per-face flat shading to a mark's base colour. */
34
- function shadeChart3DFace(baseColor, face) {
35
- const amount = FACE_SHADE_AMOUNT[face];
36
- return amount === 0 ? baseColor : shade(baseColor, amount);
37
- }
38
- /**
39
- * The six face colours for a box mesh, in the order three.js `BoxGeometry`
40
- * expects its `material` array (`[+x, -x, +y, -y, +z, -z]`): right, left,
41
- * top, bottom, front, back. `front`/`back` name whichever world axis the
42
- * scene treats as the camera-facing depth axis; the caller picks that
43
- * mapping (see `chart-3d-view-scene.ts`).
44
- */
45
- function buildChart3DBoxFaceColors(baseColor) {
46
- return [
47
- shadeChart3DFace(baseColor, 'right'),
48
- shadeChart3DFace(baseColor, 'left'),
49
- shadeChart3DFace(baseColor, 'top'),
50
- shadeChart3DFace(baseColor, 'bottom'),
51
- shadeChart3DFace(baseColor, 'front'),
52
- shadeChart3DFace(baseColor, 'back'),
53
- ];
54
- }
55
-
56
- /**
57
- * Build one `THREE.Mesh` per box and add them to a new `THREE.Group`. World
58
- * coordinates: X/Y centred on the chart's own `svgWidth`/`svgHeight` (X
59
- * right, Y UP - the SVG Y-down front rect is flipped here), Z=0 at the
60
- * front face, extending negative (away from the camera) by the box's own
61
- * depth.
62
- */
63
- function buildChart3DBarMeshes(three, boxes, svgWidth, svgHeight) {
64
- const group = new three.Group();
65
- const meshes = [];
66
- const geometries = [];
67
- const materials = [];
68
- const halfW = svgWidth / 2;
69
- const halfH = svgHeight / 2;
70
- for (const box of boxes) {
71
- const geometry = new three.BoxGeometry(1, 1, 1);
72
- geometries.push(geometry);
73
- const faceMaterials = buildChart3DBoxFaceColors(box.color).map((color) => new three.MeshBasicMaterial({ color }));
74
- materials.push(...faceMaterials);
75
- const mesh = new three.Mesh(geometry, faceMaterials);
76
- const zDepth = box.depthMagnitude;
77
- mesh.position.set(box.x + box.w / 2 - halfW, halfH - (box.y + box.h / 2), -zDepth / 2);
78
- mesh.scale.set(box.w, box.h, zDepth);
79
- mesh.userData = { seriesIndex: box.seriesIndex, categoryIndex: box.categoryIndex };
80
- group.add(mesh);
81
- meshes.push(mesh);
82
- }
83
- return {
84
- group,
85
- meshes,
86
- dispose: () => {
87
- for (const geometry of geometries) {
88
- geometry.dispose();
89
- }
90
- for (const material of materials) {
91
- material.dispose();
92
- }
93
- },
94
- };
95
- }
96
-
97
- /**
98
- * chart-3d-chrome-overlay.ts: the SVG "chrome" (chart-area fill/border,
99
- * title, legend, value-axis gridlines/ticks, category labels) a 3D chart
100
- * scene draws OVER its WebGL canvas via `ctx.overlay`.
101
- *
102
- * PowerPoint's own 3D charts always show this chrome exactly like the 2D
103
- * chart does (see the parity brief's "hybrid rendering" requirement); for a
104
- * chart in the oblique (`rAngAx=1`) projection family this chrome is
105
- * ALREADY pixel-correct in the flat 2D `ChartViewModel` (verified against
106
- * `gt/chart-01.webp`: axes/gridlines/title/legend sit exactly where a plain
107
- * 2D chart would put them, perfectly undistorted), so this module reuses the
108
- * SAME `chart-view-model-dom.ts` piece-renderers the 2D/vanilla projector
109
- * uses, just WITHOUT `vm.primitives`/`vm.dataLabels` (the flat oblique
110
- * bars/extrusion polygons, replaced by real WebGL geometry).
111
- *
112
- * @module chart-3d-chrome-overlay
113
- */
114
- /**
115
- * Render a `ChartViewModel`'s chrome (everything except data marks) to an
116
- * `<svg>` sized to `vm.svgWidth` x `vm.svgHeight`, matching the WebGL
117
- * scene's own world-unit convention (1 world unit = 1 authored chart px) so
118
- * an element positioned from the same view-model's rects lines up exactly.
119
- */
120
- function renderChart3DChromeOverlaySvg(doc, vm) {
121
- const svg = createSvgEl(doc, 'svg', {
122
- class: 'pptxv-chart-3d-chrome',
123
- viewBox: `0 0 ${vm.svgWidth} ${vm.svgHeight}`,
124
- preserveAspectRatio: 'none',
125
- });
126
- svg.style.setProperty('width', '100%');
127
- svg.style.setProperty('height', '100%');
128
- svg.style.setProperty('display', 'block');
129
- svg.style.setProperty('position', 'absolute');
130
- svg.style.setProperty('inset', '0');
131
- // The WebGL canvas paints the marks; this overlay only adds chrome on top
132
- // of them, so pointer events must fall through to the canvas underneath.
133
- svg.style.setProperty('pointer-events', 'none');
134
- if (vm.areaFill) {
135
- svg.appendChild(createSvgEl(doc, 'rect', {
136
- x: 0,
137
- y: 0,
138
- width: vm.svgWidth,
139
- height: vm.svgHeight,
140
- rx: vm.areaRadius,
141
- fill: vm.areaFill,
142
- }));
143
- }
144
- if (vm.title) {
145
- const title = createSvgEl(doc, 'text', {
146
- x: vm.titleX,
147
- y: vm.titleY,
148
- 'text-anchor': 'middle',
149
- 'font-size': vm.titleStyle?.fontSize ?? 12,
150
- 'font-weight': vm.titleStyle?.fontWeight ?? 600,
151
- 'font-family': vm.titleStyle?.fontFamily,
152
- fill: vm.titleStyle?.fill ?? '#1e293b',
153
- 'data-chart-part': 'title',
154
- });
155
- if (vm.titleRunSpans && vm.titleRunSpans.length > 0) {
156
- for (const run of vm.titleRunSpans) {
157
- const tspan = createSvgEl(doc, 'tspan', {
158
- 'font-size': run.fontSize,
159
- 'font-weight': run.fontWeight,
160
- 'font-style': run.fontStyle,
161
- 'font-family': run.fontFamily,
162
- fill: run.fill,
163
- });
164
- tspan.textContent = run.text;
165
- title.appendChild(tspan);
166
- }
167
- }
168
- else {
169
- title.textContent = vm.title;
170
- }
171
- svg.appendChild(title);
172
- }
173
- for (const gl of vm.gridlines) {
174
- svg.appendChild(renderChartLineSvg(doc, gl));
175
- }
176
- for (const gl of vm.secondaryGridlines ?? []) {
177
- svg.appendChild(renderChartLineSvg(doc, gl));
178
- }
179
- for (const lbl of vm.axisLabels) {
180
- svg.appendChild(renderChartTextSvg(doc, lbl));
181
- }
182
- for (const lbl of vm.secondaryAxisLabels ?? []) {
183
- svg.appendChild(renderChartTextSvg(doc, lbl));
184
- }
185
- if (vm.zeroLine) {
186
- svg.appendChild(renderChartLineSvg(doc, vm.zeroLine));
187
- }
188
- for (const lbl of vm.categoryLabels) {
189
- svg.appendChild(renderChartTextSvg(doc, lbl));
190
- }
191
- appendChartLegendSvg(doc, svg, vm);
192
- return svg;
193
- }
194
-
195
- /** Colour of the selected box's outline (matches the 2D selected-mark accent). */
196
- const SELECTED_OUTLINE_COLOR = 0x2563eb;
197
- /** Front-face rect of a box after a live drag to `value` (the bar's baseline edge stays put). */
198
- function draggedRect(box, state, startValue, value) {
199
- const startY = dragAnchorViewY(startValue, state.drag, state.part.seriesIndex);
200
- const base = Math.abs(startY - box.y) <= Math.abs(startY - (box.y + box.h)) ? box.y + box.h : box.y;
201
- const valueY = dragAnchorViewY(value, state.drag, state.part.seriesIndex);
202
- return { y: Math.min(base, valueY), h: Math.abs(base - valueY) };
203
- }
204
- /** Attach hover/select/drag to an oblique bar scene's boxes. */
205
- function attachObliqueBarInteraction(options) {
206
- const { ctx, camera, meshes, boxes, vm, chartData } = options;
207
- const three = ctx.three;
208
- const target = ctx.eventTarget;
209
- const raycaster = new three.Raycaster();
210
- const far = new three.Vector3();
211
- let interactive = ctx.interactive;
212
- let press = null;
213
- let hoveredTooltip;
214
- const outline = new three.LineSegments(new three.EdgesGeometry(new three.BoxGeometry(1, 1, 1)), new three.LineBasicMaterial({ color: SELECTED_OUTLINE_COLOR }));
215
- outline.visible = false;
216
- options.scene.add(outline);
217
- function hitAt(clientX, clientY) {
218
- const rect = target.getBoundingClientRect();
219
- if (rect.width <= 0 || rect.height <= 0) {
220
- return undefined;
221
- }
222
- // World matrices are otherwise only refreshed by a render; a pointer
223
- // event can arrive before the first frame.
224
- options.scene.updateMatrixWorld();
225
- camera.updateMatrixWorld();
226
- const x = ((clientX - rect.left) / rect.width) * 2 - 1;
227
- const y = -((clientY - rect.top) / rect.height) * 2 + 1;
228
- raycaster.ray.origin.set(x, y, -1).unproject(camera);
229
- far.set(x, y, 1).unproject(camera);
230
- raycaster.ray.direction.copy(far).sub(raycaster.ray.origin).normalize();
231
- return raycaster.intersectObjects(meshes, false)[0];
232
- }
233
- function partOf(hit) {
234
- const data = hit?.object.userData;
235
- if (data?.seriesIndex === undefined || data.categoryIndex === undefined) {
236
- return null;
237
- }
238
- return { role: 'dataPoint', seriesIndex: data.seriesIndex, pointIndex: data.categoryIndex };
239
- }
240
- function indexOf(part) {
241
- if (!part || part.role !== 'dataPoint') {
242
- return -1;
243
- }
244
- return boxes.findIndex((b) => b.seriesIndex === part.seriesIndex && b.categoryIndex === part.pointIndex);
245
- }
246
- function setSelectedPart(part) {
247
- const i = indexOf(part);
248
- outline.visible = i >= 0;
249
- if (i >= 0) {
250
- outline.position.copy(meshes[i].position);
251
- outline.scale.copy(meshes[i].scale);
252
- }
253
- ctx.requestRender();
254
- }
255
- /** Resize box `i`'s mesh to a new front-face rect (live drag preview). */
256
- function applyRect(i, rect) {
257
- const mesh = meshes[i];
258
- const h = Math.max(rect.h, 0.001);
259
- mesh.position.y = vm.svgHeight / 2 - (rect.y + rect.h / 2);
260
- mesh.scale.y = h;
261
- if (outline.visible) {
262
- outline.position.copy(mesh.position);
263
- outline.scale.copy(mesh.scale);
264
- }
265
- ctx.requestRender();
266
- }
267
- const onPointerMove = (event) => {
268
- if (press?.drag) {
269
- const step = advanceChartValueDrag(press.drag, event.clientY, target.getBoundingClientRect().height);
270
- if (step) {
271
- const i = indexOf(press.drag.part);
272
- const start = boxes[i]?.value ?? 0;
273
- if (i >= 0) {
274
- applyRect(i, draggedRect(boxes[i], press.drag, start, step.value));
275
- }
276
- press.lastValue = step.value;
277
- ctx.emit({
278
- type: 'drag',
279
- detail: { part: press.drag.part, value: step.value, phase: 'move' },
280
- });
281
- }
282
- return;
283
- }
284
- const hit = hitAt(event.clientX, event.clientY);
285
- const data = hit?.object.userData;
286
- const box = data ? boxes[indexOf(partOf(hit))] : undefined;
287
- const tooltip = box
288
- ? buildBarChart3DHoverTooltip({ seriesIndex: box.seriesIndex, categoryIndex: box.categoryIndex, value: box.value }, {
289
- categoryLabels: options.categoryLabels,
290
- seriesNames: options.seriesNames,
291
- numberFormats: chartData.series.map((s) => s.numberFormat),
292
- })
293
- : undefined;
294
- if (tooltip !== hoveredTooltip) {
295
- hoveredTooltip = tooltip;
296
- target.title = tooltip ?? '';
297
- }
298
- };
299
- const onPointerDown = (event) => {
300
- if (!interactive) {
301
- return;
302
- }
303
- const part = partOf(hitAt(event.clientX, event.clientY));
304
- const armed = part !== null && isChartInteractionArmed(target);
305
- if (armed) {
306
- event.stopPropagation();
307
- }
308
- const drag = armed && part
309
- ? beginChartValueDrag({ part, viewModel: vm, chartData, clientY: event.clientY })
310
- : null;
311
- if (drag) {
312
- event.preventDefault();
313
- target.setPointerCapture?.(event.pointerId);
314
- }
315
- press = { part, drag, startX: event.clientX, startY: event.clientY, lastValue: null };
316
- };
317
- const onPointerUp = (event) => {
318
- const current = press;
319
- press = null;
320
- if (!current || !interactive) {
321
- return;
322
- }
323
- if (current.drag?.moved && current.lastValue !== null) {
324
- ctx.emit({
325
- type: 'drag',
326
- detail: { part: current.drag.part, value: current.lastValue, phase: 'commit' },
327
- });
328
- return;
329
- }
330
- const travel = Math.hypot(event.clientX - current.startX, event.clientY - current.startY);
331
- if (travel < CHART_3D_DRAG_THRESHOLD_PX) {
332
- ctx.emit({ type: 'select', part: current.part });
333
- }
334
- };
335
- const onPointerLeave = () => {
336
- if (hoveredTooltip !== undefined) {
337
- hoveredTooltip = undefined;
338
- target.title = '';
339
- }
340
- };
341
- target.addEventListener('pointermove', onPointerMove);
342
- target.addEventListener('pointerdown', onPointerDown);
343
- target.addEventListener('pointerup', onPointerUp);
344
- target.addEventListener('pointerleave', onPointerLeave);
345
- return {
346
- setInteractive(on) {
347
- interactive = on;
348
- if (!on) {
349
- press = null;
350
- }
351
- },
352
- setSelectedPart,
353
- dispose() {
354
- target.removeEventListener('pointermove', onPointerMove);
355
- target.removeEventListener('pointerdown', onPointerDown);
356
- target.removeEventListener('pointerup', onPointerUp);
357
- target.removeEventListener('pointerleave', onPointerLeave);
358
- outline.geometry.dispose();
359
- outline.material.dispose();
360
- outline.removeFromParent();
361
- },
362
- };
363
- }
364
-
365
- /**
366
- * The oblique chart camera. Camera distance is chosen so `NEAR`/`FAR` stay
367
- * tight around the scene's own (tiny) depth extent. Exported for tests.
368
- */
369
- function buildObliqueCamera(three, svgWidth, svgHeight, shearX, shearY) {
370
- const halfW = svgWidth / 2;
371
- const halfH = svgHeight / 2;
372
- const distance = halfW + halfH + 500;
373
- const camera = new three.OrthographicCamera(-halfW, halfW, halfH, -halfH, 1, distance + 2000);
374
- camera.position.set(0, 0, distance);
375
- camera.lookAt(0, 0, 0);
376
- camera.updateProjectionMatrix();
377
- // Hand-insert the oblique shear: clip_x += kX * ndcScaleX * world_z,
378
- // clip_y += kY * ndcScaleY * world_z (see the module doc + the chart
379
- // track's progress log for the sign derivation between the flat 2D
380
- // fallback's SVG-Y-down depth vector and this scene's world-Y-up frame:
381
- // X needs no flip (kX = -shearX), Y does (kY = +shearY)).
382
- const m = camera.projectionMatrix.elements;
383
- const ndcScaleX = m[0];
384
- const ndcScaleY = m[5];
385
- m[8] = -shearX * ndcScaleX;
386
- m[9] = shearY * ndcScaleY;
387
- // The shear multiplies VIEW-space z, which is `-distance` at the chart's
388
- // front plane (world z = 0). Offset it so the front plane is unsheared
389
- // and lands exactly on the 2D layout; only depth behind it shifts.
390
- m[12] += m[8] * distance;
391
- m[13] += m[9] * distance;
392
- camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
393
- return camera;
394
- }
395
- /** The hosted perspective scene for a spec whose oblique geometry is `null`. */
396
- function mountPerspectiveScene(perspective, ctx) {
397
- switch (perspective.kind) {
398
- case 'bar':
399
- return createBarChart3DScene(ctx, perspective.options);
400
- case 'line':
401
- return createLineChart3DScene(ctx, perspective.options);
402
- case 'area':
403
- return createAreaChart3DScene(ctx, perspective.options);
404
- case 'pie':
405
- return createPieChart3DScene(ctx, perspective.options);
406
- case 'surface':
407
- return createSurfaceChart3DScene(ctx, perspective.options);
408
- default: {
409
- const exhaustive = perspective;
410
- return exhaustive;
411
- }
412
- }
413
- }
414
- async function mountChart3DView(spec, ctx) {
415
- if (spec.projection.mode !== 'oblique' || spec.geometry?.kind !== 'bar') {
416
- if (spec.perspective) {
417
- return mountPerspectiveScene(spec.perspective, ctx);
418
- }
419
- throw new Error(`no 3D chart scene for chartType=${spec.chartType}`);
420
- }
421
- const three = ctx.three;
422
- const { vm, geometry } = spec;
423
- const chartData = spec.element.chartData;
424
- if (!chartData) {
425
- throw new Error('3D chart spec without chart data');
426
- }
427
- const camera = buildObliqueCamera(three, vm.svgWidth, vm.svgHeight, spec.projection.shearX, spec.projection.shearY);
428
- const scene = new three.Scene();
429
- const bars = buildChart3DBarMeshes(three, geometry.boxes, vm.svgWidth, vm.svgHeight);
430
- scene.add(bars.group);
431
- const overlay = renderChart3DChromeOverlaySvg(ctx.document, vm);
432
- ctx.overlay.appendChild(overlay);
433
- const interaction = attachObliqueBarInteraction({
434
- ctx,
435
- camera,
436
- meshes: bars.meshes,
437
- boxes: geometry.boxes,
438
- vm,
439
- chartData,
440
- categoryLabels: spec.categoryLabels,
441
- seriesNames: chartData.series.map((series) => series.name),
442
- scene,
443
- });
444
- let disposed = false;
445
- return {
446
- render(renderer) {
447
- renderer.render(scene, camera);
448
- },
449
- resize() {
450
- // The orthographic frustum is fixed in authored chart-px units
451
- // (svgWidth/svgHeight), independent of the element's on-screen CSS
452
- // size, so nothing needs recomputing here.
453
- },
454
- isAnimating: () => false,
455
- setInteractive: (on) => interaction.setInteractive(on),
456
- setSelectedPart: (part) => interaction.setSelectedPart(part),
457
- dispose() {
458
- if (disposed) {
459
- return;
460
- }
461
- disposed = true;
462
- interaction.dispose();
463
- bars.dispose();
464
- overlay.remove();
465
- },
466
- };
467
- }
468
-
469
- export { buildObliqueCamera, mountChart3DView };
470
- //# sourceMappingURL=pptx-angular-viewer-chart-3d-view-scene-CFWKnfML.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pptx-angular-viewer-chart-3d-view-scene-CFWKnfML.mjs","sources":["../../src/internal/shared-src/render/chart-3d-shading.ts","../../src/internal/shared-src/render/chart-3d-bar-mesh.ts","../../src/internal/shared-src/render/chart-3d-chrome-overlay.ts","../../src/internal/shared-src/render/chart-3d-oblique-interaction.ts","../../src/internal/shared-src/render/chart-3d-view-scene.ts"],"sourcesContent":["/**\n * chart-3d-shading.ts: PowerPoint's flat chart-space shading for a 3D chart's\n * box faces, as one colour multiplier per named face.\n *\n * PowerPoint's 3D charts (bar3D, pie3D, line3D ribbons, area3D slabs, surface\n * bands) are flat-shaded in \"chart space\": every face of a given orientation\n * gets the SAME multiplier applied to the mark's base colour, regardless of\n * the chart's `c:view3D` tilt. Measured directly off the pixels of\n * `gt/chart-01.webp` (a 3-D Clustered Column, series 1 = theme accent1\n * `#156082`): the front (camera-facing) rect samples the base colour exactly\n * (`front = base`), the top face samples ~0.75x, and the visible side face\n * ~0.64x. `back`/`left` (mirrors of `right`) and `bottom` (rarely visible)\n * are not independently measured; `back`/`left` reuse the measured side\n * multiplier and `bottom` is a reasonable approximation between side and a\n * fully unlit face.\n *\n * @module chart-3d-shading\n */\nimport { shade } from './chart-palette';\n\n/** A box mesh's six face orientations, in the chart's own (unrotated) local frame. */\nexport type Chart3DFace = 'front' | 'back' | 'top' | 'bottom' | 'left' | 'right';\n\n/**\n * Darken amount (0-1, `chart-palette.ts#shade`'s `amount`) per face,\n * derived from the measured multipliers: `amount = 1 - multiplier`.\n */\nconst FACE_SHADE_AMOUNT: Record<Chart3DFace, number> = {\n\tfront: 0,\n\ttop: 0.25,\n\tright: 0.36,\n\tleft: 0.36,\n\tback: 0.36,\n\tbottom: 0.5,\n};\n\n/** Apply PowerPoint's measured per-face flat shading to a mark's base colour. */\nexport function shadeChart3DFace(baseColor: string, face: Chart3DFace): string {\n\tconst amount = FACE_SHADE_AMOUNT[face];\n\treturn amount === 0 ? baseColor : shade(baseColor, amount);\n}\n\n/**\n * The six face colours for a box mesh, in the order three.js `BoxGeometry`\n * expects its `material` array (`[+x, -x, +y, -y, +z, -z]`): right, left,\n * top, bottom, front, back. `front`/`back` name whichever world axis the\n * scene treats as the camera-facing depth axis; the caller picks that\n * mapping (see `chart-3d-view-scene.ts`).\n */\nexport function buildChart3DBoxFaceColors(\n\tbaseColor: string,\n): readonly [string, string, string, string, string, string] {\n\treturn [\n\t\tshadeChart3DFace(baseColor, 'right'),\n\t\tshadeChart3DFace(baseColor, 'left'),\n\t\tshadeChart3DFace(baseColor, 'top'),\n\t\tshadeChart3DFace(baseColor, 'bottom'),\n\t\tshadeChart3DFace(baseColor, 'front'),\n\t\tshadeChart3DFace(baseColor, 'back'),\n\t];\n}\n","/**\n * Build the real WebGL box meshes for a `bar3D` chart's `Chart3DBarGeometry`\n * (see `chart-3d-spec.ts`). Split out of `chart-3d-view-scene.ts` to keep\n * that file within the repo's ~300-LOC limit.\n *\n * Every box is positioned so its FRONT face (world Z=0) sits exactly where\n * the flat 2D fallback's front-face rectangle would be drawn, in \"1 world\n * unit = 1 authored chart px\" coordinates matching `chart-3d-chrome-overlay.ts`'s\n * overlay `<svg>` viewBox. The box then extrudes backward (negative Z) by its\n * own depth, so the oblique camera's shear (`chart-3d-view-scene.ts`) shifts\n * only the BACK face, reproducing the same silhouette the flat 2D depth pass\n * draws as a hand-built parallelogram (`chart-3d-depth.ts#barExtrusion`).\n *\n * Only `PptxBar3DShape === 'box'` reaches this module today\n * (`chart-3d-spec.ts#isSupportedBoxShape` gates everything else out at the\n * spec level), so every box gets flat, per-face-group `MeshBasicMaterial`s\n * (no lights involved: PowerPoint's box faces are flat-shaded in chart\n * space, not lit) built from `chart-3d-shading.ts`'s measured multipliers.\n *\n * @module chart-3d-bar-mesh\n */\nimport type * as THREE from 'three';\n\nimport { buildChart3DBoxFaceColors } from './chart-3d-shading';\nimport type { Chart3DBarBox } from './chart-3d-spec';\n\ntype ThreeModule = typeof THREE;\n\nexport interface Chart3DBarMeshResult {\n\tgroup: THREE.Group;\n\t/** One mesh per box, same order as `boxes`; carries `{ seriesIndex, categoryIndex }` in `userData`. */\n\tmeshes: THREE.Mesh[];\n\tdispose: () => void;\n}\n\n/**\n * Build one `THREE.Mesh` per box and add them to a new `THREE.Group`. World\n * coordinates: X/Y centred on the chart's own `svgWidth`/`svgHeight` (X\n * right, Y UP - the SVG Y-down front rect is flipped here), Z=0 at the\n * front face, extending negative (away from the camera) by the box's own\n * depth.\n */\nexport function buildChart3DBarMeshes(\n\tthree: ThreeModule,\n\tboxes: ReadonlyArray<Chart3DBarBox>,\n\tsvgWidth: number,\n\tsvgHeight: number,\n): Chart3DBarMeshResult {\n\tconst group = new three.Group();\n\tconst meshes: THREE.Mesh[] = [];\n\tconst geometries: THREE.BufferGeometry[] = [];\n\tconst materials: THREE.Material[] = [];\n\tconst halfW = svgWidth / 2;\n\tconst halfH = svgHeight / 2;\n\n\tfor (const box of boxes) {\n\t\tconst geometry = new three.BoxGeometry(1, 1, 1);\n\t\tgeometries.push(geometry);\n\t\tconst faceMaterials = buildChart3DBoxFaceColors(box.color).map(\n\t\t\t(color) => new three.MeshBasicMaterial({ color }),\n\t\t);\n\t\tmaterials.push(...faceMaterials);\n\n\t\tconst mesh = new three.Mesh(geometry, faceMaterials);\n\t\tconst zDepth = box.depthMagnitude;\n\t\tmesh.position.set(box.x + box.w / 2 - halfW, halfH - (box.y + box.h / 2), -zDepth / 2);\n\t\tmesh.scale.set(box.w, box.h, zDepth);\n\t\tmesh.userData = { seriesIndex: box.seriesIndex, categoryIndex: box.categoryIndex };\n\t\tgroup.add(mesh);\n\t\tmeshes.push(mesh);\n\t}\n\n\treturn {\n\t\tgroup,\n\t\tmeshes,\n\t\tdispose: () => {\n\t\t\tfor (const geometry of geometries) {\n\t\t\t\tgeometry.dispose();\n\t\t\t}\n\t\t\tfor (const material of materials) {\n\t\t\t\tmaterial.dispose();\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * chart-3d-chrome-overlay.ts: the SVG \"chrome\" (chart-area fill/border,\n * title, legend, value-axis gridlines/ticks, category labels) a 3D chart\n * scene draws OVER its WebGL canvas via `ctx.overlay`.\n *\n * PowerPoint's own 3D charts always show this chrome exactly like the 2D\n * chart does (see the parity brief's \"hybrid rendering\" requirement); for a\n * chart in the oblique (`rAngAx=1`) projection family this chrome is\n * ALREADY pixel-correct in the flat 2D `ChartViewModel` (verified against\n * `gt/chart-01.webp`: axes/gridlines/title/legend sit exactly where a plain\n * 2D chart would put them, perfectly undistorted), so this module reuses the\n * SAME `chart-view-model-dom.ts` piece-renderers the 2D/vanilla projector\n * uses, just WITHOUT `vm.primitives`/`vm.dataLabels` (the flat oblique\n * bars/extrusion polygons, replaced by real WebGL geometry).\n *\n * @module chart-3d-chrome-overlay\n */\nimport {\n\tappendChartLegendSvg,\n\trenderChartLineSvg,\n\trenderChartTextSvg,\n} from './chart-view-model-dom';\nimport { createSvgEl } from './chart-view-model-dom-helpers';\nimport type { ChartViewModel } from './chart-view-model-types';\n\n/**\n * Render a `ChartViewModel`'s chrome (everything except data marks) to an\n * `<svg>` sized to `vm.svgWidth` x `vm.svgHeight`, matching the WebGL\n * scene's own world-unit convention (1 world unit = 1 authored chart px) so\n * an element positioned from the same view-model's rects lines up exactly.\n */\nexport function renderChart3DChromeOverlaySvg(doc: Document, vm: ChartViewModel): SVGSVGElement {\n\tconst svg = createSvgEl(doc, 'svg', {\n\t\tclass: 'pptxv-chart-3d-chrome',\n\t\tviewBox: `0 0 ${vm.svgWidth} ${vm.svgHeight}`,\n\t\tpreserveAspectRatio: 'none',\n\t});\n\tsvg.style.setProperty('width', '100%');\n\tsvg.style.setProperty('height', '100%');\n\tsvg.style.setProperty('display', 'block');\n\tsvg.style.setProperty('position', 'absolute');\n\tsvg.style.setProperty('inset', '0');\n\t// The WebGL canvas paints the marks; this overlay only adds chrome on top\n\t// of them, so pointer events must fall through to the canvas underneath.\n\tsvg.style.setProperty('pointer-events', 'none');\n\n\tif (vm.areaFill) {\n\t\tsvg.appendChild(\n\t\t\tcreateSvgEl(doc, 'rect', {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\twidth: vm.svgWidth,\n\t\t\t\theight: vm.svgHeight,\n\t\t\t\trx: vm.areaRadius,\n\t\t\t\tfill: vm.areaFill,\n\t\t\t}),\n\t\t);\n\t}\n\n\tif (vm.title) {\n\t\tconst title = createSvgEl(doc, 'text', {\n\t\t\tx: vm.titleX,\n\t\t\ty: vm.titleY,\n\t\t\t'text-anchor': 'middle',\n\t\t\t'font-size': vm.titleStyle?.fontSize ?? 12,\n\t\t\t'font-weight': vm.titleStyle?.fontWeight ?? 600,\n\t\t\t'font-family': vm.titleStyle?.fontFamily,\n\t\t\tfill: vm.titleStyle?.fill ?? '#1e293b',\n\t\t\t'data-chart-part': 'title',\n\t\t});\n\t\tif (vm.titleRunSpans && vm.titleRunSpans.length > 0) {\n\t\t\tfor (const run of vm.titleRunSpans) {\n\t\t\t\tconst tspan = createSvgEl(doc, 'tspan', {\n\t\t\t\t\t'font-size': run.fontSize,\n\t\t\t\t\t'font-weight': run.fontWeight,\n\t\t\t\t\t'font-style': run.fontStyle,\n\t\t\t\t\t'font-family': run.fontFamily,\n\t\t\t\t\tfill: run.fill,\n\t\t\t\t});\n\t\t\t\ttspan.textContent = run.text;\n\t\t\t\ttitle.appendChild(tspan);\n\t\t\t}\n\t\t} else {\n\t\t\ttitle.textContent = vm.title;\n\t\t}\n\t\tsvg.appendChild(title);\n\t}\n\n\tfor (const gl of vm.gridlines) {\n\t\tsvg.appendChild(renderChartLineSvg(doc, gl));\n\t}\n\tfor (const gl of vm.secondaryGridlines ?? []) {\n\t\tsvg.appendChild(renderChartLineSvg(doc, gl));\n\t}\n\tfor (const lbl of vm.axisLabels) {\n\t\tsvg.appendChild(renderChartTextSvg(doc, lbl));\n\t}\n\tfor (const lbl of vm.secondaryAxisLabels ?? []) {\n\t\tsvg.appendChild(renderChartTextSvg(doc, lbl));\n\t}\n\tif (vm.zeroLine) {\n\t\tsvg.appendChild(renderChartLineSvg(doc, vm.zeroLine));\n\t}\n\tfor (const lbl of vm.categoryLabels) {\n\t\tsvg.appendChild(renderChartTextSvg(doc, lbl));\n\t}\n\n\tappendChartLegendSvg(doc, svg, vm);\n\treturn svg;\n}\n","import type { PptxChartData } from 'pptx-viewer-core';\n/**\n * Pointer interaction for the oblique `bar3D` scene (`chart-3d-view-scene.ts`):\n * hover tooltip, click-to-select and drag-to-value on the WebGL boxes.\n *\n * The oblique scene draws each box's FRONT face exactly where the flat 2D\n * chart draws the bar (1 world unit = 1 authored chart px), so a value drag\n * reuses the 2D engine's own drag maths unchanged: `beginChartValueDrag` /\n * `advanceChartValueDrag` from `chart-canvas-drag.ts`, driven by the view\n * model the spec was built from. That keeps a 3D bar's drag identical to the\n * 2D bar's (same rounding, same axis range, same \"stacked marks are not\n * value-draggable\" rule).\n *\n * Picking casts its own ray instead of `Raycaster.setFromCamera`: the camera\n * carries a hand-inserted shear in its projection matrix, which\n * `setFromCamera`'s orthographic branch ignores (it always casts straight\n * down the camera's -Z). Unprojecting the near and far NDC points through the\n * full inverse projection gives the correctly sheared ray.\n *\n * @module chart-3d-oblique-interaction\n */\nimport type * as THREE from 'three';\n\nimport type { ThreeViewContext } from '../three-view/types';\nimport { buildBarChart3DHoverTooltip } from './bar-chart-3d-hit-test';\nimport { CHART_3D_DRAG_THRESHOLD_PX } from './chart-3d-interaction';\nimport type { Chart3DBarBox } from './chart-3d-spec';\nimport {\n\tadvanceChartValueDrag,\n\tbeginChartValueDrag,\n\tisChartInteractionArmed,\n} from './chart-canvas-drag';\nimport type { ChartValueDragState } from './chart-canvas-drag';\nimport { dragAnchorViewY } from './chart-interaction';\nimport type { ChartPartRef } from './chart-view-model';\nimport type { ChartViewModel } from './chart-view-model-types';\n\n/** Colour of the selected box's outline (matches the 2D selected-mark accent). */\nconst SELECTED_OUTLINE_COLOR = 0x2563eb;\n\nexport interface ObliqueBarInteractionOptions {\n\tctx: ThreeViewContext;\n\tcamera: THREE.Camera;\n\tmeshes: ReadonlyArray<THREE.Mesh>;\n\tboxes: ReadonlyArray<Chart3DBarBox>;\n\tvm: ChartViewModel;\n\tchartData: PptxChartData;\n\tcategoryLabels: ReadonlyArray<string>;\n\tseriesNames: ReadonlyArray<string>;\n\t/** Scene the selection outline is added to. */\n\tscene: THREE.Object3D;\n}\n\nexport interface ObliqueBarInteraction {\n\tsetInteractive: (on: boolean) => void;\n\tsetSelectedPart: (part: ChartPartRef | null) => void;\n\tdispose: () => void;\n}\n\ninterface PressState {\n\tpart: ChartPartRef | null;\n\tdrag: ChartValueDragState | null;\n\tstartX: number;\n\tstartY: number;\n\tlastValue: number | null;\n}\n\n/** Front-face rect of a box after a live drag to `value` (the bar's baseline edge stays put). */\nfunction draggedRect(\n\tbox: Chart3DBarBox,\n\tstate: ChartValueDragState,\n\tstartValue: number,\n\tvalue: number,\n): { y: number; h: number } {\n\tconst startY = dragAnchorViewY(startValue, state.drag, state.part.seriesIndex);\n\tconst base =\n\t\tMath.abs(startY - box.y) <= Math.abs(startY - (box.y + box.h)) ? box.y + box.h : box.y;\n\tconst valueY = dragAnchorViewY(value, state.drag, state.part.seriesIndex);\n\treturn { y: Math.min(base, valueY), h: Math.abs(base - valueY) };\n}\n\n/** Attach hover/select/drag to an oblique bar scene's boxes. */\nexport function attachObliqueBarInteraction(\n\toptions: ObliqueBarInteractionOptions,\n): ObliqueBarInteraction {\n\tconst { ctx, camera, meshes, boxes, vm, chartData } = options;\n\tconst three = ctx.three;\n\tconst target = ctx.eventTarget;\n\tconst raycaster = new three.Raycaster();\n\tconst far = new three.Vector3();\n\tlet interactive = ctx.interactive;\n\tlet press: PressState | null = null;\n\tlet hoveredTooltip: string | undefined;\n\n\tconst outline = new three.LineSegments(\n\t\tnew three.EdgesGeometry(new three.BoxGeometry(1, 1, 1)),\n\t\tnew three.LineBasicMaterial({ color: SELECTED_OUTLINE_COLOR }),\n\t);\n\toutline.visible = false;\n\toptions.scene.add(outline);\n\n\tfunction hitAt(clientX: number, clientY: number): THREE.Intersection | undefined {\n\t\tconst rect = target.getBoundingClientRect();\n\t\tif (rect.width <= 0 || rect.height <= 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\t// World matrices are otherwise only refreshed by a render; a pointer\n\t\t// event can arrive before the first frame.\n\t\toptions.scene.updateMatrixWorld();\n\t\tcamera.updateMatrixWorld();\n\t\tconst x = ((clientX - rect.left) / rect.width) * 2 - 1;\n\t\tconst y = -((clientY - rect.top) / rect.height) * 2 + 1;\n\t\traycaster.ray.origin.set(x, y, -1).unproject(camera);\n\t\tfar.set(x, y, 1).unproject(camera);\n\t\traycaster.ray.direction.copy(far).sub(raycaster.ray.origin).normalize();\n\t\treturn raycaster.intersectObjects(meshes as THREE.Mesh[], false)[0];\n\t}\n\n\tfunction partOf(hit: THREE.Intersection | undefined): ChartPartRef | null {\n\t\tconst data = hit?.object.userData as\n\t\t\t| { seriesIndex?: number; categoryIndex?: number }\n\t\t\t| undefined;\n\t\tif (data?.seriesIndex === undefined || data.categoryIndex === undefined) {\n\t\t\treturn null;\n\t\t}\n\t\treturn { role: 'dataPoint', seriesIndex: data.seriesIndex, pointIndex: data.categoryIndex };\n\t}\n\n\tfunction indexOf(part: ChartPartRef | null): number {\n\t\tif (!part || part.role !== 'dataPoint') {\n\t\t\treturn -1;\n\t\t}\n\t\treturn boxes.findIndex(\n\t\t\t(b) => b.seriesIndex === part.seriesIndex && b.categoryIndex === part.pointIndex,\n\t\t);\n\t}\n\n\tfunction setSelectedPart(part: ChartPartRef | null): void {\n\t\tconst i = indexOf(part);\n\t\toutline.visible = i >= 0;\n\t\tif (i >= 0) {\n\t\t\toutline.position.copy(meshes[i].position);\n\t\t\toutline.scale.copy(meshes[i].scale);\n\t\t}\n\t\tctx.requestRender();\n\t}\n\n\t/** Resize box `i`'s mesh to a new front-face rect (live drag preview). */\n\tfunction applyRect(i: number, rect: { y: number; h: number }): void {\n\t\tconst mesh = meshes[i];\n\t\tconst h = Math.max(rect.h, 0.001);\n\t\tmesh.position.y = vm.svgHeight / 2 - (rect.y + rect.h / 2);\n\t\tmesh.scale.y = h;\n\t\tif (outline.visible) {\n\t\t\toutline.position.copy(mesh.position);\n\t\t\toutline.scale.copy(mesh.scale);\n\t\t}\n\t\tctx.requestRender();\n\t}\n\n\tconst onPointerMove = (event: PointerEvent): void => {\n\t\tif (press?.drag) {\n\t\t\tconst step = advanceChartValueDrag(\n\t\t\t\tpress.drag,\n\t\t\t\tevent.clientY,\n\t\t\t\ttarget.getBoundingClientRect().height,\n\t\t\t);\n\t\t\tif (step) {\n\t\t\t\tconst i = indexOf(press.drag.part);\n\t\t\t\tconst start = boxes[i]?.value ?? 0;\n\t\t\t\tif (i >= 0) {\n\t\t\t\t\tapplyRect(i, draggedRect(boxes[i], press.drag, start, step.value));\n\t\t\t\t}\n\t\t\t\tpress.lastValue = step.value;\n\t\t\t\tctx.emit({\n\t\t\t\t\ttype: 'drag',\n\t\t\t\t\tdetail: { part: press.drag.part, value: step.value, phase: 'move' },\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tconst hit = hitAt(event.clientX, event.clientY);\n\t\tconst data = hit?.object.userData as { seriesIndex: number; categoryIndex: number } | undefined;\n\t\tconst box = data ? boxes[indexOf(partOf(hit))] : undefined;\n\t\tconst tooltip = box\n\t\t\t? buildBarChart3DHoverTooltip(\n\t\t\t\t\t{ seriesIndex: box.seriesIndex, categoryIndex: box.categoryIndex, value: box.value },\n\t\t\t\t\t{\n\t\t\t\t\t\tcategoryLabels: options.categoryLabels,\n\t\t\t\t\t\tseriesNames: options.seriesNames,\n\t\t\t\t\t\tnumberFormats: chartData.series.map((s) => s.numberFormat),\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tif (tooltip !== hoveredTooltip) {\n\t\t\thoveredTooltip = tooltip;\n\t\t\ttarget.title = tooltip ?? '';\n\t\t}\n\t};\n\n\tconst onPointerDown = (event: PointerEvent): void => {\n\t\tif (!interactive) {\n\t\t\treturn;\n\t\t}\n\t\tconst part = partOf(hitAt(event.clientX, event.clientY));\n\t\tconst armed = part !== null && isChartInteractionArmed(target);\n\t\tif (armed) {\n\t\t\tevent.stopPropagation();\n\t\t}\n\t\tconst drag =\n\t\t\tarmed && part\n\t\t\t\t? beginChartValueDrag({ part, viewModel: vm, chartData, clientY: event.clientY })\n\t\t\t\t: null;\n\t\tif (drag) {\n\t\t\tevent.preventDefault();\n\t\t\t(target as { setPointerCapture?: (id: number) => void }).setPointerCapture?.(event.pointerId);\n\t\t}\n\t\tpress = { part, drag, startX: event.clientX, startY: event.clientY, lastValue: null };\n\t};\n\n\tconst onPointerUp = (event: PointerEvent): void => {\n\t\tconst current = press;\n\t\tpress = null;\n\t\tif (!current || !interactive) {\n\t\t\treturn;\n\t\t}\n\t\tif (current.drag?.moved && current.lastValue !== null) {\n\t\t\tctx.emit({\n\t\t\t\ttype: 'drag',\n\t\t\t\tdetail: { part: current.drag.part, value: current.lastValue, phase: 'commit' },\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst travel = Math.hypot(event.clientX - current.startX, event.clientY - current.startY);\n\t\tif (travel < CHART_3D_DRAG_THRESHOLD_PX) {\n\t\t\tctx.emit({ type: 'select', part: current.part });\n\t\t}\n\t};\n\n\tconst onPointerLeave = (): void => {\n\t\tif (hoveredTooltip !== undefined) {\n\t\t\thoveredTooltip = undefined;\n\t\t\ttarget.title = '';\n\t\t}\n\t};\n\n\ttarget.addEventListener('pointermove', onPointerMove);\n\ttarget.addEventListener('pointerdown', onPointerDown);\n\ttarget.addEventListener('pointerup', onPointerUp);\n\ttarget.addEventListener('pointerleave', onPointerLeave);\n\n\treturn {\n\t\tsetInteractive(on) {\n\t\t\tinteractive = on;\n\t\t\tif (!on) {\n\t\t\t\tpress = null;\n\t\t\t}\n\t\t},\n\t\tsetSelectedPart,\n\t\tdispose() {\n\t\t\ttarget.removeEventListener('pointermove', onPointerMove);\n\t\t\ttarget.removeEventListener('pointerdown', onPointerDown);\n\t\t\ttarget.removeEventListener('pointerup', onPointerUp);\n\t\t\ttarget.removeEventListener('pointerleave', onPointerLeave);\n\t\t\toutline.geometry.dispose();\n\t\t\t(outline.material as THREE.Material).dispose();\n\t\t\toutline.removeFromParent();\n\t\t},\n\t};\n}\n","import type { ChartPptxElement } from 'pptx-viewer-core';\n/**\n * `<pptx-three-view>` scene module for 3D charts.\n *\n * The oblique-projection family (`c:view3D/@rAngAx=1`, `bar3D`'s own\n * default; verified against `gt/chart-01.webp`) is drawn here. Everything\n * else (line3D/area3D/pie3D/surface3D, and bar3D's `standard` grouping, a\n * horizontal `c:barDir val=\"bar\"` or round shapes) has `geometry: null` and\n * mounts the matching perspective scene from `spec.perspective` (the\n * pre-`<pptx-three-view>` scenes, hosted on the shared renderer). Those are\n * not yet at PowerPoint parity; see `demos/demo-three-parity/README.md`.\n *\n * The oblique projection is built as a plain `OrthographicCamera` (1 world\n * unit = 1 authored chart px, matching `chart-3d-chrome-overlay.ts`'s\n * overlay `<svg>` viewBox exactly) with a SHEAR term hand-inserted into its\n * projection matrix, rather than tilting the camera or shearing the scene\n * graph: this keeps a future `OrbitControls` well-defined, since only the camera moves, and keeps every box's world\n * position/size meaningful on its own instead of encoding the illusion into\n * mesh transforms.\n *\n * @module chart-3d-view-scene\n */\nimport type * as THREE from 'three';\n\nimport type { ThreeViewContext, ThreeViewScene } from '../three-view/types';\nimport { createAreaChart3DScene } from './area-chart-3d-scene';\nimport { createBarChart3DScene } from './bar-chart-3d-scene';\nimport { buildChart3DBarMeshes } from './chart-3d-bar-mesh';\nimport { renderChart3DChromeOverlaySvg } from './chart-3d-chrome-overlay';\nimport { attachObliqueBarInteraction } from './chart-3d-oblique-interaction';\nimport type { Chart3DPerspectiveScene, Chart3DSpec } from './chart-3d-spec';\nimport { createLineChart3DScene } from './line-chart-3d-scene';\nimport { createPieChart3DScene } from './pie-chart-3d-scene';\nimport { createSurfaceChart3DScene } from './surface-chart-3d-scene';\n\n/**\n * The oblique chart camera. Camera distance is chosen so `NEAR`/`FAR` stay\n * tight around the scene's own (tiny) depth extent. Exported for tests.\n */\nexport function buildObliqueCamera(\n\tthree: ThreeModule,\n\tsvgWidth: number,\n\tsvgHeight: number,\n\tshearX: number,\n\tshearY: number,\n): THREE.OrthographicCamera {\n\tconst halfW = svgWidth / 2;\n\tconst halfH = svgHeight / 2;\n\tconst distance = halfW + halfH + 500;\n\tconst camera = new three.OrthographicCamera(-halfW, halfW, halfH, -halfH, 1, distance + 2000);\n\tcamera.position.set(0, 0, distance);\n\tcamera.lookAt(0, 0, 0);\n\tcamera.updateProjectionMatrix();\n\n\t// Hand-insert the oblique shear: clip_x += kX * ndcScaleX * world_z,\n\t// clip_y += kY * ndcScaleY * world_z (see the module doc + the chart\n\t// track's progress log for the sign derivation between the flat 2D\n\t// fallback's SVG-Y-down depth vector and this scene's world-Y-up frame:\n\t// X needs no flip (kX = -shearX), Y does (kY = +shearY)).\n\tconst m = camera.projectionMatrix.elements;\n\tconst ndcScaleX = m[0];\n\tconst ndcScaleY = m[5];\n\tm[8] = -shearX * ndcScaleX;\n\tm[9] = shearY * ndcScaleY;\n\t// The shear multiplies VIEW-space z, which is `-distance` at the chart's\n\t// front plane (world z = 0). Offset it so the front plane is unsheared\n\t// and lands exactly on the 2D layout; only depth behind it shifts.\n\tm[12] += m[8] * distance;\n\tm[13] += m[9] * distance;\n\tcamera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\n\treturn camera;\n}\n\ntype ThreeModule = typeof THREE;\n\n/** The hosted perspective scene for a spec whose oblique geometry is `null`. */\nfunction mountPerspectiveScene(\n\tperspective: Chart3DPerspectiveScene,\n\tctx: ThreeViewContext,\n): ThreeViewScene {\n\tswitch (perspective.kind) {\n\t\tcase 'bar':\n\t\t\treturn createBarChart3DScene(ctx, perspective.options);\n\t\tcase 'line':\n\t\t\treturn createLineChart3DScene(ctx, perspective.options);\n\t\tcase 'area':\n\t\t\treturn createAreaChart3DScene(ctx, perspective.options);\n\t\tcase 'pie':\n\t\t\treturn createPieChart3DScene(ctx, perspective.options);\n\t\tcase 'surface':\n\t\t\treturn createSurfaceChart3DScene(ctx, perspective.options);\n\t\tdefault: {\n\t\t\tconst exhaustive: never = perspective;\n\t\t\treturn exhaustive;\n\t\t}\n\t}\n}\n\nexport async function mountChart3DView(\n\tspec: Chart3DSpec,\n\tctx: ThreeViewContext,\n): Promise<ThreeViewScene> {\n\tif (spec.projection.mode !== 'oblique' || spec.geometry?.kind !== 'bar') {\n\t\tif (spec.perspective) {\n\t\t\treturn mountPerspectiveScene(spec.perspective, ctx);\n\t\t}\n\t\tthrow new Error(`no 3D chart scene for chartType=${spec.chartType}`);\n\t}\n\tconst three = ctx.three;\n\tconst { vm, geometry } = spec;\n\tconst chartData = (spec.element as ChartPptxElement).chartData;\n\tif (!chartData) {\n\t\tthrow new Error('3D chart spec without chart data');\n\t}\n\n\tconst camera = buildObliqueCamera(\n\t\tthree,\n\t\tvm.svgWidth,\n\t\tvm.svgHeight,\n\t\tspec.projection.shearX,\n\t\tspec.projection.shearY,\n\t);\n\n\tconst scene = new three.Scene();\n\tconst bars = buildChart3DBarMeshes(three, geometry.boxes, vm.svgWidth, vm.svgHeight);\n\tscene.add(bars.group);\n\n\tconst overlay = renderChart3DChromeOverlaySvg(ctx.document, vm);\n\tctx.overlay.appendChild(overlay);\n\n\tconst interaction = attachObliqueBarInteraction({\n\t\tctx,\n\t\tcamera,\n\t\tmeshes: bars.meshes,\n\t\tboxes: geometry.boxes,\n\t\tvm,\n\t\tchartData,\n\t\tcategoryLabels: spec.categoryLabels,\n\t\tseriesNames: chartData.series.map((series) => series.name),\n\t\tscene,\n\t});\n\n\tlet disposed = false;\n\treturn {\n\t\trender(renderer: THREE.WebGLRenderer) {\n\t\t\trenderer.render(scene, camera);\n\t\t},\n\t\tresize() {\n\t\t\t// The orthographic frustum is fixed in authored chart-px units\n\t\t\t// (svgWidth/svgHeight), independent of the element's on-screen CSS\n\t\t\t// size, so nothing needs recomputing here.\n\t\t},\n\t\tisAnimating: () => false,\n\t\tsetInteractive: (on) => interaction.setInteractive(on),\n\t\tsetSelectedPart: (part) => interaction.setSelectedPart(part),\n\t\tdispose() {\n\t\t\tif (disposed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdisposed = true;\n\t\t\tinteraction.dispose();\n\t\t\tbars.dispose();\n\t\t\toverlay.remove();\n\t\t},\n\t};\n}\n"],"names":[],"mappings":"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"}