Introduction
Bryntum components are data-driven by design—data is not just an enhancement, it is a core requirement. Whether you're rendering a Scheduler, Gantt chart, or Grid, each component depends on well-structured data to function correctly.
This guide serves as an introduction to Bryntum’s data management concepts, helping you understand the underlying data structures, loading mechanisms, and integration strategies needed to build functional and efficient applications.
Let's start by exploring the two main sources of data:
- Inline data
- Remote data
Inline data
The easiest way to feed data into your Bryntum Gantt is by using inline data. Just as HTML allows inline CSS, you can include the data directly inside the new Gantt({}) instance. Here's how to do it:
new Gantt({
tasks : [
{
id : 1,
name : 'Write docs',
expanded : true,
children : [
{ id : 2, name : 'Proof-read docs', startDate : '2020-01-02', endDate : '2020-01-05' },
{ id : 3, name : 'Release docs', startDate : '2020-01-09', endDate : '2020-01-10' }
]
}
],
dependencies : [
{ fromEvent : 2, toEvent : 3 }
]
})
const App = props => {
const [tasks, setTasks] = useState([
{
id : 1,
name : 'Write docs',
expanded : true,
children : [
{ id : 2, name : 'Proof-read docs', startDate : '2020-01-02', endDate : '2020-01-05' },
{ id : 3, name : 'Release docs', startDate : '2020-01-09', endDate : '2020-01-10' }
]
}
]);
const [dependencies, setDependencies] = useState([
{ fromEvent : 2, toEvent : 3 }
]);
return <BryntumGantt tasks={tasks} dependencies={dependencies} />
}
<bryntum-gantt :tasks="tasks" :dependencies="dependencies" />
<script setup>
{/* other config */}
const
tasks = reactive([
{
id : 1,
name : 'Write docs',
expanded : true,
children : [
{ id : 2, name : 'Proof-read docs', startDate : '2020-01-02', endDate : '2020-01-05' },
{ id : 3, name : 'Release docs', startDate : '2020-01-09', endDate : '2020-01-10' }
]
}
]),
dependencies = reactive([
{ fromEvent : 2, toEvent : 3 }
])
</setup>
<bryntum-gantt [tasks]="tasks" [dependencies]="dependencies"></bryntum-gantt>
@Component()
export class AppComponent {
tasks = [
{
id : 1,
name : 'Write docs',
expanded : true,
children : [
{ id : 2, name : 'Proof-read docs', startDate : '2020-01-02', endDate : '2020-01-05' },
{ id : 3, name : 'Release docs', startDate : '2020-01-09', endDate : '2020-01-10' }
]
}
]
dependencies = [
{ fromEvent : 2, toEvent : 3 }
]
}
The above config results in the following Gantt:
const gantt = new Gantt({ appendTo : targetElement, autoHeight : true, columns : [ { type : 'name', field : 'name', text : 'Name' } ], tasks : [ { id : 1, name : 'Documentation Project', expanded : true, children : [ { id : 2, name : 'Preparation', expanded : true, children : [ { id : 6, name : 'Proof-read docs', startDate : '2026-01-02', endDate : '2026-01-09' }, { id : 3, name : 'Release docs', startDate : '2026-01-09', endDate : '2026-01-10' } ] }, { id : 4, name : 'Development', expanded : true, children : [ { id : 7, name : 'Write API docs', startDate : '2026-01-05', endDate : '2026-01-12' }, { id : 8, name : 'Write tutorials', startDate : '2026-01-10', endDate : '2026-01-16' }, { id : 9, name : 'Create examples', startDate : '2026-01-12', endDate : '2026-01-18' } ] }, { id : 5, name : 'Review & Release', expanded : true, children : [ { id : 10, name : 'Team review', startDate : '2026-01-18', endDate : '2026-01-20' }, { id : 11, name : 'Final approval', startDate : '2026-01-20', endDate : '2026-01-21' }, { id : 12, name : 'Public release', startDate : '2026-01-22', endDate : '2026-01-22' } ] } ] } ], dependencies : [ { fromTask : 6, toTask : 3 }, { fromTask : 7, toTask : 8 }, { fromTask : 8, toTask : 9 }, { fromTask : 9, toTask : 10 }, { fromTask : 10, toTask : 11 }, { fromTask : 11, toTask : 12 } ], startDate : new Date(2026, 0, 1), endDate : new Date(2026, 0, 30) }); Remote data
Remote data can come from a static .json file hosted on a web server (e.g., in the /public folder of your project or on a CDN), or it can be retrieved dynamically from a server through an API call (e.g., data.php).
If you have a /data.php endpoint, you can access the data as follows:
new Gantt({
project : {
loadUrl : '/data.php',
autoLoad : true // auto load on initialization
}
})
// GanttConfig.tsx
import { BryntumGanttProps } from "@bryntum/gantt-react";
const ganttProps: BryntumGanttProps = {
// other config
project : {
transport : {
loadUrl : 'data.json' // can be replaced with an API endpoint (e.g. read.php)
},
autoLoad : true // auto load on initialization
}
};
export { ganttProps };
import { ganttProps } from "./ganttProps";
// App.tsx
const App = props => {
return <BryntumGantt {...ganttProps} />
}
<script setup lang="ts">
import { BryntumGantt } from '@bryntum/gantt-vue-3';
import { ganttConfig } from './AppConfig.ts';
</script>
<template>
<bryntum-gantt v-bind="ganttConfig" />
</template>
import { type BryntumGanttProps } from '@bryntum/gantt-vue-3';
export const ganttConfig : BryntumGanttProps = {
// other config
project : {
transport : {
loadUrl : 'data.json' // can be replaced with an API endpoint (e.g. read.php)
},
autoLoad : true // auto load on initialization
}
};
<bryntum-gantt-project-model
#project
[startDate]="projectModelProps.startDate!"
[endDate]="projectModelProps.endDate!"
[calendar]="projectModelProps.calendar!"
[loadUrl]="projectModelProps.loadUrl!"
[autoLoad]="projectModelProps.autoLoad!"
></bryntum-gantt-project-model>
<bryntum-gantt
#gantt
[project]="project"
></bryntum-gantt>
// app.config.ts
import { BryntumGanttProjectModelProps } from '@bryntum/gantt-angular';
export const projectModelProps : BryntumGanttProjectModelProps = {
loadUrl : 'data.json', // can be replaced with an API endpoint (e.g. read.php)
autoLoad : true,
autoSetConstraints : true
};
// app.component.ts
import { projectModelProps } from './app.config';
export class AppComponent implements AfterViewInit {
public projectModelProps = projectModelProps;
}
The project approach populates all stores in one request, reducing the API calls when loading the data. Take a look at the load request or response structure to understand how to work with the project.
const gantt = new Gantt({ project : { transport : { load : { url : 'data/Gantt/examples/guides/readme/intro.json' } }, autoLoad : true }, style : 'font-size:0.85em', appendTo : targetElement, height : 500, rowHeight : 40, columns : [ { type : 'name', width : 250 }, { type : 'startdate' }, { type : 'duration' }, { type : 'percentdone', width : 70 }, { type : 'predecessor', width : 112 }, { type : 'addnew' } ], subGridConfigs : { locked : { width : 220 }, normal : { flex : 2 } }, startDate : '2025-01-12', endDate : '2025-02-13', tbar : { items : { createButton : { color : 'b-green', icon : 'fa fa-plus', text : 'Create', tooltip : 'Create new task', style : 'margin-right: .5em', async onAction() { const added = gantt.taskStore.rootNode.appendChild({ name : 'New task', duration : 1 }); // run propagation to calculate new task fields await gantt.project.commitAsync(); // scroll to the added task. Smoothly. await gantt.scrollRowIntoView(added, { animate : true }); gantt.features.cellEdit.startEditing({ record : added, field : 'name' }); } }, editButton : { color : 'b-green', icon : 'fa fa-pen', text : 'Edit', tooltip : 'Edit selected task', onAction() { if (gantt.selectedRecord) { gantt.editTask(gantt.selectedRecord); } else { Toast.show('First select the task you want to edit'); } } } } } }); You can also use axios or fetch API:
async function loadData() {
const response = await fetch('backend/load.php');
return await response.json();
}
// Extract data from loadData() via `await` or `.then`
// Assuming it has been saved to `data`
const gantt = new Gantt({
project : {
inlineData : data
}
})
// or
gantt.project.inlineData = data;
Working with remote data is more complex as it offers multiple ways of interaction. Let's move on to the next topic to learn more about how stores work.
Continue reading: Understanding the Store