← Commit history

Fix: milestone line tags never overlap. Row pitch used each cap's own height, so a wrapped two-line tag was ridden into by the shorter tag on the row below. Use a uniform row pitch set by the tallest tag, and re-run cap layout after web-fonts load. Bump 0.7.1.

Drew Owens ·3a1ec38bf0 · ·parent 62d4055
3 files changed +12−4
gantt.html+10−2
@@ -820,8 +820,13 @@ function layoutMsCaps(){     rows[0].push([tx-tw/2-GAP, tx+tw/2+GAP]);   }   const fits=(row,l,r)=>row.every(([a,b])=>r<a||l>b);+  // Uniform row pitch set by the tallest tag: a wrapped (two-line) tag on an upper+  // row can never be ridden into by a shorter tag on the row below.+  let rowH=14;+  caps.forEach(c=>{rowH=Math.max(rowH,c.cap.offsetHeight||14);});+  rowH+=3;   caps.forEach(c=>{-    const w=c.cap.offsetWidth||80, h=c.cap.offsetHeight||14;+    const w=c.cap.offsetWidth||80;     const l=c.x-w/2-GAP, r=c.x+w/2+GAP;     let n=0;     while(true){@@ -830,7 +835,7 @@ function layoutMsCaps(){       n++;     }     rows[n].push([l,r]);-    c.cap.style.top=(2+n*(h+3))+'px';+    c.cap.style.top=(2+n*rowH)+'px';   }); } @@ -862,6 +867,9 @@ function scheduleRelayout(){clearTimeout(rlTimer);rlTimer=setTimeout(()=>{ let lastRelayoutW=timelineEl.clientWidth; window.addEventListener('resize',scheduleRelayout); if(window.ResizeObserver)new ResizeObserver(scheduleRelayout).observe(timelineEl);+// Web-font load changes tag widths and heights after the first measure, so re-run the+// milestone cap collision layout once fonts settle, or tags can overlap on a cold load.+if(document.fonts&&document.fonts.ready)document.fonts.ready.then(()=>{if(prefs.msStyle==='line')layoutMsCaps();});  // ── Filter ── function applyFilter(){items.forEach(r=>{let vis=true;if(r.phase!==undefined&&!phaseVis[r.phase])vis=false;if(r.type==='milestone'&&!msVis)vis=false;r._lDiv.classList.toggle('dim',!vis);r._bDiv.classList.toggle('dim',!vis);});drawDeps();}
package.json+1−1
@@ -2,7 +2,7 @@   "slug": "adom-gantt",   "title": "Adom Gantt",   "type": "app",-  "version": "0.7.0",+  "version": "0.7.1",   "description": "Interactive Gantt chart viewer for project timelines. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. Every edit is recorded in an append-only changelog so an AI can read what a human changed and build on it. Imports JSON, CSV, MS Project XML and Jira CSV; exports JSON, CSV, SVG and a self-contained HTML snapshot.",   "main": "server.js",   "bin": {
page.json+1−1
@@ -2,7 +2,7 @@   "slug": "adom-gantt",   "title": "Adom Gantt",   "type": "app",-  "version": "0.7.0",+  "version": "0.7.1",   "description": "Interactive Gantt chart viewer for project timelines. Data-driven, dark by default with a print-friendly light mode, and fully editable in the browser: drag bars to move or resize, multi-select and batch-shift dates, manage dependency arrows inline, reorder rows, filter by phase, and undo. Every edit is recorded in an append-only changelog so an AI can read what a human changed and build on it. Imports JSON, CSV, MS Project XML and Jira CSV; exports JSON, CSV, SVG and a self-contained HTML snapshot.",   "main": "server.js",   "bin": {