diff --git a/plantuml-3d-renderer.html b/plantuml-3d-renderer.html index 878bd3d..9cae5ce 100644 --- a/plantuml-3d-renderer.html +++ b/plantuml-3d-renderer.html @@ -285,6 +285,14 @@ C --> ConC
+
Bug counts (JSON — alias: count)
+ +
+ + +
+
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) {