Available only in PRO Edition

Benutzerdefinierte Elemente im Zeitachsenbereich

Diese Funktionalität ist nur in der PRO-Edition verfügbar

dhtmlxGantt enthält eingebaute Funktionen, um standardmäßig zusätzliche Elemente wie Basislinien, Fristen und Aufgabenbeschränkungen anzuzeigen. Wenn Sie diese Funktionen anpassen oder erweitern möchten, können Sie manuell benutzerdefinierte Elemente zur Zeitachse hinzufügen, wie unten beschrieben.

Das Hinzufügen zusätzlicher Elemente beinhaltet normalerweise das Erstellen einer neuen Anzeigeschicht und das Positionieren benutzerdefinierter Elemente dort mit absoluter Positionierung, um sie mit den zugehörigen Aufgaben auszurichten.

Um eine neue Schicht zum Zeitachsenbereich hinzuzufügen, können Sie die Methode gantt.addTaskLayer verwenden. Diese Methode nimmt eine Funktion als Parameter an, die:

  • Ein Aufgabenobjekt erhält;
  • Entweder ein DOM-Element zum Anzeigen zurückgibt oder false, wenn das Element für eine Aufgabe nicht erscheinen soll.
gantt.addTaskLayer(function myNewElement(task) {
    var el = document.createElement('div');
    // Ihr Code
    return el;
});

Related sample:  Displaying deadlines

Wichtige Punkte zu beachten:

  1. Wenn Sie diese Methode aufrufen, fügt dhtmlxGantt einen Container zum Zeitachsenbereich hinzu.
  2. Während der Datenwiedergabe wird die Methode gantt.addTaskLayer für jede Aufgabe ausgeführt, und das zurückgegebene DOM-Element wird dem Container hinzugefügt.
  3. Sie können standardmäßige absolute Positionierung verwenden, um Elemente zu platzieren.
  4. Wenn eine Aufgabe in Gantt aktualisiert wird, wird sie auch in allen Schichten, einschließlich benutzerdefinierter, aktualisiert, da die Funktion für die aktualisierte Aufgabe erneut ausgeführt wird und das entsprechende DOM-Element ersetzt.
  5. Um die Position und Größe einer Aufgabe zu berechnen, können Sie die Methode gantt.getTaskPosition verwenden, was es einfacher macht, die Platzierung und Dimensionen Ihrer benutzerdefinierten Elemente zu bestimmen.

Für Tipps zur Verbesserung der Rendering-Geschwindigkeit benutzerdefinierter Elemente, lesen Sie die Anleitung zum intelligenten Rendering für benutzerdefinierte Schichten.

Wenn Sie benutzerdefinierte Inhalte in jeder Zeitachse-Zelle anzeigen möchten, können Sie HTML direkt in die Zellen einbetten, indem Sie die Vorlage gantt.timeline_cell_content_template verwenden. Dieser Ansatz ist einfacher und performanter.

Beispiel für die Verwendung

Hier ist ein Beispiel: Sie haben geplante und tatsächliche Zeiten für Aufgaben und müssen beide anzeigen.

Schritt 1. Passen Sie die Aufgabenhöhe an und positionieren Sie die Aufgabenlinien

Anfangs erscheinen Aufgaben wie folgt:

Um Platz für Basislinien unter den Aufgaben zu schaffen, reduzieren Sie die Aufgabenleistenhöhe auf etwa die Hälfte der Zeilenhöhe:

gantt.config.bar_height = 16;
gantt.config.row_height = 40;

Verschieben Sie dann die Aufgabenlinie mit diesem CSS an den oberen Rand der Zeile:

.gantt_task_line, .gantt_line_wrapper {
    margin-top: -9px;
}
.gantt_side_content {
    margin-bottom: 7px;
}
.gantt_task_link .gantt_link_arrow {
    margin-top: -12px
}
.gantt_side_content.gantt_right {
    bottom: 0;
}

Das Ergebnis wird so aussehen:

Schritt 2. Neue Datenattribute hinzufügen

Fügen Sie als Nächstes zusätzliche Eigenschaften zum Aufgabenobjekt hinzu. Verwenden Sie beispielsweise 'planned_start' und 'planned_end':

Schritt 3. Neue Datenattribute in Datumsobjekte parsen

