跳到主要内容

Data Model

Gantt works with two main representations of task and link data:

  • Serialized: JSON-compatible shapes with string dates, used in server responses, persisted JSON, and DataProcessor exchange
  • Runtime: client-side objects with Date fields and computed $-prefixed properties, returned by methods like gantt.getTask() and gantt.getLink()

When you provide data to Gantt (rather than read it back), date fields may be either a Date or a string. The TaskInput type captures this lenient input shape, so you don't have to commit to Task or SerializedTask for data you author or hold in application state.

The canonical top-level payload passed to gantt.parse() is GanttData.

Core runtime and serialized types are exported from @dhx/gantt. Wrapper packages re-export and consume these types in their public APIs, but the exact prop surface differs by wrapper.

Data Lifecycle

Data flows through two transformations:

  1. Loading: serialized task and link data is passed to gantt.parse() or gantt.load(). Gantt parses date strings into Date objects and adds computed $-prefixed properties, producing runtime Task and Link objects.
  2. Saving: when changes are sent to the server via DataProcessor, dates are serialized back to strings and temporary $-prefixed fields are stripped.

See Data Loading and Server-Side Integration for behavior details.

SerializedTask

The JSON-compatible task shape. Date fields are strings, so this object can be safely passed through JSON.stringify() / JSON.parse().

interface SerializedTask {
id?: string | number;
start_date?: string;
end_date?: string;
duration?: number;
text?: any;
type?: string;
parent?: string | number;
progress?: number;
open?: boolean;

auto_scheduling?: boolean;
unscheduled?: boolean;
constraint_date?: string;
constraint_type?: string;
deadline?: string;

color?: string;
textColor?: string;
progressColor?: string;
bar_height?: number;
row_height?: number;
hide_bar?: boolean;

baselines?: SerializedBaseline[];
calendar_id?: string | number;
editable?: boolean;
readonly?: boolean;
render?: string;
resource?: string[];
rollup?: boolean;
target?: string;

[customProperty: string]: any;
}

For a meaningful scheduled task in serialized JSON, provide one valid scheduling combination:

  • start_date + duration
  • start_date + end_date
  • duration + end_date

If unscheduled: true, dates can be omitted.

For detailed property descriptions, see Task Properties.

interface SerializedLink {
id: string | number;
source: string | number;
target: string | number;
type: string;
lag?: number;
readonly?: boolean;
editable?: boolean;

[customProperty: string]: any;
}

For detailed property descriptions, see Link Properties.

After loading, Gantt stores tasks as runtime Task objects.

Main differences from SerializedTask:

  • task date fields such as start_date, end_date, constraint_date, and deadline are JavaScript Date objects
  • computed $-prefixed fields are added and maintained on the client

Common runtime-only task fields:

PropertyTypeDescription
$indexnumberGlobal vertical position in the visible list
$levelnumberNesting depth in the task hierarchy
$openbooleanWhether the branch is currently expanded
$sourceArrayIDs of links going out of the task
$targetArrayIDs of links coming into the task
$has_childbooleanWhether the task has child tasks

The runtime Link object has the same field set as SerializedLink, but it is the client-side object returned by methods like gantt.getLink().

For the full runtime lists, see Task Properties and Link Properties.

TaskInput

When you provide task data to Gantt - gantt.parse(), gantt.addTask(), the tasks config/prop, or your own application store - use TaskInput. It is the lenient input shape: date fields accept either a Date or a string, and every field (including id) is optional, since Gantt generates an id when one is not supplied.

type TaskInput = Partial<SerializedTask> | Partial<Task>;

Use TaskInput for data you author or hold in application state. Use Task (runtime, Date dates, $-prefixed fields) when reading Gantt's own objects via methods like gantt.getTask(), and SerializedTask (string dates only) for JSON you exchange with a server.

// Application-owned task data handed to Gantt - either date form is accepted:
const tasks: TaskInput[] = [
{ id: 1, text: "Task #1", start_date: new Date(2026, 3, 1), duration: 5 },
{ id: 2, text: "Task #2", start_date: "2026-04-02", duration: 3 }
];

Storing application state as TaskInput[] is preferable to typing it as SerializedTask[] or Task[]: it avoids mismatches when your seed data uses Date objects but the type expects strings (or vice versa). Pick Task / SerializedTask only for the specific boundaries where the date representation is fixed.

Supporting Types

Baseline and SerializedBaseline

interface Baseline {
id: string | number;
task_id: string | number;
start_date: Date;
duration: number;
end_date: Date;
[customProperty: string]: any;
}

interface SerializedBaseline {
id?: string | number;
task_id?: string | number;
start_date?: string;
duration?: number;
end_date?: string;
[customProperty: string]: any;
}

