Вид "Timeline"
Данный вид доступен только в версии Scheduler PRO.
Вид Timeline отображает события по горизонтали, организуя отдельные временные линии (таймлайны) бок о бок слева направо.

Инициализация
Чтобы добавить вид Timeline в планировщик, выполните следующие шаги:
- Включите расширение Timeline на странице:
- Timeline - для режимов 'Bar' и 'Cell'
- Timeline, Treetimeline - для режима 'Tree'
- Timeline, Daytimeline - для режима 'Days'
scheduler.plugins({
timeline: true,
treetimeline: true,
daytimeline: true
});
- Добавьте вкладку вида в разметку планировщика:
<div id="scheduler_here" class="dhx_cal_container" ...>
<div class="dhx_cal_navline">
...
<div class="dhx_cal_tab" name="timeline_tab"></div>
</div>
...
</div>
- Установите метку для вкладки:
//'timeline_tab' соответствует имени нашего div
scheduler.locale.labels.timeline_tab ="Timeline";
- Вызовите метод createTimelineView:
scheduler.createTimelineView({
name:"timeline",
x_unit:"minute", // единица измерения по оси X
x_date:"%H:%i", // формат даты на оси X
x_step:30, // шаг на оси X в 'x_unit'
x_size:24, // общее количество шагов 'x_step' на оси X
x_start:16, // смещение по оси X в 'x_unit'
x_length:48, // количество шагов 'x_step' для прокрутки за раз
y_unit: // секции, отображаемые по оси Y
[{key:1, label:"Section A"},
{key:2, label:"Section B"},
{key:3, label:"Section C"},
{key:4, label:"Section D"}],
y_property:"section_id", // свойство для сопоставления данных с секциями
render:"bar" // режим отображения
});
При использовании режима 'Days' временная шкала должна охватывать ровно один день. Если в конфигурации указана более короткая или длинная длительность, таймлайн будет отображаться некорректно.
Пример конфигурации шкалы
Хотя метод createTimelineView включает множество параметров, его использование довольно просто.
Пример: временная шкала с 09:00 до 15:00 с шагом 30 минут и прокруткой по дням.
{
x_unit:"minute",// единицы шкалы — минуты
x_step:30, // шаг 30 минут, например, 09:00 - 09:30
x_size:12, // количество 30-минутных интервалов между 09:00 и 15:00
// 15 - 9 = 6 часов = 360 минут = 360/30 = 12
x_start:18, // шкала начинается с 09:00, это 9 часов от 00:00
// 9 часов = 540 минут = 540/30 = 18 шагов 'x_step'
x_length:48,// прокрутка на один день: 1 день = 24 часа = 1440 минут = 1440/30 = 48 шагов 'x_step'
...
}
Конфигурация вида Timeline
Все функции-шаблоны с именами, содержащими (timeline)_some, должны определяться после создания вида, так как они динамически назначаются конструктором таймлайна и будут перезаписаны вызовом createTimelineView.
Установка начальной даты для Timeline
Например, вот как установить начальную дату для вида Timeline.
Начальная дата любого вида управляется функцией scheduler.date[<viewName> +"_start"]. Чтобы изменить первый день шкалы таймлайна, переопределите функцию scheduler.date.timeline_start после вызова scheduler.createTimelineView():
// неделя начинается с понедельника
scheduler.config.start_on_monday = true;
// создаём таймлайн
scheduler.createTimelineView({
name: "timeline",
render: "tree",
days: 7,
folder_dy: 20,
x_unit: "day",
x_date: "%D %j %F",
x_step: 1,
x_size: 7,
x_start: 0,
x_length: 7,
y_unit:[],
y_property: "section_id"
});
// переопределяем функцию начальной даты после создания
scheduler.date.timeline_start = scheduler.date.week_start;
// инициализируем планировщик
scheduler.init("timeline_tree", new Date(), "timeline");
API объекта Timeline
Существует несколько методов для взаимодействия с видом Timeline.
Создание вида timeline
Для начала создайте экземпляр таймлайна в планировщике:
scheduler.createTimelineView({
name:'timeline',
...
});
const timeline = scheduler.matrix.timeline;
После создания можно использовать приведённые ниже методы.
Получение объекта timeline
Чтобы получить объект таймлайна, используйте метод getView. Он принимает имя вида в качестве параметра. Если параметр не передан, возвращается текущий вид.
const timeline = scheduler.getView();
timeline.x_size = 8;
scheduler.setCurrentView();
Установка диапазона шкалы
Для задания диапазона шкалы используйте метод setRange(). Требуется два параметра:
- startDate - (Date) начало диапазона
- endDate - (Date) конец диапазона
timeline.setRange(startDate, endDate);
Задание колонок в левой панели
Содержимое левой панели можно задать двумя способ ами.
По умолчанию она содержит одну колонку. Подписи секций берутся из свойства label объекта y_unit, который можно настроить с помощью шаблона timeline_scale_label.
Чтобы определить несколько колонок, используйте свойство columns в методе createTimelineView:
scheduler.createTimelineView({
name: "timeline",
x_unit: "minute",
x_date: "%H:%i",
x_step: 30,
x_size: 24,
x_start: 16,
x_length: 48,
y_unit: sections,
event_dy: "full",
y_property: "section_id",
render:"bar",
columns: [
{ label: "Room #", width: 70, template: function(obj){ return obj.room_no; } },
{ label: "Type", width: 90, template: function(obj){ return obj.room_type; } },
{ label: "Status", width: 90, template: function(obj){ return obj.room_status; } }
]
});
Каждый объект колонки может иметь следующие свойства:
- label -
string- необязательная подпись заголовка - width -
number- необязательная ширина колонки - template -
function- шаблон ячейки, получает объект секции
Прокрутка к определённой позиции/дате/секции
Эта функциональность работает только при включённой горизонтальной прокрутке Timeline.
Для прокрутки к определённой точке используйте метод scrollTo(). Поддерживаются различные типы параметров:
- Прокрутка к определённой дате (Date):
timeline.scrollTo(new Date());
- Прокрутка к определённой позиции по пикселям:
timeline.scrollTo(500);
- Прокрутка горизонтально и вертикально к определённой секции на определённую дату (объект с date и section):
timeline.scrollTo({date:new Date(), section:4});
- Прокрутка к определённой позиции по пикселям горизонтально и вертикально (объект с left и top):
timeline.scrollTo({left:300, top:500});
Получение координат определённой позиции
- Для получения X-координаты определённой даты на шкале используйте posFromDate() с параметром Date:
const left = timeline.posFromDate(new Date());
Этот метод возвращает 0 или максимальную X-координату, если дата вне шкалы.
- Для получения Y-координаты определённой строки используйте getSectionTop() с номером секции:
const top = timeline.getSectionTop(section.key);
Возвращает -1, если строка не найдена.
- Чтобы найти дату и секцию по определённым координатам таймлайна, используйте resolvePosition() с объектом
(left: number, top: number):
const position = timeline.resolvePosition({top: 120, left: 400});
- Для получения
Dateпо определённой координатеleftна временной шкале используйте dateFromPos():
const date = timeline.dateFromPos(300);
- Для получения координаты
topопределённого события используйте getEventTop() с объектом события:
const top = timeline.getEventTop(scheduler.getEvent(event.id));
Получение позиции скролла
Чтобы узнать текущую позицию скроллбара, вызовите timeline.getScrollPosition(), который возвращает объект с координатами прокрутки:
const timeline = scheduler.getView();
timeline.getScrollPosition(); // { left: 0, top: 0 }
Возвращаемый объект содержит:
- left - (number) позиция горизонтального скролла
- top - (number) позиция вертикального скролла
Также можно отслеживать изменения скролла через событие onScroll, которое получает новые значения left и top:
const timeline = scheduler.getView();
timeline.attachEvent("onScroll", function(left, top){});
Получение событий, назначенных секции
Чтобы получить массив событий, назначенных определённой секции, используйте timeline.selectEvents() с объектом конфигурации:
{
section: string|number,
date: Date,
selectNested: boolean
}
где:
- section - id секции
- date - необязательно, фильтрует события, пересекающиеся с заданной датой
- selectNested - необязательно, если true и секция - папка в древовидном таймлайне, выбирает события всех вложенных секций
Метод возвращает массив объектов событий.
const timeline = scheduler.getView();
const events = timeline.selectEvents({
section: section.key,
date: date,
selectNested: true
});
Динамическое изменение свойств
Все объекты таймлайна хранятся в объекте scheduler.matrix. Вы можете получить доступ к любому виду таймлайна по имени и обновить его свойства. Изменения вступают в силу после обновления планировщика:
scheduler.getView('timeline').x_size = 12;
scheduler.setCurrentView(); // перерисовывает планировщик
Здесь 'timeline' соответствует имени, заданному в методе createTimelineView:
scheduler.createTimelineView({
name:'timeline',
...
});
Динамическое изменение секций
Когда возникает необходимость обновить список ресурсов в представлении Timeline на лету, рекомендуется использовать методы serverList и updateCollection.
Загрузка данных
В отличие от более простых представлений, таких как День, Месяц или Год, многоресурсные представления, такие как Units и Timeline, требуют наличия в каждом элементе данных дополнительного обязательного поля:
- y_property - (string) определяет свойство данных, используемое для привязки событий к определённым секциям.

