Methods

Static Methods

ApexGantt.setLicense (key)

Registers your license key. Set it once at application start; since 3.17.0 a later call also removes the watermark from charts already rendered, and calling it before the first new ApexGantt() avoids a one-frame watermark. From 3.20.0 the key's plan must be Premium or higher. See Setting the License.


ApexGantt.setLicense('YOUR-LICENSE-KEY');

Core Methods

render ()

Renders the chart and initializes all components.


apexGantt.render();

update (newOptions)

Merges new options into the current configuration and re-renders. Only the keys you pass change; pass a key as undefined to reset it to its default. Scroll position, collapsed rows and the current zoom are kept unless you pass pixelsPerDay.


apexGantt.update({
  series: [
    {
      id: 'task-1',
      name: 'Design Phase',
      startTime: '07-01-2025',
      endTime: '07-10-2025',
      progress: 40
    },
    // more tasks...
  ],
  pixelsPerDay: 25.7,
});

Task dates use the startTime / endTime keys and are parsed with inputDateFormat ('MM-DD-YYYY' by default).

Since 3.20.0 update() keeps the current task data: edits made by dragging, updateTask(), addTask(), deleteTask(), moveTask() and dependency changes survive any update() that does not pass series or parsing. Passing series replaces the data and clears the undo history. update() also rebuilds the working calendar when you pass calendar or inputDateFormat, and its type is update(options: Partial<GanttUserOptions>) (exported as GanttUpdateOptions), so series is no longer required. Before 3.20.0 every update() rebuilt the tasks from the original series, discarding those edits.

Since 3.20.0 a call that switches theme (light to dark or back) returns only the colour options the theme owns to the new theme's values, even ones you set yourself: annotationBgColor, annotationBorderColor, arrowColor, backgroundColor, barBackgroundColor, barTextColor, borderColor, cellBorderColor, criticalArrowColor, criticalBarColor, crosshairColor, fontColor, headerBackground, milestoneColor, rowBackgroundColors, summaryBarColor, tooltipBGColor and tooltipBorderColor. Pass a colour in the same call to keep it. Every other option (columns, toolbar items, hooks, locale, sortBy, barLabel, dependencies, calendar, ...) carries over. Before 3.20.0 a theme change rebuilt the options from the theme's defaults and kept only a fixed list of 18 keys, so columns, toolbar items, hooks and locale had to be passed again.


// keep the brand bar colour through a light/dark switch
apexGantt.update({ theme: 'dark', barBackgroundColor: brandColor });

Since 3.20.0 an update() that throws (for example a series with a task that has no dates and no children) leaves the previous data and options in place, so the chart keeps working. Before, the chart was left half-built.

Task Methods

updateTask (taskId, taskData, options?)

Applies a partial update to one task without a full re-render. Pass only the fields you want to change: taskData is a Partial<TaskInput> (since 3.20.0, so type: 'milestone' compiles), the same shape as a row in series. Runs through beforeTaskUpdate, is recorded in the undo history, and throws when taskId does not exist or the result fails validation (after firing taskUpdateError). Since 3.20.0 a throwing call leaves the previous data in place.


apexGantt.updateTask('task-1', {
  name: 'Design Phase',
  startTime: '07-01-2025',
  endTime: '07-10-2025',
  progress: 40
});

Since 3.20.0 updateTask emits taskUpdate and taskUpdateSuccess with source: 'api'. Pass { silent: true } to suppress both, for example when applying a server echo or rolling back a failed save. Before 3.20.0 updateTask emitted no events. Since 3.20.0 a change to a task whose row is not rendered (under a collapsed parent, filtered out, or outside the virtualized window) is stored like any other, and updateTask(id, { collapsed }) re-renders so the rows appear or disappear at once.


// apply a server echo without re-triggering your save handler (3.20.0+)
apexGantt.updateTask('task-1', { progress: 60 }, { silent: true });

Since 3.20.0 an edit keeps the task's place in the tree: getTask(id).level, the updatedTask.level in taskUpdateSuccess, the row indent and aria-level stay right after later renders. A segments list with exactly one entry is stored as a plain task (that segment sets startTime and endTime, and segments is not kept), so updateTask(id, { segments: [one] }) turns a split task back into a normal one.