dhtmlxGantt parst automatisch 'start_date' und 'end_date' in Datumsobjekte. Für andere Datumsattribute ist zusätzliche Verarbeitung erforderlich. Um 'planned_start' und 'planned_end' erkennbar zu machen, parsen Sie sie mit der Methode gantt.date.parseDate innerhalb des Ereignis-Handlers onTaskLoading:

gantt.attachEvent("onTaskLoading", function(task){
    task.planned_start = gantt.date.parseDate(task.planned_start, "xml_date");
    task.planned_end = gantt.date.parseDate(task.planned_end, "xml_date");
    return true;
});

Schritt 4. Benutzerdefinierte Elemente für geplante Zeit rendern

Verwenden Sie nun die Methode gantt.addTaskLayer, um die geplante Zeit für Aufgaben anzuzeigen (basierend auf 'planned_start' und 'planned_end'):

gantt.addTaskLayer(function draw_planned(task) {
    if (task.planned_start && task.planned_end) {
        var sizes = gantt.getTaskPosition(task, task.planned_start, task.planned_end);
        var el = document.createElement('div');
        el.className = 'baseline';
        el.style.left = sizes.left + 'px';
        el.style.width = sizes.width + 'px';
        el.style.top = sizes.top + gantt.config.task_height  + 13 + 'px';
        return el;
    }
    return false;
});

Schritt 5. CSS für die benutzerdefinierten Elemente hinzufügen

Definieren Sie schließlich den Stil für Ihre benutzerdefinierten Elemente:

.baseline {
    position: absolute;
    border-radius: 2px;
    opacity: 0.6;
    margin-top: -7px;
    height: 12px;
    background: #ffd180;
    border: 1px solid rgb(255,153,0);
}

Schritt 6. Bearbeitung der hinzugefügten Datenattribute im Lightbox aktivieren

Um die Bearbeitung der neu hinzugefügten Eigenschaften direkt über die Benutzeroberfläche zu ermöglichen, können Sie die Lightbox-Struktur neu definieren.

gantt.config.lightbox.sections = [
    {name: "description", height: 70, map_to: "text", type: "textarea", focus: true},
    {name: "time", height: 72, map_to: "auto", type: "duration"},
    {name: "baseline", height: 72, map_to: { 
        start_date: "planned_start", end_date: "planned_end"}, type: "duration"}
];
gantt.locale.labels.section_baseline = "Geplant";

Die vollständige Implementierung dieses Beispiels finden Sie im zugehörigen Beispiel.

Related sample:  Display baselines

Beispiele für benutzerdefinierte Inhalte

Hier sind einige Beispiele, die zeigen, wie Sie die Methode addTaskLayer() verwenden können, um die Gantt-Diagramm-Zeitachse mit benutzerdefinierten Elementen zu verbessern:

Drag-and-Drop für benutzerdefinierte Elemente

Wenn Sie Drag-and-Drop-Funktionalität für benutzerdefinierte Elemente benötigen, können Sie diese manuell implementieren. Obwohl DHTMLX Gantt keine integrierte Lösung dafür bietet, ist es relativ einfach, dies einzurichten, indem Sie drei DOM-Ereignisse behandeln: mousedown, mousemove und mouseup. Sie benötigen auch einige Flags, um den Drag-and-Drop-Status zu verfolgen.

  1. Verwenden Sie das mousedown-Ereignis, um zu erkennen, wann Drag-and-Drop beginnen könnte. Speichern Sie an diesem Punkt die anfängliche Mausposition und alle anderen relevanten Daten.
var dndRequested = false;
var dndActivated = false;
var startPosition = null;
var startTimestamp = null
var taskId = null;
var domUtils = gantt.utils.dom;
 
gantt.event(gantt.$task_data, 'mousedown', function(e) {
  var draggableElement = domUtils.closest(e.target, '.baseline');
 
  if (draggableElement) {
    dndRequested = true;
    startTimestamp = Date.now();
    startPosition = domUtils.getRelativeEventPosition(e, gantt.$task_data);
    taskId = draggableElement.getAttribute("data-task");
  }
});

