跳到主要内容

指定列

可以通过 columns 参数设置网格列。

gantt_left

// 默认列定义
gantt.config.columns = [
{ name: "text", label: "Task name", width: "*", tree: true },
{ name: "start_date", label: "Start time", align: "center" },
{ name: "duration", label: "Duration", align: "center" },
{ name: "add", label: "", width: 44 }
];

我们还为如何配置网格列提供了视频教程。

概述

默认情况下,网格显示 4 列:

  1. Task name
  2. Start date
  3. Duration
  4. "+" 列。此特殊列,name="add",显示一个"+"号,允许用户添加子任务。
注释

注意,无需指定 columns 参数即可在网格中显示默认列。

columns 参数是一个数组,每个对象定义一列。 例如,要定义名为 'Task'、'Start Date'、'End Date'、'Holder' 和 'Progress' 的 5 列,可以这样设置 columns 参数:

gantt.config.columns = [
{ name: "text", label: "Task name", tree: true, width: "*" },
{ name: "holder", label: "Holder", align: "center" },
{ name: "start_date", label: "Start time", align: "center" },
{ name: "end_date", label: "End date", align: "center" },
{ name: "progress", label: "Progress", align: "center" }
];

gantt.init("gantt_here");

这里,'text'、'holder'、'start_date'、'end_date' 和 'progress' 对应于数据属性的名称

显示任务结束日期

如果任务数据对象包含格式为 "%Y-%m-%d" 或 "%d-%m-%Y"(不含小时和分钟)的开始和结束日期,默认格式下显示的结束日期可能不是你期望的。有关结束日期格式化的详细信息,请参阅 Task end date display & Inclusive end dates 文章。

为特定任务隐藏"添加"按钮

一种简单的方式是通过 CSS 隐藏"Add"按钮,防止用户为某些任务添加子任务。

  1. 首先,使用 grid_row_class 模板为每一行任务分配 CSS 类:
gantt.templates.grid_row_class = ( start, end, task ) => {
if ( task.$level > 1 ) {
return "nested_task"
}

return "";
};
  1. 然后,用 CSS 隐藏这些行中的"Add"按钮:
.nested_task .gantt_add {
display: none !important;
}

Predefined Project Structure

宽度

要控制列的宽度,可在配置对象中使用 width 属性:

gantt.config.columns = [
{ name: "text", label: "Task name", width: "*", tree: true },
{ name: "start_date", label: "Start time", width: 150 },
{ name: "duration", label: "Duration", width: 120 }
];

gantt.init("gantt_here");
注释

使用 '*' 作为宽度会让该列占据所有剩余空间。

请注意,网格列的宽度取决于两项设置:列的 width 和整体 grid_width。如果所有列宽之和与网格宽度不一致,Gantt 会调整其中之一。

Related example: Column width priority over grid width at initialization

Related example: Grid width priority over column width during rendering

Related example: Grid width priority when column width is undefined or set to '*' at initialization

最小/最大列宽

你可以通过 min_widthmax_width 属性限制列在调整大小时的宽度:

gantt.config.columns = [
{ name: "text", label: "Task name", width: "*", tree: true, min_width: 150,
max_width: 300
},
{ name: "start_date", label: "Start time", width: 150 },
{ name: "duration", label: "Duration", width: 120 }
];

gantt.init("gantt_here");
注释

列的 min_width 属性会覆盖 gantt 的 min_grid_column_width 设置。

调整大小时的最小网格宽度

网格可调整到的最小宽度由 gantt.config.min_grid_column_width 设置。该选项定义了调整网格大小时每列的最小宽度:

gantt.config.columns = [
{ name: "text", label: "Task name", width: 150, tree: true },
{ name: "start_date", label: "Start time", width: 100 },
{ name: "duration", label: "Duration", width: 50 }
];

gantt.config.min_grid_column_width = 30; // 网格总宽度最小可调整到 90 px

gantt.init("gantt_here");

Related example: Minimal grid width

另外,调整大小时的最小网格宽度还受"add"列的最小宽度影响(默认为 44)。如果要将网格缩小到小于 44 px,请为"add"列设置 min_width:

{ name: "add", label: "", min_width: 1 }

数据映射与模板

默认情况下,dhtmlxGantt 使用与列名相同的数据属性填充网格。例如,如果某列为 name:"holder",dhtmlxGantt 会查找 JSON 数据中的 'holder' 属性,并在该列显示。

为列数据使用模板

如果你希望在一列中显示多个数据属性的组合,可以为该列指定任意名称,并通过 columns 参数的 template 属性设置数据模板。

例如,你可以将列命名为 name:"staff",并创建一个模板函数,返回 holderprogress 属性的组合值:

gantt.config.columns = [
{ name: "text", label: "Task name", tree: true, width: "*" },
{ name: "start_date", label: "Start time", align: "center" },
{ name: "staff", label: "Holder(s)", template: (obj) => {
return `${obj.holder} (${obj.progress})`;
} }
];

gantt.init("gantt_here");

文本对齐

要设置列中文本的水平对齐方式,可在该列配置中使用 align 属性:

