Начиная с версии 5.0, Gantt поддерживает настраиваемый макет, который позволяет размещать элементы компонента как внутренние представления внутри макета. Эта функция позволяет добавлять дополнительные временные шкалы и гриды, создавая гибкую структуру диаграммы Gantt с различными способами организации её частей.
Например, вы можете добавить дополнительный грид справа от временной шкалы:
Related sample: Grid columns rightside of gantt
Или разместить ещё один грид и временную шкалу под основными.
Related sample: Gantt chart with resource panel
Макет управляется через настройку gantt.config.layout. Вот конфигурация макета по умолчанию:
gantt.config.layout = {
css: "gantt_container",
rows:[
{
cols: [
{
// основное представление грида
view: "grid",
scrollX:"scrollHor",
scrollY:"scrollVer"
},
{ resizer: true, width: 1 },
{
// основное представление временной шкалы
view: "timeline",
scrollX:"scrollHor",
scrollY:"scrollVer"
},
{
view: "scrollbar",
id:"scrollVer"
}
]},
{
view: "scrollbar",
id:"scrollHor"
}
]
}
Макет Gantt состоит из ячеек, заполненных представлениями. Эти представления отображают основные и вспомогательные элементы Gantt, такие как:
Каждое представление настраивается через объект с соответствующими свойствами. Вы можете настроить параметры для представлений grid и timeline. По умолчанию параметры берутся из глобального объекта gantt.config.
Учтите, что конфигурацию макета необходимо задавать до инициализации Gantt. Если вы изменяете макет после, обновите его с помощью resetLayout.
Скроллбары в макете определяются представлением "scrollbar". Можно использовать как горизонтальные, так и вертикальные скроллбары.
Чтобы добавить скроллбар, свяжите его с нужным представлением, указав в свойствах scrollX или scrollY id скроллбара.
Несколько представлений могут использовать один и тот же скроллбар. Для связывания представления со скроллбаром:
Размещение скроллбара внутри массива cols
создаёт вертикальный скроллбар, а внутри массива rows
— горизонтальный. Также можно явно указать направление прокрутки с помощью свойства scroll:
{ view: "scrollbar", id:"scroller", scroll: "x" } // горизонтальный
или:
{ view: "scrollbar", id:"scroller", scroll: "y" } // вертикальный
Вот пример привязки пользовательских представлений грида и временной шкалы к вертикальному скроллбару:
gantt.config.layout = {
css: "gantt_container",
rows:[
{
cols: [
{
view: "grid",
scrollY:"scrollVer"
},
{ resizer: true, width: 1 },
{
view: "timeline",
scrollY:"scrollVer"
},
{
view: "scrollbar",
id:"scrollVer"
}
]}
]
}
Прокрутка вертикального скроллбара будет перемещать одновременно грид и временную шкалу. В стандартном макете представления грида и временной шкалы связаны как с горизонтальным, так и с вертикальным скроллбарами.
Также можно задать отдельный горизонтальный скроллбар только для грида. Подробнее в соответствующем разделе.
Ранее мы рассмотрели, как добавить один скроллбар к представлению с помощью простой конфигурации макета, например:
{cols: [ {rows: [{}, {}]}, {rows: [{}, {}]}]}
или
{rows: [ {cols: [{}, {}]}, {cols: [{}, {}]}]}
Если вы хотите связать представление и с вертикальным, и с горизонтальным скроллбаром, потребуется более сложный макет с несколькими уровнями вложенности cols
и rows
, например:
{cols: [
{
rows: [
{
cols: [{}, {}]
},
{
cols: [{}, {}]
}
]
},
{
rows: [
{
cols: [{}, {}]
},
{
cols: [
{
rows: [{}, {}]
},
{
rows: [{}, {}]
}
]
}
]
}
]}
Посмотрите эти примеры:
Вы можете изменить макет по умолчанию и задать схему, которая соответствует вашим требованиям, добавляя дополнительные представления в диаграмму Gantt.
Например, чтобы создать панель ресурсов под основной диаграммой Gantt с дополнительными представлениями грида и временной шкалы, выполните следующие шаги:
Пример конфигурации:
gantt.config.layout = {
css: "gantt_container",
rows:[
{
// макет по умолчанию
cols: [
{view: "grid",
config: mainGridConfig, scrollY:"scrollVer"},
{resizer: true, width: 1},
{view: "timeline",
scrollX:"scrollHor", scrollY:"scrollVer"},
{view: "scrollbar", id:"scrollVer"}
]
},
{resizer: true, width: 1},
{
// пользовательский макет
cols: [
{view: "grid", id: "resourceGrid", bind:"resource",
config:resourceGridConfig, scrollY:"resourceVScroll"},
{resizer: true, width: 1},
{view:"timeline", id:"resourceTimeline", scrollX:"scrollHor",
bind:"resource", bindLinks: null, layers: resourceLayers,
scrollY:"resourceVScroll"},
{view: "scrollbar", id:"resourceVScroll"}
]
},
{view: "scrollbar", id:"scrollHor"}
]
};
В этом примере дополнительный грид отображает ресурсы и их загрузку, а дополнительная временная шкала показывает распределение рабочих часов по месяцам с выделением стандартных и сверхурочных часов.
Пользовательские представления grid и timeline содержат дополнительные свойства:
Чтобы заполнить пользовательские представления нужными данными, необходимо добавить отдельное хранилище данных. Создание нового хранилища выполняется с помощью метода
createDatastore, где вы указываете конфигурацию хранилища данных:
var resourcesStore = gantt.createDatastore({
name:"resource",
initItem: function(item){
item.id = item.key || gantt.uid();
return item;
}
});
В этом примере создаётся хранилище данных с именем "resource".
Для загрузки данных из хранилища в пользовательские представления используется метод parse:
resourcesStore.parse([// resources
{key:'0', label: "N/A"},
{key:'1', label: "John"},
{key:'2', label: "Mike"},
{key:'3', label: "Anna"}
]);
Чтобы получить объект конфигурации определённого хранилища данных, используйте метод getDatastore:
var tasksStore = gantt.getDatastore("task");
Этот метод принимает имя хранилища данных в качестве параметра.
При использовании встроенных представлений ресурсов Gantt может создавать хранилище данных автоматически. Подробнее здесь.
Иногда требуется динамически отключать разделители между ячейками Gantt. Самый простой способ сделать это — скрыть их с помощью CSS.
Вы можете использовать такое CSS-правило:
.no_resizers .gantt_resizer{
display:none;
}
Далее добавьте этот класс к контейнеру Gantt, чтобы скрыть разделители:
gantt.$container.classList.add("no_resizers");
Чтобы вернуть разделители, просто удалите класс:
gantt.$container.classList.remove("no_resizers");
Пользовательский HTML также может использоваться в качестве внутренних представлений внутри макета Gantt. Пример:
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{view: "grid",scrollX: "scrollHor", scrollY: "scrollVer"},
{ html:"<div class='custom-content'>custom content</div>",
css:"custom-content", width:50},
{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{ html:"<div class='custom-content'>custom content</div>",
css:"custom-content", width:50},
{view: "scrollbar", id: "scrollVer"}
]
},
{view: "scrollbar", scroll: "x", id: "scrollHor"}
]
}
Публичный API объекта gantt включает методы, связанные с определёнными представлениями макета, такими как getTaskPosition, getTaskNode и getScrollState.
Для корректной работы этих методов макет должен включать стандартные грид, временную шкалу, полосы прокрутки, и Gantt должен иметь возможность их найти. Это достигается назначением определённых id стандартным представлениям:
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{view: "grid", id: "grid", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "timeline", id: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "scrollbar", id: "scrollVer"}
]
},
{view: "scrollbar", id: "scrollHor"}
]
};
Обязательные представления и их id:
Если id не задан, Gantt либо использует имя представления в качестве id по умолчанию, либо сгенерирует уникальный автоматически. Поэтому для стандартных грид и timeline параметр "id" можно не указывать:
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{view: "grid", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "scrollbar", id: "scrollVer"}
]
},
{view: "scrollbar", id: "scrollHor"}
]
};
Вы можете добавить любое количество дополнительных представлений в макет.
Грид и Timeline используют шаблоны и конфигурацию из глобальных gantt.config/gantt.templates. Однако их можно переопределить для конкретных представлений на уровне макета.
Например:
var secondGridColumns = {
columns: [
{
name: "status", label: "Status", width: 60, align: "center",
template: function (task) {
var progress = task.progress || 0;
return Math.floor(progress * 100) + "";
}
},
{
name: "impact", width: 80, label: "Impact", template: function (task) {
return (task.duration * 1000).toLocaleString("en-US", {
style: 'currency', currency: 'USD'
});
}
}
]
};
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{view: "grid", id: "grid", width: 320, scrollY: "scrollVer"},
{resizer: true, width: 1},
{view: "timeline", id: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{resizer: true, width: 1},
{view: "grid", width: 120, bind:"task",
scrollY:"scrollVer", config:secondGridColumns}, {view: "scrollbar", scroll: "y", id: "scrollVer"}
]
},
{view: "scrollbar", id: "scrollHor", height: 20}
]
};
Представления также могут наследовать конфигурацию и шаблоны от родительского макета:
var resourceConfig = { scale_height: 30 };
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{view: "grid", group:"grids", scrollY: "scrollVer"},
{resizer: true, width: 1},
{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "scrollbar", id: "scrollVer", group:"vertical"}
],
gravity:2
},
{resizer: true, width: 1},
{
config: resourceConfig, cols: [
{view: "resourceGrid", group:"grids", width: 435, scrollY: "resourceVScroll" },
{resizer: true, width: 1},
{view: "resourceTimeline", scrollX: "scrollHor", scrollY: "resourceVScroll"},
{view: "scrollbar", id: "resourceVScroll", group:"vertical"}
],
gravity:1
},
{view: "scrollbar", id: "scrollHor"}
]
};
Более подробную информацию смотрите в статье Resource Management.
Иногда бывает полезно синхронизировать видимость определённых элементов макета. Например, если есть горизонтальные полосы прокрутки в соседних ячейках, возможно, вы захотите, чтобы обе отображались или скрывались одновременно.
Related sample: Horizontal scroll inside Grid
Другой пример — несколько гридов в разных строках временной шкалы, которые должны иметь одинаковую ширину. Когда один грид изменяет размер, другие также должны подстраиваться.
Related sample: Resource load diagram
Обе эти задачи решаются с помощью свойства group в представлении. Это свойство принимает любую строку, и представления с одинаковым значением group будут синхронизированы.
Пример синхронизации видимости полос прокрутки:
gantt.config.layout = {
css: "gantt_container",
cols: [
{
width:400,
minWidth: 200,
maxWidth: 600,
rows:[
{view: "grid", scrollX: "gridScroll", scrollable: true, scrollY: "scrollVer"},
{view: "scrollbar", id: "gridScroll", group:"horizontal"} ]
},
{resizer: true, width: 1},
{
rows:[
{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "scrollbar", id: "scrollHor", group:"horizontal"} ]
},
{view: "scrollbar", id: "scrollVer"}
]
};
Пример синхронизации ширины гридов:
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{view: "grid", group:"grids", scrollY: "scrollVer"},
{resizer: true, width: 1},
{view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"},
{view: "scrollbar", id: "scrollVer", group:"vertical"} ],
gravity:2
},
{resizer: true, width: 1},
{
config: resourceConfig,
cols: [
{view: "resourceGrid", group:"grids", width: 435, scrollY: "resourceVScroll" },
{resizer: true, width: 1},
{view: "resourceTimeline", scrollX: "scrollHor", scrollY: "resourceVScroll"},
{view: "scrollbar", id: "resourceVScroll", group:"vertical"} ],
gravity:1
},
{view: "scrollbar", id: "scrollHor"}
]
};
Относительные размеры ячеек макета Gantt можно управлять с помощью свойства gravity в конфигурации каждой ячейки. Это значение определяет пропорцию размеров между ячейками.
gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
// columns config
],
gravity:2 },
{ resizer: true, width: 1 },
{
config: resourceConfig,
cols: [
// columns config
],
gravity:1 },
{view: "scrollbar", id: "scrollHor"}
]
};
В этом примере Gantt и диаграмма ресурсов делят пространство в пропорции 2:1. То есть, Gantt занимает примерно 66%, а диаграмма ресурсов — около 33%. Использование пропорции 1:1 разделит пространство поровну.
Чтобы ограничить размер частей макета при изменении размера, используйте свойства minWidth/maxWidth для ячеек внутри массива cols. Аналогично, minHeight/maxHeight можно задать для ячеек в массиве rows для ограничения высоты.
Пример использования minWidth/maxWidth в конфигурации колонок:
gantt.config.grid_elastic_columns = true;
gantt.config.layout = {
css: "gantt_container",
cols: [
{
width: 400,
minWidth: 200, maxWidth: 600, rows: [
{
view: "grid", scrollable: true, scrollX: "scrollHor1", scrollY: "scrollVer"
},
{
view: "scrollbar", id: "scrollHor1", scroll: 'x', group: 'hor'
},
]
},
{ resizer: true, width: 1 },
{
rows: [
{
view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer"
},
{
view: "scrollbar", id: "scrollHor", scroll: 'x', group: 'hor'
},
]
},
{
view: "scrollbar", id: "scrollVer"
}
]
}
Если нужно скрыть представление макета при скрытии всех его дочерних представлений, задайте hide_empty:true в конфигурации этой ячейки макета, например:
gantt.config.layout = {
css: "gantt_container",
cols: [
{
hide_empty: true, rows:[
{view: "grid"}
]
},
{resizer: true},
{
hide_empty: true, rows:[
{view: "timeline"}
]
}
]
};
Related sample: Скрытие grid/timeline представлений
Для переключения между разными представлениями макета смотрите разделы Решения: Переключение grid/диаграммы и Решения: Переключение представления ресурсов.
Можно инициализировать Gantt с одной или несколькими замороженными колонками. Инструкции по этому вопросу смотрите в разделе Решения: Как заморозить/зафиксировать колонки в grid.
К началу