Files
spring-state-machine-renderer/state_machine_exporter/flow_renderer_plan/interactive_poc.html

91 lines
2.9 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; display: flex; }
#sidebar { width: 300px; padding: 20px; background: #f4f4f4; }
#diagram { flex-grow: 1; padding: 20px; }
.flow-btn { padding: 10px; margin-bottom: 5px; cursor: pointer; background: #ddd; border: 1px solid #ccc; border-radius: 4px;}
.flow-btn:hover { background: #bdf; }
/* Dim everything by default when a flow is active */
.diagram-container.flow-active svg g {
opacity: 0.2;
transition: opacity 0.3s;
}
/* Highlight active elements */
.diagram-container.flow-active svg g.highlighted {
opacity: 1 !important;
}
/* Make highlighted paths thicker/red */
.diagram-container.flow-active svg g.highlighted path,
.diagram-container.flow-active svg g.highlighted polygon {
stroke: red !important;
stroke-width: 3px !important;
}
.diagram-container.flow-active svg g.highlighted rect,
.diagram-container.flow-active svg g.highlighted ellipse {
stroke: red !important;
stroke-width: 3px !important;
}
</style>
</head>
<body>
<div id="sidebar">
<h3>Flows</h3>
<div class="flow-btn" data-flow='["SUBMITTED", "link_SUBMITTED_PAID", "PAID", "link_PAID_FULFILLED", "FULFILLED"]'>Flow: Successful Payment</div>
<div class="flow-btn" data-flow='["SUBMITTED", "link_SUBMITTED_CANCELED", "CANCELED"]'>Flow: Cancel Before Pay</div>
</div>
<div id="diagram" class="diagram-container">
<!-- SVG will be injected here -->
</div>
<script>
// Load SVG
fetch('SimpleEnumStateMachineConfiguration.svg')
.then(r => r.text())
.then(svg => {
document.getElementById('diagram').innerHTML = svg;
setupInteractivity();
});
function setupInteractivity() {
const container = document.getElementById('diagram');
document.querySelectorAll('.flow-btn').forEach(btn => {
btn.addEventListener('mouseenter', (e) => {
container.classList.add('flow-active');
const flowIds = JSON.parse(e.target.getAttribute('data-flow'));
flowIds.forEach(id => {
// PlantUML sometimes prepends entity_
let el = document.getElementById(id) || document.getElementById('entity_' + id);
if(el) {
el.classList.add('highlighted');
} else {
// For links, fallback to data-attributes if id parsing fails
if (id.startsWith('link_')) {
const parts = id.split('_');
let link = document.querySelector(`g[data-entity-1="${parts[1]}"][data-entity-2="${parts[2]}"]`);
if (link) link.classList.add('highlighted');
}
}
});
});
btn.addEventListener('mouseleave', () => {
container.classList.remove('flow-active');
document.querySelectorAll('.highlighted').forEach(el => el.classList.remove('highlighted'));
});
});
}
</script>
</body>
</html>