Skip to content

Programmatic updates

Everything a user can do with the mouse, code can do with a method: updateTask moves, resizes or re-progresses a task, addLink and removeLink change the dependencies, and setTasks replaces the tasks. The first three return a promise of a result that says what happened, so a caller knows more than the events can tell it. Each button calls one method, and the block under the chart shows the call and its result.

Terminal window
pnpm add @ganttlane/dom # vanilla
pnpm add @ganttlane/react react react-dom # React
View on GitHub
data.ts
import type { Link, Task } from '@ganttlane/core';
// 2026-03-02 is a Monday. Discovery is finished and locked: `updateTask` leaves it alone, too.
export const tasks: Task[] = [
{
id: 'discovery',
name: 'Discovery',
start: '2026-03-02',
end: '2026-03-06',
progress: 100,
locked: true,
},
{ id: 'design', name: 'Design', start: '2026-03-09', end: '2026-03-13', progress: 60 },
{ id: 'build', name: 'Build', start: '2026-03-16', end: '2026-03-20', progress: 20 },
// No links yet: the buttons add and remove one.
{ id: 'docs', name: 'Docs', start: '2026-03-16', end: '2026-03-18' },
{ id: 'qa', name: 'QA', start: '2026-03-23', end: '2026-03-25' },
{ id: 'launch', name: 'Launch', type: 'milestone', start: '2026-03-26' },
];
export const links: Link[] = [
{ source: 'discovery', target: 'design' },
{ source: 'design', target: 'build' },
{ source: 'build', target: 'qa' },
{ source: 'qa', target: 'launch' },
];
/** The task that `setTasks` adds and removes in the example. */
export const review: Task = {
id: 'review',
name: 'Review',
start: '2026-03-26',
end: '2026-03-27',
};

Files

  • data.ts: six tasks, four links, and the review task that setTasks adds.
  • options.ts: onBeforeTaskChange (the freeze), the view mode and the layout.
  • actions.ts: the calls, one for each button, and the text of their results.
  • styles.css: your own styles for the rows of buttons and the result.
  • vanilla.ts and react.tsx: the chart, the buttons and the events.

Options

Option Value What it does
onBeforeTaskChange a function The freeze: cancels a change that makes a task end after 3 April, a drag or a call
onTasksChange a function (in the example) One ChangeSet for each committed call (reason: 'api')
onLinkCreate a function (in the example) addLink created a link
onLinkDelete a function (in the example) removeLink deleted a link
onIssues a function (in the example) A rejected value is reported here too (source: 'change-set')
viewMode 'week' The scale of the timeline (React: defaultViewMode)
scroll.initial 'first-task' Opens on the plan
layout.rowHeight, .barHeight 36, 24 Smaller rows, so that every task is in view

Methods

Method Resolves to
updateTask(id, { start, end, progress }) committed (with the changeSet), unchanged, cancelled, busy or rejected (unknown-task, invalid-value)
addLink(link) created, cancelled, busy or rejected (invalid, unknown-task, duplicate, cycle)
removeLink(id) deleted, cancelled, busy or rejected (unknown-link)
setTasks(tasks) nothing: it replaces the tasks and the chart finds the difference by id

What to try

  • Move Build. start alone moves the task and keeps its length, and QA and Launch follow along their links: one onTasksChange, with every task it moved. Press it again: the answer is unchanged, since Build is already there.
  • Resize changes the end edge (end alone), Reschedule sets both ends, Build to 75% the progress.
  • Locked task. Discovery is locked, so updateTask answers unchanged and the issue locked-task.
  • End before start and Unknown task are rejected: the first with the issue and its path, the second because a task that is not there has no bar to change.
  • Past the freeze. The before-hook cancels the change, and the call resolves cancelled with the reason hook. A drag that ends after 3 April is cancelled by the same hook.
  • Links. addLink Docs → QA is created; press it again and it is rejected as a duplicate. QA → Design would close a cycle. removeLink is deleted, and the second time rejected as unknown-link.
  • setTasks. Add Review and remove it again: the chart gets a new row and loses it.

Notes

  • The same rules as the mouse. A call propagates through links and children like the same drag and goes through onBeforeTaskChange, which sees reason: 'api'. It does not snap to the view mode’s step and does not roll a bar onto a working day: the dates are exact. The editing flags and linkable do not apply to code (see Read-only), but a locked task does stay put.
  • A value that does not fit. A date off the scheduling.granularity is aligned (and reported as misaligned, or the call is rejected with alignInput: 'reject'). A date-only end is read the way the data is: the last day.
  • busy. While a before-hook waits for an answer, updateTask, addLink and removeLink resolve busy and change nothing: see Before-hooks.
  • setTasks starts from the chart’s own tasks (gantt.core.getSnapshot().state.tasks), which hold what the user dragged. Passing your first array again would put those tasks back. In the uncontrolled mode used here, replacing the tasks also clears the undo history.
  • React. The buttons call the methods of the handle (ref.current?.updateTask(…)). tasks and links are controlled props in React; the example passes defaultTasks and defaultLinks, so the chart owns its data and these calls change it. If your own state owns the tasks, change that state instead and let the new array reach the chart: see Controlled data.