ResourceAssignment and SerializedResourceAssignment

interface ResourceAssignment {
id: string | number;
task_id: string | number;
resource_id: string | number;
value: number | string;
delay: number;
start_date: Date;
end_date: Date;
duration: number;
mode: string;
[customProperty: string]: any;
}

interface SerializedResourceAssignment {
id?: string | number;
task_id: string | number;
resource_id: string | number;
value?: number | string;
mode?: string;
delay?: number;
start_date?: string;
duration?: number;
end_date?: string;
[customProperty: string]: any;
}

ResourceItem

interface ResourceItem {
id: string | number;
text?: string;
parent?: string | number;
open?: boolean;
unit?: string | number;
default_value?: string | number;
[customProperty: string]: any;
}

See Inbuilt Baselines and Resource Management for feature-specific details.

GanttData

The object passed to gantt.parse():

type GanttData =
| {
data: (SerializedTask | Task)[];
tasks?: undefined;
links?: (SerializedLink | Link)[];
resources?: Partial<ResourceItem>[];
assignments?: (SerializedResourceAssignment | ResourceAssignment)[];
baselines?: (SerializedBaseline | Baseline)[];
collections?: Record<string, Array<Record<string, unknown>>>;
}
| {
tasks: (SerializedTask | Task)[];
data?: undefined;
links?: (SerializedLink | Link)[];
resources?: Partial<ResourceItem>[];
assignments?: (SerializedResourceAssignment | ResourceAssignment)[];
baselines?: (SerializedBaseline | Baseline)[];
collections?: Record<string, Array<Record<string, unknown>>>;
};

Both tasks and data keys are accepted for the task array. tasks is preferred in new code.

gantt.parse({
tasks: [
{ id: 1, text: "Project #1", start_date: "2026-04-01", duration: 18 },
{ id: 2, text: "Task #1", start_date: "2026-04-02", duration: 8, parent: 1 }
],
links: [
{ id: 1, source: 1, target: 2, type: "0" }
]
});

Legacy Compatibility Aliases

Older API docs and typings still use several compatibility names:

  • DataToLoad1, DataToLoad2: deprecated keyed variants of GanttData
  • NewTask: legacy alias of TaskInput (defined as TaskInput | string | {}), kept for backward compatibility. Prefer TaskInput in new code.
  • NewResourceItem: deprecated compatibility alias for Partial<ResourceItem>
  • NewAssignmentItem: deprecated compatibility alias for SerializedResourceAssignment | ResourceAssignment

These names are kept for backward compatibility, but GanttData, TaskInput, SerializedTask, SerializedLink, Task, and Link are the canonical concepts used in this guide.

Date Rules

  • When exchanging JSON with the server, use strings for date fields
  • If you build a JavaScript object directly and pass it to gantt.parse(), runtime task and assignment objects may contain Date
  • After loading, Gantt stores task dates as Date objects in runtime Task
  • Since v9.1.3, Gantt automatically detects ISO 8601 date strings

For details and examples, see Data Loading - Loading Task Dates.

Custom Properties

All data types support custom properties via [customProperty: string]: any. Custom properties are preserved on the client side after loading and can be used in templates, columns, editors, and backend storage.

gantt.parse({
tasks: [
{
id: 1,
text: "Task #1",
start_date: "2026-04-01",
duration: 10,
priority: "high",
owner: "John"
}
],
links: []
});

const task = gantt.getTask(1);
console.log(task.priority); // "high"

Task Order

Gantt displays tasks in the order they appear in the tasks array. The position of each item in the array - together with the parent hierarchy - is the only thing that determines the visual order on the client. The runtime $index property is calculated from this array position and is not persisted.

This means the data source controls the display order. If users can reorder tasks via drag-and-drop, the data source needs a way to remember the new order so that subsequent loads return tasks in the correct sequence.

The standard approach is a numeric sortorder column in the backend storage. The data source sorts tasks by this column before returning them. sortorder is a backend-only concept - Gantt does not read or interpret it on the client. It travels as a custom property if included in the payload, but has no built-in effect.

When a user reorders a task on the UI, Gantt populates the target property on the task object sent to the server via DataProcessor. The value indicates where the task was moved relative to its siblings:

  • target="taskId" - place this task before the task with the given id
  • target="next:taskId" - place this task after the task with the given id

The backend uses this value to recalculate sortorder for the affected tasks.

For the full implementation pattern - database schema, initial values, and reorder logic - see Storing the Order of Tasks in the Server-Side Integration guide. For client-side drag-and-drop configuration, see Reordering Tasks.

Need help?
Got a question about the documentation? Reach out to our technical support team for help and guidance. For custom component solutions, visit the Services page.