app
Adom Gantt
Public Made by Adomby adom
Interactive Gantt chart viewer for project timelines, with a table view and an analytics page over the same data. 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. One click auto-schedules the whole plan so every dependency lines up finish-to-start on working days, skipping weekends and US federal holidays, push
← Commit history
0.42.0: keep the Files tab byte-identical to the published 0.42.0 package
3 files changed
+3−3
README.md+1−1@@ -8,7 +8,7 @@ Interactive Gantt chart viewer for project timelines. Data-driven, dark by defau **Critical path.** **Critical** lights up the chain of work with no slack in it, the one that decides the finish date: the bars, the dependency arrows along it and any milestone on it glow white and breathe, in a saturated indigo on paper. Classic CPM over business days, on the dates the plan has right now, so it is independent of Auto-schedule and answers the question about the plan as it stands. Everything else stays exactly as it was, selection and dependency mode included, and the glow recomputes as you edit. -**Analytics.** A third lens, next to Gantt and Table. Total effort for the plan in hours (business days times eight, a forty-hour week), hours per person with shares and the unassigned bucket, status counts overall and per person, per-section totals with the range each section spans, milestones with days from today, dependency stats with a cycle warning, and everything overdue. Read-only, whole-plan, and re-derived from the same rows every time you switch to it.+**Analytics.** A third lens, next to Gantt and Table. Total effort for the plan in hours (business days times eight, a forty-hour week), hours per person with shares and the unassigned bucket, status counts overall and per person, per-section totals with the range each section actually covers, milestones with days from today, dependency stats with a cycle warning, and everything overdue. Read-only, whole-plan, and re-derived from the same rows every time you switch to it. **Three lenses over one plan.** A **Gantt / Table / Analytics** toggle in the header. The chart answers "when". The table answers "whose, and by when": every task and every milestone as a row with Owner, Start, Deadline, Status and Notes, sortable on any column, filtered to one person with the owner dropdown, and editable in place. An edit made in the table is already true on the chart when you toggle back, because there is only one set of items underneath. The choice of lens persists, and `project.view.mode` can pin it for a plan that is an assignment list more than a timeline.
SKILL.md+1−1@@ -327,7 +327,7 @@ Eight cards: | Hours per person | Every owner, unassigned included, with hours, share of the total and item counts, sorted by hours | | Status | The four status counts over every task and milestone, with shares | | Status per person | The same four counts, one row per owner |-| Per section | Items, hours and the date range each section spans, derived from its rows rather than declared |+| Per section | Items, hours and the date range each section actually covers, derived from its rows | | Milestones | Every dated milestone with its date, days from today and owner | | Dependencies | Link count, rows in the graph, rows outside it, and a cycle warning naming the rows | | Overdue | Every row with a deadline in the past and a status that is not complete |
gantt.html+1−1@@ -7692,7 +7692,7 @@ function renderAnalytics(){ const lr=m.lanes.map(l=>'<tr><td class="name"><span class="an-chip" style="background:'+esc(l.color)+'"></span>'+esc(l.name)+'</td>' +'<td class="n">'+l.items+'</td><td class="n">'+esc(hrs(l.hours))+'</td>' +'<td class="n muted">'+(l.from?esc(fmt(l.from))+' to '+esc(fmt(l.to)):'no dates')+'</td></tr>').join('');- out.push(card('wide','Per section','Items, effort and the date range the section spans, derived from its rows rather than declared.',+ out.push(card('wide','Per section','Items, effort and the range the section actually covers, which is derived from its rows and not declared.', m.lanes.length?('<table class="an-table"><thead><tr><th>Section</th><th class="n">Items</th><th class="n">Hours</th><th class="n">Range</th></tr></thead><tbody>' +lr+'<tr class="total"><td>Total</td><td class="n">'+m.rows.length+'</td><td class="n">'+esc(hrs(m.totalHours))+'</td>' +'<td class="n">'+(m.first?esc(fmt(m.first))+' to '+esc(fmt(m.last)):'')+'</td></tr></tbody></table>'):'<div class="an-empty">This plan has no sections.</div>'));