Datenladen

dhtmlxGantt unterstützt zwei Datenformate zum Laden:

Um Daten in ein Gantt-Diagramm zu laden, können Sie die Methoden gantt.parse oder gantt.load verwenden.

gantt.init("gantt_here");
gantt.load("tasks.json");

Related sample:  Basic initialization

Wenn die an Gantt übergebenen Daten fehlerhaft sind, kann ihre baumartige Struktur zyklisch werden, was zu einem zyklischen Referenzfehler führen kann.

Laden aus einem Objekt

Wenn Sie Daten direkt aus einem Objekt laden möchten, ist die Methode gantt.parse die richtige Wahl:

Laden aus einer Inline-Datenquelle

var data = {
  tasks:[
     {id:1, text:"Projekt #1", start_date:"01-04-2020", duration:18},
     {id:2, text:"Aufgabe #1", start_date:"02-04-2020", duration:8, parent:1},
     {id:3, text:"Aufgabe #2", start_date:"11-04-2020", duration:8, parent:1}
   ]
};
gantt.init("gantt_here");
gantt.parse(data);

Related sample:  Basic initialization

Wenn Ihre Daten sowohl "start_date" als auch "end_date" Werte enthalten und die Daten in einem vereinfachten Format vorliegen (wie 01-12-2021 ohne Zeit), benötigen Sie möglicherweise zusätzliche Konfigurationen. Schauen Sie sich diesen Leitfaden an: Task end date display & Inclusive end dates.

Laden vom Server

Clientseite

Um Daten von einem Server abzurufen, verwenden Sie die Methode gantt.load:

gantt.html

gantt.init("gantt_here");
gantt.load("data.json");

Die load-Methode sendet eine AJAX-Anfrage an die angegebene URL und erwartet eine Antwort in einem der unterstützten Formate. Zum Beispiel:

data.json

{
  "tasks":[
     {"id":1, "text":"Projekt #1", "start_date":"01-04-2020", "duration":18},
     {"id":2, "text":"Aufgabe #1", "start_date":"02-04-2020","duration":8, "parent":1},
     {"id":3, "text":"Aufgabe #2", "start_date":"11-04-2020","duration":8, "parent":1}
  ],
  "links":[
     {"id":1, "source":1, "target":2, "type":"1"},
     {"id":2, "source":2, "target":3, "type":"0"}
  ]
}

Sie können das Datenformat im zweiten Parameter angeben, wie "json", "xml" oder "oldxml":

gantt.load("data.xml", "xml");

Serverseite

Auf der Serverseite können Sie entweder eine statische Datei oder ein Skript verwenden, um Daten aus einer Datenbank oder anderen Quellen zu sammeln und in der Antwort zu senden. Die Implementierung hängt vom verwendeten Server-Framework ab.

Detaillierte Anweisungen und Beispiele für verschiedene Plattformen finden Sie im Artikel Serverseitige Integration.

Zum Beispiel können Sie mit Node.js eine Server-Route definieren, um Gantts AJAX-Anfragen zu bearbeiten.

gantt.load("/data");

Diese Route sollte eine JSON-Antwort wie diese zurückgeben:

app.get("/data", function(req, res){
    db.query("SELECT * FROM gantt_tasks", function(err, rows){
        if (err) console.log(err);
        db.query("SELECT * FROM gantt_links", function(err, links){
            if (err) console.log(err);
            for (var i = 0; i < rows.length; i++){
                rows[i].start_date = rows[i].start_date.format("YYYY-MM-DD");
                rows[i].open = true;
            }
 
            res.send({ tasks:rows, links : links });
        });
    });
});

Die Liste der unterstützten Datenformate finden Sie im Artikel Unterstützte Datenformate.

Laden von Aufgabendaten

Festlegen des Aufgabenplans

Es gibt drei Möglichkeiten, den Zeitplan einer Aufgabe im Datenfeed zu definieren:

  • Verwendung von start_date und duration
  • Verwendung von start_date und end_date
  • Verwendung von duration und end_date

Wenn eine Eigenschaft fehlt, berechnet Gantt sie basierend auf den anderen beiden.

Related sample:  Backward planning

Die end_date-Eigenschaft hat Vorrang vor duration. Wenn alle drei Eigenschaften angegeben sind, ignoriert Gantt die duration und berechnet einen neuen Wert dafür. Zum Beispiel:

