Skip to content

Commit f78de13

Browse files
committed
Visual working
1 parent dba7384 commit f78de13

6 files changed

Lines changed: 27 additions & 231 deletions

File tree

modules/visualization/lattice_interactions.js

Lines changed: 24 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -35,101 +35,54 @@ function highlightPaths(targetId) {
3535
const traceUp = (id) => { allEdges.forEach(e => { if (e.target === id && !upE.has(e.id)) { upE.add(e.id); upN.add(e.source); traceUp(e.source); } }); };
3636
const traceDown = (id) => { allEdges.forEach(e => { if (e.source === id && !downE.has(e.id)) { downE.add(e.id); downN.add(e.target); traceDown(e.target); } }); };
3737
traceUp(targetId); traceDown(targetId);
38-
nodes.forEach(n => {
39-
n.el.classList.remove('dimmed', 'highlighted');
40-
if (n.id === targetId || upN.has(n.id) || downN.has(n.id)) n.el.classList.add('highlighted');
41-
else n.el.classList.add('dimmed');
38+
39+
const visibleNodes = document.querySelectorAll('.node');
40+
visibleNodes.forEach(el => {
41+
const idAttr = el.getAttribute('id');
42+
const nodeId = idAttr.replace('node-', '');
43+
44+
el.classList.remove('dimmed', 'highlighted');
45+
if (nodeId === targetId || nodeId.includes(targetId) || upN.has(nodeId) || downN.has(nodeId)) {
46+
el.classList.add('highlighted');
47+
} else {
48+
el.classList.add('dimmed');
49+
}
4250
});
43-
edges.forEach(e => {
44-
e.el.classList.remove('dimmed', 'highlighted-up', 'highlighted-down');
45-
if (upE.has(e.id)) e.el.classList.add('highlighted-up');
46-
else if (downE.has(e.id)) e.el.classList.add('highlighted-down');
47-
else e.el.classList.add('dimmed');
51+
52+
const visibleEdges = document.querySelectorAll('.edge');
53+
visibleEdges.forEach(el => {
54+
const edgeId = el.getAttribute('id');
55+
el.classList.remove('dimmed', 'highlighted-up', 'highlighted-down');
56+
if (upE.has(edgeId) || upE.some(ue => edgeId.includes(ue))) el.classList.add('highlighted-up');
57+
else if (downE.has(edgeId) || downE.some(de => edgeId.includes(de))) el.classList.add('highlighted-down');
58+
else el.classList.add('dimmed');
4859
});
4960
}
5061

5162
function setupInteractions() {
52-
document.getElementById('toggle-progression').addEventListener('click', (e) => {
53-
showProgressionOnly = !showProgressionOnly;
54-
e.target.classList.toggle('on', showProgressionOnly);
55-
filterEdges(); renderLattice();
56-
});
57-
58-
document.getElementById('toggle-hubs').addEventListener('click', (e) => {
59-
showHubs = !showHubs;
60-
e.target.classList.toggle('on', showHubs);
61-
filterEdges(); renderLattice();
62-
});
63-
64-
document.getElementById('toggle-sim').addEventListener('click', (e) => {
65-
showSimOverlay = !showSimOverlay;
66-
e.target.classList.toggle('on', showSimOverlay);
67-
renderLattice();
68-
});
69-
70-
document.getElementById('btn-lattice').addEventListener('click', () => {
71-
currentView = 'lattice';
72-
document.getElementById('btn-lattice').classList.add('active');
73-
document.getElementById('btn-hierarchy').classList.remove('active');
74-
document.getElementById('graph-svg').style.display = 'block';
75-
document.getElementById('hierarchy-view').style.display = 'none';
76-
updateLayout();
77-
});
78-
79-
document.getElementById('btn-quest-flow').addEventListener('click', () => {
80-
currentView = 'quest-flow';
81-
document.getElementById('btn-lattice').classList.remove('active');
82-
document.getElementById('btn-quest-flow').classList.add('active');
83-
document.getElementById('btn-hierarchy').classList.remove('active');
84-
document.getElementById('graph-svg').style.display = 'block';
85-
document.getElementById('hierarchy-view').style.display = 'none';
86-
renderQuestFlow();
87-
});
88-
89-
document.getElementById('btn-hierarchy').addEventListener('click', () => {
90-
currentView = 'hierarchy';
91-
document.getElementById('btn-hierarchy').classList.add('active');
92-
document.getElementById('btn-lattice').classList.remove('active');
93-
document.getElementById('graph-svg').style.display = 'none';
94-
document.getElementById('hierarchy-view').style.display = 'flex';
95-
renderHierarchy();
96-
});
97-
98-
document.getElementById('btn-reset').addEventListener('click', () => {
99-
// Reload original coordinates from data
100-
processData();
101-
renderLattice();
102-
transform = { x: 50, y: 50, k: 0.6 }; updateTransform();
103-
});
104-
10563
let isDragging = false, startPos = { x: 0, y: 0 };
10664
svg.addEventListener('mousedown', e => {
107-
if (e.target === svg || e.target.closest('#clusters-layer') || e.target.closest('#tiers-layer')) {
65+
if (e.target === svg || e.target.closest('#tiers-layer')) {
10866
isDragging = true; startPos = { x: e.clientX - transform.x, y: e.clientY - transform.y };
10967
svg.style.cursor = 'grabbing';
11068
}
11169
});
11270

11371
window.addEventListener('mousemove', e => {
114-
if (draggedNode) {
115-
const r = svg.getBoundingClientRect();
116-
draggedNode.x = (e.clientX - r.left - transform.x) / transform.k;
117-
draggedNode.y = (e.clientY - r.top - transform.y) / transform.k;
118-
updateLayout();
119-
} else if (isDragging) {
72+
if (isDragging) {
12073
transform.x = e.clientX - startPos.x; transform.y = e.clientY - startPos.y;
12174
updateTransform();
12275
}
12376
if (tooltip.style.display === 'block') { tooltip.style.left = (e.pageX + 15) + 'px'; tooltip.style.top = (e.pageY + 15) + 'px'; }
12477
});
12578

126-
window.addEventListener('mouseup', () => { isDragging = false; draggedNode = null; svg.style.cursor = 'grab'; });
79+
window.addEventListener('mouseup', () => { isDragging = false; svg.style.cursor = 'grab'; });
12780

12881
svg.addEventListener('wheel', e => {
12982
e.preventDefault();
13083
const delta = e.deltaY > 0 ? 0.9 : 1.1;
13184
const bX = (e.clientX - transform.x) / transform.k, bY = (e.clientY - transform.y) / transform.k;
132-
transform.k = Math.max(0.1, Math.min(transform.k * delta, 3));
85+
transform.k = Math.max(0.05, Math.min(transform.k * delta, 5));
13386
transform.x = e.clientX - bX * transform.k; transform.y = e.clientY - bY * transform.k;
13487
updateTransform();
13588
}, { passive: false });

modules/visualization/lattice_main.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
function init() {
33
processData();
44
setupInteractions();
5-
renderTiers();
6-
renderLattice();
5+
renderQuestFlow();
76
updateStats();
87
updateTransform();
98
}

modules/visualization/lattice_rendering.js

Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,7 @@
1-
function renderTiers() {
2-
const layer = document.getElementById('tiers-layer');
3-
const maxTier = Math.max(...nodes.map(n => n.tier));
4-
for(let i=0; i<=maxTier; i++) {
5-
const x = i * TIER_WIDTH;
6-
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
7-
line.setAttribute('class', 'tier-line');
8-
line.setAttribute('x1', x); line.setAttribute('y1', -5000);
9-
line.setAttribute('x2', x); line.setAttribute('y2', 5000);
10-
layer.appendChild(line);
11-
12-
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
13-
text.setAttribute('class', 'tier-label');
14-
text.setAttribute('x', x); text.setAttribute('y', 20);
15-
text.textContent = `PROGRESSION TIER ${i}`;
16-
layer.appendChild(text);
17-
}
18-
}
19-
20-
function renderLattice() {
21-
const nodesLayer = document.getElementById('nodes-layer');
22-
const edgesLayer = document.getElementById('edges-layer');
23-
nodesLayer.innerHTML = ''; edgesLayer.innerHTML = '';
24-
25-
edges.forEach(edge => {
26-
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
27-
let cls = `edge ${edge.category}`;
28-
path.setAttribute('class', cls);
29-
path.setAttribute('id', edge.id);
30-
edgesLayer.appendChild(path);
31-
edge.el = path;
32-
});
33-
34-
nodes.forEach(node => {
35-
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
36-
let cls = 'node';
37-
if (!node.visible) cls += ' dimmed';
38-
if (node.is_milestone) cls += ' milestone';
39-
if (showSimOverlay) {
40-
if (node.simulation.sustainable) cls += ' sustainable';
41-
if (node.simulation.unsustainable) cls += ' unsustainable';
42-
}
43-
44-
g.setAttribute('class', cls);
45-
g.setAttribute('id', `node-${node.id}`);
46-
47-
let shape;
48-
const color = getCategoryColor(node.type);
49-
50-
if (node.type === 'Quest') {
51-
shape = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
52-
shape.setAttribute('points', '-16,-8 -16,8 0,16 16,8 16,-8 0,-16');
53-
} else if (node.type === 'Ability') {
54-
shape = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
55-
shape.setAttribute('points', '0,-16 16,0 0,16 -16,0');
56-
} else if (node.type === 'Item') {
57-
shape = document.createElementNS("http://www.w3.org/2000/svg", "circle");
58-
shape.setAttribute('r', '14');
59-
} else if (node.type === 'Cadence') {
60-
shape = document.createElementNS("http://www.w3.org/2000/svg", "rect");
61-
shape.setAttribute('x', '-14'); shape.setAttribute('y', '-14');
62-
shape.setAttribute('width', '28'); shape.setAttribute('height', '28');
63-
shape.setAttribute('rx', '4');
64-
} else {
65-
shape = document.createElementNS("http://www.w3.org/2000/svg", "rect");
66-
shape.setAttribute('x', '-12'); shape.setAttribute('y', '-12');
67-
shape.setAttribute('width', '24'); shape.setAttribute('height', '24');
68-
}
69-
70-
shape.setAttribute('fill', color);
71-
g.appendChild(shape);
72-
73-
const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
74-
text.setAttribute('class', 'label');
75-
text.setAttribute('y', '32'); text.setAttribute('text-anchor', 'middle');
76-
text.textContent = node.name;
77-
g.appendChild(text);
78-
79-
if (node.visible) {
80-
g.addEventListener('mouseenter', (e) => showTooltip(e, node));
81-
g.addEventListener('mouseleave', hideTooltip);
82-
g.addEventListener('click', () => selectNode(node));
83-
}
84-
85-
nodesLayer.appendChild(g);
86-
node.el = g;
87-
});
88-
89-
updateLayout();
90-
}
91-
92-
function renderClusterBoxes(clusters) {
93-
const layer = document.getElementById('clusters-layer');
94-
layer.innerHTML = '';
95-
for (const [id, c] of clusters.entries()) {
96-
if (id === 'cluster_none') continue;
97-
const clusterNodes = nodes.filter(n => n.cluster_id === id);
98-
if (clusterNodes.length < 2) continue;
99-
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
100-
clusterNodes.forEach(n => {
101-
minX = Math.min(minX, n.x); minY = Math.min(minY, n.y);
102-
maxX = Math.max(maxX, n.x); maxY = Math.max(maxY, n.y);
103-
});
104-
const padding = 50;
105-
const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
106-
rect.setAttribute('class', 'cluster-box');
107-
rect.setAttribute('x', minX - padding); rect.setAttribute('y', minY - padding);
108-
rect.setAttribute('width', maxX - minX + padding * 2);
109-
rect.setAttribute('height', maxY - minY + padding * 2);
110-
layer.appendChild(rect);
111-
const label = document.createElementNS("http://www.w3.org/2000/svg", "text");
112-
label.setAttribute('class', 'cluster-label');
113-
label.setAttribute('x', minX - padding + 10); label.setAttribute('y', minY - padding - 10);
114-
label.textContent = clusterNames[id] || id;
115-
layer.appendChild(label);
116-
}
117-
}
118-
1191
function renderQuestFlow() {
1202
const nodesLayer = document.getElementById('nodes-layer');
1213
const edgesLayer = document.getElementById('edges-layer');
1224
nodesLayer.innerHTML = ''; edgesLayer.innerHTML = '';
123-
document.getElementById('clusters-layer').innerHTML = '';
1245

1256
// 1. Filter to Quests
1267
const quests = nodesData.filter(n => n.type === 'Quest');

modules/visualization/lattice_simulation.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

modules/visualization/orchestrator.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ def run_visualization(no_serve=False):
1818
"lattice_state.js",
1919
"lattice_data.js",
2020
"lattice_rendering.js",
21-
"lattice_simulation.js",
2221
"lattice_interactions.js",
2322
"lattice_main.js"
2423
]

modules/visualization/template_engine.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,14 @@ def get_html_skeleton(nodes_json, clusters_json, css_content, js_content):
9797
<head>
9898
<meta charset="UTF-8">
9999
<meta name="viewport" content="width=device-width, initial-scale=1.0">
100-
<title>Mythril Visual Dashboard V2</title>
100+
<title>Mythril Quest Flow</title>
101101
<style>{css_content}</style>
102102
</head>
103103
<body>
104104
<div class="dashboard">
105105
<header>
106106
<div style="display: flex; align-items: center; gap: 20px;">
107-
<h2 style="margin:0; letter-spacing: -0.5px;">Mythril <span style="color:var(--accent-color)">Lattice</span></h2>
108-
<div class="controls">
109-
<button id="btn-lattice" class="active">Lattice View</button>
110-
<button id="btn-quest-flow">Quest Flow</button>
111-
<button id="btn-hierarchy">Hierarchy View</button>
112-
<button id="btn-reset">Reset Layout</button>
113-
<div style="width: 1px; background: var(--border-color); margin: 0 5px;"></div>
114-
<button id="toggle-progression" class="toggle-btn on">Progression Only</button>
115-
<button id="toggle-hubs" class="toggle-btn">Show Hubs</button>
116-
<button id="toggle-sim" class="toggle-btn">Sim Overlay</button>
117-
</div>
107+
<h2 style="margin:0; letter-spacing: -0.5px;">Mythril <span style="color:var(--accent-color)">Quest Flow</span></h2>
118108
</div>
119109
<div id="stats" style="font-size: 12px; color: #8b949e; font-family: monospace;"></div>
120110
</header>
@@ -128,12 +118,10 @@ def get_html_skeleton(nodes_json, clusters_json, css_content, js_content):
128118
</defs>
129119
<g id="viewport">
130120
<g id="tiers-layer"></g>
131-
<g id="clusters-layer"></g>
132121
<g id="edges-layer"></g>
133122
<g id="nodes-layer"></g>
134123
</g>
135124
</svg>
136-
<div id="hierarchy-view"></div>
137125
</div>
138126
<div id="sidebar" class="sidebar">
139127
<div style="display:flex; justify-content: space-between; align-items: flex-start;">

0 commit comments

Comments
 (0)