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.
- pyegeria/mermaid_utilities.py +218 -86
- pyegeria/test_m.html +113 -86
- pyegeria/test_mer.ipynb +596 -0
- {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/METADATA +1 -1
- {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/RECORD +8 -93
- pyegeria/.DS_Store +0 -0
- pyegeria/commands/.DS_Store +0 -0
- pyegeria/commands/__pycache__/__init__.cpython-312.pyc +0 -0
- pyegeria/commands/__pycache__/server_status_widget.cpython-312-pytest-7.4.4.pyc +0 -0
- pyegeria/commands/cat/__pycache__/__init__.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/get_asset_graph.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/get_collection.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/get_project_dependencies.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/get_project_structure.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/get_tech_type_elements.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/glossary_actions.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_assets.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_cert_types.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_collections.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_deployed_catalogs.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_deployed_database_schemas.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_deployed_databases.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_glossaries.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_projects.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_servers_deployed_imp.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_tech_type_elements.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_tech_types.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_terms.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_todos.cpython-312.pyc +0 -0
- pyegeria/commands/cat/__pycache__/list_user_ids.cpython-312.pyc +0 -0
- pyegeria/commands/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- pyegeria/commands/cli/__pycache__/egeria_login_tui.cpython-312.pyc +0 -0
- pyegeria/commands/cli/__pycache__/egeria_ops.cpython-312.pyc +0 -0
- pyegeria/commands/cli/__pycache__/ops_config.cpython-312.pyc +0 -0
- pyegeria/commands/doc/.DS_Store +0 -0
- pyegeria/commands/doc/Visual Command Reference/.DS_Store +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/.DS_Store +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/.DS_Store +0 -0
- pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/.DS_Store +0 -0
- pyegeria/commands/doc/glossary/.DS_Store +0 -0
- pyegeria/commands/doc/glossary/images/.DS_Store +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/.DS_Store +0 -0
- pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/.DS_Store +0 -0
- pyegeria/commands/my/__pycache__/__init__.cpython-312.pyc +0 -0
- pyegeria/commands/my/__pycache__/list_my_profile.cpython-312.pyc +0 -0
- pyegeria/commands/my/__pycache__/list_my_roles.cpython-312.pyc +0 -0
- pyegeria/commands/my/__pycache__/monitor_my_todos.cpython-312.pyc +0 -0
- pyegeria/commands/my/__pycache__/monitor_open_todos.cpython-312.pyc +0 -0
- pyegeria/commands/my/__pycache__/todo_actions.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/__init__.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/gov_server_actions.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/list_archives.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/list_catalog_targets.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/load_archive.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_engine_activity.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_engine_activity_c.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_gov_eng_status.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_integ_daemon_status.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_platform_status.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_server_startup.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/monitor_server_status.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/refresh_integration_daemon.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/restart_integration_daemon.cpython-312.pyc +0 -0
- pyegeria/commands/ops/__pycache__/table_integ_daemon_status.cpython-312.pyc +0 -0
- pyegeria/commands/tech/.DS_Store +0 -0
- pyegeria/commands/tech/__pycache__/__init__.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/get_element_info.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/get_guid_info.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/get_tech_details.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/get_tech_type_template.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_all_om_type_elements.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_all_om_type_elements_x.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_all_related_elements.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_anchored_elements.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_asset_types.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_elements_by_classification_by_property_value.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_elements_by_property_value.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_elements_by_property_value_x.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_elements_for_classification.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_gov_action_processes.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_information_supply_chains.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_registered_services.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_related_elements_with_prop_value.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_related_specification.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_relationship_types.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_relationships.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_solution_blueprints.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_solution_components.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_solution_roles.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_tech_templates.cpython-312.pyc +0 -0
- pyegeria/commands/tech/__pycache__/list_valid_metadata_values.cpython-312.pyc +0 -0
- {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/LICENSE +0 -0
- {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/WHEEL +0 -0
- {pyegeria-5.3.4.6.dist-info → pyegeria-5.3.4.7.dev1.dist-info}/entry_points.txt +0 -0
pyegeria/mermaid_utilities.py
CHANGED
@@ -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
|
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
|
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"
|
245
|
-
|
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
|
-
|
265
|
+
|
251
266
|
<script>
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
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
|
-
|
275
|
+
initializeMermaid();
|
297
276
|
}}
|
298
277
|
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
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
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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: {"flowchart": {"htmlLabels": 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
|
-
|
121
|
+
|
112
122
|
<script>
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
131
|
+
initializeMermaid();
|
158
132
|
}
|
159
133
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
+
|