{
    "id":"20", "text":"Projekt #2", 
    "start_date":"01-04-2025", 
    "duration":3, 
    "end_date":"05-04-2025", 
    "order":10,"progress":0.4, 
    "type": "project", "open": true
}
 
// Die Aufgabe wird mit einer auf 'start_date' und 'end_date' basierenden neu berechneten Dauer geladen
{
    "id":"20", "text":"Projekt #2", 
    "start_date":"01-04-2025", 
    "duration":4, 
    "end_date":"05-04-2025", 
    "order":10,"progress":0.4, 
    "type": "project", "open": true
}

Laden von Daten im ISO-Format

Um das ISO-Datenformat zu verwenden, definieren Sie die Funktionen zur Datumsanalyse und -formatierung in Gantt neu:

gantt.templates.parse_date = function(date) { 
    return new Date(date);
};
gantt.templates.format_date = function(date) { 
    return date.toISOString();
};

Dynamisches Ändern des Datumsformats

Wenn Sie das Datumsformat spontan anpassen müssen, aktualisieren Sie die parse_date Vorlage folgendermaßen:

var cfg = gantt.config;
var strToDate = gantt.date.str_to_date(cfg.date_format, cfg.server_utc);
 
gantt.templates.parse_date = function(date){
    return strToDate(date);
};

Anzeige des Aufgabenenddatums & Inklusive Enddaten

Hier finden Sie einige Klarstellungen, wie Sie Aufgabenenddaten richtig behandeln und anzeigen.

Zu berücksichtigende Szenarien

Szenario 1

  • Die Aufgabendauer wird in vollen Tagen angegeben (duration_unit="day").
  • Die Aufgabendaten enthalten Start- und Enddaten in Formaten wie "%Y-%m-%d" oder "%d-%m-%Y" (ohne Zeit).

Gantt könnte diese Daten so interpretieren, dass unerwartete Ergebnisse entstehen. Zum Beispiel:

gantt.parse({ tasks: [
    { 
        id: 1,
        text: "Aufgabe 1",
        start_date: "22-12-2021",
        end_date: "22-12-2021"
    }
]}, links:[]);
 
console.log(gantt.getTask(1).end_date);
// 22. Dezember 2021 00:00:00
 
console.log(gantt.getTask(1).duration);
// 0

Hier verweisen Start- und Enddaten auf denselben Zeitpunkt, was zu einer Dauer von 0 führt.

Szenario 2

  • Das Enddatum der Aufgabe ist im Raster sichtbar.
  • Das Enddatumsformat enthält keine Zeitdetails.
gantt.config.columns = [
    {name: "text", label: "Name", tree: true, width: 200, resize: true},
    {name: "duration", label: "Dauer", width:80, align: "center", resize: true},
    {name: "start_date", label: "Start", width:80, align: "center", resize: true},
    {name: "end_date", label: "Ende", width:80, align: "center", resize: true}
];
 
gantt.init("gantt_here");
 
gantt.parse({ tasks: [
    { 
        id: 1,
        text: "Aufgabe 1",
        start_date: "02-04-2020",
        end_date: "02-04-2020"
    }
]}, links:[]);

In diesem Fall könnte das angezeigte Enddatum irreführend erscheinen, da es als 3. April angezeigt werden könnte, während die Aufgabe tatsächlich am 2. April endet.

Wie speichert Gantt Enddaten?

Selbst wenn die Aufgabendaten keine Zeitdetails enthalten, speichert Gantt sie als JS-Date-Objekte mit Zeitangabe. So funktioniert es:

  • Sekunden und Millisekunden werden immer auf 0 gesetzt.
  • Das Enddatum repräsentiert den Beginn des nächsten Tages oder der nächsten Stunde nach dem letzten arbeitsintensiven Moment der Aufgabe:
    • Für eine Aufgabe, die am 2. April beginnt und 1 Tag dauert: "02-04-2022 00:00:00 - 03-04-2022 00:00:00".
    • Für eine Aufgabe, die am 2. April um 13:00 beginnt und 1 Stunde dauert: "02-04-2022 13:00:00 - 02-04-2022 14:00:00".

Wenn das Enddatum ohne Zeitangabe angezeigt wird, könnte es irreführend erscheinen, wie in Szenario 2. Dieses Standardverhalten kann jedoch über die Konfiguration angepasst werden. Der nächste Abschnitt bietet Lösungen für die Handhabung dieses Problems.

Anpassen des Standardverhaltens

1) Das Erste, was vermieden werden sollte, ist die Änderung der tatsächlichen Aufgabendaten, die im Gantt-Diagramm gespeichert sind.

