ECU / top-level
@@ -396,7 +404,7 @@ function makePoly(pts, cssVar) {
return el;
}
-function makeBlock(svg, x, y, W, H, pal, label, sublabel, clickable) {
+function makeBlock(svg, x, y, W, H, pal, label, sublabel, clickable, bugCount = 0) {
const g = ns('g');
if (clickable) g.classList.add('zoomable');
@@ -424,6 +432,25 @@ function makeBlock(svg, x, y, W, H, pal, label, sublabel, clickable) {
g.appendChild(ts);
}
+ if (bugCount > 0) {
+ const bx = x + hw - 8, by = y + 8;
+ const circle = ns('circle');
+ circle.setAttribute('cx', bx); circle.setAttribute('cy', by);
+ circle.setAttribute('r', '9');
+ circle.setAttribute('fill', '#d32f2f');
+ circle.setAttribute('stroke', '#fff'); circle.setAttribute('stroke-width', '1.5');
+ g.appendChild(circle);
+ const bt = ns('text');
+ bt.setAttribute('x', bx); bt.setAttribute('y', by);
+ bt.setAttribute('text-anchor', 'middle');
+ bt.setAttribute('dominant-baseline', 'central');
+ bt.setAttribute('fill', '#fff');
+ bt.setAttribute('font-size', '8');
+ bt.setAttribute('font-weight', 'bold');
+ bt.textContent = bugCount > 99 ? '99+' : String(bugCount);
+ g.appendChild(bt);
+ }
+
svg.appendChild(g);
return {
g,
@@ -463,7 +490,7 @@ function makeLine(svg, x1, y1, x2, y2) {
svg.appendChild(p);
}
-let state = { parsed: null, viewStack: [] };
+let state = { parsed: null, viewStack: [], bugData: {}, currentNode: null };
function render() {
const src = document.getElementById('puml').value;
@@ -476,7 +503,30 @@ function render() {
drawLevel(parsed.root);
}
+function setBugData(data) {
+ state.bugData = data || {};
+ if (state.currentNode) drawLevel(state.currentNode);
+}
+window.setBugData = setBugData;
+
+function applyBugs() {
+ const raw = document.getElementById('bugJson').value.trim();
+ document.getElementById('err').textContent = '';
+ if (!raw) { setBugData({}); return; }
+ try {
+ setBugData(JSON.parse(raw));
+ } catch (e) {
+ document.getElementById('err').textContent = 'Bug JSON error: ' + e.message;
+ }
+}
+
+function clearBugs() {
+ document.getElementById('bugJson').value = '';
+ setBugData({});
+}
+
function drawLevel(node) {
+ state.currentNode = node;
const svg = document.getElementById('iso');
svg.innerHTML = '';
makeArrow(svg);
@@ -510,7 +560,8 @@ function drawLevel(node) {
const pal = guessColor(child);
const canZoom = child.children.length > 0;
const sub = canZoom ? 'click to expand →' : null;
- const blk = makeBlock(svg, x, y, W, H, pal, child.label, sub, canZoom);
+ const bugs = state.bugData[child.id] || 0;
+ const blk = makeBlock(svg, x, y, W, H, pal, child.label, sub, canZoom, bugs);
positions[child.id] = blk;
if (canZoom) {