Die Verwendung von gantt.event anstelle von nativen Event-Listenern stellt sicher, dass alle Handler automatisch entfernt werden, wenn Sie die Gantt-Instanz mit gantt.destructor zerstören.

  1. Das mousemove-Ereignis ist der Punkt, an dem der eigentliche Drag-and-Drop-Prozess beginnt. Vergleichen Sie die aktuelle Mausposition mit der Anfangsposition, um festzustellen, ob ein Ziehen stattfindet. Aktualisieren Sie in diesem Fall die Position des gezogenen Elements.
gantt.event(window, 'mousemove', function(e) {
  if (dndRequested && gantt.isTaskExists(taskId)) {
    var currentPosition = domUtils.getRelativeEventPosition(e, gantt.$task_data);
    if (!dndActivated) {
      if(Math.abs(currentPosition.x - startPosition.x) > 5 || (Date.now() - startTimestamp) > 500) {
          dndActivated = true;
      }
    }
    if (dndActivated) {
      var pointerDate = gantt.dateFromPos(currentPosition.x);
      gantt.getTask(taskId).baseline_date = pointerDate;
      gantt.refreshTask(taskId);
    }
  }
});
  1. Verwenden Sie schließlich das mouseup-Ereignis, um den Drag-and-Drop-Prozess abzuschließen. Wenden Sie Änderungen am bewegten Objekt an und setzen Sie alle temporären Flags zurück.
gantt.event(window, 'mouseup', function(e) {
  if (dndActivated) {
    var task = gantt.getTask(taskId);
    task.baseline_date = gantt.roundDate({
      date: task.baseline_date,
      unit: "hour",
      step: 1    
    });
    gantt.updateTask(taskId);
  }
  dndRequested = false;
  dndActivated = false;
  startPosition = null;
  startTimestamp = null;
  taskId = null;
});

Hinzufügen eines zusätzlichen Overlays zum Diagramm

Sie können benutzerdefinierte Inhalte zum Gantt-Diagramm hinzufügen, indem Sie ein zusätzliches Overlay verwenden. Dies könnte ein div-Container, ein HTML-Canvas oder ähnliche Elemente sein. Jede Drittanbieter-Bibliothek kann verwendet werden, um die Overlay-Inhalte zu rendern.

Zum Beispiel könnten Sie eine S-Kurve einfügen, um Ausgaben oder Projektfortschritte zu verfolgen. So fügen Sie ein Overlay hinzu:

  1. Aktivieren Sie die overlay-Erweiterung mit gantt.plugins.
gantt.plugins({
    overlay: true
});
  1. Verwenden Sie addOverlay() vom gantt.ext.overlay-Objekt, um den Inhalt des Overlays zu definieren.
var overlay = gantt.ext.overlay.addOverlay(function(container){
    var canvas = document.createElement("canvas");
    container.appendChild(canvas);
    canvas.style.height = container.offsetHeight + "px";
    canvas.style.width = container.offsetWidth + "px";
 
    var ctx = canvas.getContext("2d");
    var myChart = new Chart(ctx, {
        type: "line",
        // vollständige Diagrammkonfiguration
    });
});

Die Methode gantt.ext.overlay.addOverlay() gibt die ID des Overlays zurück.

Related sample:  Gantt chart with overlay and zoom (S-Curve)

Overlay-Erweiterungs-API

Die Overlay-Erweiterung bietet mehrere Methoden zur Verwaltung von Overlays, die über gantt.ext.overlay zugänglich sind:

  • addOverlay: Fügt ein neues Overlay hinzu und gibt dessen ID zurück.
var overlay = gantt.ext.overlay.addOverlay(function(container){});
  • deleteOverlay: Entfernt ein Overlay anhand seiner ID.
gantt.ext.overlay.deleteOverlay(id);
  • getOverlaysIds: Ruft ein Array von Overlay-IDs ab.
var ids = gantt.ext.overlay.getOverlaysIds();
  • refreshOverlay: Malt ein bestimmtes Overlay neu.
gantt.ext.overlay.refreshOverlay(id);
  • showOverlay: Zeigt ein Overlay anhand seiner ID an.
gantt.ext.overlay.showOverlay(id);
  • hideOverlay: Verbirgt ein Overlay anhand seiner ID.
gantt.ext.overlay.hideOverlay(id);
  • isOverlayVisible: Überprüft, ob ein Overlay sichtbar ist.
var isVisible = gantt.ext.overlay.isOverlayVisible(id);
Zurück nach oben