Manchmal könnte man in Erwägung ziehen, die in Gantt geladenen Aufgabendaten zu ändern, z. B. Enddaten auf "02-04-2022 23:59:59" zu setzen. Diese Vorgehensweise könnte jedoch Berechnungen der Aufgabendauer und automatische Planungen beeinträchtigen, daher wird dies nicht empfohlen.

Stattdessen gibt es einige bessere Alternativen:

2a) Wenn Sie anpassen möchten, wie Aufgabendaten im Gantt angezeigt werden (z. B. das Enddatum in die Aufgabendauer einbeziehen), können Sie die task_end_date Vorlage neu definieren.

Zum Beispiel, eine Aufgabe, die am 2. April 2020 beginnt und einen Tag dauert. Standardmäßig wird das Enddatum als 3. April 2020 angezeigt (03-04-2020 00:00:00):

Durch Anwenden der task_end_date Vorlage würde das Enddatum stattdessen als 2. April 2020 angezeigt:

Hier ist der Code für diese Anpassung:

// Überschreiben der Spaltenkonfiguration
gantt.config.columns = [
  {name: "wbs", label: "#", width: 60, align: "center", template: gantt.getWBSCode},
  {name: "text", label: "Name", tree: true, width: 200, resize: true},
  {name: "start_date", label: "Start", width:80, align: "center", resize: true},
  {name: "end_date", label: "Ende", width:80, align: "center", resize: true}, 
  {name:"add"}
];
 
// Die Vorlage neu definieren
gantt.templates.task_end_date = function(date){
   return gantt.templates.task_date(new Date(date.valueOf() - 1)); 
};
 
var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
gantt.templates.grid_date_format = function(date, column){
   if(column === "end_date"){
     return gridDateToStr(new Date(date.valueOf() - 1)); 
   }else{
     return gridDateToStr(date); 
   }
}
gantt.init("gantt_here");

Dieser Ansatz aktualisiert das Aufgabenenddatum im gesamten Raster, in den Lightbox-Kopfzeilen und anderen Bereichen, in denen das Enddatum erscheint.

Wenn Sie das inklusive Enddatumsformat verwenden und es mit Inline-Editing funktionieren soll, müssen Sie einen benutzerdefinierten Editor für die Bearbeitung inklusiver Aufgabenenddaten erstellen. Hier ist ein Beispiel:

// Inklusiver Editor für Enddaten
// Verwenden Sie den Standard-Editor, aber überschreiben Sie die Methoden set_value/get_value
var dateEditor = gantt.config.editor_types.date;
gantt.config.editor_types.end_date = gantt.mixin({
    set_value: function(value, id, column, node){
        var correctedValue = gantt.date.add(value, -1, "day");
        return dateEditor.set_value.apply(this, [correctedValue, id, column, node]);
    },
    get_value: function(id, column, node) {
        var selectedValue = dateEditor.get_value.apply(this, [id, column, node]);
        return gantt.date.add(selectedValue, 1, "day");
    },
}, dateEditor);
 
var textEditor = {type: "text", map_to: "text"};
var startDateEditor = {type: "date", map_to: "start_date"};
var endDateEditor = {type: "end_date", map_to: "end_date"};
var durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
 
gantt.config.columns = [
    {name: "text", label: "Name", tree: true, width: 200, editor: textEditor, 
        resize: true},
    {name: "duration", label: "Dauer", width:80, align: "center", 
        editor: durationEditor, resize: true},
    {name: "start_date", label: "Start", width:140, align: "center", 
        editor: startDateEditor, resize: true},
    {name: "end_date", label: "Ende", width:140, align: "center", 
        editor: endDateEditor, resize: true}
];
 
// Ändern Sie die Lightbox- und Rastervorlagen, um Daten von Aufgaben in einem inklusiven Format anzuzeigen
gantt.templates.task_end_date = function(date){
    return gantt.templates.task_date(new Date(date.valueOf() - 1)); 
};
 
var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
gantt.templates.grid_date_format = function(date, column){
    if(column === "end_date"){
        return gridDateToStr(new Date(date.valueOf() - 1)); 
    }else{
        return gridDateToStr(date); 
    }
}

Related sample:  Inklusiver Enddatum-Editor