getTask (taskId)

Since 3.20.0. Returns a copy of the stored task with its current values, edits included, or null for an unknown id. Its baseline, segments, assignees and object dependency are copied too, so changing the result never changes the chart (use updateTask() for that). Custom fields you added to a task are copied by reference.


const task = apexGantt.getTask('task-1');
if (task) console.log(task.startTime, task.endTime, task.progress);

getTasks ()

Since 3.20.0. Returns copies of every task (like getTask()), including collapsed and filtered-out ones, in tree order (a parent before its children).

The tasks do not carry every link. A task's dependency holds only the link it was loaded with (removing that link clears it), so a link added with addDependency() or drawn by the user is not in the returned tasks. To save the chart after the user edited it, save getDependencies() with the tasks.


const all = apexGantt.getTasks();

getDependencies ()

Since 3.20.0. Returns every dependency link as it is now, as DependencyLink copies ({ fromId, toId, type, lag }): the links the tasks were loaded with plus the ones added with addDependency() or drawn by the user, less any removed. Undo and redo are reflected.

Save it with getTasks() to keep the links. After loading the saved tasks, add each link that canAddDependency() accepts (the links the tasks carry are already there), then clear the undo history so the restore cannot be undone:


// save
await saveChart({ tasks: apexGantt.getTasks(), links: apexGantt.getDependencies() });

// load
const { tasks, links } = await loadChart();
const gantt = new ApexGantt(el, { series: tasks });
gantt.render();
for (const { fromId, toId, type, lag } of links) {
  if (gantt.canAddDependency(fromId, toId).ok) gantt.addDependency(fromId, toId, { type, lag });
}
gantt.clearHistory();

Each added link runs through beforeDependencyChange and emits dependencyAdded, like any other addDependency() call.


expandTask (taskId) / collapseTask (taskId)

Since 3.20.0. Opens or closes a parent row. This is view state only: it is not recorded in undo history, it is saved with the view state like setState({ collapsed }), and it renders once. Returns false for an unknown id or a task with no children, otherwise true.


apexGantt.expandTask('phase-1');
apexGantt.collapseTask('phase-2');

addTask (input, options?)

Inserts a new task and re-renders the chart. The operation is recorded in the undo history and emits a taskAdded event on success. If a beforeTaskAdd hook is configured and returns false, the insertion is cancelled and the method returns null. Throws when input.id is missing or already exists.

options.parentId inserts the task under the given parent; omit for a root-level task. Returns the inserted Task, or null when the hook cancels. A task added under a parent starts one level below it.

Since 3.20.0 beforeTaskAdd and taskAdded report the parent the task lands under: options.parentId, else input.parentId, and undefined for an id that matches no task (the task is then added at the root). Before, input.parentId was ignored by both, so a hook that checked the parent was bypassed and taskAdded reported a root task. A throwing addTask() leaves the previous data in place.


apexGantt.addTask({
  id: 'task-9',
  name: 'Review',
  startTime: '2026-08-01',
  endTime: '2026-08-05',
});

apexGantt.addTask(
  { id: 'subA', name: 'Subtask', startTime: '2026-08-01', endTime: '2026-08-03' },
  { parentId: 'task-9' }
);

deleteTask (taskId, options?)

Removes a task and re-renders. Recorded in the undo history. Dependency edges that reference removed tasks are auto-cleaned in the same transaction, so undo restores tasks and edges atomically.

Cascade modes via options.cascade:

  • forbid (default): throws when the task has children. Safe default that prevents accidental subtree loss.
  • children: deletes the task plus every descendant in a single undoable transaction.
  • orphan: reparents the immediate children to the deleted task's parent, then removes just the task itself.

If beforeTaskDelete returns false, the removal is cancelled and the method returns false. Returns true when the task was removed.


apexGantt.deleteTask('task-3');                          // leaf, uses default 'forbid'
apexGantt.deleteTask('task-1', { cascade: 'children' }); // summary + descendants
apexGantt.deleteTask('task-1', { cascade: 'orphan' });   // keep children, remove summary

moveTask (taskId, options?)

Re-parents a task and re-renders. Recorded in the undo history. Emits a taskMoved event. Pass newParentId: null (or omit) to promote the task to the root level.

