pyegeria 5.3.4.6__py3-none-any.whl → 5.3.4.7.dev1__py3-none-any.whl

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 (94) hide show
  1. pyegeria/mermaid_utilities.py +218 -86
  2. pyegeria/test_m.html +113 -86
  3. pyegeria/test_mer.ipynb +596 -0
  4. {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/METADATA +1 -1
  5. {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/RECORD +8 -93
  6. pyegeria/.DS_Store +0 -0
  7. pyegeria/commands/.DS_Store +0 -0
  8. pyegeria/commands/__pycache__/__init__.cpython-312.pyc +0 -0
  9. pyegeria/commands/__pycache__/server_status_widget.cpython-312-pytest-7.4.4.pyc +0 -0
  10. pyegeria/commands/cat/__pycache__/__init__.cpython-312.pyc +0 -0
  11. pyegeria/commands/cat/__pycache__/get_asset_graph.cpython-312.pyc +0 -0
  12. pyegeria/commands/cat/__pycache__/get_collection.cpython-312.pyc +0 -0
  13. pyegeria/commands/cat/__pycache__/get_project_dependencies.cpython-312.pyc +0 -0
  14. pyegeria/commands/cat/__pycache__/get_project_structure.cpython-312.pyc +0 -0
  15. pyegeria/commands/cat/__pycache__/get_tech_type_elements.cpython-312.pyc +0 -0
  16. pyegeria/commands/cat/__pycache__/glossary_actions.cpython-312.pyc +0 -0
  17. pyegeria/commands/cat/__pycache__/list_assets.cpython-312.pyc +0 -0
  18. pyegeria/commands/cat/__pycache__/list_cert_types.cpython-312.pyc +0 -0
  19. pyegeria/commands/cat/__pycache__/list_collections.cpython-312.pyc +0 -0
  20. pyegeria/commands/cat/__pycache__/list_deployed_catalogs.cpython-312.pyc +0 -0
  21. pyegeria/commands/cat/__pycache__/list_deployed_database_schemas.cpython-312.pyc +0 -0
  22. pyegeria/commands/cat/__pycache__/list_deployed_databases.cpython-312.pyc +0 -0
  23. pyegeria/commands/cat/__pycache__/list_glossaries.cpython-312.pyc +0 -0
  24. pyegeria/commands/cat/__pycache__/list_projects.cpython-312.pyc +0 -0
  25. pyegeria/commands/cat/__pycache__/list_servers_deployed_imp.cpython-312.pyc +0 -0
  26. pyegeria/commands/cat/__pycache__/list_tech_type_elements.cpython-312.pyc +0 -0
  27. pyegeria/commands/cat/__pycache__/list_tech_types.cpython-312.pyc +0 -0
  28. pyegeria/commands/cat/__pycache__/list_terms.cpython-312.pyc +0 -0
  29. pyegeria/commands/cat/__pycache__/list_todos.cpython-312.pyc +0 -0
  30. pyegeria/commands/cat/__pycache__/list_user_ids.cpython-312.pyc +0 -0
  31. pyegeria/commands/cli/__pycache__/__init__.cpython-312.pyc +0 -0
  32. pyegeria/commands/cli/__pycache__/egeria_login_tui.cpython-312.pyc +0 -0
  33. pyegeria/commands/cli/__pycache__/egeria_ops.cpython-312.pyc +0 -0
  34. pyegeria/commands/cli/__pycache__/ops_config.cpython-312.pyc +0 -0
  35. pyegeria/commands/doc/.DS_Store +0 -0
  36. pyegeria/commands/doc/Visual Command Reference/.DS_Store +0 -0
  37. pyegeria/commands/doc/Visual Command Reference/cat/.DS_Store +0 -0
  38. pyegeria/commands/doc/Visual Command Reference/cat/show/.DS_Store +0 -0
  39. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/.DS_Store +0 -0
  40. pyegeria/commands/doc/glossary/.DS_Store +0 -0
  41. pyegeria/commands/doc/glossary/images/.DS_Store +0 -0
  42. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/.DS_Store +0 -0
  43. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/.DS_Store +0 -0
  44. pyegeria/commands/my/__pycache__/__init__.cpython-312.pyc +0 -0
  45. pyegeria/commands/my/__pycache__/list_my_profile.cpython-312.pyc +0 -0
  46. pyegeria/commands/my/__pycache__/list_my_roles.cpython-312.pyc +0 -0
  47. pyegeria/commands/my/__pycache__/monitor_my_todos.cpython-312.pyc +0 -0
  48. pyegeria/commands/my/__pycache__/monitor_open_todos.cpython-312.pyc +0 -0
  49. pyegeria/commands/my/__pycache__/todo_actions.cpython-312.pyc +0 -0
  50. pyegeria/commands/ops/__pycache__/__init__.cpython-312.pyc +0 -0
  51. pyegeria/commands/ops/__pycache__/gov_server_actions.cpython-312.pyc +0 -0
  52. pyegeria/commands/ops/__pycache__/list_archives.cpython-312.pyc +0 -0
  53. pyegeria/commands/ops/__pycache__/list_catalog_targets.cpython-312.pyc +0 -0
  54. pyegeria/commands/ops/__pycache__/load_archive.cpython-312.pyc +0 -0
  55. pyegeria/commands/ops/__pycache__/monitor_engine_activity.cpython-312.pyc +0 -0
  56. pyegeria/commands/ops/__pycache__/monitor_engine_activity_c.cpython-312.pyc +0 -0
  57. pyegeria/commands/ops/__pycache__/monitor_gov_eng_status.cpython-312.pyc +0 -0
  58. pyegeria/commands/ops/__pycache__/monitor_integ_daemon_status.cpython-312.pyc +0 -0
  59. pyegeria/commands/ops/__pycache__/monitor_platform_status.cpython-312.pyc +0 -0
  60. pyegeria/commands/ops/__pycache__/monitor_server_startup.cpython-312.pyc +0 -0
  61. pyegeria/commands/ops/__pycache__/monitor_server_status.cpython-312.pyc +0 -0
  62. pyegeria/commands/ops/__pycache__/refresh_integration_daemon.cpython-312.pyc +0 -0
  63. pyegeria/commands/ops/__pycache__/restart_integration_daemon.cpython-312.pyc +0 -0
  64. pyegeria/commands/ops/__pycache__/table_integ_daemon_status.cpython-312.pyc +0 -0
  65. pyegeria/commands/tech/.DS_Store +0 -0
  66. pyegeria/commands/tech/__pycache__/__init__.cpython-312.pyc +0 -0
  67. pyegeria/commands/tech/__pycache__/get_element_info.cpython-312.pyc +0 -0
  68. pyegeria/commands/tech/__pycache__/get_guid_info.cpython-312.pyc +0 -0
  69. pyegeria/commands/tech/__pycache__/get_tech_details.cpython-312.pyc +0 -0
  70. pyegeria/commands/tech/__pycache__/get_tech_type_template.cpython-312.pyc +0 -0
  71. pyegeria/commands/tech/__pycache__/list_all_om_type_elements.cpython-312.pyc +0 -0
  72. pyegeria/commands/tech/__pycache__/list_all_om_type_elements_x.cpython-312.pyc +0 -0
  73. pyegeria/commands/tech/__pycache__/list_all_related_elements.cpython-312.pyc +0 -0
  74. pyegeria/commands/tech/__pycache__/list_anchored_elements.cpython-312.pyc +0 -0
  75. pyegeria/commands/tech/__pycache__/list_asset_types.cpython-312.pyc +0 -0
  76. pyegeria/commands/tech/__pycache__/list_elements_by_classification_by_property_value.cpython-312.pyc +0 -0
  77. pyegeria/commands/tech/__pycache__/list_elements_by_property_value.cpython-312.pyc +0 -0
  78. pyegeria/commands/tech/__pycache__/list_elements_by_property_value_x.cpython-312.pyc +0 -0
  79. pyegeria/commands/tech/__pycache__/list_elements_for_classification.cpython-312.pyc +0 -0
  80. pyegeria/commands/tech/__pycache__/list_gov_action_processes.cpython-312.pyc +0 -0
  81. pyegeria/commands/tech/__pycache__/list_information_supply_chains.cpython-312.pyc +0 -0
  82. pyegeria/commands/tech/__pycache__/list_registered_services.cpython-312.pyc +0 -0
  83. pyegeria/commands/tech/__pycache__/list_related_elements_with_prop_value.cpython-312.pyc +0 -0
  84. pyegeria/commands/tech/__pycache__/list_related_specification.cpython-312.pyc +0 -0
  85. pyegeria/commands/tech/__pycache__/list_relationship_types.cpython-312.pyc +0 -0
  86. pyegeria/commands/tech/__pycache__/list_relationships.cpython-312.pyc +0 -0
  87. pyegeria/commands/tech/__pycache__/list_solution_blueprints.cpython-312.pyc +0 -0
  88. pyegeria/commands/tech/__pycache__/list_solution_components.cpython-312.pyc +0 -0
  89. pyegeria/commands/tech/__pycache__/list_solution_roles.cpython-312.pyc +0 -0
  90. pyegeria/commands/tech/__pycache__/list_tech_templates.cpython-312.pyc +0 -0
  91. pyegeria/commands/tech/__pycache__/list_valid_metadata_values.cpython-312.pyc +0 -0
  92. {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/LICENSE +0 -0
  93. {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/WHEEL +0 -0
  94. {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/entry_points.txt +0 -0
@@ -235,107 +235,239 @@ def construct_mermaid_html(mermaid_str: str) -> str:
235
235
  escaped_header = html.escape(title_label) if title_label else "" # Sanitize the header safely
236
236
  escaped_mermaid_code = html.escape(mermaid_code)
237
237
 
238
- header_html = f"<h2 class='diagram-header'>{escaped_header}</h2>\nGUID: {guid}" if {title_label} else ""
238
+ # header_html = f"<h2 class='diagram-header'>{escaped_header}</h2>\nGUID: {guid}" if title_label else ""
239
+ # Header HTML (display only if header exists)
240
+ header_html = f"""
241
+ <h2 style="text-align: center; color: #007acc; margin-bottom: 16px;">
242
+ {escaped_header}
243
+ </h2>
244
+ """ if title_label else ""
239
245
 
240
246
  # Construct the HTML content with Mermaid.js initialization and zoom/pan support
247
+
248
+
241
249
  mermaid_html = f"""
242
- <div class="diagram-container" style="width: 90%; max-width: 800px; margin: auto; padding: 20px; background: white; border: 1px solid #ddd; border-radius: 12px; position: relative;">
250
+ <div id="{graph_id}-container" class="diagram-container"
251
+ style="width: 90%; max-width: 800px; margin: auto; padding: 20px;
252
+ background: white; border: 1px solid #ddd;
253
+ border-radius: 12px; position: relative;">
243
254
  {header_html}
244
- <div class="pan-zoom-container" style="width: 100%; height: 500px; overflow: hidden; position: relative; background: #f9f9f9; border: 1px solid #ccc; cursor: grab;">
245
- <div id="{graph_id}" class="mermaid pan-zoom-content" style="position: absolute; transform-origin: 0 0; cursor: grab;">
255
+ <div class="pan-zoom-container"
256
+ style="width: 100%; height: 500px; overflow: hidden;
257
+ position: relative; background: #f9f9f9;
258
+ border: 1px solid #ccc; cursor: grab;">
259
+ <div id="pz-{graph_id}" class="mermaid pan-zoom-content"
260
+ style="position: absolute; transform-origin: 0 0;">
246
261
  {escaped_mermaid_code}
247
262
  </div>
248
263
  </div>
249
264
  </div>
250
- <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
265
+
251
266
  <script>
252
- // Initialize Mermaid.js and set up pan/zoom
253
- mermaid.initialize({{ startOnLoad: true }});
254
-
255
- const container = document.querySelector('.pan-zoom-container');
256
- const content = document.querySelector('.pan-zoom-content');
257
- const rect = content.getBoundingClientRect();
258
-
259
- let scale = 1; // Current zoom level
260
- let panX = 0; // X-axis pan offset
261
- let panY = 0; // Y-axis pan offset
262
- let isDragging = false;
263
- let startX, startY;
264
-
265
- // Helper: Apply transformations
266
- const applyTransform = () => {{
267
- content.style.transform = `translate(${{panX}}px, ${{panY}}px) scale(${{scale}})`;
268
- }};
269
-
270
- // Helper: Center the diagram and fit it to the container
271
- const centerAndFitDiagram = () => {{
272
- const containerRect = container.getBoundingClientRect();
273
- const rect = content.getBoundingClientRect();
274
-
275
- scale = Math.min(
276
- containerRect.width / rect.width,
277
- containerRect.height / rect.height
278
- );
279
-
280
- panX = (containerRect.width - rect.width * scale) / 2;
281
- panY = (containerRect.height - rect.height * scale) / 2;
282
-
283
- applyTransform();
284
- console.log("Diagram centered and fitted.");
285
- }};
286
-
287
- // Add zoom functionality
288
- container.addEventListener('wheel', function(event) {{
289
- event.preventDefault();
290
- const zoomSpeed = 0.1;
291
- const previousScale = scale;
292
-
293
- if (event.deltaY < 0) {{
294
- scale = Math.min(scale + zoomSpeed, 4);
267
+ (function() {{
268
+ // Check if Mermaid.js is already loaded; load if not
269
+ if (typeof mermaid === "undefined") {{
270
+ const script = document.createElement('script');
271
+ script.src = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js";
272
+ script.onload = () => initializeMermaid();
273
+ document.head.appendChild(script);
295
274
  }} else {{
296
- scale = Math.max(scale - zoomSpeed, 0.5);
275
+ initializeMermaid();
297
276
  }}
298
277
 
299
- const zoomRatio = scale / previousScale;
300
- panX -= (event.clientX - container.getBoundingClientRect().left) * (zoomRatio - 1);
301
- panY -= (event.clientY - container.getBoundingClientRect().top) * (zoomRatio - 1);
302
-
303
- applyTransform();
304
- }});
305
-
306
- // Add drag functionality for panning
307
- container.addEventListener('mousedown', function(event) {{
308
- isDragging = true;
309
- startX = event.clientX - panX;
310
- startY = event.clientY - panY;
311
- container.style.cursor = "grabbing";
312
- }});
313
-
314
- container.addEventListener('mousemove', function(event) {{
315
- if (!isDragging) return;
316
-
317
- panX = event.clientX - startX;
318
- panY = event.clientY - startY;
319
-
320
- applyTransform();
321
- }});
322
-
323
- container.addEventListener('mouseup', function() {{
324
- isDragging = false;
325
- container.style.cursor = "grab";
326
- }});
327
-
328
- container.addEventListener('mouseleave', function() {{
329
- isDragging = false;
330
- container.style.cursor = "grab";
331
- }});
332
-
333
- // Center diagram after rendering by Mermaid
334
- setTimeout(centerAndFitDiagram, 200);
278
+ function initializeMermaid() {{
279
+ // Re-render the Mermaid chart
280
+ mermaid.initialize({{ startOnLoad: true }});
281
+ mermaid.init(undefined, document.querySelector("#pz-{graph_id}"));
282
+
283
+ // Add interactivity for pan and zoom
284
+ const container = document.querySelector('.pan-zoom-container');
285
+ const content = document.querySelector('.pan-zoom-content');
286
+
287
+ let scale = 1; // Current zoom level
288
+ let panX = 0; // X-axis pan
289
+ let panY = 0; // Y-axis pan
290
+ let isDragging = false;
291
+ let startX, startY;
292
+
293
+ // Apply Transformations
294
+ const applyTransform = () => {{
295
+ content.style.transform = `translate(${{panX}}px, ${{panY}}px) scale(${{scale}})`;
296
+ }};
297
+
298
+ // Center Diagram on Load
299
+ const centerAndFitDiagram = () => {{
300
+ const containerRect = container.getBoundingClientRect();
301
+ const rect = content.getBoundingClientRect();
302
+
303
+ scale = Math.min(
304
+ containerRect.width / rect.width,
305
+ containerRect.height / rect.height
306
+ );
307
+
308
+ panX = (containerRect.width - rect.width * scale) / 2;
309
+ panY = (containerRect.height - rect.height * scale) / 2;
310
+
311
+ applyTransform();
312
+ }};
313
+
314
+ setTimeout(centerAndFitDiagram, 200); // Allow rendering time
315
+
316
+ // Enable Mouse-Wheel Zoom
317
+ container.addEventListener('wheel', (event) => {{
318
+ event.preventDefault();
319
+ const zoomSpeed = 0.1;
320
+ const previousScale = scale;
321
+
322
+ if (event.deltaY < 0) {{
323
+ scale = Math.min(scale + zoomSpeed, 4);
324
+ }} else {{
325
+ scale = Math.max(scale - zoomSpeed, 0.5);
326
+ }}
327
+
328
+ const zoomRatio = scale / previousScale;
329
+ const clientRect = container.getBoundingClientRect();
330
+
331
+ panX -= (event.clientX - clientRect.left) * (zoomRatio - 1);
332
+ panY -= (event.clientY - clientRect.top) * (zoomRatio - 1);
333
+
334
+ applyTransform();
335
+ }});
336
+
337
+ // Enable Drag-to-Pan
338
+ container.addEventListener('mousedown', (event) => {{
339
+ isDragging = true;
340
+ startX = event.clientX - panX;
341
+ startY = event.clientY - panY;
342
+ container.style.cursor = "grabbing";
343
+ }});
344
+
345
+ container.addEventListener('mousemove', (event) => {{
346
+ if (!isDragging) return;
347
+
348
+ panX = event.clientX - startX;
349
+ panY = event.clientY - startY;
350
+
351
+ applyTransform();
352
+ }});
353
+
354
+ container.addEventListener('mouseup', () => {{
355
+ isDragging = false;
356
+ container.style.cursor = "grab";
357
+ }});
358
+
359
+ container.addEventListener('mouseleave', () => {{
360
+ isDragging = false;
361
+ container.style.cursor = "grab";
362
+ }});
363
+ }}
364
+ }})();
335
365
  </script>
336
- """
337
366
 
367
+ """
338
368
  return mermaid_html
369
+ # mermaid_html = f"""
370
+ # <h2 style="text-align: center; color: #007acc; margin-bottom: 16px;">
371
+ # {escaped_header}
372
+ # </h2>
373
+ # """ if header else ""
374
+ # # <div class="diagram-container" style="width: 90%; max-width: 800px; margin: auto; padding: 20px; background: white; border: 1px solid #ddd; border-radius: 12px; position: relative;">
375
+ # # {header_html}
376
+ # # <div class="pan-zoom-container" style="width: 100%; height: 500px; overflow: hidden; position: relative; background: #f9f9f9; border: 1px solid #ccc; cursor: grab;">
377
+ # # <div id="{graph_id}" class="mermaid pan-zoom-content" style="position: absolute; transform-origin: 0 0; cursor: grab;">
378
+ # # {escaped_mermaid_code}
379
+ # # </div>
380
+ # # </div>
381
+ # # </div>
382
+ # # <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
383
+ # # <script>
384
+ # # // Initialize Mermaid.js and set up pan/zoom
385
+ # # mermaid.initialize({{ startOnLoad: true }});
386
+ # #
387
+ # # const container = document.querySelector('.pan-zoom-container');
388
+ # # const content = document.querySelector('.pan-zoom-content');
389
+ # # const rect = content.getBoundingClientRect();
390
+ # #
391
+ # # let scale = 1; // Current zoom level
392
+ # # let panX = 0; // X-axis pan offset
393
+ # # let panY = 0; // Y-axis pan offset
394
+ # # let isDragging = false;
395
+ # # let startX, startY;
396
+ # #
397
+ # # // Helper: Apply transformations
398
+ # # const applyTransform = () => {{
399
+ # # content.style.transform = `translate(${{panX}}px, ${{panY}}px) scale(${{scale}})`;
400
+ # # }};
401
+ # #
402
+ # # // Helper: Center the diagram and fit it to the container
403
+ # # const centerAndFitDiagram = () => {{
404
+ # # const containerRect = container.getBoundingClientRect();
405
+ # # const rect = content.getBoundingClientRect();
406
+ # #
407
+ # # scale = Math.min(
408
+ # # containerRect.width / rect.width,
409
+ # # containerRect.height / rect.height
410
+ # # );
411
+ # #
412
+ # # panX = (containerRect.width - rect.width * scale) / 2;
413
+ # # panY = (containerRect.height - rect.height * scale) / 2;
414
+ # #
415
+ # # applyTransform();
416
+ # # console.log("Diagram centered and fitted.");
417
+ # # }};
418
+ # #
419
+ # # // Add zoom functionality
420
+ # # container.addEventListener('wheel', function(event) {{
421
+ # # event.preventDefault();
422
+ # # const zoomSpeed = 0.1;
423
+ # # const previousScale = scale;
424
+ # #
425
+ # # if (event.deltaY < 0) {{
426
+ # # scale = Math.min(scale + zoomSpeed, 4);
427
+ # # }} else {{
428
+ # # scale = Math.max(scale - zoomSpeed, 0.5);
429
+ # # }}
430
+ # #
431
+ # # const zoomRatio = scale / previousScale;
432
+ # # panX -= (event.clientX - container.getBoundingClientRect().left) * (zoomRatio - 1);
433
+ # # panY -= (event.clientY - container.getBoundingClientRect().top) * (zoomRatio - 1);
434
+ # #
435
+ # # applyTransform();
436
+ # # }});
437
+ # #
438
+ # # // Add drag functionality for panning
439
+ # # container.addEventListener('mousedown', function(event) {{
440
+ # # isDragging = true;
441
+ # # startX = event.clientX - panX;
442
+ # # startY = event.clientY - panY;
443
+ # # container.style.cursor = "grabbing";
444
+ # # }});
445
+ # #
446
+ # # container.addEventListener('mousemove', function(event) {{
447
+ # # if (!isDragging) return;
448
+ # #
449
+ # # panX = event.clientX - startX;
450
+ # # panY = event.clientY - startY;
451
+ # #
452
+ # # applyTransform();
453
+ # # }});
454
+ # #
455
+ # # container.addEventListener('mouseup', function() {{
456
+ # # isDragging = false;
457
+ # # container.style.cursor = "grab";
458
+ # # }});
459
+ # #
460
+ # # container.addEventListener('mouseleave', function() {{
461
+ # # isDragging = false;
462
+ # # container.style.cursor = "grab";
463
+ # # }});
464
+ # #
465
+ # # // Center diagram after rendering by Mermaid
466
+ # # setTimeout(centerAndFitDiagram, 200);
467
+ # # </script>
468
+ # # """
469
+ #
470
+ # return mermaid_html
339
471
 
340
472
 
341
473
 
pyegeria/test_m.html CHANGED
@@ -1,9 +1,19 @@
1
1
 
2
- <div class="diagram-container" style="width: 90%; max-width: 800px; margin: auto; padding: 20px; background: white; border: 1px solid #ddd; border-radius: 12px; position: relative;">
3
- <h2 class='diagram-header'>Component for Solution Blueprint - Clinical Trial Management Solution Blueprint </h2>
4
- GUID: c4f8d707-7c85-4125-b5fd-c3257a2ef2ef
5
- <div class="pan-zoom-container" style="width: 100%; height: 500px; overflow: hidden; position: relative; background: #f9f9f9; border: 1px solid #ccc; cursor: grab;">
6
- <div id="Component_for_Solution_Blueprint_-_Clinical_Trial_Management_Solution_Blueprint_" class="mermaid pan-zoom-content" style="position: absolute; transform-origin: 0 0; cursor: grab;">
2
+ <div id="Component_for_Solution_Blueprint_-_Clinical_Trial_Management_Solution_Blueprint_-container" class="diagram-container"
3
+ style="width: 90%; max-width: 800px; margin: auto; padding: 20px;
4
+ background: white; border: 1px solid #ddd;
5
+ border-radius: 12px; position: relative;">
6
+
7
+ <h2 style="text-align: center; color: #007acc; margin-bottom: 16px;">
8
+ Component for Solution Blueprint - Clinical Trial Management Solution Blueprint
9
+ </h2>
10
+
11
+ <div class="pan-zoom-container"
12
+ style="width: 100%; height: 500px; overflow: hidden;
13
+ position: relative; background: #f9f9f9;
14
+ border: 1px solid #ccc; cursor: grab;">
15
+ <div id="Component_for_Solution_Blueprint_-_Clinical_Trial_Management_Solution_Blueprint_" class="mermaid pan-zoom-content"
16
+ style="position: absolute; transform-origin: 0 0;">
7
17
  flowchart TD
8
18
  %%{init: {&quot;flowchart&quot;: {&quot;htmlLabels&quot;: false}} }%%
9
19
 
@@ -108,89 +118,106 @@ style fb32bef2-e79f-4893-b500-2e547f24d482 color:#FFFFFF, fill:#838cc7, stroke:#
108
118
  </div>
109
119
  </div>
110
120
  </div>
111
- <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
121
+
112
122
  <script>
113
- // Initialize Mermaid.js and set up pan/zoom
114
- mermaid.initialize({ startOnLoad: true });
115
-
116
- const container = document.querySelector('.pan-zoom-container');
117
- const content = document.querySelector('.pan-zoom-content');
118
- const rect = content.getBoundingClientRect();
119
-
120
- let scale = 1; // Current zoom level
121
- let panX = 0; // X-axis pan offset
122
- let panY = 0; // Y-axis pan offset
123
- let isDragging = false;
124
- let startX, startY;
125
-
126
- // Helper: Apply transformations
127
- const applyTransform = () => {
128
- content.style.transform = `translate(${panX}px, ${panY}px) scale(${scale})`;
129
- };
130
-
131
- // Helper: Center the diagram and fit it to the container
132
- const centerAndFitDiagram = () => {
133
- const containerRect = container.getBoundingClientRect();
134
- const rect = content.getBoundingClientRect();
135
-
136
- scale = Math.min(
137
- containerRect.width / rect.width,
138
- containerRect.height / rect.height
139
- );
140
-
141
- panX = (containerRect.width - rect.width * scale) / 2;
142
- panY = (containerRect.height - rect.height * scale) / 2;
143
-
144
- applyTransform();
145
- console.log("Diagram centered and fitted.");
146
- };
147
-
148
- // Add zoom functionality
149
- container.addEventListener('wheel', function(event) {
150
- event.preventDefault();
151
- const zoomSpeed = 0.1;
152
- const previousScale = scale;
153
-
154
- if (event.deltaY < 0) {
155
- scale = Math.min(scale + zoomSpeed, 4);
123
+ (function() {
124
+ // Check if Mermaid.js is already loaded; load if not
125
+ if (typeof mermaid === "undefined") {
126
+ const script = document.createElement('script');
127
+ script.src = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js";
128
+ script.onload = () => initializeMermaid();
129
+ document.head.appendChild(script);
156
130
  } else {
157
- scale = Math.max(scale - zoomSpeed, 0.5);
131
+ initializeMermaid();
158
132
  }
159
133
 
160
- const zoomRatio = scale / previousScale;
161
- panX -= (event.clientX - container.getBoundingClientRect().left) * (zoomRatio - 1);
162
- panY -= (event.clientY - container.getBoundingClientRect().top) * (zoomRatio - 1);
163
-
164
- applyTransform();
165
- });
166
-
167
- // Add drag functionality for panning
168
- container.addEventListener('mousedown', function(event) {
169
- isDragging = true;
170
- startX = event.clientX - panX;
171
- startY = event.clientY - panY;
172
- container.style.cursor = "grabbing";
173
- });
174
-
175
- container.addEventListener('mousemove', function(event) {
176
- if (!isDragging) return;
177
-
178
- panX = event.clientX - startX;
179
- panY = event.clientY - startY;
180
-
181
- applyTransform();
182
- });
183
-
184
- container.addEventListener('mouseup', function() {
185
- isDragging = false;
186
- container.style.cursor = "grab";
187
- });
188
-
189
- container.addEventListener('mouseleave', function() {
190
- isDragging = false;
191
- container.style.cursor = "grab";
192
- });
193
-
194
- // Center diagram after rendering by Mermaid
195
- setTimeout(centerAndFitDiagram, 200);
134
+ function initializeMermaid() {
135
+ // Re-render the Mermaid chart
136
+ mermaid.initialize({ startOnLoad: true });
137
+ mermaid.init(undefined, document.querySelector("#Component_for_Solution_Blueprint_-_Clinical_Trial_Management_Solution_Blueprint_"));
138
+
139
+ // Add interactivity for pan and zoom
140
+ const container = document.querySelector('.pan-zoom-container');
141
+ const content = document.querySelector('.pan-zoom-content');
142
+
143
+ let scale = 1; // Current zoom level
144
+ let panX = 0; // X-axis pan
145
+ let panY = 0; // Y-axis pan
146
+ let isDragging = false;
147
+ let startX, startY;
148
+
149
+ // Apply Transformations
150
+ const applyTransform = () => {
151
+ content.style.transform = `translate(${panX}px, ${panY}px) scale(${scale})`;
152
+ };
153
+
154
+ // Center Diagram on Load
155
+ const centerAndFitDiagram = () => {
156
+ const containerRect = container.getBoundingClientRect();
157
+ const rect = content.getBoundingClientRect();
158
+
159
+ scale = Math.min(
160
+ containerRect.width / rect.width,
161
+ containerRect.height / rect.height
162
+ );
163
+
164
+ panX = (containerRect.width - rect.width * scale) / 2;
165
+ panY = (containerRect.height - rect.height * scale) / 2;
166
+
167
+ applyTransform();
168
+ };
169
+
170
+ setTimeout(centerAndFitDiagram, 200); // Allow rendering time
171
+
172
+ // Enable Mouse-Wheel Zoom
173
+ container.addEventListener('wheel', (event) => {
174
+ event.preventDefault();
175
+ const zoomSpeed = 0.1;
176
+ const previousScale = scale;
177
+
178
+ if (event.deltaY < 0) {
179
+ scale = Math.min(scale + zoomSpeed, 4);
180
+ } else {
181
+ scale = Math.max(scale - zoomSpeed, 0.5);
182
+ }
183
+
184
+ const zoomRatio = scale / previousScale;
185
+ const clientRect = container.getBoundingClientRect();
186
+
187
+ panX -= (event.clientX - clientRect.left) * (zoomRatio - 1);
188
+ panY -= (event.clientY - clientRect.top) * (zoomRatio - 1);
189
+
190
+ applyTransform();
191
+ });
192
+
193
+ // Enable Drag-to-Pan
194
+ container.addEventListener('mousedown', (event) => {
195
+ isDragging = true;
196
+ startX = event.clientX - panX;
197
+ startY = event.clientY - panY;
198
+ container.style.cursor = "grabbing";
199
+ });
200
+
201
+ container.addEventListener('mousemove', (event) => {
202
+ if (!isDragging) return;
203
+
204
+ panX = event.clientX - startX;
205
+ panY = event.clientY - startY;
206
+
207
+ applyTransform();
208
+ });
209
+
210
+ container.addEventListener('mouseup', () => {
211
+ isDragging = false;
212
+ container.style.cursor = "grab";
213
+ });
214
+
215
+ container.addEventListener('mouseleave', () => {
216
+ isDragging = false;
217
+ container.style.cursor = "grab";
218
+ });
219
+ }
220
+ })();
196
221
  </script>
222
+
223
+