aurea-eden 1.25.1 → 1.26.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 (93) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +300 -95
  3. package/dist/bpmn-diagram.es.js +37516 -25040
  4. package/dist/bpmn-diagram.umd.js +13 -5790
  5. package/package.json +17 -8
  6. package/.gitattributes +0 -2
  7. package/.github/workflows/static.yml +0 -43
  8. package/CHANGELOG.md +0 -60
  9. package/README_.md +0 -174
  10. package/assets/3diagram_logo.png +0 -0
  11. package/assets/aurea-eden-logo.jpeg +0 -0
  12. package/assets/favicon/about.txt +0 -6
  13. package/assets/favicon/android-chrome-192x192.png +0 -0
  14. package/assets/favicon/android-chrome-512x512.png +0 -0
  15. package/assets/favicon/apple-touch-icon.png +0 -0
  16. package/assets/favicon/favicon-16x16.png +0 -0
  17. package/assets/favicon/favicon-32x32.png +0 -0
  18. package/assets/favicon/favicon.ico +0 -0
  19. package/assets/favicon/site.webmanifest +0 -1
  20. package/assets/threejs_camera.jpg.webp +0 -0
  21. package/assets/threejs_camera3.jpg.webp +0 -0
  22. package/assets/threejs_cameras.webp +0 -0
  23. package/assets/threejs_cameras2.webp +0 -0
  24. package/assets/threejs_objects.webp +0 -0
  25. package/assets/threejs_scene.webp +0 -0
  26. package/assets/threejs_scene_graph.webp +0 -0
  27. package/favicon.ico +0 -0
  28. package/index.html +0 -34
  29. package/index.js +0 -153
  30. package/lib/connectors/Connector.js +0 -47
  31. package/lib/diagrams/Diagram.js +0 -710
  32. package/lib/diagrams/DiagramConstants.js +0 -22
  33. package/lib/elements/Element.js +0 -860
  34. package/lib/materials/BarMaterial.js +0 -17
  35. package/lib/materials/DiagramEditMaterial.js +0 -28
  36. package/lib/notations/BpmnDiagram.js +0 -861
  37. package/lib/shapes/Shape.js +0 -23
  38. package/lib/shapes/bar/ValueBarConstants.js +0 -34
  39. package/lib/shapes/bar/ValueBarShape.js +0 -52
  40. package/lib/shapes/basic/BasicShapeConstants.js +0 -23
  41. package/lib/shapes/basic/BoxShape.js +0 -12
  42. package/lib/shapes/basic/CircleShape.js +0 -55
  43. package/lib/shapes/basic/DiamondShape.js +0 -169
  44. package/lib/shapes/basic/RoundedRectangleShape.js +0 -180
  45. package/lib/shapes/connector/ConnectorConstants.js +0 -7
  46. package/lib/shapes/connector/RoundedCornerOrthogonalConnectorShape.js +0 -229
  47. package/lib/shapes/icon/IconConstants.js +0 -7
  48. package/lib/shapes/icon/IconShape.js +0 -92
  49. package/lib/shapes/icon/bpmn/activities/ad-hoc-marker.svg +0 -50
  50. package/lib/shapes/icon/bpmn/activities/business-rule.svg +0 -92
  51. package/lib/shapes/icon/bpmn/activities/compensation-marker.svg +0 -50
  52. package/lib/shapes/icon/bpmn/activities/loop-marker.svg +0 -50
  53. package/lib/shapes/icon/bpmn/activities/manual.svg +0 -51
  54. package/lib/shapes/icon/bpmn/activities/parallel-mi-marker.svg +0 -70
  55. package/lib/shapes/icon/bpmn/activities/receive.svg +0 -77
  56. package/lib/shapes/icon/bpmn/activities/script.svg +0 -54
  57. package/lib/shapes/icon/bpmn/activities/send.svg +0 -86
  58. package/lib/shapes/icon/bpmn/activities/sequential-mi-marker.svg +0 -70
  59. package/lib/shapes/icon/bpmn/activities/service.svg +0 -58
  60. package/lib/shapes/icon/bpmn/activities/sub-process-marker.svg +0 -51
  61. package/lib/shapes/icon/bpmn/activities/user.svg +0 -50
  62. package/lib/shapes/icon/bpmn/events/compensation.svg +0 -47
  63. package/lib/shapes/icon/bpmn/events/conditional.svg +0 -47
  64. package/lib/shapes/icon/bpmn/events/error.svg +0 -47
  65. package/lib/shapes/icon/bpmn/events/escalation.svg +0 -47
  66. package/lib/shapes/icon/bpmn/events/intermediate-compensation.svg +0 -53
  67. package/lib/shapes/icon/bpmn/events/intermediate-conditional.svg +0 -53
  68. package/lib/shapes/icon/bpmn/events/intermediate-escalation.svg +0 -53
  69. package/lib/shapes/icon/bpmn/events/intermediate-link-catch.svg +0 -53
  70. package/lib/shapes/icon/bpmn/events/intermediate-link-throw.svg +0 -53
  71. package/lib/shapes/icon/bpmn/events/intermediate-receive.svg +0 -53
  72. package/lib/shapes/icon/bpmn/events/intermediate-send.svg +0 -69
  73. package/lib/shapes/icon/bpmn/events/intermediate-signal-catch.svg +0 -53
  74. package/lib/shapes/icon/bpmn/events/intermediate-signal-throw.svg +0 -53
  75. package/lib/shapes/icon/bpmn/events/intermediate-timer.svg +0 -107
  76. package/lib/shapes/icon/bpmn/events/intermediate.svg +0 -49
  77. package/lib/shapes/icon/bpmn/events/message-end.svg +0 -54
  78. package/lib/shapes/icon/bpmn/events/message-start.svg +0 -41
  79. package/lib/shapes/icon/bpmn/events/signal-end.svg +0 -47
  80. package/lib/shapes/icon/bpmn/events/signal-start.svg +0 -47
  81. package/lib/shapes/icon/bpmn/events/terminate.svg +0 -49
  82. package/lib/shapes/icon/bpmn/events/timer.svg +0 -104
  83. package/lib/shapes/icon/bpmn/gateways/complex.svg +0 -61
  84. package/lib/shapes/icon/bpmn/gateways/event-based.svg +0 -68
  85. package/lib/shapes/icon/bpmn/gateways/exclusive.svg +0 -57
  86. package/lib/shapes/icon/bpmn/gateways/inclusive.svg +0 -57
  87. package/lib/shapes/icon/bpmn/gateways/parallel.svg +0 -56
  88. package/lib/shapes/icon/decorators.svg +0 -262
  89. package/lib/shapes/icon/hexagon.svg +0 -5
  90. package/lib/shapes/text/Roboto_Regular.json +0 -5610
  91. package/lib/shapes/text/TextShape.js +0 -29
  92. package/lib/shapes/text/fonts/Roboto.zip +0 -0
  93. package/vite.config.js +0 -15