Throws when taskId doesn't exist, when newParentId doesn't exist, when moving onto itself, or when the move would create a cycle. Returns true on success, false if beforeTaskMove cancelled. The moved subtree takes its new depth (indent, level and aria-level).


apexGantt.moveTask('subA', { newParentId: 'task-2' });
apexGantt.moveTask('subA', { newParentId: null });   // promote to root

Dependency Methods

addDependency (fromId, toId, options?)

Creates a dependency edge between two tasks and re-renders the arrow. Recorded in undo history. Emits dependencyAdded. Runs through beforeDependencyChange. The link is drawn and analysed but never moves either task.

options accepts { type?: 'FS' | 'FF' | 'SS' | 'SF', lag?: number }. Defaults to type: 'FS', lag: 0. Throws when the edge breaks one of the rules canAddDependency() checks: a link from a task to itself, a task that doesn't exist, an edge that already exists, an edge that would close a cycle, or (unless dependencies.allowSummaryDescendantLinks is true) a link between a task and its own ancestor or descendant. A beforeDependencyChange veto returns false instead of throwing.

Since 3.20.0 the self-link, cycle and ancestor/descendant cases throw. Before 3.20.0 only a missing task or a duplicate threw, so the others were added. Call canAddDependency() first when the ids come from user input.


apexGantt.addDependency('t1', 't2');                          // FS, lag 0
apexGantt.addDependency('t1', 't2', { type: 'SS', lag: 2 });

removeDependency (fromId, toId)

Removes a dependency edge and re-renders. Recorded in undo history. Emits dependencyRemoved with the captured type and lag. Runs through beforeDependencyChange. Throws when no edge exists between the two tasks.


apexGantt.removeDependency('t1', 't2');

canAddDependency (fromId, toId, options?)

Returns whether a new edge fromId → toId would be accepted right now, without committing it. Shared by the programmatic API and the interactive draw UI so both apply the same rules.

Returns { ok: true } when the edge would be accepted, or { ok: false, reason } where reason is one of 'self', 'task-missing', 'duplicate', 'cycle', 'summary-descendant', or 'hook-veto'.


const verdict = apexGantt.canAddDependency('t1', 't2');
if (verdict.ok) apexGantt.addDependency('t1', 't2');
else console.warn(verdict.reason);

History Methods

undo ()

Rolls back the most recent recorded transaction; data and DOM return to the pre-operation state. Emits historyChange with kind: 'undo'. Returns true if a transaction was undone, false when the undo stack is empty or history.enabled is false.


apexGantt.updateTask('t1', { progress: 90 });
apexGantt.undo();

redo ()

Replays the most recently undone transaction. Emits historyChange with kind: 'redo'. Any new mutating call between undo() and redo() discards the redo stack. Returns true if a transaction was redone.


apexGantt.redo();

canUndo () / canRedo ()

Returns whether an undoable or redoable transaction is currently on top of the stack. Use to gate custom Undo/Redo UI affordances.


myUndoButton.disabled = !apexGantt.canUndo();
myRedoButton.disabled = !apexGantt.canRedo();

clearHistory ()

Drops every recorded transaction and emits historyChange with kind: 'clear'. Useful after loading a fresh dataset where rolling back to a previous tree state would be incoherent. Since 3.20.0 update({ series }) clears the history itself, so the call below is only needed on earlier versions.


apexGantt.update({ series: freshTasks });
apexGantt.clearHistory();

getHistorySize ()

Returns the current undo/redo stack sizes as { undo: number, redo: number }.


const { undo, redo } = apexGantt.getHistorySize();

Selection Methods

getSelectedTasks ()

Returns the selected tasks as Task[] (full task objects, not ids). Requires enableSelection: true; without it the selection methods do nothing (since 3.20.0 they log a one-time console warning).


const selected = apexGantt.getSelectedTasks();

setSelectedTasks (ids)

Programmatically set the selection to the given task IDs. Requires enableSelection: true.


apexGantt.setSelectedTasks(['task-1', 'task-3']);

clearSelection ()

Clear all selected tasks. Requires enableSelection: true.


apexGantt.clearSelection();

Sorting Methods

sort (criteria)