scheduler.createTimelineView({
name:"timeline",
...
y_unit:
[{key:1, label:"Room 1"},
{key:2, label:"Room 2"},
{key:3, label:"Room 3"}],
y_property:"room_id",
});
scheduler.init('scheduler_here');
scheduler.parse([
{text:"Conference", start_date:"17/09/2027 12:00", end_date:"18/09/2027 21:00",
room_id:"1"},
{text:"Meeting", start_date:"17/09/2027 09:00", end_date:"17/09/2027 21:00",
room_id:"2"},
{text:"Conference", start_date:"17/09/2027 15:00", end_date:"18/09/2027 15:00",
room_id:"3"}
]);
Назначение событий нескольким секциям
Планировщик поддерживает назначение событий сразу нескольким секциям.

Чтобы включить эту возможность:
- Подключите расширение Multisection на вашей странице
- Установите свойство multisection в true
- (Опционально) Добавьте расширение "Multiselect" для удобного управления Multiselect в планировщике, чтобы было проще переключаться между секциями
<script src="codebase/dhtmlxscheduler.js"></script>
<link rel="stylesheet" href="codebase/dhtmlxscheduler.css" type="text/css">
<script>
scheduler.plugins({
multisection: true, /*!*/
multiselect: true,
timeline: true
});
scheduler.config.multisection = true; /*!*/
scheduler.init('scheduler_here');
</script>
После настройки вы можете перечислить несколько секций (по умолчанию, разделённых запятыми, как указано в section_delimiter) в соответствующем свойстве данных события, и событие будет отображаться во всех этих секциях:
scheduler.createTimelineView({
name: "timeline",
y_unit: [
{key: 1, label: "James Smith"},
{key: 2, label: "John Williams"},
{key: 3, label: "David Miller"},
{key: 4, label: "Linda Brown"}],
y_property: "section_id", /*!*/
...
});
scheduler.init('scheduler_here', new Date(2027, 5, 30), "timeline");
scheduler.parse([
{ id:1, text:"Task A", section_id:'1', ...},/*!*/
{ id:2, text:"Task B", section_id:'1,3', ...},/*!*/
{ id:3, text:"Task C", section_id:'4', ...},/*!*/
{ id:4, text:"Task D", section_id:'2,3,4', ...}/*!*/
]);
Multisection events in Timeline and Units view
Режимы отображения
В представлении Timeline доступны четыре режима:
- Bar

