Sie können Skalen über die Eigenschaft scales konfigurieren. Es ist möglich, mehrere Skalen zu definieren, indem Sie Skalenobjekte zum scales-Array in der Konfiguration hinzufügen:
// eine einzelne Tagesskala
gantt.config.scales = [
{unit: "day", step: 1, format: "%j, %D"}
];
// mehrere Skalen gleichzeitig
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: weekScaleTemplate},
{unit: "day", step:1, format: "%D", css:daysStyle }
];
Sie können folgende Aspekte der Zeitskala (X-Achse) anpassen:
Es besteht außerdem die Möglichkeit, eine benutzerdefinierte Skala hinzuzufügen.
Um die Einheit für die Skala festzulegen, verwenden Sie die Eigenschaft unit im Skalenobjekt:
Verfügbare Werte sind: "minute", "hour", "day" (Standard), "week", "quarter", "month" und "year".
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "day", step: 1, format: "%j, %D"}
];
gantt.init("gantt_here");
Wenn der Datumsbereich nicht explizit angegeben wird, übernimmt Gantt die Daten aus den geladenen Aufgaben und fügt vor der ersten und nach der letzten Aufgabe im Zeitmaßstab einige Offsets hinzu. Diese Offsets hängen von den Einstellungen des Zeitmaßstabs ab.
Basierend auf dem Wert von scale_offset_minimal ist das Offset entweder die Zeiteinheit, die durch das unit-Attribut in der Option scales definiert ist, oder die kleinste Einheit des Zeitmaßstabs.
Den aktuell angezeigten Datumsbereich können Sie programmatisch mit der Methode getState abrufen.
var state = gantt.getState();
console.log(state.min_date);
// -> Mon Jan 01 2018 00:00:00
console.log(state.max_date);
// -> Tue Jan 01 2019 00:00:00
Der Maßstabsbereich wird beim Gantt-Rendering neu berechnet. Wenn ein Benutzer eine Aufgabe außerhalb des sichtbaren Zeitbereichs verschiebt, bleibt die Aufgabenzeile sichtbar, aber das Balkenelement wird erst wieder angezeigt, wenn das gesamte Diagramm neu gerendert wird.
Um den Maßstab automatisch anpassen zu lassen, aktivieren Sie die Option fit_tasks.
gantt.config.fit_tasks = true;
gantt.init("gantt_here");
Related sample: Auto resize scale
Alternativ können Sie den Datumsbereich explizit über die Optionen start_date und end_date definieren:
gantt.config.start_date = new Date(2018, 02, 31);
gantt.config.end_date = new Date(2018, 03, 09);
gantt.init("gantt_here");
Diese Daten können auch direkt während der Gantt-Initialisierung gesetzt werden:
gantt.init("gantt_here", new Date(2018, 02, 31), new Date(2018, 03, 09));
Related sample: Define displayed date range
Aufgaben, die außerhalb des definierten Intervalls liegen, werden im Gantt-Diagramm nicht angezeigt, es sei denn, sie sind als nicht geplant markiert.
Related sample: Show Unscheduled Tasks
Wenn sowohl start_date als auch end_date gesetzt sind und Sie eine Aufgabe außerhalb dieses Bereichs hinzufügen, ist die Aufgabe im Diagramm nicht sichtbar.
Um solche Aufgaben anzuzeigen, aktivieren Sie die Option show_tasks_outside_timescale.
gantt.config.start_date = new Date(2019, 02, 31);
gantt.config.end_date = new Date(2019, 03, 09);
gantt.config.show_tasks_outside_timescale = true;
gantt.init("gantt_here");
Wenn Sie diese Option nicht verwenden, können Sie den Datumsbereich dynamisch erweitern:
gantt.attachEvent("onLightboxSave", function(id, task, is_new){
var taskStart = task.start_date;
var taskEnd = task.end_date;
var scaleStart = gantt.config.start_date;
var scaleEnd = gantt.config.end_date;
// falls die Aufgabe außerhalb des Bereichs liegt
if(scaleStart > taskEnd || scaleEnd < taskStart ){
// Zeitbereich aktualisieren
gantt.config.end_date = new Date(Math.max(taskEnd.valueOf(), scaleEnd.valueOf()));
gantt.config.start_date = new Date(Math.min(taskStart.valueOf(), scaleStart.valueOf()));
gantt.render();
}
return true;
});
Alternativ können Sie eine Validierung im Lightbox hinzufügen, um das Speichern von Aufgaben außerhalb des Bereichs zu verhindern:
gantt.attachEvent("onLightboxSave", function(id, task, is_new){
var taskStart = task.start_date;
var taskEnd = task.end_date;
var scaleStart = gantt.config.start_date;
var scaleEnd = gantt.config.end_date;
// prüfen, ob die Aufgabe außerhalb des Bereichs liegt
if(scaleStart > taskEnd || scaleEnd < taskStart ){
gantt.message({
type: "warning",
text: "Warnung! Die Aufgabe liegt außerhalb des Datumsbereichs!",
expire: 5000
});
return false;
}
return true;
});
Es gibt verschiedene Möglichkeiten, den angezeigten Datumsbereich dynamisch zu aktualisieren:
gantt.attachEvent("onBeforeGanttRender", function(){
var range = gantt.getSubtaskDates();
var scaleUnit = gantt.getState().scale_unit;
if(range.start_date && range.end_date){
gantt.config.start_date = gantt.calculateEndDate(range.start_date, -4, scaleUnit);
gantt.config.end_date = gantt.calculateEndDate(range.end_date, 5, scaleUnit);
}
});
gantt.init("gantt_here");
gantt.config.fit_tasks = true;
gantt.init("gantt_here");
Wenn sowohl start_date als auch end_date gesetzt sind, denken Sie daran, eine der oben beschriebenen Methoden zu verwenden, damit die fit_tasks-Option korrekt funktioniert.
gantt.attachEvent("onTaskDrag", function(id, mode, task, original){
var state = gantt.getState();
var minDate = state.min_date,
maxDate = state.max_date;
var scaleStep = gantt.date.add(new Date(), state.scale_step, state.scale_unit) - new Date();
var showDate,
repaint = false;
if(mode == "resize" || mode == "move"){
if(Math.abs(task.start_date - minDate) < scaleStep){
showDate = task.start_date;
repaint = true;
} else if(Math.abs(task.end_date - maxDate) < scaleStep){
showDate = task.end_date;
repaint = true;
}
if(repaint){
gantt.render();
gantt.showDate(showDate);
}
}
});
Related sample: Re-Rendering des Maßstabs beim Ziehen von Aufgaben
Sie können Aufgaben anzeigen, die außerhalb des festgelegten Datumsbereichs im Gantt-Diagramm liegen.
Um dies zu aktivieren, setzen Sie die Option show_tasks_outside_timescale auf true:
var data = {
"tasks": [
{"id":1, "text":"Project #1", "start_date": "01-09-2018", "end_date": "02-09-2018"},
{"id":2, "text":"Project #2", "start_date": "01-09-2021", "end_date": "02-09-2021"},
{"id":3, "text":"Task #1", "start_date": "03-02-2020", "end_date": "05-02-2020"},
],
"links":[]
};
gantt.config.show_tasks_outside_timescale = true;
gantt.init("gantt_here", new Date(2020, 1, 1), new Date(2020, 2, 1));
Related sample: Tasks outside timescale
Als Ergebnis erscheinen Aufgaben mit den IDs "1" und "2" als leere Zeilen im Zeitachsenbereich, wobei ihre Namen und Startdaten im Grid angezeigt werden.
Um die Schrittweite des Zeitmaßstabs festzulegen, verwenden Sie die step-Eigenschaft im Konfigurationsobjekt des Maßstabs:
var monthScaleTemplate = function (date) {
var dateToStr = gantt.date.date_to_str("%M");
var endDate = gantt.date.add(date, 2, "month");
return dateToStr(date) + " - " + dateToStr(endDate);
};
gantt.config.scales = [
{unit: "year", step: 1, format: "%Y"},
{unit: "month", step: 3, format: monthScaleTemplate},
{unit: "month", step: 1, format: "%M"}
];
gantt.init("gantt_here");
Related sample: Step config for the Quarter scale
Um die Höhe des Maßstabs anzupassen, verwenden Sie die Eigenschaft scale_height:
gantt.config.scale_height = 54;
gantt.init("gantt_here");
Wenn mehrere Maßstäbe verwendet werden, wird die angegebene Höhe gleichmäßig aufgeteilt. Beispielsweise erhält bei scale_height von 60 Pixeln und 3 Maßstäben jeder Maßstab 20 Pixel Höhe.
Siehe den Artikel Datumsformat-Spezifikation für verfügbare Formatzeichen
Das Datumsformat für den Maßstab können Sie über die format-Eigenschaft in jedem Maßstabsobjekt festlegen. Dies kann ein String sein:
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: weekScaleTemplate},
{unit: "day", step: 1, format: "%D", css: daysStyle }
];
gantt.init("gantt_here");
Related sample: Multiple scales
Oder eine Funktion, die ein Date-Objekt entgegennimmt und einen formatierten String zurückgibt:
gantt.config.scales = [
{ unit: "day", step: 1, format: function(date){
return "<strong>Tag " + dayNumber(date) + "</strong><br/>" + dateFormat(date);
}}
]
Um die Zellen des Zeitmaßstabs zu gestalten, verwenden Sie das css-Attribut im Maßstabsobjekt.
function getWeekOfMonthNumber(date){
let adjustedDate = date.getDate() + date.getDay();
let prefixes = ['0', '1', '2', '3', '4', '5'];
return (parseInt(prefixes[0 | adjustedDate / 7]) + 1);
}
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: function(date){
return "Woche #" + getWeekOfMonthNumber(date);
}},
{unit: "day", step: 1, format: "%j %D", css: function(date) { if(!gantt.isWorkTime(date)){
return "week-end";
}
}}
];
Related sample: Zellen-Styling des Zeitmaßstabs
Wenn die css-Eigenschaft in den Maßstabskonfigurationen nicht gesetzt ist, können Sie das Template scale_cell_class verwenden, um CSS-Klassen auf den ersten Zeitmaßstab im scales-Array anzuwenden.
function getWeekOfMonthNumber(date){
let adjustedDate = date.getDate() + date.getDay();
let prefixes = ['0', '1', '2', '3', '4', '5'];
return (parseInt(prefixes[0 | adjustedDate / 7]) + 1);
}
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: function(date){
return "Woche #" + getWeekOfMonthNumber(date);
}},
{unit: "day", step: 1, format: "%j %D"}
];
gantt.templates.scale_cell_class = function(date) {
if(!gantt.isWorkTime(date)){
return "week-end";
}
};
Related sample: Styling des ersten Zeitmaßstabs
Um das Template scale_cell_class auf alle Maßstäbe anzuwenden, setzen Sie die Option inherit_scale_class auf true.
gantt.config.scales = [
{unit: "month", step: 1, format: "%F, %Y"},
{unit: "week", step: 1, format: function(date){
return "Woche #" + getWeekOfMonthNumber(date);
}},
{unit: "day", step: 1, format: "%j %D"}
];
gantt.templates.scale_cell_class = function(date) {
if(!gantt.isWorkTime(date)){
return "week-end";
}
};
gantt.config.inherit_scale_class = true;
Related sample: Styling aller Maßstäbe
Bei der Arbeit mit Berechnungen der Arbeitszeit empfiehlt es sich, isWorkTime anstelle von fest codierten Werten zu verwenden:
gantt.config.work_time = true;
gantt.templates.scale_cell_class = function(date){
if(!gantt.isWorkTime(date)){
return "weekend";
}
};
Weitere Informationen zur Anpassung des Stils des Zeitachsenbereichs finden Sie im Artikel Hervorheben von Zeitfenstern.
dhtmlxGantt ermöglicht es Ihnen, benutzerdefinierte Zeiteinheiten zu erstellen und Vorlagen für Beschriftungen in der Maßstabskonfiguration zu definieren.
Um eine benutzerdefinierte Einheit zu definieren, implementieren Sie zwei Funktionen am Date-Objekt:
Date gantt.date.<unit>_start(Date date);
Date gantt.date.add_<unit>(Date date, Integer increment);
In der Regel sind Inkremente positiv, da Maßstabszellen von links nach rechts erstellt werden. Die erste Zelle wird jedoch von rechts nach links erstellt, daher verwendet Gantt in diesem Fall einen negativen Inkrementwert.
So definieren Sie eine "fiscal_year"-Einheit, wobei das Geschäftsjahr am 31. Januar endet. So können Sie die neue Einheit angeben:
var firstMonth = 1,
firstDay = 1;
gantt.date.fiscal_year_start = function(date){ var next = new Date(date);
if(next.getMonth() < firstMonth ||
(next.getMonth() === firstMonth && next.getDate() < firstDay)){
next = gantt.date.add(next, -1, "year");
}
next = gantt.date.year_start(next);
next.setMonth(firstMonth);
next.setDate(firstDay);
return next;
};
gantt.date.add_fiscal_year = function(date, inc){ return gantt.date.add(date, inc, "year");
};
Danach kann die Einheit wie folgt im Code verwendet werden:
var dateToStr = gantt.date.date_to_str("%Y");
function fiscalYearLabel(date){
return dateToStr(gantt.date.fiscal_year_start(date));
};
gantt.config.scales = [
{unit:"year", step:1, format:"Calendar year %Y"},
{unit:"fiscal_year", step:1, format:fiscalYearLabel},
{unit:"month", step: 1, format: "%M %Y"},
{unit:"day", step: 1, format:"%d %M"}
];
Es ist möglich, jede "day"-Zelle in drei "hour"-Zellen mit den Bezeichnungen 00, 08 und 16 zu unterteilen. Die Logik sieht folgendermaßen aus:
gantt.date.hour_custom_start = function (date) {
return date;
};
gantt.date.add_hour_custom = function (date, inc) { // inc hängt vom "step" ab
const nextDate = new Date(date);
if (nextDate.getHours() % 8 != 0) { // der Stundenwert ist nicht 0, 8 oder 16 const diff = Math.abs(8 - nextDate.getHours()); return gantt.date.add(nextDate, diff * inc, "hour"); } return gantt.date.add(date, 8 * inc, "hour"); };
gantt.config.scales = [
{ unit: "day", step: 1, date: "%d %F" },
{ unit: "hour_custom", step: 1, date: "%H" },
];
gantt.config.date_grid = "%Y-%m-%d %H:%i"
Related sample: Custom hours on the scale
Um zu verstehen, wie Gantt die erste "hour"-Zelle bestimmt, nehmen wir an, dass die früheste Aufgabe um 07:00 Uhr beginnt. Da 7 kein Vielfaches von acht ist, wendet Gantt folgende Regel an:
if (nextDate.getHours() % 8 != 0) {
const diff = Math.abs(8 - nextDate.getHours()); // 8 - 7 = 1
return gantt.date.add(nextDate, diff * inc, "hour"); // 7 - 1 = 6
}
Gantt berechnet die Zeitdifferenz zwischen 8:00 und 7:00:
diff = 08:00 - 07:00 = 1 Stunde
Dann multipliziert es diese Differenz mit dem Inkrement:
diff * inc = 1 Stunde * (-1) = -1 Stunde
Hier ist inc der negative Wert des Zeitschritts (-1).
Schließlich wird dieser Wert zur Startzeit der frühesten Aufgabe addiert:
07:00 + (- 1 Stunde) = 06:00
Der Wert der ersten Zelle ist somit 06.
Für die zweite "hour"-Zelle gilt die gleiche Logik, jedoch mit einem positiven Inkrement:
diff = 08:00 - 06:00 = 2 Stunden
diff * inc = 2 Stunden * 1 = 2 Stunden
06:00 + 2 Stunden = 08:00
Die zweite Zelle zeigt 08 an.
Da 8 ein Vielfaches von acht ist, wird die nächste Zelle einfach als 08:00 + 8 Stunden = 16:00 berechnet und dieses Muster setzt sich für die folgenden Zellen fort.
Dieses Vorgehen funktioniert, da der Datumsbereich nicht explizit festgelegt ist.
Weitere Beispiele finden Sie im Artikel How to add a custom scale.
In diesem Abschnitt finden Sie Beispiele dafür, wie Sie die Zeitskala anpassen können, um arbeitsfreie Zeiträume anzuzeigen oder auszublenden. Außerdem wird gezeigt, wie Zellen mit arbeitsfreien Stunden am Anfang der Skala ausgeblendet werden können, selbst wenn der skip_off_time-Modus aktiv ist.
Hier ein Beispiel für eine benutzerdefinierte Skala mit typischen Arbeitszeiten von 08:00 bis 12:00 und 13:00 bis 17:00:
gantt.date.day_custom_start = function (date) {
return date;
};
gantt.date.add_day_custom = function (date, inc) { const nextDate = new Date(date); if (nextDate.getHours() < 8) { // Anweisung 1 const diff = 8 - nextDate.getHours(); return gantt.date.add(nextDate, diff * inc, "hour"); } if (nextDate.getHours() == 8) { // Anweisung 2 return gantt.date.add(nextDate, 9 * inc, "hour"); } if (nextDate.getHours() == 17) { // Anweisung 3 return gantt.date.add(nextDate, 15 * inc, "hour"); }
return gantt.date.add(date, 8 * inc, "hour"); };
gantt.config.scales = [
{ unit: "day_custom", step: 1, date: "%d %H:00" },
];
// gantt.config.skip_off_time = true;
gantt.config.work_time = true;
gantt.config.correct_work_time = true;
gantt.plugins({
auto_scheduling: true,
});
gantt.setWorkTime({ hours: ["8:00-12:00", "13:00-17:00"] });
gantt.config.duration_unit = "minute";
gantt.config.duration_step = 1;
gantt.config.time_step = 1;
gantt.config.round_dnd_dates = false;
Related sample: Custom time spans
Angenommen, die früheste Aufgabe beginnt am 1. April 2025 um 08:00 Uhr. Sehen wir uns an, wie Gantt die Offsets vor dieser Aufgabe berechnet, abhängig von der Einstellung gantt.config.skip_off_time.
Beginnen wir mit der Konfiguration, bei der arbeitsfreie Stunden ausgeblendet werden:
gantt.config.skip_off_time = true;
In diesem Fall subtrahiert Gantt zur Erzeugung der ersten "hour"-Zelle Stunden von der Zeit der frühesten Aufgabe, bis es die Arbeitszeit des Vortages erreicht.
Die erste Zelle zeigt also 31 15:00 an.
Um die Berechnung weiterer Zellen zu verstehen, deaktivieren Sie gantt.config.skip_off_time:
gantt.config.skip_off_time = false;
Wie bereits erwähnt, bleibt die erste Zelle 31 15:00, aber nun erscheinen vor der frühesten Aufgabe mehr leere Zellen, da auch arbeitsfreie Stunden angezeigt werden.
Für diese Zellen gilt folgende Logik:
08:00 Uhr am 1. April 2025 entspricht dem Startzeitpunkt der frühesten Aufgabe.
Die weiteren Zellen werden nach demselben Prinzip erstellt.
Wenn skip_off_time deaktiviert ist, kann Gantt mehr als eine leere Zelle vor der frühesten Aufgabe hinzufügen. Um sicherzustellen, dass unabhängig von dieser Einstellung immer nur eine Zelle erscheint, kann folgende Logik verwendet werden:
gantt.date.add_day_custom = function (date, inc) {
// Wenn work_time aktiviert ist und Aufgaben geladen sind,
// berechne das Datum der ersten Zelle.
// Starte beim Minimaldatum, gehe rückwärts,
// finde das nächstgelegene Datum innerhalb der Arbeitszeit,
// dann ziehe 1 Stunde davon ab
if (inc < 0 && gantt.getTaskByTime().length) {
return gantt.calculateEndDate({
start_date: date, duration: -1, unit: gantt.config._duration_unit
})
}
// Beginn der Arbeitszeit (Arbeitstag);
// berechne, wann der Arbeitstag endet
if (date.getHours() == 8) {
return gantt.calculateEndDate(date, 8);
}
// Ende der Arbeitszeit (Arbeitstag);
// berechne, wann der nächste Arbeitstag beginnt
if (date.getHours() == 17) {
return gantt.date.add(date, 15 * inc, "hour");
}
// Wenn Aufgaben geladen sind, berechne Arbeitsdaten für die zweite Skalen-Zelle
// Wenn keine Aufgaben, berechne Daten für alle Skalen-Zellen
date = gantt.date.add(date, 1 * inc, "day");
gantt.date.day_start(date);
date = gantt.getClosestWorkTime({ date, dir: "future" })
return date
};
gantt.config.scales = [
{ unit: "day_custom", step: 1, date: "%d %H:%i" },
];
gantt.config.work_time = true;
gantt.config.skip_off_time = false;
Related sample: Equal offset for custom scales
So sieht die Skala aus, wenn arbeitsfreie Stunden ausgeblendet werden:
Und so sieht die Ansicht aus, wenn arbeitsfreie Stunden angezeigt werden (gantt.config.skip_off_time deaktiviert):
Detaillierte Beispiele zur Implementierung des unendlichen Scrollens in der Timeline finden Sie im zugehörigen Artikel.
Ab Version 9.0 sind Zeitskalen-Beschriftungen standardmäßig sticky. Das bedeutet, dass eine Beschriftung sichtbar bleibt, wenn eine Zelle wesentlich breiter als ihr Label ist, und beim Scrollen am Viewport "klebt", bis sie natürlich verschwindet. So bleiben Skalenbeschriftungen immer sichtbar, insbesondere beim Zoomen.
Wenn Sie das frühere Verhalten bevorzugen, bei dem die Beschriftungen zentriert sind und beim Scrollen nicht sichtbar bleiben, können Sie sticky labels deaktivieren, indem Sie die Eigenschaft sticky
der Skala auf false
setzen:
gantt.config.scales = [
{unit: "year", step: 1, format: "%Y", sticky: false},
{unit: "month", step: 1, format: "%F", sticky: false},
{unit: "day", step: 1, format: "%j", sticky: false}
];
gantt.init("gantt_here");
Alternativ können Sie für eine bestimmte Skala sticky labels erzwingen, indem Sie sticky: true
setzen. Dadurch bleiben die Labels auch dann sticky, wenn ihre Breite kleiner als die Zelle ist:
gantt.config.scales = [
{unit: "year", step: 1, format: "%Y", sticky: true},
{unit: "month", step: 1, format: "%F", sticky: true},
{unit: "day", step: 1, format: "%j", sticky: true}
];
gantt.init("gantt_here");
Zurück nach oben