Applies a sort to the task list and re-renders. Pass one SortCriterion or an array; an empty array clears the sort (natural input order). Sorting is hierarchy-preserving: siblings reorder within each parent and a child never leaves its parent. Emits sortChange.


apexGantt.sort({ key: ColumnKey.Progress, direction: 'desc' });
apexGantt.sort([{ key: ColumnKey.Progress, direction: 'desc' }, { key: ColumnKey.Name }]);

toggleSort (key, opts?)

Cycles a column's sort through ascending, descending, and none. Backs the header-click UX. No-op when the column is not sortable. With { append: true } (Shift+click) the column is added as an additional sort key instead of replacing the sort. Emits sortChange.


apexGantt.toggleSort(ColumnKey.Name);
apexGantt.toggleSort(ColumnKey.StartTime, { append: true });

getSort ()

Returns the active sort criteria as a SortCriterion[] (empty array when in natural order).


const criteria = apexGantt.getSort();

clearSort ()

Clears the active sort and returns to natural (input) order. Emits sortChange.


apexGantt.clearSort();

Filtering Methods

filter (predicate)

Applies a view-only filter. A task is kept when it matches the predicate or has a matching descendant, so ancestors of matches stay visible. Changes which rows render, never the tree, WBS, or task data. Emits filterChange.


apexGantt.filter((task) => task.progress < 100);

setFilterRules (ruleSet)

Applies a structured filter: a FilterRuleSet of conditions combined with 'all' (AND) or 'any' (OR), compiled to the same view-only filter as filter(). Pass null (or an empty rule list) to clear. Emits filterChange.


apexGantt.setFilterRules({
  match: 'all',
  rules: [{ field: ColumnKey.Progress, operator: 'lt', value: 100 }],
});

getFilterRules ()

Returns the active structured filter rules, or null when none are set.


const rules = apexGantt.getFilterRules();

clearFilter ()

Clears the active filter so every row is shown again. Emits filterChange.


apexGantt.clearFilter();

isFiltered ()

Returns whether a filter is currently active.


if (apexGantt.isFiltered()) { /* ... */ }

Grouping Methods

groupBy (criterion)

Groups the task list by a column key or a GroupCriterion. While grouping is active the parent/child tree is suspended and tasks appear flat under collapsible group headers. View-only: it never mutates the task tree or data. Emits groupChange.


apexGantt.groupBy(ColumnKey.Progress);
apexGantt.groupBy({ field: 'status', label: (v) => `Status: ${v}`, direction: 'desc' });

clearGrouping ()

Clears grouping and restores the exact prior hierarchy. Emits groupChange.


apexGantt.clearGrouping();

getGroupBy ()

Returns the active grouping criterion as a GroupCriterion, or null when not grouping.


const criterion = apexGantt.getGroupBy();

isGrouping ()

Returns whether grouping is currently active.


if (apexGantt.isGrouping()) { /* ... */ }

Column Methods

setColumnWidth (key, px)

Pins a task-list column to an exact pixel width; the other columns absorb the remaining panel space. Mirrors dragging the column-header resize handle. Emits columnResize.


apexGantt.setColumnWidth(ColumnKey.Name, 260);

resetColumnWidths (key?)

Clears the manual width of one column (pass its key) or of every column (omit the argument), returning them to their auto/flex width. Emits columnResize.


apexGantt.resetColumnWidths(ColumnKey.Name);   // one column
apexGantt.resetColumnWidths();                 // all columns

getColumnWidths ()

Returns the active manual column-width overrides as a plain object (key → pixels).


const widths = apexGantt.getColumnWidths();

setColumnOrder (keys)

Sets the left-to-right order of the task-list columns by key. Listed keys are placed first in that order; any visible columns you omit keep their relative position at the end. Emits columnReorder.


apexGantt.setColumnOrder([ColumnKey.Name, ColumnKey.Progress, ColumnKey.StartTime]);

getColumnOrder ()

Returns the current column order as an array of keys (left-to-right), reflecting any reorder.


const order = apexGantt.getColumnOrder();

Split Task Methods

splitTask (taskId, at, options?)

