Recipe: a Gantt-style plan
Tasks in work streams, a milestone, a kickoff the plan cannot start before, and undo. Drag a task to move it — also into another stream — drag its end to resize it, or use the keys (Alt + arrows).
Live example: Gantt-style project plan
Loading…
Run “Gantt-style project plan” on your own machine
Make an empty folder and put this example’s two files in it:
index.html— the page the code runs in, its markup and styles:<style> /* An item's class sets the token its fill reads: no specificity fight. */ #timeline .phase-design { --tl-item-fill: #d6e4ff; } #timeline .phase-build { --tl-item-fill: #d8f3dc; } #timeline .phase-ship { --tl-item-fill: #ffe2c6; } .toolbar { display: flex; gap: 8px; align-items: center; padding: 6px 10px; border-bottom: 1px solid #d5d9de; } </style> <div class="toolbar"> <button id="undo" type="button" disabled>Undo</button> <button id="redo" type="button" disabled>Redo</button> <span id="status" aria-live="polite">Drag a task to move it, drag its end to resize it.</span> </div> <div id="timeline" style="height: 380px"></div>main.js— the code, as it is in the editor now, your edits included:In a terminal in that folder, install the library and Vite (it lets the browser follow the
imports), then start it:npm init -y npm install @temporeum/timeline-element npm install --save-dev vite npx viteOpen the address it prints,
http://localhost:5173/.
How it is made
- Streams are lanes, tasks are items with a
laneId, and the milestone is an item without anend: an instant, which covers its day (granularity: "day"). - Colour per stream is a class on the item that sets the fill token:
className: "phase-design"and#timeline .phase-design { --tl-item-fill: #d6e4ff; }. See theming. - The kickoff is a rule, not a check afterwards.
canMoveis asked before every step of a move or a resize, by pointer and by key, and afalseholds the item where it was. - Undo is the command's inverse. The timeline emits one
commandper edit; the page keeps two stacks. - Decorations draw what is not an item:
bandingstripes the weeks, amarkercalls out the kickoff on the axis, anerashades the code freeze behind the tasks.
decorations: [
{ kind: "banding" },
{ kind: "marker", id: "kickoff", time: KICKOFF, label: "Kickoff" },
{ kind: "era", id: "freeze", start: at(31), end: at(35), label: "Code freeze" },
],From the running example example/recipe-gantt
Arrows, progress and a task table
This recipe draws the plan with decorations and rules. Dependency arrows, progress, baselines, milestone diamonds and a task table beside the chart are built in: see Gantt charts. The scheduler puts tasks back in order and finds the critical path when you call it; nothing reschedules on its own — canMove can refuse a move that would break an order, and a command handler can call the scheduler.