- Cell (по умолчанию)

- Tree

- Days

Желаемый режим можно выбрать с помощью параметра render:
scheduler.createTimelineView({
name: "timeline",
render: "bar"
});
Особенности режима 'Days'
При использовании режима Days учитывайте следующее:
- Шкала времени должна покрывать ровно один день. Если настроить на меньший или больший период, timeline может отображаться некорректно:
scheduler.createTimelineView({
name:"timeline",
render:"days",
days:7,
// шкала времени настроена на 1 день /*!*/
x_unit:"minute", /*!*/
x_date:"%H:%i", /*!*/
x_step:30, /*!*/
x_size:24, /*!*/
x_start:16 /*!*/
});
- Этот режим не поддерживает функционал блокировки и выделения
- Формат подписей Y-оси управляется шаблоном scale_label:
scheduler.templates.timeline_scale_label = function(key, label, section){
// используются те же подписи, что и в представлении Day
return scheduler.templates.day_date(label);
};
- Для изменения начального дня отображаемого интервала используйте функцию scheduler.date.(timeline_name)_start:
scheduler.date.timeline_start = function (date) {
date = scheduler.date.week_start(date);
date = scheduler.date.add(date, config.x_step*config.x_start, config.x_unit);
return date;
};
Интервал времени для ячеек
По умолчанию каждая ячейка охватывает интервал в один день, и события располагаются соответственно. Чтобы изменить этот интервал, например, чтобы сосредоточиться на рабочих часах и исключить менее актуальное время, можно воспользоваться одним из следующих способов:
- Параметры first_hour и last_hour:
// интервал ячейки ограничен днем с 10:00 до 18:00
scheduler.createTimelineView({
name:"timeline",
first_hour:10,
last_hour:18
});
Changing the time interval for the view cells
- Функция ignore_(viewName), где viewName соответствует опции name для созданного Timeline через createTimelineView. Эта функция получает дату ячейки и возвращает 'true' для часов, которые должны быть исключены:
// интервал ячейки ограничен днем с 10:00 до 18:00
scheduler.ignore_timeline = function(date){ // "timeline" — имя представления
// исключить нерабочие часы
if (date.getHours() < 10 || date.getHours() > 18) return true;
};
Подробнее о методе ignore_(viewName) см. в разделе Скрытие единиц времени на оси X в представлении.
Hiding hours in the scale of Timeline view