Splits a task into separate worked segments at at, producing a gap on the timeline. The segment containing at is cut so its first piece ends at at and the rest resumes at options.resumeAt (default: the next day, which leaves no visible gap when dates are whole days). The task keeps its finish date: the gap removes worked time rather than pushing the end out. To show a slip, pass new segments through updateTask(). Routed through updateTask, so it is validated by beforeTaskUpdate and undoable (and since 3.20.0 emits taskUpdate). No-op on milestones, summary bars, or when at does not fall strictly inside a worked span.

Since 3.20.0 resumeAt must fall after at and no later than that segment's last day; anything else is rejected with a console warning and the task is left unchanged. With a day-only format the end day is worked, so resumeAt may be that last day (a one-day remainder); with a format that carries time the end is exclusive and resumeAt must be before it. Before 3.20.0 a resumeAt that was not after at, or past the segment end, produced overlapping or backwards segments.


// t3 runs 06-01-2026 to 06-20-2026: work stops after the 10th and resumes on the 14th
apexGantt.splitTask('t3', '06-10-2026', { resumeAt: '06-14-2026' });

isSplit (taskId)

Returns whether a task is currently split into multiple worked segments.


if (apexGantt.isSplit('t3')) { /* ... */ }

State Methods

getState ()

Captures the current UI view state (zoom, scroll, collapse, selection, sort, filter, grouping, manual column widths, and column order) as a JSON-serializable GanttUiState. Pair with setState() to save and restore where the user left off.


const saved = apexGantt.getState();

setState (state, opts?)

Restores a UI view state produced by getState(). Any omitted field is left untouched, so a partial state (for example { sort: [...] }) applies just that slice. Re-renders once, then emits sortChange / filterChange for the parts that changed. Pass { silent: true } to suppress those events.


apexGantt.setState(saved);
apexGantt.setState({ sort: [{ key: ColumnKey.Name, direction: 'asc' }] });
apexGantt.setState({ collapsed: ['phase-1'] }, { silent: true });

scrollToTask (taskId, options?)

Scrolls the timeline (and, if needed, the row list) so a task's bar is in view, using nearest-edge alignment. Works even when the target row is virtualized out of the DOM.

Since 3.20.0 options.expand (default true) first opens any collapsed ancestors (and a collapsed group) so the row can be shown. It returns false for an unknown id, a task hidden by the active filter, or expand: false with a collapsed ancestor. Before 3.20.0 there was no options argument: it returned true only when a scroll was applied, and false for an unknown task, one already in view, or one under a collapsed parent. It also works in right-to-left charts since 3.20.0.


apexGantt.scrollToTask('task-42');
apexGantt.scrollToTask('task-42', { expand: false }); // leave collapsed parents closed

Export Methods

exportChart (format?)

Exports the chart as SVG, PNG, or PDF and resolves when the download starts. format defaults to the exportFormat option ('svg'). Under row virtualization the full dataset is captured, not just the visible rows.


await apexGantt.exportChart('png');
await apexGantt.exportChart('pdf');

Lifecycle Methods

destroy ()

Destroys the chart instance and frees all associated resources: removes event listeners, disconnects ResizeObservers, clears the tooltip, removes the DOM the chart added, and nulls internal references. From 3.19 destroy() and re-renders remove only what the chart added, so other content you put in the container stays. After calling destroy(), the instance cannot be reused. Create a new ApexGantt instead. Call before removing the host element from the DOM or in framework cleanup hooks (ngOnDestroy, React useEffect cleanup, Vue onBeforeUnmount).


apexGantt.destroy();

isDestroyed ()

Returns true if the chart has been destroyed or the host element is empty. Use as a guard before calling other methods when unsure whether destroy() has already been called.


if (!apexGantt.isDestroyed()) {
  apexGantt.update({ series: nextTasks });
}

Zoom Methods

zoomIn()

Multiplies the zoom (pixelsPerDay) by 1.4, up to the maximum of about 7680. It is a continuous step, not a jump between named presets; the header tier (year → quarter → month → week → day → halfday → hour → minute) is auto-picked from the new density.


apexGantt.zoomIn();

zoomOut()

Divides the zoom (pixelsPerDay) by 1.4, down to the minimum of about 0.25. The header tier (minute → hour → halfday → day → week → month → quarter → year) is auto-picked from the new density.


apexGantt.zoomOut();