|
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 | | - |
119 | 1 | function renderQuestFlow() { |
120 | 2 | const nodesLayer = document.getElementById('nodes-layer'); |
121 | 3 | const edgesLayer = document.getElementById('edges-layer'); |
122 | 4 | nodesLayer.innerHTML = ''; edgesLayer.innerHTML = ''; |
123 | | - document.getElementById('clusters-layer').innerHTML = ''; |
124 | 5 |
|
125 | 6 | // 1. Filter to Quests |
126 | 7 | const quests = nodesData.filter(n => n.type === 'Quest'); |
|
0 commit comments