Имейте в виду, что игнорируемый интервал не может быть равен или больше общего интервала, установленного для timeline.
Например, если timeline охватывает полный день и вы попытаетесь исключить весь день через функцию ignore_(viewName), это не даст ожидаемого эффекта. Планировщик всё равно отобразит этот день, но без шкалы и событий.
Чтобы полностью исключить такие интервалы, необходимо динамически изменять настройку x_length внутри функции scheduler._click.dhx_cal_next_button. Например, чтобы полностью исключить выходные из timeline, используйте следующий подход:
scheduler._click.dhx_cal_next_button = function(dummy,step){
const mode = scheduler.getState().mode;
const minDate = scheduler.getState().min_date;
const formFunc = scheduler.date.date_to_str("%D");
// пропустить выходные
if(mode=='timeline'){
if((formFunc(minDate)=='Fri' && step!=-1) || (formFunc(minDate)=='Mon' && step==-1))
scheduler.matrix['timeline'].x_length = 24*3;
else
scheduler.matrix['timeline'].x_length = 24;
}
scheduler.setCurrentView(scheduler.date.add(
scheduler.date[scheduler._mode+"_start"](scheduler._date),(step||1),scheduler._mode));
};
Related sample Игнорирование выходных
Данные для секций Y-оси в режимах 'Bar' и 'Cell'
Для указания значений Y-оси в режимах 'Bar' и 'Cell' используйте параметр y_unit:
scheduler.createTimelineView({
name:"timeline",
...
y_unit:[
{key:1, label:"James Smith"},
{key:2, label:"John Williams"},
{key:3, label:"David Miller"},
{key:4, label:"Linda Brown"}
]
});
Каждый элемент y_unit должен содержать два обязательных свойства:
- key - уникальный идентификатор элемента
- label - текстовая метка элемента
Данные для секций Y-оси в режиме 'Tree'
Режим 'Tree' позволяет группировать элементы в многоуровневые папки, что не только улучшает организацию, но и позволяет назначать события на целые папки на любом уровне иерархии.
Для настройки 'Tree' timeline используйте тот же параметр y_unit, что и в режимах 'Bar' и 'Cell', но с дополнительными свойствами:
scheduler.createTimelineView({
name: "timeline",
render:"tree",
...
y_unit:[
{key:"production", label:"Production Department", children:[
{key:"p1", label:"Managers", children:[
{key:"pm1", label:"John Williams"},
{key:"pm2", label:"David Miller"}
]},
{key:"p2", label:"Linda Brown"},
{key:"p3", label:"George Lucas"}
]},
{key:"sales", label:"Sales and Marketing", children:[
{key:"s1", label:"Kate Moss"},
{key:"s2", label:"Dian Fossey"}
]}
]
});
Элементы y_unit включают:
- Два обязательных свойства:
- key - id элемента
- label - метка элемента
- Два необязательных свойства:
- open - должна ли секция быть изначально раскрыта
- children - массив вложенных объектов
Данные для секций Y-оси в режиме 'Days'
Для режима 'Days' укажите количество дней на Y-оси с помощью параметра days:
scheduler.createTimelineView({
name:"timeline",
...
days:7 // количество дней на Y-оси
});
Данные для секций Y-оси с сервера
Для загрузки секций Y-оси с сервера используйте:
- На клиенте - метод serverList:
scheduler.createTimelineView({
name:"timeline",
...
y_unit:scheduler.serverList("sections"),
});
Здесь serverList получает список опций с именем 'sections'.
- На сервере