При построении отчетов и мониторов загрузки оборудования или персонала с помощью объекта ДиаграммаГанта разработчики часто сталкиваются с задачей отображения только рабочих часов (например, с 09:00 до 18:00) за несколько дней подряд. По умолчанию шкала времени строится непрерывно, включая все 24 часа каждых суток, из-за чего полезное пространство диаграммы заполняется пустыми ночными интервалами и нерабочими днями.
В платформе 1С:Предприятие объект ДиаграммаГанта использует линейную и непрерывную ось времени, в которой нет штатного переключателя для исключения разрывов или привязки шкалы к графикам работы. Однако эту задачу можно решить несколькими практическими способами: от программного масштабирования координат до визуального зонирования и использования альтернативных элементов интерфейса.
Разберем наиболее эффективный способ сжатия шкалы времени, позволяющий исключить ночные часы. Идея метода заключается в том, чтобы математически растянуть реальный рабочий диапазон времени (например, с ВремяНачала до ВремяОкончания) на полные 24-часовые сутки для каждого дня, а затем вручную расставить нужные подписи меток времени на шкале.
Рассмотрим реализацию пересчета координат времени. Для этого создадим функцию преобразования даты и времени интервала задачи:
Функция ДиаграммаМонитораЗагрузкиОпределитьПериодИнтервала(Период, ВремяНачала, ВремяОкончания)
Если (ВремяНачала > 0) Или (ВремяОкончания < 24) Тогда
ПериодНачала = НачалоДня(Период) + ВремяНачала * 3600;
ПериодОкончания = НачалоДня(Период) + ВремяОкончания * 3600;
Если Период < ПериодНачала Тогда
Период = ПериодНачала;
ИначеЕсли Период > ПериодОкончания Тогда
Период = ПериодОкончания;
КонецЕсли;
// Растягиваем рабочий отрезок на 24 часа
Период = НачалоДня(Период) + (Период - НачалоДня(Период) - ВремяНачала * 3600) * 24 / (ВремяОкончания - ВремяНачала);
КонецЕсли;
Возврат Период;
КонецФункции
Теперь проанализируем, как сформировать пользовательскую шкалу меток на диаграмме Ганта. Отключаем автоматические периодические метки и вручную заполняем коллекцию меток для суток, часов и минут:
Процедура НастроитьШкалуВремениДиаграммы(ДиаграммаГанта, ПериодНачало, ПериодОкончание, ВремяНачала, ВремяОкончания, ШкалаМинутКратность)
ШкалаСутки = ДиаграммаГанта.ОбластьПостроения.ШкалаВремени.Элементы[0];
ШкалаЧасы = ДиаграммаГанта.ОбластьПостроения.ШкалаВремени.Элементы[1];
ШкалаМинуты = ДиаграммаГанта.ОбластьПостроения.ШкалаВремени.Элементы[2];
Если (ВремяНачала > 0) Или (ВремяОкончания < 24) Тогда
ШкалаСутки.Видимость = Истина;
ШкалаСутки.ЛинииДелений = Новый Линия(ТипЛинииДиаграммы.Пунктир);
ШкалаЧасы.Видимость = Истина;
ШкалаЧасы.ОтображатьПериодическиеМетки = Ложь;
ШкалаЧасы.ЛинииДелений = Новый Линия(ТипЛинииДиаграммы.Пунктир);
ШкалаМинуты.Видимость = Истина;
ШкалаМинуты.ОтображатьПериодическиеМетки = Ложь;
ШкалаМинуты.ЛинииДелений = Новый Линия(ТипЛинииДиаграммы.Пунктир);
// Отметка текущего времени
МеткаТекущая = ШкалаСутки.Метки.Добавить(ДиаграммаМонитораЗагрузкиОпределитьПериодИнтервала(ТекущаяДата(), ВремяНачала, ВремяОкончания));
МеткаТекущая.ЦветЛинии = WebЦвета.Красный;
Сутки = НачалоДня(ПериодНачало);
Пока Сутки <= ПериодОкончание Цикл
// Метка дня
МеткаДня = ШкалаСутки.Метки.Добавить(ДиаграммаМонитораЗагрузкиОпределитьПериодИнтервала(Сутки, ВремяНачала, ВремяОкончания));
МеткаДня.Текст = Формат(Сутки, "ДЛФ=DD") + ", " + Формат(Сутки, "ДФ=дддд");
// Метки рабочих часов
Для Час = ВремяНачала По (ВремяОкончания - 1) Цикл
ДатаЧаса = Сутки + Час * 3600;
МеткаЧаса = ШкалаЧасы.Метки.Добавить(ДиаграммаМонитораЗагрузкиОпределитьПериодИнтервала(ДатаЧаса, ВремяНачала, ВремяОкончания));
МеткаЧаса.Текст = Формат(Час, "ЧЦ=2; ЧН=; ЧВН=") + ":00";
// Метки минут внутри часа
Минуты = 0;
Пока Минуты < 60 Цикл
ДатаМинуты = ДатаЧаса + Минуты * 60;
МеткаМинуты = ШкалаМинуты.Метки.Добавить(ДиаграммаМонитораЗагрузкиОпределитьПериодИнтервала(ДатаМинуты, ВремяНачала, ВремяОкончания));
МеткаМинуты.Текст = Формат(Минуты, "ЧЦ=2; ЧН=; ЧВН=");
Минуты = Минуты + ШкалаМинутКратность;
КонецЦикла;
КонецЦикла;
Сутки = НачалоДня(Сутки + 86400);
КонецЦикла;
Иначе
// Стандартное отображение при круглосуточном режиме
ШкалаСутки.ОтображатьПериодическиеМетки = Истина;
ШкалаСутки.Единица = ТипЕдиницыШкалыВремени.День;
ШкалаЧасы.ОтображатьПериодическиеМетки = Истина;
ШкалаЧасы.Единица = ТипЕдиницыШкалыВремени.Час;
ШкалаМинуты.ОтображатьПериодическиеМетки = Истина;
ШкалаМинуты.Единица = ТипЕдиницыШкалыВремени.Минута;
КонецЕсли;
КонецПроцедуры
Обратите внимание: если на форме включена интерактивная работа с диаграммой (перетаскивание или изменение длительности интервалов пользователем), вам потребуется реализовать обратную функцию пересчета из экранных координат в реальные даты и время документа.
Если математическая модификация временных интервалов не подходит из-за сложности интерактивного редактирования, стандартным подходом в типовых конфигурациях 1С является сохранение реальной шкалы с затемнением нерабочих интервалов.
Для этого используется коллекция ИнтервалыФона объекта диаграммы:
ИнтервалыФона диаграммы, задавая начальную и конечную дату, а также свойство ЦветФона (например, серый цвет или штриховку).Этот вариант не убирает часы физически, но делает визуальное восприятие графика понятным и не искажает реальные интервалы дат в базе данных.
В ситуациях, когда требуется максимальная детализация рабочих интервалов без отображения ночи, эффективным решением является ограничение периода диаграммы ровно одним рабочим днем.
Посмотрим на алгоритм реализации:
НачалоПолногоИнтервала и КонецПолногоИнтервала присваиваются значения времени начала и окончания рабочего дня выбранной даты (например, 01.09.2024 08:00:00 и 01.09.2024 17:00:00).Если встроенных возможностей ДиаграммаГанта недостаточно для комплексного планирования с разрывами времени, рассмотрим альтернативные варианты:
ТабличныйДокумент: создается сетка, где колонками выступают только рабочие часы нужных дней. Интервалы задач формируются объединением ячеек и фоновой заливкой. Это позволяет полностью убрать любые нерабочие часы и выходные дни.ПолеHTMLДокумента и JavaScript-библиотек: график строится в веб-компоненте на базе специализированных библиотек (например, Vis.js Timeline, FullCalendar или DHTMLX Gantt), которые нативно поддерживают скрытие нерабочих часов (work time ranges) и гибкое масштабирование.