@@ -1,710 +0,0 @@
1
- import * as THREE from 'three';
2
- import { Tween, Easing } from '@tweenjs/tween.js'
3
- import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
4
- import { MapControls } from 'three/examples/jsm/controls/MapControls';
5
- import { ArcballControls } from 'three/addons/controls/ArcballControls.js';
6
- import { mx_bilerp_0 } from 'three/src/nodes/materialx/lib/mx_noise.js';
7
-
8
- /**
9
- * Represents a 3D diagram using THREE.js.
10
- */
11
- class Diagram {
12
-
13
- /**
14
- * Creates a new Diagram instance.
15
- * @param {HTMLElement} container - The HTML container element for the diagram.
16
- */
17
- constructor(container) {
18
-
19
- // init Diagram features
20
-
21
- /**
22
- * Array of elements in the diagram.
23
- * @type {Array<Object3D>}
24
- */
25
- this.elements = [];
26
-
27
- /**
28
- * Array of connectors in the diagram.
29
- * @type {Array<Object3D>}
30
- */
31
- this.connectors = [];
32
-
33
- /**
34
- * Current mode of the diagram. Modes: 'EDIT', 'VIEW', 'ANALYZE'.
35
- * @type {string}
36
- */
37
- this.mode = 'VIEW';
38
-
39
- /**
40
- * Whether helpers (axes, grid, etc.) are visible.
41
- * @type {boolean}
42
- */
43
- this.helpers = false;
44
-
45
- // init THREE.js features
46
-
47
- /**
48
- * The HTML container element for the diagram.
49
- * @type {HTMLElement}
50
- */
51
- this.container = container;
52
-
53
- this.initScene();
54
- this.initCamera();
55
- this.setHelpers(); // Optionally set helpers
56
- this.initRenderer();
57
- this.initLighting();
58
- this.initControls();
59
- this.addEventListeners();
60
- this.animate();
61
- console.log('THREE', THREE);
62
- console.log(this);
63
- }
64
-
65
- /**
66
- * Initializes the THREE.js scene.
67
- */
68
- initScene() {
69
- this.scene = new THREE.Scene();
70
- this.scene.background = new THREE.Color( 0xf0f0f0 );
71
- }
72
-
73
- /**
74
- * Initializes the camera with a perspective projection.
75
- */
76
- initCamera() { // Perspective
77
- // const aspectRatio = this.container.clientWidth / window.innerHeight;
78
- const aspectRatio = window.innerWidth / window.innerHeight;
79
- this.camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 2000);
80
- this.camera.position.set(0, 0, 500);
81
- this.camera.updateProjectionMatrix();
82
- }
83
-
84
- // initCamera() { // Orthographic
85
- // // const aspectRatio = this.container.clientWidth / window.innerHeight;
86
- // const aspectRatio = window.innerWidth / window.innerHeight;
87
- // const frustumSize = 100;
88
- // this.camera = new THREE.OrthographicCamera(
89
- // frustumSize * aspectRatio / -2,
90
- // frustumSize * aspectRatio / 2,
91
- // frustumSize / 2,
92
- // frustumSize / -2,
93
- // 0.1,
94
- // 1000
95
- // );
96
- // this.camera.position.set(0, 0, 50);
97
- // }
98
-
99
- /**
100
- * Sets up helpers (axes, grid, etc.) for the scene.
101
- */
102
- setHelpers() {
103
- this.axesHelper = new THREE.AxesHelper(100);
104
- this.cameraHelper = new THREE.CameraHelper(this.camera);
105
- const size = 400;
106
- const divisions = 50;
107
- this.gridHelper = new THREE.GridHelper(size, divisions);
108
- // Set camera helper - define cameraDirection and span variables
109
- this.cameraDirection = new THREE.Vector3()
110
- this.camPositionSpan = document.querySelector("#position"); // set the spans with the queried HTML DOM elements
111
- this.camLookAtSpan = document.querySelector("#lookingAt");
112
-
113
- this.helpers = false;
114
- }
115
-
116
- /**
117
- * Shows the helpers in the scene.
118
- */
119
- showHelpers() {
120
- if (!this.helpers) {
121
- this.scene.add(this.axesHelper);
122
- this.scene.add(this.cameraHelper);
123
- this.scene.add(this.gridHelper);
124
- this.helpers = true;
125
- }
126
- }
127
-
128
- /**
129
- * Hides the helpers in the scene.
130
- */
131
- hideHelpers() {
132
- if (this.helpers) {
133
- this.scene.remove(this.axesHelper);
134
- this.scene.remove(this.cameraHelper);
135
- this.scene.remove(this.gridHelper);
136
- this.helpers = false;
137
- }
138
- }
139
-
140
- /**
141
- * Initializes the renderer and attaches it to the container.
142
- */
143
- initRenderer() {
144
- this.renderer = new THREE.WebGLRenderer({ antialias: true });
145
- this.renderer.setSize(window.innerWidth, window.innerHeight);
146
- // TODO: Ustawić na pełny ekran dla konkretnego kontenera.
147
- // this.renderer.setSize(this.container.clientWidth, this.container.innerHeight);
148
- // codepen at https://codepen.io/snakeo/pen/XWOoGPL
149
- document.body.appendChild(this.renderer.domElement);
150
- // TODO: Ustawić diagram w konkretnym kontenerze.
151
- // this.container.appendChild(this.renderer.domElement);
152
- console.log('initRenderer', this.container, this.renderer.domElement)
153
- }
154
-
155
- /**
156
- * Initializes the lighting for the scene.
157
- */
158
- initLighting() {
159
-
160
- // Main light
161
- let mainLightColor = 0xffffff; // white
162
- let mainLightIntensity = 4.0; // twice as bright as default
163
- let mainLightDistance = 0 // infinite range
164
- let mainLightDecay = 0 // no falloff
165
- const mainLight = new THREE.PointLight(mainLightColor, mainLightIntensity, mainLightDistance, mainLightDecay);
166
- // for diagram size { "x": 580, "y": 209, "z": 3.3 }
167
- let mainLightPosX = (-1 * (580 / 2)) + ((1/3) * 580); // Proportion 1/3 : 2/3
168
- let mainLightPosY = -1 * 209 * 4; // Below the diagram at the distance of 4 diagram height
169
- let mainLightPosZ = Math.abs(mainLightPosY); // The elevation is the same as the absolute Y distance
170
- mainLight.position.set(mainLightPosX, mainLightPosY, mainLightPosZ);
171
- this.scene.add(mainLight);
172
-
173
- // spot light
174
- this.spotLight = new THREE.PointLight( 0xffffff, 4, 0, 0 );
175
- this.spotLightPosX = 0; // Centered on the X axis. This will be moved in the animete() method.
176
- this.spotLightPosY = (-1 * 209) - 300; // Below the diagram at the distance of 500 points
177
- this.spotLightPosZ = 70;
178
- // this.spotLight.position.set(spotLightPosX, spotLightPosY, spotLightPosZ);
179
- this.scene.add(this.spotLight);
180
- this.spotLightDirection = 1;
181
-
182
- // // Old lights
183
- // // ----------------------------------------------------------------------
184
-
185
- // // light
186
- // const light = new THREE.PointLight( 0xffffff );
187
- // light.position.set(-500, -2500, 2500);
188
- // this.scene.add(light);
189
-
190
- // // spot light
191
- // const spotLight = new THREE.PointLight( 0xffffff );
192
- // spotLight.position.set( 0, -2500, 30 );
193
-
194
- // // ----------------------------------------------------------------------
195
- // // New lights
196
-
197
- // const ambientLight = new THREE.AmbientLight(0xCCCCCC, 4);
198
- // this.scene.add(ambientLight);
199
-
200
- // const directionalLight1 = new THREE.DirectionalLight(0xFFFFFF, 1);
201
- // directionalLight1.position.set(1, 3, 1).normalize();
202
- // this.scene.add(directionalLight1);
203
-
204
- // // Adding a second directional light
205
- // const directionalLight2 = new THREE.DirectionalLight(0xFFFFFF, 1);
206
- // directionalLight2.position.set(-1, -1, -1).normalize();
207
- // this.scene.add(directionalLight2);
208
-
209
- // // Add spot light
210
- // this.spotLight = new THREE.PointLight(0xffffff);
211
- // this.spotLight.position.set(0, -2500, 30);
212
- // this.scene.add(this.spotLight);
213
-
214
- // this.spotLightDirection = 1;
215
- // this.spotLightPosX = -2500;
216
- }
217
-
218
- /**
219
- * Initializes the controls for the camera.
220
- */
221
- initControls() {
222
- // this.controlsAnalyze = new OrbitControls(this.camera, this.renderer.domElement);
223
- // this.controlsAnalyze.enableDamping = true;
224
- // this.controlsAnalyze.dampingFactor = 0.25;
225
- // this.controlsAnalyze.screenSpacePanning = false;
226
- // this.controlsAnalyze.minPolarAngle = Math.PI / 2;
227
- // this.controlsAnalyze.maxPolarAngle = Math.PI;
228
- // this.controlsAnalyze.enabled = false;
229
- // this.controlsAnalyze.saveState();
230
-
231
- // this.controlsViewEdit = new MapControls(this.camera, this.renderer.domElement);
232
- // this.controlsViewEdit.enableDamping = true;
233
- // this.controlsViewEdit.dampingFactor = 0.25;
234
- // this.controlsViewEdit.screenSpacePanning = true;
235
- // this.controlsViewEdit.maxPolarAngle = Math.PI / 2;
236
- // this.controlsViewEdit.enabled = true;
237
- // this.controlsViewEdit.saveState();
238
-
239
- // this.controls = new ArcballControls(this.camera, this.renderer.domElement, this.scene);
240
- this.controls = new MapControls(this.camera, this.renderer.domElement);
241
- this.controls.enableDamping = true;
242
- this.controls.dampingFactor = 0.1;
243
- this.controls.screenSpacePanning = true;
244
- this.controls.zoomToCursor = true;
245
- this.controls.saveState();
246
-
247
- }
248
-
249
- /**
250
- * Adds event listeners for window resize and other interactions.
251
- */
252
- addEventListeners() {
253
- // Add event listener for window resize
254
- window.addEventListener('resize', this.onWindowResize.bind(this), false);
255
- // Add event listener for mouse events
256
- // this.renderer.domElement.addEventListener('mousedown', this.onDocumentMouseDown.bind(this), false);
257
- // this.renderer.domElement.addEventListener('mousemove', this.onDocumentMouseMove.bind(this), false);
258
- // this.renderer.domElement.addEventListener('mouseup', this.onDocumentMouseUp.bind(this), false);
259
- }
260
-
261
- // onDocumentMouseDown(event) {
262
- // this.isDragging = true;
263
- // this.previousMousePosition = { x: event.offsetX, y: event.offsetY };
264
- // }
265
-
266
- // onDocumentMouseMove(event) {
267
- // if (this.isDragging && this.mugGroup) {
268
- // const deltaMove = {
269
- // x: event.offsetX - this.previousMousePosition.x,
270
- // y: event.offsetY - this.previousMousePosition.y
271
- // };
272
-
273
- // let rotateAngleX = this.toRadians(deltaMove.y * 1);
274
- // let rotateAngleY = this.toRadians(deltaMove.x * 1);
275
-
276
- // this.currentRotation = this.currentRotation || { x: 0, y: 0 };
277
- // this.currentRotation.x += rotateAngleX;
278
- // this.currentRotation.y += rotateAngleY;
279
-
280
- // const maxRotation = Math.PI / 2;
281
- // this.currentRotation.x = Math.min(Math.max(this.currentRotation.x, -maxRotation), maxRotation);
282
-
283
- // this.pivotGroup.rotation.x = this.currentRotation.x;
284
- // this.pivotGroup.rotation.y = this.currentRotation.y;
285
-
286
- // this.previousMousePosition = { x: event.offsetX, y: event.offsetY };
287
- // }
288
- // }
289
-
290
- // onDocumentMouseUp() {
291
- // this.isDragging = false;
292
- // }
293
-
294
- // toRadians(angle) {
295
- // return angle * (Math.PI / 180);
296
- // }
297
-
298
- /**
299
- * Handles window resize events to update the camera and renderer.
300
- */
301
- onWindowResize() {
302
- this.camera.aspect = window.innerWidth / window.innerHeight;
303
- this.camera.updateProjectionMatrix();
304
- this.renderer.setSize(window.innerWidth, window.innerHeight);
305
- }
306
-
307
- /**
308
- * Animates the scene and updates controls.
309
- */
310
- animate() {
311
- if (this.tween) this.tween.update();
312
- requestAnimationFrame(this.animate.bind(this));
313
- this.controls.update();
314
- this.renderer.render(this.scene, this.camera);
315
-
316
- // Animate spot light
317
- if (this.spotLightPosX > 500) {
318
- this.spotLightDirection = -1;
319
- this.spotLightPosX = 500;
320
- }
321
- if (this.spotLightPosX < -500) {
322
- this.spotLightDirection = 1;
323
- this.spotLightPosX = -500;
324
- }
325
- this.spotLightPosX += 10 * this.spotLightDirection;
326
- this.spotLight.position.set(this.spotLightPosX, this.spotLightPosY, this.spotLightPosZ);
327
-
328
- // Show camera helpers
329
- // calculate and display the vector values on screen
330
- // this copies the camera's unit vector direction to cameraDirection
331
- this.camera.getWorldDirection(this.cameraDirection);
332
- // scale the unit vector up to get a more intuitive value
333
- this.cameraDirection.set(this.cameraDirection.x * 100, this.cameraDirection.y * 100, this.cameraDirection.z * 100);
334
- // update the onscreen spans with the camera's position and lookAt vectors
335
- this.camPositionSpan.innerHTML = `Position: (${this.camera.position.x.toFixed(1)}, ${this.camera.position.y.toFixed(1)}, ${this.camera.position.z.toFixed(1)})`;
336
- this.camLookAtSpan.innerHTML = `LookAt: (${(this.camera.position.x + this.cameraDirection.x).toFixed(1)}, ${(this.camera.position.y + this.cameraDirection.y).toFixed(1)}, ${(this.camera.position.z + this.cameraDirection.z).toFixed(1)})`;
337
- }
338
-
339
- reset() {
340
- this.hideHelpers();
341
- this.controls.reset();
342
- this.setMode('VIEW');
343
- this.fitScreen();
344
- }
345
-
346
-
347
- // ================================================================
348
- // Diagram arrangement
349
- // ================================================================
350
-
351
- arrange() {
352
- //
353
- // The method calculates the center of the diagram and moves all elements to center the diagram at {0, 0, 0}.
354
- // It also calculates the camera Z position to place the camera above the center.
355
- // Finally, it updates the controls target and updates the controls.
356
- if (this.scene.children.length === 0) {
357
- console.warn('Scene is empty. Cannot calculate center.');
358
- return;
359
- }
360
- const box = new THREE.Box3().setFromObject(this.scene);
361
- const center = box.getCenter(new THREE.Vector3());
362
- // Translate all elements to center the diagram at {0, 0, 0}
363
- const translation = new THREE.Vector3(-center.x, -center.y, -center.z);
364
- this.scene.children.forEach(child => {
365
- if (child instanceof THREE.Object3D) {
366
- child.position.add(translation);
367
- }
368
- });
369
- }
370
-
371
- fitScreen() {
372
- // The method ensures all the elements are visible.
373
- // Calculate the camera Z position
374
- const box = new THREE.Box3().setFromObject(this.scene);
375
- const size = box.getSize(new THREE.Vector3());
376
- console.log('fitScreen() -> size:', size);
377
- const maxDim = Math.max(size.x, size.y, size.z);
378
- const fov = this.camera.fov * (Math.PI / 180); // convert FOV to radians
379
- const cameraZ = Math.abs((maxDim / 2) / Math.tan(fov / 2));
380
- this.camera.position.set(0, 0, cameraZ); // Place camera above the center
381
- this.camera.lookAt(new THREE.Vector3(0, 0, 0));
382
- this.camera.updateProjectionMatrix();
383
- this.controls.saveState(); // Save the state of controls. This can later be recovered with .reset.
384
-
385
- // Save the initial camera position and target for later use
386
- this.initialCameraPosition = this.camera.position.clone();
387
- this.initialTarget = this.controls.target.clone();
388
- }
389
-
390
- center() {
391
- // The method centers the diagram by moving the camera to its initial state (as calculated by the fitScreen() method).
392
- // It also uses the Tween.js library to animate the camera movement.
393
- if (!this.initialCameraPosition || !this.initialTarget) {
394
- console.warn('Initial camera position or target is not defined.');
395
- return;
396
- }
397
-
398
- const from = {
399
- cameraPositionX: this.camera.position.x,
400
- cameraPositionY: this.camera.position.y,
401
- cameraPositionZ: this.camera.position.z,
402
- controlsTargetX: this.controls.target.x,
403
- controlsTargetY: this.controls.target.y,
404
- controlsTargetZ: this.controls.target.z
405
- };
406
- const to = {
407
- cameraPositionX: this.initialCameraPosition.x,
408
- cameraPositionY: this.initialCameraPosition.y,
409
- cameraPositionZ: this.initialCameraPosition.z,
410
- controlsTargetX: this.initialTarget.x,
411
- controlsTargetY: this.initialTarget.y,
412
- controlsTargetZ: this.initialTarget.z
413
- };
414
-
415
- const camera = this.camera;
416
- const controls = this.controls;
417
-
418
- this.tween = new Tween(from)
419
- .to(to, 1200)
420
- .easing(Easing.Quartic.Out)
421
- .onUpdate(function () {
422
- camera.position.set(
423
- from.cameraPositionX,
424
- from.cameraPositionY,
425
- from.cameraPositionZ
426
- );
427
- controls.target.set(
428
- from.controlsTargetX,
429
- from.controlsTargetY,
430
- from.controlsTargetZ
431
- );
432
- })
433
- .onComplete(function () {
434
- // controls.update();
435
- })
436
- .start();
437
- }
438
-
439
- rotate(targetAngle) { // in degrees (e.g. 60)
440
- // The method centers the diagram and rotates it around the Y axis by a specified angle.
441
- if (!this.initialCameraPosition || !this.initialTarget) {
442
- console.warn('Initial camera position or target is not defined.');
443
- return;
444
- }
445
-
446
- const radius = Math.sqrt(
447
- this.initialCameraPosition.y * this.initialCameraPosition.y +
448
- this.initialCameraPosition.z * this.initialCameraPosition.z
449
- );
450
-
451
- const from = {
452
- cameraPositionX: this.camera.position.x,
453
- cameraPositionY: this.camera.position.y,
454
- cameraPositionZ: this.camera.position.z,
455
- controlsTargetX: this.controls.target.x,
456
- controlsTargetY: this.controls.target.y,
457
- controlsTargetZ: this.controls.target.z
458
- };
459
-
460
- // Convert target angle to radians and calculate new positions
461
- const targetAngleRad = THREE.MathUtils.degToRad(targetAngle);
462
- const to = {
463
- cameraPositionX: this.initialCameraPosition.x,
464
- cameraPositionY: radius * Math.sin(targetAngleRad),
465
- cameraPositionZ: radius * Math.cos(targetAngleRad),
466
- controlsTargetX: this.initialTarget.x,
467
- controlsTargetY: this.initialTarget.y,
468
- controlsTargetZ: this.initialTarget.z
469
- };
470
-
471
- console.log('rotate() -> from:', from);
472
- console.log('rotate() -> to:', to);
473
-
474
- const camera = this.camera;
475
- const controls = this.controls;
476
-
477
- this.tween = new Tween(from)
478
- .to(to, 1200)
479
- .easing(Easing.Quartic.Out)
480
- .onUpdate(function() {
481
- camera.position.set(
482
- from.cameraPositionX,
483
- from.cameraPositionY,
484
- from.cameraPositionZ
485
- );
486
- controls.target.set(
487
- from.controlsTargetX,
488
- from.controlsTargetY,
489
- from.controlsTargetZ
490
- );
491
- })
492
- .start();
493
- }
494
-
495
- // ================================================================
496
- // Diagram modes
497
- // ================================================================
498
-
499
- /**
500
- * Removes all elements of type 'ValueBarShape' from the diagram.
501
- * Iterates through the `elements` array in reverse order to safely remove
502
- * elements without affecting the iteration process. For each matching element,
503
- * it removes the element from its parent (and thus from the scene) and also
504
- * removes it from the `elements` array.
505
- */
506
- removeValueBars() {
507
- // Iterate in reverse order to safely remove elements
508
- for (let i = this.elements.length - 1; i >= 0; i--) {
509
- const element = this.elements[i];
510
- if (element.type === 'ValueBarShape') {
511
- // Remove from parent AND scene
512
- if (element.parent) {
513
- element.parent.remove(element);
514
- }
515
- this.scene.remove(element);
516
- this.elements.splice(i, 1);
517
- }
518
- }
519
- }
520
-
521
- /**
522
- * Adds value bars to the diagram to visualize the elements' parameters.
523
- *
524
- * This method processes the elements in the diagram, calculates the height
525
- * of the bars based on their parameter values, and assigns a color to each
526
- * bar based on a normalized value. The bars are then added to the scene.
527
- *
528
- * @method
529
- * @memberof Diagram
530
- * @description
531
- * - Filters elements to include only those with a defined `parameters.value`.
532
- * - Calculates the range of parameter values to normalize them.
533
- * - Assigns a color to each bar using an HSL color scale (green to red).
534
- * - Calls the `valueBar` method on each element to set the bar's height and color.
535
- *
536
- * @example
537
- * // Assuming `diagram` is an instance of Diagram with elements having parameters:
538
- * diagram.addValueBars();
539
- *
540
- * @throws {Error} If no elements with `parameters.value` are found.
541
- */
542
- addValueBars() {
543
- const elements = this.elements.filter(el => el.parameters && el.parameters.value !== undefined);
544
- if (elements.length === 0) {
545
- throw new Error('No elements with `parameters.value` found.');
546
- }
547
- const max = Math.max(...elements.map(el => el.parameters.value));
548
- const min = 0;
549
- const range = max - min;
550
- elements.forEach((element, i) => {
551
- const value = element.parameters.value;
552
- const normalizedValue = (value - min) / range;
553
- const color = new THREE.Color(`hsl(${(normalizedValue * 120).toString(10)}, 100%, 50%)`);
554
- element.addValueBar(normalizedValue * 100, color);
555
- });
556
- }
557
-
558
- /**
559
- * Sets the mode of the diagram and adjusts its state accordingly.
560
- *
561
- * @param {string} mode - The mode to set. Possible values are:
562
- * - 'EDIT': Sets the diagram to edit mode and resets rotation.
563
- * - 'VIEW': Sets the diagram to view mode and resets rotation.
564
- * - 'ANALYZE': Sets the diagram to analyze mode, rotates it to -60 degrees,
565
- * and adds value bars.
566
- * - Any other value will log a warning about an unknown mode.
567
- */
568
- setMode(mode) {
569
- this.removeValueBars();
570
- this.mode = mode;
571
-
572
- switch (mode) {
573
- case 'EDIT':
574
- case 'VIEW':
575
- this.rotate(0);
576
- break;
577
- case 'ANALYZE':
578
- this.rotate(-65);
579
- this.addValueBars();
580
- break;
581
- default:
582
- console.warn(`Unknown mode: ${mode}`);
583
- }
584
- }
585
-
586
- // ================================================================
587
- // Diagram elements
588
- // ================================================================
589
-
590
- /**
591
- * Adds an element to the diagram.
592
- * @param {Object3D} element - The element to add.
593
- * @param {Vector3} [position] - The position to place the element.
594
- * @returns {Object3D} The added element.
595
- */
596
- addElement(element, position) {
597
- this.elements.push(element);
598
- this.scene.add(element);
599
- if (position) element.position.set(position.x, position.y, 0);
600
- // this.renderer.render(this.scene, this.camera);
601
- element.setDiagram(this);
602
- return element;
603
- }
604
-
605
- /**
606
- * Removes an element from the diagram by its ID.
607
- * @param {string} elementId - The ID of the element to remove.
608
- */
609
- removeElement(elementId) {
610
- const element = this.elements.find(el => el.id === elementId);
611
- if (element) {
612
- this.scene.remove(element);
613
- this.elements = this.elements.filter(el => el.id !== elementId);
614
- }
615
- }
616
-
617
- /**
618
- * Retrieves an element from the `elements` array by its unique `elementId`.
619
- *
620
- * @param {string} elementId - The unique identifier of the element to find.
621
- * @returns {Object|undefined} The element with the matching `elementId`, or `undefined` if not found.
622
- */
623
- getElementById(elementId) {
624
- return this.elements.find(el => el.elementId === elementId);
625
- }
626
-
627
- /**
628
- * Retrieves the elements of the diagram.
629
- *
630
- * @returns {Array} The array of elements in the diagram.
631
- */
632
- getElements() {
633
- return this.elements;
634
- }
635
-
636
- // ================================================================
637
- // Diagram Connectors
638
- // ================================================================
639
-
640
- /**
641
- * Adds a connector to the diagram, registers it with the diagram,
642
- * and adds it to the scene for rendering.
643
- *
644
- * @param {Object} connector - The connector object to be added to the diagram.
645
- * @returns {Object} The connector that was added.
646
- */
647
- addConnector(connector) {
648
- this.connectors.push(connector);
649
- this.scene.add(connector);
650
- connector.setDiagram(this);
651
- return connector;
652
- }
653
-
654
- // ================================================================
655
- // Clear diagram
656
- // ================================================================
657
-
658
- /**
659
- * Clears all elements and connectors from the diagram.
660
- */
661
- clear() {
662
- this.elements = [];
663
- this.connectors = [];
664
- this.scene.children = this.scene.children.filter(child => child instanceof THREE.AmbientLight);
665
- }
666
-
667
- // ================================================================
668
- // Diagram JSON
669
- // ================================================================
670
-
671
- toJSON() {
672
- return JSON.stringify(this.elements);
673
- }
674
-
675
- fromJSON(json) {
676
- this.elements = JSON.parse(json);
677
- }
678
-
679
- // ================================================================
680
- // Diagram export and import to/from file
681
- // ================================================================
682
-
683
- /**
684
- * Exports the diagram to a JSON file.
685
- */
686
- export() {
687
- const data = JSON.stringify(this.scene.toJSON());
688
- const blob = new Blob([data], { type: 'application/json' });
689
- const url = URL.createObjectURL(blob);
690
- const a = document.createElement('a');
691
- a.href = url;
692
- a.download = 'diagram.json';
693
- a.click();
694
- URL.revokeObjectURL(url);
695
- }
696
-
697
- /**
698
- * Placeholder for importing a diagram from a file.
699
- * This method should be implemented by subclasses.
700
- * @param {File} file - The file to import.
701
- * @throws {Error} If the method is not implemented.
702
- * @returns {Promise<void>}
703
- */
704
- import(file) {
705
- console.error('Import method should be implemented by subclasses.');
706
- }
707
-
708
- }
709
-
710
- export { Diagram };