gantt.config.columns = [
{ name: "text", label: "Task name", align: "center", tree: true },
{ name: "start_date", label: "Start time", align: "center" },
{ name: "duration", label: "Duration", align: "center" }
];

gantt.init("gantt_here");

WBS 编码

你可以添加一列来显示任务的大纲编号(WBS 编码)。为此,在该列的模板中使用 getWBSCode 方法。

gantt.config.columns = [
{ name: "wbs", label: "WBS", width: 40, template: gantt.getWBSCode }, /*!*/
{ name: "text", label: "Task name", width: 170, tree: true },
{ name: "start_date", label: "Start time", width: 90, align: "center" },
{ name: "duration", label: "Duration", width: 60, align: "center" },
{ name: "add", width: 40 }
];

Show Task WBS Codes (Outline Numbers)

获取任务的 WBS 编码

getWBSCode 方法返回指定任务的 WBS 编码。例如,如果你将如下任务加载到 gantt:

gantt.parse({
tasks: [
{ id: 1, text: "Project", start_date: "28-03-2025", duration: 5, open: true },
{ id: 2, text: "Task #1", start_date: "01-04-2025", duration: 3, parent: 1 },
{ id: 3, text: "Task #2", start_date: "02-04-2025", duration: 4, parent: 1 }
],
links: []
});

如果你想获取 id="3" 的任务的 WBS 编码,只需将该任务对象传递给 getWBSCode。它会返回 WBS 编码字符串:

const wbsCode = gantt.getWBSCode(gantt.getTask(3)); // -> 返回 "1.2"

通过 WBS 代码获取任务

可以通过将任务的 WBS 代码传递给 getTaskByWBSCode 方法来获取任务对象:

const task = gantt.getTaskByWBSCode("1.2");
// => { id: 3, text: "Task #2", start_date: …}

任务的时间约束

信息

此功能仅在 PRO 版本中可用

你可以添加特定的网格列,以便为任务设置时间约束类型,以及在所选类型需要时设置约束日期。这些列分别命名为 "constraint_type" 和 "constraint_date"。

