Features
The JavaScript Scheduler component includes several options for adjusting event placement within a row.
-
event sorting - rules for ordering overlapping events within a row
-
event stacking - an option to compact the view by specifying the vertical overlap of concurrent events
-
event containers - render related events in a virtual container that keeps them in the same line within a row
-
force a specific line - set the zero-based line index used to display an event
-
dedicated line - require an event to be displayed in a new line used exclusively by that event
-
moving events to a position within a row - switch the drag-and-drop event moving mode to allow dropping events at a specified line within a row
-
Gantt chart - display each event in a special row
You can compare the strategies in the JavaScript Scheduler Event Placement Strategies demo. The downloadable sample includes a toolbar that switches between the configurations on one page.
The sample includes a trial version of DayPilot Pro for JavaScript (see also License below).
License
Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.
Default Event Position: Row vs. Line
The row is determined by the resource property of the event data object.
If there are multiple concurrent events, each of them will be placed in a special line within the row.
The exact line is calculated using the following rules:
-
The events that start first will be placed first.
-
If multiple events have the same start, the longer ones will be placed first.
-
Each event will be placed in the topmost available line.
This default sorting rule can be described as start asc, end desc. The sample derives its visible range from the current month, so the same placement rules remain easy to inspect without relying on a fixed historical date:
const start = DayPilot.Date.today().firstDayOfMonth();
Event Sorting
The default event sorting rule of start asc, end desc can be overridden by specifying custom sort fields. This affects the vertical position within a row, but it does not force the event into a specific line: the topmost available line is still used.
The sorting strategy assigns a numeric sort value to each event and sets the sort direction to ascending. Because smaller values come first, Event 3 is placed above Event 2 and Event 1:
sorting: {
name: "Custom event sorting",
sortDirections: ["asc"],
events: [
{
start: start.addDays(3),
end: start.addDays(8),
id: 1,
resource: "R2",
text: "Event 1 (sort: 3)",
sort: [3]
},
{
start: start.addDays(4),
end: start.addDays(9),
id: 2,
resource: "R2",
text: "Event 2 (sort: 2)",
sort: [2]
},
{
start: start.addDays(5),
end: start.addDays(10),
id: 3,
resource: "R2",
text: "Event 3 (sort: 1)",
sort: [1]
}
]
},
Stacking of Overlapping Events
By default, the lines within a row do not overlap. In some cases, you may want to make the view more compact by setting a percentage of line height overlap using eventStackingLineHeight. This property accepts a percentage value from 0 to 100. The default value is 100, which gives every line its full height. A smaller value compacts the view.
The following strategy uses eventStackingLineHeight: 50:
stacking: {
name: "Overlapping lines at 50% height",
eventStackingLineHeight: 50,
events: [
{
start: start.addDays(3),
end: start.addDays(8),
id: 1,
resource: "R2",
text: "Event 1"
},
{
start: start.addDays(5),
end: start.addDays(10),
id: 2,
resource: "R2",
text: "Event 2"
},
{
start: start.addDays(7),
end: start.addDays(12),
id: 3,
resource: "R2",
text: "Event 3"
}
]
},
The sample also makes events slightly transparent in this mode so that the text of a partially covered event remains readable:
.stacking-mode .scheduler_default_event {
opacity: 0.82;
}
Event Containers
All previous examples used the default event line assignment rule. Sometimes, it is useful to display several related events in the same line. The Scheduler supports this scenario through virtual event containers. Specify the same container value in the event data objects (DayPilot.Event.data). The first event is placed using the standard rules, and all events with the same container ID share that line, with no other events placed between them.
In this example, Event 3 and its follow-up use the same series-1 container ID:
containers: {
name: "Related events in a virtual container",
events: [
{
start: start.addDays(3),
end: start.addDays(8),
id: 1,
resource: "R2",
text: "Event 1"
},
{
start: start.addDays(5),
end: start.addDays(10),
id: 2,
resource: "R2",
text: "Event 2"
},
{
start: start.addDays(7),
end: start.addDays(12),
id: 3,
resource: "R2",
text: "Event 3",
container: "series-1"
},
{
start: start.addDays(13),
end: start.addDays(17),
id: 4,
resource: "R2",
text: "Event 3 (Follow Up)",
container: "series-1"
}
]
},
Forcing a Specific Line
Use the event data line property to specify the exact line in which an event should be displayed. The value is a zero-based index, so line: 0 selects the first line within the row.
The events below use line indexes 0, 1, and 2. Explicit indexes reserve the requested vertical positions even though the event time ranges do not all overlap:
forcing: {
name: "Events forced to zero-based line indexes",
events: [
{
start: start.addDays(3),
end: start.addDays(8),
id: 1,
resource: "R2",
text: "Event 1 (line 0)",
line: 0
},
{
start: start.addDays(9),
end: start.addDays(13),
id: 2,
resource: "R2",
text: "Event 2 (line 1)",
line: 1
},
{
start: start.addDays(7),
end: start.addDays(12),
id: 3,
resource: "R2",
text: "Event 3 (line 2)",
line: 2
}
]
},
Dedicated Line
You can also use line: "dedicated" to place an event in its own line. The first available line is used, and no other event will be rendered in that line. This is useful when an event needs exclusive vertical space even if its time range does not overlap the neighboring events.
dedicated: {
name: "Exclusive dedicated lines",
events: [
{
start: start.addDays(3),
end: start.addDays(7),
id: 1,
resource: "R2",
text: "Event 1",
line: "dedicated"
},
{
start: start.addDays(8),
end: start.addDays(11),
id: 2,
resource: "R2",
text: "Event 2",
line: "dedicated"
},
{
start: start.addDays(12),
end: start.addDays(15),
id: 3,
resource: "R2",
text: "Event 3",
line: "dedicated"
}
]
}
See Also
History
-
July 2026: Updated the sample and code examples to use the current DayPilot Scheduler API and a current-month timeline.
DayPilot




