addTaskLayer

在时间线区域显示带有自定义任务元素的额外图层

string addTaskLayer(TaskLayerRender | TaskLayerConfig func);
funcTaskLayerRender | TaskLayerConfig一个渲染函数或配置对象
string一个将显示在图层中的DOM元素

Available only in PRO Edition

Example

gantt.init("gantt_here");
gantt.addTaskLayer(function draw_deadline(task) {
    if (task.deadline) {
        var el = document.createElement('div');
        el.className = 'deadline';
        var sizes = gantt.getTaskPosition(task, task.deadline);
 
        el.style.left = sizes.left + 'px';
        el.style.top = sizes.top + 'px';
 
        el.setAttribute('title', gantt.templates.task_date(task.deadline));
        return el;
    }
    return false;
});

Related samples

Details

此功能仅在PRO版中可用。

参数可以是以下类型之一:

  • taskLayerRender (task, timeline, config, viewport): HTMLElement|boolean|void - 一个函数,接收任务对象并返回一个要显示在图层中的DOM元素。

    • task - (Task) - 任务对象
    • timeline? - (any) - 时间线视图
    • config? - (GanttConfigOptions) - Gantt配置对象
    • viewport? - (LayerViewport) - 视口对象
  • taskLayerConfig - (object) - 额外任务图层的配置对象,包含:

    • id? - (string | number) - 可选的图层ID
    • renderer - (object) - 必需,负责渲染图层元素的对象
      • render - (TaskLayerRender) - 返回要渲染的HTML元素的函数
      • update? - (Function): void - 可选,用于更新已渲染HTML元素的函数
        • task - (Task) - 任务对象
        • node - (HTMLElement) - 渲染节点的容器
        • timeline? - (any) - 时间线视图
        • config? - (GanttConfigOptions) - Gantt配置对象
        • viewport? - (LayerViewport) - 视口对象
      • onrender? - (Function): void - 可选,渲染完成后调用,适合渲染原生组件(例如使用 ReactDOM.render
        • task - (Task) - 任务对象
        • node - (HTMLElement) - 渲染节点的容器
        • view? - (any) - 添加图层的布局单元(默认是时间线)
      • getRectangle? - (Function): { left: number, top: number, height: number, width: number } | void - 可选,返回视口矩形的坐标
        • task - (Task) - 任务对象
        • view? - (any) - 添加图层的布局单元(默认是时间线)
        • config? - (GanttConfigOptions) - Gantt配置对象
        • gantt? - (GanttStatic) - Gantt对象
      • getVisibleRange - (Function): {start: number, end: number} | undefined | void - 可选,返回可见范围对象
        • gantt? - (GanttStatic) - Gantt对象
        • view? - (any) - 添加图层的布局单元(默认是时间线)
        • config? - (GanttConfigOptions) - Gantt配置对象
        • datastore? - (any) - 任务数据存储对象
        • viewport? - (LayerViewport) - 视口对象
    • container? - (HTMLElement) - 可选,图层的容器元素
    • topmost? - (boolean) - 可选,若为true,元素将显示在任务之上
    • filter? - (Function): boolean - 可选,接收任务对象,返回false时跳过该任务的渲染
      • task - (Task) - 任务对象

图层视口包含以下属性:

  • viewport - (object) - 图层的视口对象

    • x - (number) - 矩形左边位置
    • x_end - (number) - 矩形右边位置
    • y - (number) - 矩形顶部位置
    • y_end - (number) - 矩形底部位置
    • width - (number) - 矩形宽度
    • height - (number) - 矩形高度
  • 请注意,自定义图层会在下一次调用 gantt.init 后被清除。

  • 同时,调用 gantt.resetLayout() 会重置自定义图层。若要保持自定义图层可见,需要在调用 resetLayout 后重新定义 gantt.addTaskLayer

自定义图层的智能渲染

智能渲染旨在仅显示用户可见的HTML元素,避免渲染被滚动条遮挡的元素。

然而,对于自定义图层,Gantt本身并不知道自定义元素的位置,因为渲染逻辑完全由用户控制。

为了解决这个问题,智能渲染假设自定义元素位于其关联任务的同一行。只有当任务所在行在屏幕上可见时,自定义元素才会被添加到DOM中。在此方式下,Gantt忽略水平滚动条的位置,因此自定义元素可能存在于标记中,但如果水平滚动超出视野,则不可见。

这种方法通常效果良好,但如果你有很多图层,可能需要通过提供自定义元素的精确位置来进一步优化渲染。

为此,请使用 addTaskLayer() 方法的对象参数,并向 renderer 对象提供以下方法:

  • render - 渲染函数
  • getRectangle - 返回自定义元素坐标的函数
gantt.addTaskLayer({
    renderer: {
        render: function(task, timeline, viewport){
            ...
            return  HTMLElement
        },
        getRectangle: function(task, view){
            ....
            return {left, top, height, width};
        }
    }
});

自定义元素的渲染流程如下:

1. 当水平滚动位置变化时,智能渲染获取当前可见区域的坐标。
2. dhtmlxGantt 调用 getRectangle 获取每个任务/链接的自定义元素精确坐标。
3. 若 getRectangle 返回 null,则跳过调用 render,不显示自定义元素。
4. 若 getRectangle 返回的坐标与当前视口重叠,则调用 render 显示自定义元素。

gantt.addTaskLayer({
    renderer: {
      render: 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;
      },
      // 定义 getRectangle 使图层接入智能渲染
      getRectangle: function(task, view){
        return gantt.getTaskPosition(task, task.planned_start, task.planned_end);
      }
    }
});

渲染自定义元素的可见部分

addTaskLayer() 中的 renderer 对象还支持通过 update 方法更新节点标记,仅显示自定义元素的可见部分:

gantt.addTaskLayer({
    renderer: {
        render: function(task, timeline, viewport){
            ...
            return  HTMLElement
        },
        update: function(task, node, timeline, viewport){
            ...
            // 更新节点内部HTML以显示当前可见部分
        },
        getRectangle: function(task, view){
            ....
            return {left, top, height, width};
        }
    }
});
  • update - 允许刷新自定义元素的内部HTML,例如隐藏不可见部分,仅显示可见部分

update 方法会在 onGanttScroll 事件后触发,提供由 render 创建的任务节点及当前视口。

渲染可见的任务行

从v7.1.8开始,renderer 对象支持 getVisibleRange 函数,用于指定任务行的可见范围:

gantt.addTaskLayer({
    renderer: {
        render: function(task, timeline, viewport){
            ...
            return  HTMLElement
        },
        getVisibleRange: function(){
            ...
            return { 
                start: indexStart,
                end: indexEnd
            }
        }
    }
});
  • getVisibleRange - 返回一个对象,包含可见任务行的起始和结束索引。范围外的任务不会渲染额外图层。

如果 getVisibleRange 返回 false 而非对象,Gantt 会假设所有任务均可见,并为所有任务渲染额外图层。

元素渲染回调

renderer 对象还包含一个 onrender 回调:

gantt.addTaskLayer({
    renderer: {
        render: function(task, timeline, viewport){
            ...
            return  HTMLElement
        },
        onrender: function(item, node, view){
            console.log("render", item, node)
        }
    }
});

onrender 函数在每次数据项渲染到DOM时调用,提供对数据项、生成的DOM元素以及触发渲染的视图(grid或timeline)的访问。

此回调可用于渲染后修改DOM元素,或在渲染元素内初始化第三方控件。

See also
  • API
  • Articles
  • Back to top