gantt.config.columns = [
{ name: "constraint_type", align: "center", width: 100, resize: true,
editor: constraintTypeEditor, template: (task) => { //template logic }
},
{ name: "constraint_date", align: "center", width: 120, resize: true,
editor: constraintDateEditor, template: (task) => { //template logic }
},
...
];

这些列与内联编辑器对象关联,可让你直接在网格中选择任务的约束类型并修改其日期。

const constraintTypeEditor = {
type: "select", map_to: "constraint_type", options: [
{ key: "asap", label: gantt.locale.labels.asap },
{ key: "alap", label: gantt.locale.labels.alap },
{ key: "snet", label: gantt.locale.labels.snet },
{ key: "snlt", label: gantt.locale.labels.snlt },
{ key: "fnet", label: gantt.locale.labels.fnet },
{ key: "fnlt", label: gantt.locale.labels.fnlt },
{ key: "mso", label: gantt.locale.labels.mso },
{ key: "mfo", label: gantt.locale.labels.mfo }
]
};

const constraintDateEditor = {
type: "date",
map_to: "constraint_date",
min: new Date(2025, 0, 1),
max: new Date(2030, 0, 1)
};

Auto-Schedule From Project Start & Constraints

调整列宽

信息

此功能仅在 PRO 版本中可用

若要允许用户通过拖动列的右边框来调整列宽,需要在相应列的配置中启用 resize 属性:

gantt.config.columns = [
{ name: "text", resize: true, tree: true, width: "*" }, // 启用 'resize'
{ name: "start_date", resize: true, min_width: 100 }, // 受 'min_width' 限制
{ name: "duration", align: "center" }, // 未启用调整
{ name: "add", width: "44" }
];

Grid columns resize events

如果要让整个网格通过拖动边界进行缩放,请使用 gantt.config.layout 选项,并定义包含合适设置的 grid 和 resizer 对象:

gantt.config.layout = {
css: "gantt_container",
rows: [
{
cols: [
{ view: "grid", id: "grid", scrollX: "scrollHor",
scrollY: "scrollVer"
},
{ resizer: true, width: 1 },
{ view: "timeline", id: "timeline", scrollX: "scrollHor",
scrollY: "scrollVer"
},
{ view: "scrollbar", id: "scrollVer", scroll: "y" }
]
},
{ view: "scrollbar", id: "scrollHor", scroll: "x", height: 20 }
]
};

gantt.init("gantt_here");

若要在调整列宽时保持网格宽度不变,可将 keep_grid_width 选项设置为 true:

gantt.config.columns = [
{ name: "text", width: "*", tree: true, resize: true },
{ name: "start_date", width: 100, align: "center" },
{ name: "duration", width: 70, align: "center" },
{ name: "add", width: 44 }
];

gantt.config.keep_grid_width = true; /*!*/
gantt.init("gantt_here");

Grid columns resize events

事件

dhtmlxGantt 提供了 6 个与调整大小相关的事件:

列可见性

要控制列的可见性,请在列配置中使用 hide 属性。

你可以通过动态更新 'hide' 属性并刷新 Gantt 图来改变列的可见性:

信息

此功能仅在 PRO 版本中可用

在基础视图和详细视图之间切换

gantt.config.columns = [
{ name: "text", label: "Task name", width: "*", tree: true, resize: true },
{ name: "start_date", label: "Start time" },
{ name: "duration", label: "Duration", width: 60, hide: true }, /*!*/
{ name: "planned_start", label: "Planned start", width: 80, hide: true }, /*!*/
{ name: "planned_end", label: "Planned end", width: 80, hide: true }, /*!*/
{ name: "add", label: "", width: 36 }
];

const showDetails = false;

function toggleView() {
showDetails = !showDetails;
gantt.getGridColumn("duration").hide = !showDetails;
gantt.getGridColumn("planned_start").hide = !showDetails;
gantt.getGridColumn("planned_end").hide = !showDetails;

if (showDetails) {
gantt.config.grid_width = 600;
} else {
gantt.config.grid_width = 300;
}

gantt.render();
};

gantt.init("gantt_here");

Hiding grid columns

此外,还提供了一个视频指南,演示如何管理网格中列的可见性。

渲染后修改单元格

有时需要在网格单元格渲染后调整其外观或行为。

自 7.1 版本起,库在 columns 配置中引入了 onrender 属性,可以用来在渲染后修改单元格,例如:

gantt.config.columns = [
{ name: "text", tree: true, width: "*", resize: true },
{ name: "start_date", align: "center", resize: true },
{ name: "duration", align: "center", onrender: (task, node) => {
node.setAttribute("title", task.text);
} },
{ name: "add", width: 44 }
];

onrender 回调的另一个用例是将外部组件注入到网格单元格中。例如,如果你在 DHTMLX Gantt 中使用 React,并希望在单元格中插入 React 组件,可以参考如下代码:

gantt.config.columns = [
{ name: "text", label: "Task name", tree: true, width: "*" },
{ name: "start_date", label: "Start time", align: "center" },
{ name: "duration", label: "Duration", align: "center" },
{
name: "external", label: "Element 1", align: "center",
onrender: (item, node) => {
return <DemoButton
text="Edit 1"
onClick="{()" => alert("Element as React Component")}
/>
}
}
];

要启用 React 组件的渲染,必须指定 gantt.config.external_render 配置:

import ReactDOM from 'react-dom';
import React from 'react';

gantt.config.external_render = {
// 检查元素是否为 React 元素
isElement: (element) => {
return React.isValidElement(element);
},
// 在 DOM 中渲染 React 元素
renderElement: (element, container) => {
ReactDOM.render(element, container);
}
};

流程说明如下:

  • onrender 回调返回的对象会传递给 isElement 函数,用于判断其是否为当前框架/库可渲染的对象。
  • 如果 isElement 返回 true,则对象会传递给 renderElement,在单元格 DOM 元素内部初始化组件。

水平滚动条

通过在 layout 配置中启用 scrollable 属性,可以让网格支持滚动。 了解更多关于将布局视图绑定到滚动条的信息

为网格添加水平滚动条后,Gantt 可在调整网格大小时自动调整列宽。了解更多关于启用此功能的信息

除了设置 scrollable 属性外,还需要在布局中添加 水平滚动条元素 并将其与网格关联,如下所示:

gantt.config.layout = {
css: "gantt_container",
cols: [
{
width: 400,
minWidth: 200,
maxWidth: 600,

// 通过 scrollX 属性为网格添加水平滚动条
rows: [
{ view: "grid", scrollX: "gridScroll", scrollable: true, /*!*/
scrollY: "scrollVer" /*!*/
}, /*!*/
{ view: "scrollbar", id: "gridScroll" } /*!*/
]
},
{ resizer: true, width: 1 },
{
rows: [
{ view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
{ view: "scrollbar", id: "scrollHor" }
]
},
{ view: "scrollbar", id: "scrollVer" }
]
};

当为网格和时间线分别使用滚动条时,可以通过同步它们的可见性,使两者同时显示或隐藏。

scrollable_grid

实现方法是将两个滚动条分配到同一个 visibility group:

gantt.config.layout = {
css: "gantt_container",
cols: [
{
width: 400,
minWidth: 200,
maxWidth: 600,
rows: [
{ view: "grid", scrollX: "gridScroll", scrollable: true,
scrollY: "scrollVer"
},
// 网格的水平滚动条
{ view: "scrollbar", id: "gridScroll", group: "horizontal" } /*!*/
]
},
{ resizer: true, width: 1 },
{
rows: [
{ view: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
// 时间线的水平滚动条
{ view: "scrollbar", id: "scrollHor", group: "horizontal" } /*!*/
]
},
{ view: "scrollbar", id: "scrollVer" }
]
};

只要组内有任意一个滚动条可见,组内所有滚动条都会显示。

Horizontal scroll inside Grid

样式

关于网格单元格样式的详细信息,请参见 Gantt 스타일 작업하기