In der Standardlayout-Konfiguration ist es einfach, zwischen Gitter- und Diagrammansichten umzuschalten. Sie müssen nur die Optionen show_grid oder show_chart anpassen und dann die Methode render() aufrufen, um die Änderungen anzuwenden.
function toggleGrid(){
gantt.config.show_grid = !gantt.config.show_grid;
gantt.render();
}
Related sample: Gantt. Toggle grid (default layout)
function toggleChart(){
gantt.config.show_chart = !gantt.config.show_chart;
gantt.render();
}
Related sample: Gantt. Toggle timeline (default layout)
Wenn Sie mit einem benutzerdefinierten Layout arbeiten, benötigen Sie separate Konfigurationen für Layouts mit und ohne Gitter oder Zeitachse. Um zwischen ihnen zu wechseln, aktualisieren Sie die Eigenschaft gantt.config.layout und initialisieren Sie Gantt erneut mit der Methode init().
let showGrid = true;
function toggleGrid() {
showGrid = !showGrid;
if (showGrid) {
gantt.config.layout = gridAndChart; // Layout mit Gitter und Zeitachse
} else {
gantt.config.layout = onlyChart; // Layout nur mit der Zeitachse
}
gantt.init("gantt_here");
}
Related sample: Gantt. Toggle grid (custom layout)
let showChart = true;
function toggleChart() {
showChart = !showChart;
if (showChart) {
gantt.config.layout = gridAndChart; // Layout mit Gitter und Zeitachse
} else {
gantt.config.layout = onlyGrid; // Layout nur mit dem Gitter
}
gantt.init("gantt_here");
}
Related sample: Gantt. Toggle timeline (custom layout)
Ähnlich wie beim Umschalten zwischen Gitter- und Diagrammansichten können Sie Ressourcenansichten verwalten, indem Sie verschiedene Layoutkonfigurationen einrichten. Sie passen die Eigenschaft gantt.config.layout an und aktualisieren Gantt mit der Methode init().
let resourceChart = true;
function layoutChange() {
resourceChart = !resourceChart;
gantt.config.layout = resourceChart ? resourceLayout : noresourceLayout;
gantt.init("gantt_here");
};
Related sample: Gantt. Toggle resource load diagram
let histogramView = true;
function layoutChange() {
histogramView = !histogramView;
gantt.config.layout = histogramView ? histogramLayout : simpleLayout;
gantt.init("gantt_here");
};
Related sample: Gantt. Toggle resource histogram
Alternativ können Sie dynamisch ein Layout mithilfe von Layoutansichten generieren und Gantt neu initialisieren, um die Änderungen widerzuspiegeln.
Related sample: Gantt. Generate layout
Um unendliches Scrollen umzusetzen, müssen Sie wahrscheinlich den angezeigten Datumsbereich mithilfe der Eigenschaften gantt.config.start_date und gantt.config.end_date anpassen.
Verfolgen Sie die Scrollposition und erweitern Sie den Datumsbereich bei Bedarf. Beachten Sie, dass häufiges Neuzeichnen mit render() die Leistung beeinträchtigen kann, daher ist es besser, dies mit einer Verzögerung zu tun.
gantt.init("gantt_here");
gantt.parse(tasks);
gantt.attachEvent("onGanttScroll", function (left, top) {
const left_date = gantt.dateFromPos(left);
const right_date = gantt.dateFromPos(left + gantt.$task.offsetWidth);
gantt.config.start_date = gantt.config.start_date || gantt.getState().min_date;
gantt.config.end_date = gantt.config.end_date || gantt.getState().max_date;
const min_allowed_date = gantt.date.add(gantt.config.start_date, 1, "day");
const max_allowed_date = gantt.date.add(gantt.config.end_date, -2, "day");
let repaint = false;
if (+left_date <= +min_allowed_date) {
gantt.config.start_date = gantt.date.add(gantt.config.start_date, -2, "day");
repaint = true;
}
if (+right_date >= +max_allowed_date) {
gantt.config.end_date = gantt.date.add(gantt.config.end_date, 2, "day");
repaint = true;
}
if (repaint) {
setTimeout(function () {
gantt.render();
gantt.showDate(left_date);
}, 20);
}
});
Related sample: Gantt. Infinite scroll while using scrollbar
Überprüfen Sie die Scrollposition während des Ziehens und erweitern Sie den Datumsbereich, wenn sie sich in der Nähe der Kanten der Zeitachse befindet.
gantt.attachEvent("onMouseMove", function (id, e) {
if (!gantt.getState().drag_id && e.buttons == 1) {
const left_date = gantt.dateFromPos(gantt.getScrollState().x);
const right_date = gantt.dateFromPos(
gantt.getScrollState().x + gantt.$task.offsetWidth - 1
);
if (left_date && +left_date <= +gantt.config.start_date) {
gantt.config.start_date = gantt.date.add(gantt.config.start_date, -1, 'day');
gantt.render();
}
if (right_date && +gantt.config.end_date < +gantt.date.add(right_date, 1, 'day')) {
gantt.config.end_date = gantt.date.add(gantt.config.end_date, 1, 'day');
gantt.render();
}
}
});
Related sample: Gantt. Infinite scroll while dragging the timeline
Wenn kein Datumsbereich festgelegt ist, rufen Sie einfach render() auf, wenn eine Aufgabe in der Nähe der Kanten der Zeitachse gezogen wird.
gantt.init("gantt_here");
gantt.parse(tasks);
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
if (task.start_date <= gantt.getState().min_date ||
task.end_date >= gantt.getState().max_date) {
gantt.render();
}
});
Related sample: Gantt. Infinite scroll while dragging a task (default range settings)
Wenn Sie einen festgelegten Datumsbereich haben, passen Sie ihn bei Bedarf an.
gantt.init("gantt_here");
gantt.parse(tasks);
gantt.config.start_date = new Date(2025, 02, 28);
gantt.config.end_date = new Date(2025, 03, 10);
gantt.render();
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
if (+task.start_date <= +gantt.config.start_date) {
gantt.config.start_date = gantt.date.add(
gantt.config.start_date, -1, gantt.config.duration_unit
);
gantt.render();
}
if (+task.end_date >= +gantt.config.end_date) {
gantt.config.end_date = gantt.date.add(
gantt.config.end_date, 1, gantt.config.duration_unit
);
gantt.render();
}
});
Related sample: Gantt. Infinite scroll while dragging a task (explicit range settings)
Sie können das Ereignis onGanttScroll verwenden, um zu erkennen, wann Sie die letzte sichtbare Aufgabe erreicht haben, und weitere Aufgaben mit der Methode parse() laden.
gantt.attachEvent("onGanttScroll", function (left, top) {
const visibleTasks = gantt.getVisibleTaskCount();
const lastVisibleTask = gantt.getTaskByIndex(visibleTasks - 1);
if (gantt.getTaskRowNode(lastVisibleTask.id)) {
const tasks = load_tasks();
gantt.parse(tasks);
}
});
Related sample: Gantt. Load data dynamically
Um alle Aufgaben zu öffnen oder zu schließen, verwenden Sie die Methoden open() und close() innerhalb der Funktion eachTask(). Das Einwickeln in batchUpdate() stellt sicher, dass das Diagramm nur einmal aktualisiert wird.
function collapseAll() {
gantt.batchUpdate(function () {
gantt.eachTask(function (task) {
gantt.close(task.id);
});
});
}
function expandAll() {
gantt.batchUpdate(function () {
gantt.eachTask(function (task) {
gantt.open(task.id);
});
});
}
Related sample: Gantt. Add collapse/expand buttons into Gantt header
Related sample: Gantt. Collapse/expand all tasks
Um mehrzeiligen Text im Gitterkopf zu aktivieren, können Sie folgendes CSS hinzufügen:
.gantt_grid_head_text {
line-height: 12px;
white-space: normal;
}
Related sample: Gantt. Multiline text in the grid header
Für Gitterzellen verwenden Sie dieses CSS:
.gantt_tree_content, .gantt_task_content {
line-height: 12px;
white-space: normal;
overflow-wrap: break-word;
}
Related sample: Gantt. Multiline text in Grid cells and Timeline
Related sample: Gantt. Multiline text in cells of a Grid column
Um eine benutzerdefinierte Spalte hinzuzufügen, ändern Sie den Parameter gantt.config.columns. Die Eigenschaft name sollte mit der Aufgaben-Eigenschaft übereinstimmen, die Sie anzeigen möchten, oder Sie können die Funktion template() für benutzerdefinierte Inhalte verwenden.
gantt.config.columns = [
/*
andere Spalten
*/
{
name: "progress", label: "Fortschritt", width: 50, resize: true, align: "center",
template: function (task) {
return Math.round(task.progress * 100) + "%";
}
},
/*
andere Spalten
*/
];
Related sample: Gantt. Custom column with template for task progress
Related sample: Gantt. Custom column with template for action buttons
Um eine benutzerdefinierte Hinzufügen-Schaltfläche zu erstellen, definieren Sie eine Spalte im Parameter gantt.config.columns. Vermeiden Sie es, sie add zu nennen, um das Standardverhalten zu verhindern. Verwenden Sie die Funktion template, um eine HTML-Schaltfläche mit einem benutzerdefinierten Klick-Handler zurückzugeben.
gantt.config.columns = [
/*
andere Spalten
*/
{
name: "add_tasks", label: "+", width: 50, resize: true, align: "center",
template: function (task) {
return `<button onclick='addTask(${task.id})';>`;
}
},
];
Related sample: Gantt. Custom columns with templates for add (+) buttons
Um eine benutzerdefinierte Skala zu erstellen, müssen Sie eine benutzerdefinierte Skalaeinheit definieren und die Logik für die Berechnung von Daten implementieren.
Hier ist ein Beispiel für das Erstellen einer benutzerdefinierten Skala für Arbeitsschichtstunden (06:30, 18:30):
gantt.date.custom_scale_start = function (date) {
return date;
};
gantt.date.add_custom_scale = function (date, inc) {
let next = new Date(date)
if (!next.getMinutes()) {
gantt.date.day_start(next)
next = gantt.date.add(next, 6, "hour");
next = gantt.date.add(next, 30, "minute");
}
else {
next = gantt.date.add(next, 12 * inc, "hour");
}
return next
};
gantt.config.scales = [
{ unit: "day", step: 1, date: "%d" },
{ unit: "custom_scale", step: 1, date: "%H:%i" },
];
Related sample: Gantt. Custom work shift hours on the scale
Hier ist ein weiteres Beispiel, bei dem Zahlen anstelle von Tagen verwendet werden:
gantt.config.scales = [
{
unit: "day", step: 1, format: function (date) {
return gantt.getScale().trace_indexes[+date] + 1
}
}
]
Related sample: Gantt. Numbers of days on the scale
Um eine benutzerdefinierte Skala für 5-Tage-Arbeitswochen zu erstellen, können Sie das folgende Beispiel verwenden:
const weekScaleTemplate = function (date) {
const dateToStr = gantt.date.date_to_str("%d");
const endDate = gantt.date.add(gantt.date.add(date, 5, "day"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
};
gantt.date.five_days_start = function (date) {
return date;
};
gantt.date.add_five_days = function (date, inc) {
if (date.getDay() == 0 || date.getDay() == 6) {
return gantt.date.add(date, 1 * inc, "day");
}
gantt.date.week_start(date);
return gantt.date.add(date, 5 * inc, "day");
};
gantt.config.scales = [
{ unit: "month", step: 1, format: "%F, %Y" },
{ unit: "five_days", step: 1, format: weekScaleTemplate },
];
gantt.ignore_time = function (date) {
return date.getDay() == 0 || date.getDay() == 6;
};
Related sample: 5-day work weeks on the scale
Für eine benutzerdefinierte Skala, die Wochen des Jahres anzeigt (beginnend mit dem ersten Tag des Jahres), hilft Ihnen dieses Beispiel:
gantt.date.custom_week_start = function (date) {
return date;
};
gantt.date.add_custom_week = function (date, inc) {
const year_start = new Date(date);
gantt.date.year_start(year_start);
const week_number = Math.round(gantt.calculateDuration(year_start, date) / 7);
const next_week = gantt.date.add(year_start, week_number + 1, "week");
if (next_week.getYear() != date.getYear()) {
gantt.date.year_start(next_week)
}
return next_week;
};
const custom_week_template = function (date) {
const year_start = gantt.date.year_start(new Date(date));
const week_number = Math.round(gantt.calculateDuration(year_start, date) / 7) + 1;
return "Week:" + week_number
}
gantt.config.scales = [
{ unit: 'custom_week', step: 1, template: custom_week_template },
{ unit: 'day', step: 1, format: "%d, %M" },
];
Related sample: Gantt. Weeks of the year on the scale
Um Aufgaben zu duplizieren, erstellt die Methode copy() eine tiefe Kopie eines Aufgabenobjekts. Sie können dann die ID der kopierten Aufgabe ändern und sie mit addTask() oder createTask() hinzufügen.
Hier ist, wie Sie eine Schaltfläche zum Klonen einer Aufgabe hinzufügen:
function clone_task(id) {
const task = gantt.getTask(id);
const clone = gantt.copy(task);
clone.id = +(new Date());
gantt.addTask(clone, clone.parent, clone.$index)
}
gantt.config.columns = [
/*
andere Spalten
*/
{
name: "clone", label: "clone", width: 44, template: function (task) {
return "<input type=button value='V' onclick=clone_task(" + task.id + ")>"
}
}
];
Related sample: Gantt. Clone a task
Hier ist ein Beispiel, um eine Aufgabe zusammen mit allen ihren Unteraufgaben und Links zu klonen:
let child_links;
let clone_original_ids_table;
function obtain_link_ids(id) {
const task = gantt.getTask(id);
const source_links = task.$source;
for (let i = 0; i < source_links.length; i++) {
child_links.push(source_links[i]);
}
}
function create_clone_original_ids_table(original_id, clone_id) {
clone_original_ids_table[original_id] = clone_id;
}
function clone_child_links() {
for (let i = 0; i < child_links.length; i++) {
const link = gantt.getLink(child_links[i]);
if (clone_original_ids_table[link.source] && clone_original_ids_table[link.target]){
const clone_link = {};
clone_link.id = gantt.uid();
clone_link.target = clone_original_ids_table[link.target];
clone_link.source = clone_original_ids_table[link.source];
clone_link.type = link.type;
gantt.addLink(clone_link)
}
}
}
function clone_children(id, new_parent) {
const children = gantt.getChildren(id)
for (let i = 0; i < children.length; i++) {
const child_original = gantt.getTask(children[i]);
const child_clone = gantt.copy(child_original);
child_clone.id = gantt.uid();
child_clone.parent = new_parent;
gantt.addTask(child_clone, child_clone.parent, child_clone.$index);
obtain_link_ids(child_original.id);
create_clone_original_ids_table(child_original.id, child_clone.id);
if (gantt.hasChild(child_original.id)) clone_children(
child_original.id, child_clone.id
);
}
}
function clone_task(id) {
const task = gantt.getTask(id);
const clone = gantt.copy(task);
clone.id = gantt.uid();
gantt.addTask(clone, clone.parent, clone.$index);
child_links = [];
obtain_link_ids(id);
clone_original_ids_table = {};
create_clone_original_ids_table(task.id, clone.id);
if (gantt.hasChild(id)) {
clone_children(id, clone.id)
}
clone_child_links()
}
gantt.config.order_branch = true;
gantt.config.order_branch_free = true;
gantt.config.columns = [
/*
andere Spalten
*/
{
name: "clone", label: "clone", width: 44, template: function (task) {
return "<input type=button value='V' onclick=clone_task(" + task.id + ")>"
}
}
];
Related sample: Gantt. Clone a task with all its subtasks and links
Hier ist, wie Sie das Kopieren über Tastenkombinationen aktivieren können (Ctrl + C zum Kopieren, Ctrl + V zum Einfügen als Kinder):
gantt.plugins({
keyboard_navigation: true,
multiselect: true,
})
let tasks_to_copy = [];
gantt.ext.keyboardNavigation.addShortcut("ctrl+c", function (e) {
tasks_to_copy = [];
gantt.eachSelectedTask(function (task_id) {
tasks_to_copy.push(task_id);
});
}, "taskRow");
gantt.ext.keyboardNavigation.addShortcut("ctrl+v", function (e) {
const new_parent = gantt.getSelectedId();
for (let i = 0; i < tasks_to_copy.length; i++) {
const task = gantt.copy(gantt.getTask(tasks_to_copy[i]));
task.id = +new Date() + '+' + Math.floor(Math.random() * 10);
gantt.addTask(task, new_parent)
}
gantt.getTask(new_parent).$open = true;
gantt.render()
}, "taskRow");
Related sample: Gantt. Copy and paste tasks via Ctrl+C, Ctrl+V
Um benutzerdefinierte Stile oder zusätzliche Elemente in ein exportiertes PDF einzufügen, verwenden Sie den raw-Modus und fügen Sie die Stile in die header- oder footer-Parameter ein.
Zum Beispiel können Sie Stile in einer Variablen speichern und in die Kopfzeile einfügen:
const header = `
.gantt_bar_task {
background: orange;
}
.gantt_task_progress {
background-color: rgba(33, 33, 33, 0.17);
}
`
gantt.exportToPDF({
header: "<style>" + header + "</style>"
});
Related sample: Gantt. Export Gantt to PDF (styles from a variable)
Alternativ können Sie Stile aus einem <style>
-Element auf der Seite extrahieren:
gantt.exportToPDF({
raw: true,
header: "<style>" + document.getElementById("styles").innerHTML + "</style>"
});
<style id='styles'>
.gantt_bar_task {
background: orange;
}
.gantt_task_progress {
background-color: rgba(33, 33, 33, 0.17);
}
</style>
Related sample: Gantt. Export Gantt to PDF (styles from <style> element)
Related sample: Gantt. Export Gantt with custom icons to PDF
Um eine Legende in das exportierte PDF einzufügen:
Related sample: Gantt. Export Gantt with legend to PDF
Für den Export von Ressourcendiagrammen oder Histogrammen:
Related sample: Gantt. Export Gantt with resource load diagram to PDF
Related sample: Gantt. Export Gantt with resource histogram to PDF
Ein einfacher Weg, den Fortschritt einer übergeordneten Aufgabe zu ermitteln, ist, ihn jedes Mal neu zu berechnen, wenn eine untergeordnete Aufgabe aktualisiert wird. Die Methode eachParent() ist nützlich, um übergeordnete Aufgaben zu durchlaufen.
Hier ist ein Beispiel, bei dem der Fortschritt übergeordneter Aufgaben ausschließlich durch den Fortschritt ihrer untergeordneten Aufgaben bestimmt wird:
gantt.config.auto_types = true;
gantt.templates.progress_text = function (start, end, task) {
return "<span style='text-align:left;'>" + Math.round(task.progress * 100)
+ "% </span>";
};
gantt.init("gantt_here");
gantt.parse({
"data": [
...
]
});
gantt.attachEvent("onAfterTaskUpdate", function (id, task) {
parentProgress(id)
});
gantt.attachEvent("onTaskDrag", function (id, mode, task, original) {
if (mode == "progress") {
parentProgress(id)
}
});
gantt.attachEvent("onAfterTaskAdd", function (id) {
parentProgress(id)
});
gantt.attachEvent("onAfterTaskDelete", function (id, task) {
if (task.parent) {
const siblings = gantt.getChildren(task.parent);
if (siblings.length) {
parentProgress(siblings[0])
}
}
});
function parentProgress(id) {
gantt.eachParent(function (task) {
const children = gantt.getChildren(task.id);
let childProgress = 0;
for (let i = 0; i < children.length; i++) {
const child = gantt.getTask(children[i])
childProgress += (child.progress * 100);
}
task.progress = childProgress / children.length / 100;
}, id)
gantt.render();
}
Related sample: Gantt. Calculate progress of a parent task dynamically
In einem anderen Szenario kann der Fortschritt übergeordneter Aufgaben sowohl vom Fortschritt als auch von der Dauer der untergeordneten Aufgaben abhängen:
function calculateSummaryProgress(task) {
if (task.type != gantt.config.types.project)
return task.progress;
var totalToDo = 0;
var totalDone = 0;
gantt.eachTask(function (child) {
if (child.type != gantt.config.types.project) {
totalToDo += child.duration;
totalDone += (child.progress || 0) * child.duration;
}
}, task.id);
if (!totalToDo) return 0;
else return totalDone / totalToDo;
}
function refreshSummaryProgress(id, submit) {
if (!gantt.isTaskExists(id))
return;
var task = gantt.getTask(id);
var newProgress = calculateSummaryProgress(task);
if (newProgress !== task.progress) {
task.progress = newProgress;
if (!submit) {
gantt.refreshTask(id);
} else {
gantt.updateTask(id);
}
}
if (!submit && gantt.getParent(id) !== gantt.config.root_id) {
refreshSummaryProgress(gantt.getParent(id), submit);
}
}
gantt.attachEvent("onParse", function () {
gantt.eachTask(function (task) {
task.progress = calculateSummaryProgress(task);
});
});
gantt.attachEvent("onAfterTaskUpdate", function (id) {
refreshSummaryProgress(gantt.getParent(id), true);
});
gantt.attachEvent("onTaskDrag", function (id) {
refreshSummaryProgress(gantt.getParent(id), false);
});
gantt.attachEvent("onAfterTaskAdd", function (id) {
refreshSummaryProgress(gantt.getParent(id), true);
});
(function () {
var idParentBeforeDeleteTask = 0;
gantt.attachEvent("onBeforeTaskDelete", function (id) {
idParentBeforeDeleteTask = gantt.getParent(id);
});
gantt.attachEvent("onAfterTaskDelete", function () {
refreshSummaryProgress(idParentBeforeDeleteTask, true);
});
})();
...
gantt.config.auto_types = true;
gantt.templates.progress_text = function (start, end, task) {
return "<span style='text-align:left;'>" + Math.round(task.progress * 100)
+ "% </span>";
};
gantt.templates.task_class = function (start, end, task) {
if (task.type == gantt.config.types.project)
return "hide_project_progress_drag";
};
Related sample: Calculate Progress of Summary Tasks
Die Methode addTaskLayer() ermöglicht das Anzeigen benutzerdefinierter HTML-Elemente in der Zeitleiste und damit das vertikale und horizontale Ziehen von Aufgaben.
Hier ist, wie Sie eine Standardaufgabe im Gitter neu anordnen können:
Related sample: Gantt. Reorder tasks vertically in timeline
Für geteilte Aufgaben können Sie diese neu anordnen und sogar mehrere Aufgaben in derselben Zeile platzieren:
Related sample: Gantt. Reorder split tasks vertically in timeline
Das Fixieren von Spalten im Gitter kann mit CSS erreicht werden. Die Spalte, die Sie fixieren möchten, sollte eine 'relative' Position haben. Ihr 'left'-Parameter sollte der Scrollposition entsprechen und kann dynamisch über einen Scroll-Event-Handler aktualisiert werden:
gantt.attachEvent("onGanttReady", function () {
const el = document.querySelector(".gantt_hor_scroll");
if (el) {
el.addEventListener('scroll', function () {
document.documentElement.style.setProperty(
'--gantt-frozen-column-scroll-left', el.scrollLeft + "px"
);
});
}
});
const textEditor = { type: "text", map_to: "text" };
const start_dateEditor = { type: "date", map_to: "start_date" };
const end_dateEditor = { type: "date", map_to: "end_date" };
const durationEditor = { type: "number", map_to: "duration", min: 0, max: 100 };
gantt.config.columns = [
{ name: "text", tree: true, width: 150, resize: true, editor: textEditor },
{ name: "start_date", align: "center", width: 120, resize: true,
editor: start_dateEditor },
{ name: "end_date", label: "End Time", align: "center", width: 120,
resize: true, editor: end_dateEditor },
{ name: "duration", align: "center", width: 80, resize: true,
editor: durationEditor },
{ name: "progress", label: "Progress", width: 80, align: "center",
resize: true },
{
name: "custom", label: "Custom", width: 180, align: "center",
resize: true, template: function (task) {
return Math.round(Math.random() * 100)
}
},
{ name: "add", width: 44 }
];
gantt.config.layout = {
css: "gantt_container",
cols: [
{
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" }
]
}
CSS-Anpassungen für fixierte Spalten:
:root {
--gantt-frozen-column-scroll-left: 0px;
}
.gantt_cell:nth-child(1),
.gantt_grid_head_cell:nth-child(1) {
background: Azure;
position: relative;
left: var(--gantt-frozen-column-scroll-left);
}
.gantt_grid_editor_placeholder[data-column-name="text"] {
left: var(--gantt-frozen-column-scroll-left) !important;
}
.gantt_grid_head_cell:nth-child(1) {
z-index: 1;
}
Related sample: Gantt. Frozen column in Grid (via CSS)
Alternativ können Sie mehrere Gitteransichten verwenden, obwohl es möglicherweise nicht nahtlos mit Inline-Editoren funktioniert:
gantt.config.columns = [
{ name: "start_date", align: "center", width: 80, resize: true },
{ name: "end_date", label: "End Date", align: "center", width: 80, resize: true },
{ name: "duration", width: 60, align: "center", resize: true },
{ name: "progress", label: "Progress", width: 60, align: "center", resize: true },
{ name: "add", width: 44 }
];
const fixedColumn = {
columns: [
{ name: "text", tree: true, width: 200, resize: true },
]
};
gantt.config.layout = {
css: "gantt_container",
cols: [
{
width: 400,
//min_width: 100,
rows: [
{
group: "gantt",
cols: [
{
rows: [
{ view: 'grid', config: fixedColumn, bind: "task",
scrollY: 'gridScrollY' }
]
},
{
rows: [
{ view: 'grid', bind: "task", scrollX: 'gridScrollX',
scrollable: true, scrollY: 'gridScrollY' },
{ view: 'scrollbar', id: 'gridScrollX' }
]
},
{ view: 'scrollbar', id: 'gridScrollY' }
]
}
]
},
{ resizer: true, width: 1 },
{
rows: [
{
group: "gantt",
cols: [
{
rows: [
{ view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
{ view: "scrollbar", id: "scrollHor" }
]
},
{ view: 'scrollbar', id: 'scrollVer' }
]
}
]
}
]
}
Related sample: Gantt. Fixed column in Grid (several grid views)
Während es keine direkte Funktion zum Hinzufügen einer Legende zum Gantt gibt, können Sie eine manuell erstellen. Die Overlay-Erweiterung könnte etwas ähnlich sein, bietet jedoch nicht viel Flexibilität.
Um eine Legende hinzuzufügen, können Sie ein HTML-Element dafür erstellen und es in den Gantt-Container einfügen:
gantt.$root.appendChild(legend);
Hier ist ein funktionierendes Beispiel, bei dem Sie die Legende durch Klicken auf die Schaltfläche "Legende umschalten" ein- und ausschalten können:
Related sample: Gantt. Add information legend
Für interaktive Legenden können Sie Ereignislistener direkt an das Legenden-Element anhängen oder Ereignisdelegation auf Gantt-Root-Ebene verwenden:
gantt.event(gantt.$root, "click", function(e){
var closest = gantt.utils.dom.closest;
if(closest(e.target, ".gantt-legend")) {
gantt.message("Mouse click inside the legend element");
}
});
Zurück nach oben