2b) Wenn Ihre Anwendung "inklusive" Enddaten erfordert (z. B. eine eintägige Aufgabe, die am 2. April 2020 beginnt, würde start_date: "02-04-2022" und end_date: "02-04-2022" haben), müssen Sie Folgendes beachten:

  • Fügen Sie vor dem Laden der Daten in Gantt einen Tag zu den Enddaten hinzu.
  • Ziehen Sie vor dem Speichern der Änderungen in der Speicherung einen Tag von den Enddaten ab.

Daten Eigenschaften

Die Datenquelle des Gantt-Diagramms ist ein Objekt, das zwei Arten von Informationen enthält:

  • tasks - die Aufgabenelemente.
  • links - die Abhängigkeitsverknüpfungen.

Eigenschaften des Aufgabenobjekts

Für eine vollständige Liste der Eigenschaften von Aufgabenobjekten siehe den Artikel Task properties.

Das Standarddatumsformat für JSON- und XML-Daten ist "%d-%m-%Y %H:%i" (siehe Datumsformatspezifikation).
Um dies zu ändern, verwenden Sie die Konfigurationsoption date_format.

gantt.config.date_format="%Y-%m-%d";
gantt.init("gantt_here");

Sobald Daten in Gantt geladen sind, werden die Eigenschaften start_date und end_date in den Date-Typ geparst.

Wenn Sie Datumsformate verwenden, die von date_format nicht unterstützt werden, können Sie sie manuell mit der Vorlage parse_date parsen.

Für eine vollständige Liste der Eigenschaften von Verknüpfungsobjekten siehe den Artikel Link properties.

Benutzerdefinierte Eigenschaften

Sie können benutzerdefinierte Eigenschaften zu Datenelementen hinzufügen, die über die obligatorischen hinausgehen. Diese zusätzlichen Eigenschaften werden als Zeichenfolgen geparst und zur weiteren Verwendung auf der Clientseite geladen.

Sehen Sie sich Beispiele für Daten mit benutzerdefinierten Eigenschaften hier an.


Datenbankstruktur

Beim Verwenden einer Datenbank ist es am besten, separate Tabellen für Aufgaben und Verknüpfungen zu haben.

Die empfohlene Struktur für eine Datenbank zum Laden von Aufgaben und Verknüpfungen in das Gantt-Diagramm sieht folgendermaßen aus:

  • gantt_tasks Tabelle - für Gantt-Aufgaben
    • id - (string,number) Aufgaben-ID.
    • start_date - (Date) Startdatum der Aufgabe.
    • text - (string) Aufgabenbeschreibung.
    • progress - (number) Fertigstellungsgrad (0 bis 1).
    • duration - (number) Aufgabendauer in aktuellen Zeiteinheitenskalen.
    • parent - (number) ID der übergeordneten Aufgabe.
    • type - (string) optional, der Aufgabentyp.
    • readonly - (boolean) optional, markiert Aufgabe als schreibgeschützt.
    • editable - (boolean) optional, markiert Aufgabe als bearbeitbar.
  • gantt_links Tabelle - für Gantt-Abhängigkeitsverknüpfungen
    • id - (string,number) Verknüpfungs-ID.
    • source - (number) ID der Quellaufgabe.
    • target - (number) ID der Zielaufgabe.
    • type - (string) Abhängigkeitstyp:
      • 0 - 'finish_to_start'
      • 1 - 'start_to_start'
      • 2 - 'finish_to_finish'
      • 3 - 'start_to_finish'
    • lag - (number) optional, Aufgabenverzögerung.
    • readonly - (boolean) optional, markiert Verknüpfung als schreibgeschützt.
    • editable - (boolean) optional, markiert Verknüpfung als bearbeitbar.

Hier ist die SQL-Anweisung zum Erstellen der erforderlichen Datenbanktabellen:

CREATE TABLE `gantt_links` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `source` INT(11) NOT NULL,
  `target` INT(11) NOT NULL,
  `type` VARCHAR(1) NOT NULL,
  PRIMARY KEY (`id`)
);
CREATE TABLE `gantt_tasks` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `text` VARCHAR(255) NOT NULL,
  `start_date` datetime NOT NULL,
  `duration` INT(11) NOT NULL,
  `progress` FLOAT NOT NULL,
  `sortorder` INT(11) NOT NULL,
  `parent` INT(11) NOT NULL,
  PRIMARY KEY (`id`)
);

Ereignissequenz

Hier ist die Ereignissequenz für Datenlade-Methoden:

gantt.parse():

gantt.load()

gantt.refreshData():

gantt.render():

Zurück nach oben