Hi,
We've noted a bug with the width of the displayed timespans when using a custom view where the smallest timeaxis unit is a week. Below you can find two examples on how to reproduce this in the demo's. The examples all contain two day timespans (the first with two seperate days beside eachother and the second a recurrance rule for two days).
Reproduction steps:
- Copy the code
- Move to the right a few time (e.g. 5 times)
- Move back a few times till you see the issue like in the image below.
- As you can see the days around week 43 are much broader then the ones around it. Also the position is off.
click back a few times more and it displays as it should again
import { DateHelper, EventModel, Scheduler, PresetManager } from '../../build/scheduler.module.js?486179';
import shared from '../_shared/shared.module.js?486179';
//region Presets & Widgets
PresetManager.registerPreset('dayNightShift', {
name : 'Day/night shift (custom)',
tickWidth : 50,
displayDateFormat : 'HH:mm',
shiftIncrement : 1,
shiftUnit : 'month',
timeResolution : {
unit : 'week',
increment : 1
},
defaultSpan : 6,
mainHeaderLevel : 1,
headers : [
{
"unit": "year",
"dateFormat": "YYYY",
"align":"start"
},
{
"unit": "month",
"dateFormat": "MMM",
"align":"start"
},
{
"unit": "week",
"dateFormat": "Wp0",
"align":"start"
}
]
});
PresetManager.registerPreset('weekNumberAndYear', {
name : 'Year/week number',
tickWidth : 35,
displayDateFormat : '{w.}W YYYY',
shiftIncrement : 1,
shiftUnit : 'year',
timeResolution : {
unit : 'd',
increment : 1
},
defaultSpan : 24,
mainHeaderLevel : 1,
headers : [
{
unit : 'y',
increment : 1,
dateFormat : 'YYYY'
},
{
unit : 'w',
increment : 1,
dateFormat : 'WW'
}
]
});
const
requiredPresetIds = {
secondAndMinute : 1,
minuteAndHour : 1,
hourAndDay : 1,
dayNightShift : 1,
weekAndDay : 1,
weekAndMonth : 1,
weekAndDayLetter : 1,
weekDateAndMonth : 1,
weekNumberAndYear : 1,
monthAndYear : 1,
year : 1,
manyYears : 1
},
// The set of available Presets is what provides the zoom levels.
presets = PresetManager.records.filter(p => requiredPresetIds[p.id]);
//endregion
//region Data
const
resources = [
{ id : 1, name : 'Arcady', role : 'Core developer', eventColor : 'purple' },
{ id : 2, name : 'Dave', role : 'Tech Sales', eventColor : 'indigo' },
{ id : 3, name : 'Henrik', role : 'Sales', eventColor : 'blue' },
{ id : 4, name : 'Linda', role : 'Core developer', eventColor : 'cyan' },
{ id : 5, name : 'Maxim', role : 'Developer & UX', eventColor : 'green' },
{ id : 6, name : 'Mike', role : 'CEO', eventColor : 'lime' },
{ id : 7, name : 'Lee', role : 'CTO', eventColor : 'orange' }
],
events = [
{
id : 1,
resourceId : 1,
percentDone : 60,
startDate : new Date(2017, 0, 1, 10),
endDate : new Date(2017, 0, 1, 12)
},
{
id : 2,
resourceId : 2,
percentDone : 20,
startDate : new Date(2017, 0, 1, 12),
endDate : new Date(2017, 0, 1, 17)
},
{
id : 3,
resourceId : 3,
percentDone : 80,
startDate : new Date(2017, 0, 1, 14),
endDate : new Date(2017, 0, 1, 16)
},
{
id : 4,
resourceId : 4,
percentDone : 90,
startDate : new Date(2017, 0, 1, 8),
endDate : new Date(2017, 0, 1, 11)
},
{
id : 5,
resourceId : 5,
percentDone : 40,
startDate : new Date(2017, 0, 1, 15),
endDate : new Date(2017, 0, 1, 17)
},
{
id : 6,
resourceId : 6,
percentDone : 70,
startDate : new Date(2017, 0, 1, 16),
endDate : new Date(2017, 0, 1, 18)
}
],
timespans = [
];
//endregion
class EventModelWithPercent extends EventModel {
static get fields() {
return [
{ name : 'percentDone', type : 'number', defaultValue : 0 }
];
}
}
const scheduler = new Scheduler({
appendTo : 'container',
resourceImagePath : '../_shared/images/users/',
features : {
timeRanges : true,
sort : 'name'
},
columns : [
{
type : 'resourceInfo',
text : 'Staff',
width : '10em'
}
],
resources,
eventStore : {
modelClass : EventModelWithPercent,
data : events
},
timeRanges : [
{
"id": "ts0",
"startDate": "2025-08-03T22:00:00.000Z",
"endDate": "2025-08-04T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts1",
"startDate": "2025-08-02T22:00:00.000Z",
"endDate": "2025-08-03T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts2",
"startDate": "2025-08-10T22:00:00.000Z",
"endDate": "2025-08-11T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts3",
"startDate": "2025-08-09T22:00:00.000Z",
"endDate": "2025-08-10T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts4",
"startDate": "2025-08-17T22:00:00.000Z",
"endDate": "2025-08-18T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts5",
"startDate": "2025-08-16T22:00:00.000Z",
"endDate": "2025-08-17T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts6",
"startDate": "2025-08-24T22:00:00.000Z",
"endDate": "2025-08-25T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts7",
"startDate": "2025-08-23T22:00:00.000Z",
"endDate": "2025-08-24T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts8",
"startDate": "2025-08-31T22:00:00.000Z",
"endDate": "2025-09-01T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts9",
"startDate": "2025-08-30T22:00:00.000Z",
"endDate": "2025-08-31T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts10",
"startDate": "2025-09-07T22:00:00.000Z",
"endDate": "2025-09-08T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts11",
"startDate": "2025-09-06T22:00:00.000Z",
"endDate": "2025-09-07T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts12",
"startDate": "2025-09-14T22:00:00.000Z",
"endDate": "2025-09-15T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts13",
"startDate": "2025-09-13T22:00:00.000Z",
"endDate": "2025-09-14T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts14",
"startDate": "2025-09-21T22:00:00.000Z",
"endDate": "2025-09-22T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts15",
"startDate": "2025-09-20T22:00:00.000Z",
"endDate": "2025-09-21T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts16",
"startDate": "2025-09-28T22:00:00.000Z",
"endDate": "2025-09-29T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts17",
"startDate": "2025-09-27T22:00:00.000Z",
"endDate": "2025-09-28T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts18",
"startDate": "2025-10-05T22:00:00.000Z",
"endDate": "2025-10-06T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts19",
"startDate": "2025-10-04T22:00:00.000Z",
"endDate": "2025-10-05T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts20",
"startDate": "2025-10-12T22:00:00.000Z",
"endDate": "2025-10-13T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts21",
"startDate": "2025-10-11T22:00:00.000Z",
"endDate": "2025-10-12T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts22",
"startDate": "2025-10-19T22:00:00.000Z",
"endDate": "2025-10-20T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts23",
"startDate": "2025-10-18T22:00:00.000Z",
"endDate": "2025-10-19T22:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts24",
"startDate": "2025-10-26T23:00:00.000Z",
"endDate": "2025-10-27T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts25",
"startDate": "2025-10-25T22:00:00.000Z",
"endDate": "2025-10-26T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts26",
"startDate": "2025-11-02T23:00:00.000Z",
"endDate": "2025-11-03T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts27",
"startDate": "2025-11-01T23:00:00.000Z",
"endDate": "2025-11-02T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts28",
"startDate": "2025-11-09T23:00:00.000Z",
"endDate": "2025-11-10T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts29",
"startDate": "2025-11-08T23:00:00.000Z",
"endDate": "2025-11-09T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts30",
"startDate": "2025-11-16T23:00:00.000Z",
"endDate": "2025-11-17T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts31",
"startDate": "2025-11-15T23:00:00.000Z",
"endDate": "2025-11-16T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts32",
"startDate": "2025-11-23T23:00:00.000Z",
"endDate": "2025-11-24T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts33",
"startDate": "2025-11-22T23:00:00.000Z",
"endDate": "2025-11-23T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts34",
"startDate": "2025-11-30T23:00:00.000Z",
"endDate": "2025-12-01T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts35",
"startDate": "2025-11-29T23:00:00.000Z",
"endDate": "2025-11-30T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts36",
"startDate": "2025-12-07T23:00:00.000Z",
"endDate": "2025-12-08T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts37",
"startDate": "2025-12-06T23:00:00.000Z",
"endDate": "2025-12-07T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts38",
"startDate": "2025-12-14T23:00:00.000Z",
"endDate": "2025-12-15T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts39",
"startDate": "2025-12-13T23:00:00.000Z",
"endDate": "2025-12-14T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts40",
"startDate": "2025-12-21T23:00:00.000Z",
"endDate": "2025-12-22T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts41",
"startDate": "2025-12-20T23:00:00.000Z",
"endDate": "2025-12-21T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts42",
"startDate": "2025-12-28T23:00:00.000Z",
"endDate": "2025-12-29T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts43",
"startDate": "2025-12-27T23:00:00.000Z",
"endDate": "2025-12-28T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts44",
"startDate": "2026-01-04T23:00:00.000Z",
"endDate": "2026-01-05T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts45",
"startDate": "2026-01-03T23:00:00.000Z",
"endDate": "2026-01-04T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts46",
"startDate": "2026-01-11T23:00:00.000Z",
"endDate": "2026-01-12T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts47",
"startDate": "2026-01-10T23:00:00.000Z",
"endDate": "2026-01-11T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts48",
"startDate": "2026-01-18T23:00:00.000Z",
"endDate": "2026-01-19T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts49",
"startDate": "2026-01-17T23:00:00.000Z",
"endDate": "2026-01-18T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts50",
"startDate": "2026-01-25T23:00:00.000Z",
"endDate": "2026-01-26T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts51",
"startDate": "2026-01-24T23:00:00.000Z",
"endDate": "2026-01-25T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts52",
"startDate": "2026-02-01T23:00:00.000Z",
"endDate": "2026-02-02T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts53",
"startDate": "2026-01-31T23:00:00.000Z",
"endDate": "2026-02-01T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts54",
"startDate": "2026-02-08T23:00:00.000Z",
"endDate": "2026-02-09T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
},
{
"id": "ts55",
"startDate": "2026-02-07T23:00:00.000Z",
"endDate": "2026-02-08T23:00:00.000Z",
"name": "",
"cls": "timespan-type--default b-sch-color-gray"
}
],
startDate : new Date(2025, 9, 1),
endDate : new Date(2025, 12, 2),
// Use our custom list of just the ones we plucked out of the PresetManager
presets,
viewPreset : 'dayNightShift',
eventRenderer : ({ eventRecord, renderData }) => {
const value = eventRecord.percentDone || 0;
// Add a child to the event element (b-sch-event)
renderData.children.push({
className : 'value',
style : {
width : `${value}%`
},
html : value
});
},
listeners : {
presetChange({ from, to }) {
const
me = this,
{ presetCombo, zoomInButton, zoomOutButton } = me.widgetMap;
// To disable buttons based on zoom levels use this code:
// zoomOutButton.disabled = level <= 0;
// zoomInButton.disabled = level >= this.presets.length - 1;
// To disable buttons based on presets in combo use this code:
const index = this.presets.indexOf(to);
zoomOutButton.disabled = index === 0;
zoomInButton.disabled = index === presetCombo.store.count - 1;
}
},
tbar : [
{
type : 'viewpresetcombo',
width : '16em',
ref : 'presetCombo',
presets : presets.map(p => p.id),
picker : {
maxHeight : 500
}
},
{
type : 'button',
ref : 'zoomInButton',
icon : 'b-icon-search-plus',
text : 'Zoom in',
onClick() {
scheduler.zoomIn();
}
},
{
type : 'button',
ref : 'zoomOutButton',
icon : 'b-icon-search-minus',
text : 'Zoom out',
onClick() {
scheduler.zoomOut();
}
},
{
type : 'buttongroup',
items : [
{
type : 'button',
icon : 'b-icon-previous',
tooltip : 'View previous day',
onAction() {
scheduler.shiftPrevious();
}
},
{
type : 'button',
ref : 'todayButton',
text : 'Today',
tooltip : 'View today, to see the current time line',
onAction() {
const today = DateHelper.clearTime(new Date());
today.setHours(5);
scheduler.setTimeSpan(today, DateHelper.add(today, 18, 'hour'));
}
},
{
type : 'button',
icon : 'b-icon-next',
tooltip : 'View next day',
onAction() {
scheduler.shiftNext();
}
}
]
}
]
});
Another example using recurrance
import { Scheduler, DateHelper, PresetManager } from '../../build/schedulerpro.module.js?486179';
import shared from '../_shared/shared.module.js?486179';
PresetManager.registerPreset('dayNightShift', {
name : 'Day/night shift (custom)',
tickWidth : 50,
displayDateFormat : 'HH:mm',
shiftIncrement : 1,
shiftUnit : 'month',
timeResolution : {
unit : 'week',
increment : 1
},
defaultSpan : 6,
mainHeaderLevel : 1,
headers : [
{
"unit": "year",
"dateFormat": "YYYY",
"align":"start"
},
{
"unit": "month",
"dateFormat": "MMM",
"align":"start"
},
{
"unit": "week",
"dateFormat": "Wp0",
"align":"start"
}
]
});
const scheduler = new Scheduler({
appendTo : 'container',
eventStyle : 'colored',
resourceImagePath : '../_shared/images/users/',
features : {
timeRanges : {
showCurrentTimeLine : true,
showHeaderElements : false
}
},
columns : [
{ type : 'resourceInfo', text : 'Staff', field : 'name', width : '10em' }
],
events: [],
resources: [
{
"id" : "a",
"name" : "Rob",
"type" : "Sales",
"eventColor" : "green"
},
{
"id" : "b",
"name" : "Mike",
"type" : "Sales",
"eventColor" : "green"
},
{
"id" : "c",
"name" : "Kate",
"type" : "Sales",
"eventColor" : "orange"
},
{
"id" : "d",
"name" : "Lisa",
"type" : "Developer",
"eventColor" : "orange"
},
{
"id" : "e",
"name" : "Dave",
"type" : "Developer",
"eventColor" : "blue"
},
{
"id" : "f",
"name" : "Arnold",
"type" : "Developer",
"eventColor" : "blue"
},
{
"id" : "g",
"name" : "Lee",
"type" : "Marketing",
"eventColor" : "violet"
},
{
"id" : "h",
"name" : "Jong",
"type" : "Marketing",
"eventColor" : "violet"
}
],
timeRanges: [
{
"id" : 2,
"name" : "",
"recurrenceRule" : "FREQ=WEEKLY;BYDAY=SA,SU;",
"startDate" : "2019-02-07 00:00",
"endDate" : "2019-02-08 00:00"
}
]
,
// crudManager : {
// autoLoad : true,
// transport : {
// load : {
// url : 'data/data.json'
// }
// },
// // This config enables response validation and dumping of found errors to the browser console.
// // It's meant to be used as a development stage helper only so please set it to false for production systems.
// validateResponse : true
// },
barMargin : 5,
startDate : new Date(2025, 1, 7, 8),
endDate : new Date(2025, 1, 29, 18),
viewPreset : {
tickWidth : 50,
base : 'dayNightShift'
},
tbar : [
{
type : 'button',
ref : 'addCoffeeButton',
icon : 'b-fa-coffee',
text : 'More coffee',
tooltip : 'Click to add morning coffee to Thursdays too',
onAction({ source : button }) {
const coffee = scheduler.features.timeRanges.store.getById(1);
coffee.recurrenceRule = 'FREQ=WEEKLY;BYDAY=MO,TH;';
button.disable();
}
},
'->',
{
type : 'buttongroup',
items : [
{
type : 'button',
icon : 'b-icon-previous',
tooltip : 'View previous day',
cls : 'navigate',
onAction() {
scheduler.shiftPrevious();
}
},
{
type : 'button',
ref : 'todayButton',
text : 'Today',
tooltip : 'View today, to see the current time line',
onAction() {
const today = DateHelper.clearTime(new Date());
today.setHours(5);
scheduler.setTimeSpan(today, DateHelper.add(today, 18, 'hour'));
}
},
{
type : 'button',
icon : 'b-icon-next',
tooltip : 'View next day',
cls : 'navigate',
onAction() {
scheduler.shiftNext();
}
}
]
},
{
type : 'button',
text : 'Start',
tooltip : 'Return to initial view',
onAction() {
scheduler.setTimeSpan(new Date(2019, 1, 7, 8), new Date(2019, 1, 29, 18));
}
}
]
});
Thanks,
Coen