feat: track bugs per component

This commit is contained in:
Luís Murta 2026-03-14 10:24:30 +00:00
parent 8d3b5cccf9
commit 1ff6a55078
Signed by: satprog
GPG Key ID: 169EF1BBD7049F94

View File

@ -285,6 +285,14 @@ C --> ConC
</div> </div>
<div id="err"></div> <div id="err"></div>
<div class="panel-label" style="margin-top:16px">Bug counts (JSON — alias: count)</div>
<textarea id="bugJson" spellcheck="false" rows="3"
placeholder='{"ConA":3,"AdpA":1,"L":7}'></textarea>
<div class="btn-row">
<button class="primary" onclick="applyBugs()">Apply bugs</button>
<button onclick="clearBugs()">Clear</button>
</div>
<div class="legend"> <div class="legend">
<div class="legend-item"> <div class="legend-item">
<div class="legend-swatch" style="background:var(--top-gray)"></div> ECU / top-level <div class="legend-swatch" style="background:var(--top-gray)"></div> ECU / top-level
@ -396,7 +404,7 @@ function makePoly(pts, cssVar) {
return el; 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'); const g = ns('g');
if (clickable) g.classList.add('zoomable'); if (clickable) g.classList.add('zoomable');
@ -424,6 +432,25 @@ function makeBlock(svg, x, y, W, H, pal, label, sublabel, clickable) {
g.appendChild(ts); 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); svg.appendChild(g);
return { return {
g, g,
@ -463,7 +490,7 @@ function makeLine(svg, x1, y1, x2, y2) {
svg.appendChild(p); svg.appendChild(p);
} }
let state = { parsed: null, viewStack: [] }; let state = { parsed: null, viewStack: [], bugData: {}, currentNode: null };
function render() { function render() {
const src = document.getElementById('puml').value; const src = document.getElementById('puml').value;
@ -476,7 +503,30 @@ function render() {
drawLevel(parsed.root); 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) { function drawLevel(node) {
state.currentNode = node;
const svg = document.getElementById('iso'); const svg = document.getElementById('iso');
svg.innerHTML = ''; svg.innerHTML = '';
makeArrow(svg); makeArrow(svg);
@ -510,7 +560,8 @@ function drawLevel(node) {
const pal = guessColor(child); const pal = guessColor(child);
const canZoom = child.children.length > 0; const canZoom = child.children.length > 0;
const sub = canZoom ? 'click to expand →' : null; 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; positions[child.id] = blk;
if (canZoom) { if (canZoom) {