ProHorizontalLayout
Mixin
Mixin for SchedulerPro horizontal layouts (ProHorizontalLayoutPack and ProHorizontalLayoutStack). Should not be used directly, instead specify eventLayout in the SchedulerPro config (stack, pack or none):
new SchedulerPro({
eventLayout: 'stack'
});
Grouping events
By default events are not grouped and are laid out inside the row using start and end dates. Using groupBy config you can group events inside the resource row. Every group will be laid out on its own band, as if layout was applied to each group of events separately.
const scheduler = new SchedulerPro({ appendTo : targetElement, project : { events : [ { id : 1, startDate : '2021-08-23', duration : 2, prio : 'low' }, { id : 2, startDate : '2021-08-25', duration : 2, prio : 'high', eventColor : 'red' }, { id : 3, startDate : '2021-08-27', duration : 2, prio : 'high', eventColor : 'red' } ], resources : [ { id : 1, name : 'Mike' } ], assignments : [ { id : 1, resource : 1, event : 1 }, { id : 2, resource : 1, event : 2 }, { id : 3, resource : 1, event : 3 } ] }, startDate : new Date(2021, 7, 22), endDate : new Date(2021, 7, 29), autoHeight : true, rowHeight : 50, eventLayout : { type : 'stack', groupBy : 'prio' }, columns : [ { type : 'resourceInfo', text : 'Worker', field : 'name', width : 160 } ], resourceImagePath : 'data/Scheduler/images/transparent-users/', eventRenderer({ eventRecord }) { return eventRecord.prio; }, tbar : [ { type : 'buttonGroup', rendition : 'padded', toggleGroup : true, defaults : { width : '12em' }, items : [ { type : 'button', ref : 'prio', text : 'Priority', pressed : true }, { type : 'button', ref : 'prioReverse', text : 'Priority (reversed)' }, { type : 'button', ref : 'noneButton', text : 'None' } ], onAction({ source : button }) { switch (button.ref) { case 'prio': scheduler.eventLayout = { type : 'stack', groupBy : 'prio' }; break; case 'prioReverse': scheduler.eventLayout = { type : 'stack', weights : { low : 100, high : 200 }, groupBy : 'prio' }; break; case 'noneButton': default: scheduler.eventLayout = 'stack'; break; } } } ] }); By field value
You can specify field name to group events by. The following snippet would put high prio events at the top:
new SchedulerPro({
eventLayout : {
type : 'stack',
groupBy : 'prio'
},
project : {
events : [
{ id : 1, startDate : '2017-02-08', duration : 1, prio : 'low' },
{ id : 2, startDate : '2017-02-09', duration : 1, prio : 'high' },
{ id : 3, startDate : '2017-02-10', duration : 1, prio : 'high' },
],
resources : [
{ id : 1, name : 'Resource 1' }
],
assignments : [
{ id : 1, resource : 1, event : 1 },
{ id : 2, resource : 1, event : 2 },
{ id : 3, resource : 1, event : 3 }
]
}
})
Order of groups
Groups are always sorted ascending. In the example above high prio events are above low prio events because:
'high' < 'low' // true
If you want to group events in a specific order, you can define it in a special weights config:
new SchedulerPro({
eventLayout : {
type : 'stack',
weights : {
low : 100,
high : 200
},
groupBy : 'prio'
}
});
This will put low prio events at the top.
The weight value defaults to Infinity unless specified in the weights config explicitly.
Using a function
You can use a custom function to group events. The group function receives an event record as a single argument and is expected to return a non-null value for the group. This allows you to arrange events in any order you like, including grouping by multiple properties at once.
The snippet below groups events by duration and priority by creating 4 weights:
| high prio | low prio | |
|---|---|---|
| long | 2 | 10 |
| short | 3 | 15 |
new SchedulerPro({
eventLayout : {
type : 'stack',
groupBy : event => {
return (event.duration > 2 ? 2 : 3) * (event.prio === 'high' ? 1 : 5);
}
}
})
This will divide events into 4 groups as seen in this demo:
new SchedulerPro({ appendTo : targetElement, project : { events : [ { id : 1, startDate : '2021-08-23', duration : 1, prio : 'low' }, { id : 2, startDate : '2021-08-25', duration : 1, prio : 'low' }, { id : 3, startDate : '2021-08-27', duration : 1, prio : 'high' }, { id : 4, startDate : '2021-08-28', duration : 1, prio : 'high' }, { id : 5, startDate : '2021-08-23', duration : 3, prio : 'low' }, { id : 6, startDate : '2021-08-25', duration : 3, prio : 'low' }, { id : 7, startDate : '2021-08-27', duration : 3, prio : 'high' }, { id : 8, startDate : '2021-08-28', duration : 3, prio : 'high' } ], resources : [ { id : 1, name : 'Mike' } ], assignments : [ { id : 1, resource : 1, event : 1 }, { id : 2, resource : 1, event : 2 }, { id : 3, resource : 1, event : 3 }, { id : 4, resource : 1, event : 4 }, { id : 5, resource : 1, event : 5 }, { id : 6, resource : 1, event : 6 }, { id : 7, resource : 1, event : 7 }, { id : 8, resource : 1, event : 8 } ] }, startDate : new Date(2021, 7, 23), endDate : new Date(2021, 8, 5), viewPreset : 'dayAndWeek', autoHeight : true, rowHeight : 50, eventLayout : { type : 'stack', groupBy : event => (event.duration > 2 ? 2 : 3) * (event.prio === 'high' ? 1 : 5) }, columns : [], eventRenderer({ eventRecord }) { return `Event ${eventRecord.id} ${eventRecord.prio}`; } }); Manual event layout
You can provide a custom function to layout events inside the row and set the row size as required using layoutFn. The function is called with an array of render data objects. The custom function can iterate over those objects and position them inside the row using top and height attributes. The function should return the total row height in pixels.
Please note that using a custom layout function makes rowHeight obsolete.
new SchedulerPro({ appendTo : targetElement, project : { events : [ { id : 1, startDate : '2021-08-23', duration : 1, prio : 'low' }, { id : 2, startDate : '2021-08-25', duration : 1, prio : 'low' }, { id : 3, startDate : '2021-08-27', duration : 1, prio : 'high' }, { id : 4, startDate : '2021-08-28', duration : 1, prio : 'high' }, { id : 5, startDate : '2021-08-23', duration : 3, prio : 'low' }, { id : 6, startDate : '2021-08-25', duration : 3, prio : 'low' }, { id : 7, startDate : '2021-08-27', duration : 3, prio : 'high' }, { id : 8, startDate : '2021-08-28', duration : 3, prio : 'high' } ], resources : [ { id : 1, name : 'Mike' } ], assignments : [ { id : 1, resource : 1, event : 1 }, { id : 2, resource : 1, event : 2 }, { id : 3, resource : 1, event : 3 }, { id : 4, resource : 1, event : 4 }, { id : 5, resource : 1, event : 5 }, { id : 6, resource : 1, event : 6 }, { id : 7, resource : 1, event : 7 }, { id : 8, resource : 1, event : 8 } ] }, startDate : new Date(2021, 7, 23), endDate : new Date(2021, 7, 29), viewPreset : 'dayAndWeek', height : 200, rowHeight : 50, eventLayout : { layoutFn : items => { items.forEach(item => { item.top = (6 - item.eventRecord.id) * 10; item.height = (7 - item.eventRecord.id) * 10; }); return 120; } }, columns : [], eventRenderer({ eventRecord }) { return `Event ${eventRecord.id} ${eventRecord.prio}`; } }); new SchedulerPro({
eventLayout : {
layoutFn : (items, resourceRecord, scheduler) => {
// Put event element at random top position
item.top = 100 * Math.random();
}
}
});
Useful configs
| Config | Description |
|---|---|
| groupBy | Field name or function to group events in a row |
| weights | Custom ordering of event groups within a row |
| layoutFn | Custom function for manual event positioning |
| type | Layout algorithm: stack, pack, or none |
See also
- ProHorizontalLayoutStack — Stack layout that increases row height for overlapping events
- ProHorizontalLayoutPack — Pack layout that reduces event height for overlapping events
- SchedulerPro — The scheduling view that uses these layouts
Configs
Configs are options you supply in a configuration object when creating an instance of this class-
Type of horizontal layout. Supported values are
stack,packandnone.
Properties
Properties are getters/setters or publicly accessible variables on this class-
Identifies an object as an instance of ProHorizontalLayout class, or subclass thereof.
-
Returns
trueif event grouper is defined. -
Identifies an object as an instance of ProHorizontalLayout class, or subclass thereof.