甘特图(ant-gantt)
在项目管理中,甘特图的可视化操作界面,可以让项目规划与风险把控更便捷与清晰,同时该插件是一款基于HTML5、javasrcipt的一款js插件,支持在当前主流的前端框架中接入。
效果图:
如何使用
1、下载插件
官网地址:https://www.aim.link/h5/KA.html
2、导入项目
将下载到的sdk拷贝至项目工程目录,如拷贝至:
externalSdk/ant-gantt/index.js
externalSdk/ant-gantt/index.css
3、开发实践
3.1 原生js嵌入
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#ant-gantt {
width: 100%;
height: 100%;
}
</style>
<link rel="stylesheet" type="text/css" href="/externalSdk/ant-gantt/index.css"/>
<script type="text/javascript" src="/externalSdk/ant-gantt/index.js" defer></script>
</head>
<body>
<div id="ant-gantt"></div>
</body>
</html>
const columns = [
{
title: '编号',
dataIndex: 'wbs',
width: 48,
},
{
title: '任务名称',
dataIndex: 'name',
width: 200
},
];
const config = { mode: 'day', grid: { columns } };
const instance = new Gantt('#ant-gantt', config);
const data = [
{
id: 'task.1',
editable: true,
wbs: '2',
milestone:"1",
name: '任务01',
fzr: 'x先生',
type: 't',
status: 2,
beginTime: "2021-06-02",
children: []
},
];
instance.render(data);
3.2 react嵌入
import React from 'react';
import ReactDOM from 'react-dom'
import AntGantt from '@/externalSdk/ant-gantt'; // @为项目资源目录的alias
import '@/externalSdk/ant-gantt/index.css';
const GanttView = (props) => {
const gridRef = React.useRef(null);
const handleClick = (record) => {
console.log(record);
};
React.useLayoutEffect(() => {
const columns = [
{
title: '编号',
dataIndex: 'wbs',
width: 48,
},
{
title: '任务名称',
dataIndex: 'name',
width: 200,
render: (text, record) => {
/* 渲染react节点
** 如果渲染节点存在异步交互,需要传递callback
*/
return (node, callback) => {
ReactDOM.render(
<span onClick={() => handleClick(record)}>{text}</span>,
node,
callback
);
};
}
},
{
title: '负责人',
dataIndex: 'fzr',
width: 120,
}
];
const config = {
mode: 'day',
grid: {
collapseIndex: 1,
columns
}
};
gridRef.current = new AntGantt('#ant-gantt', config);
}, []);
React.useEffect(() => {
Promise.resolve().then(() => {
const data = [
{
id: 'task.1',
editable: true,
wbs: '2',
milestone:"1",
name: '任务01',
fzr: 'x先生',
type: 't',
status: 2,
beginTime: "2021-06-02",
children: []
},
];
const instance = gridRef.current;
instance.render(data);
})
return () => instance && instance.destroy();
}, []);
return (
<div id="ant-gantt"></div>
);
};
export default GanttView;
3.3 vue2嵌入
<template>
<div id="gantt" class="m-gantt"></div>
</template>
<style scoped>
.m-gantt {
width: 100%;
height: 100%;
}
</style>
<script>
import AntGantt from '@/externalSdk/ant-gantt';
import '@/externalSdk/ant-gantt/index.css';
export default {
data() {
return {
config: {
mode: 'day',
grid: {
collapseIndex: 1
}
}
}
},
mounted() {
this.init()
},
beforeDestroy() {
this.gInstance?.destroy();
},
methods: {
init() {
const { grid } = this.config;
grid.columns = this.getColumns();
this.gInstance = new AntGantt('#gantt', this.config);
this.getData().then(data => this.gInstance.render(data));
},
getColumns() {
return [
{
title: '编号',
dataIndex: 'wbs',
width: 48,
},
{
title: '任务名称',
dataIndex: 'name',
width: 200,
render: (text, record) => {
const el = document.creactElement('span');
span.innerText = text;
el.onClick = () => {
this.handleClick(record);
};
return el;
}
},
];
},
getData() {
return Promise.resolve([
{
id: 'task.1',
editable: true,
wbs: '2',
milestone:"1",
name: '任务01',
fzr: 'x先生',
type: 't',
status: 2,
beginTime: "2021-06-02",
children: []
},
]);
}
}
}
</script>
数据格式(dataItem)
1、基本类型
type为i、t、itemNew时,通用的节点字段
参数 | 说明 | 类型 | 默认值 |
---|
id | 节点id - 必填 | string | 必填项 |
name | 节点名称 | string | 必填项 |
type | 节点类型 | i - 组节点、t - 节点、itemNew - 临时节点(基本字段同类型t) | 必填项 |
total | 子节点数量 | number | - |
children | 子节点列表 | dataItem[] | - |
hasMore | 是否有更多子节点 - 用于显示加载更多 | boolean | - |
isLeaf | 是否是叶子节点 - 用于显示是否可展开 | boolean | - |
2、标准类型(type === t)
参数 | 说明 | 类型 | 默认值 |
---|
beginTime | 计划开始日期 | string | - |
endTime | 计划结束日期 | string | - |
realityBeginTime | 实际开始日期 | string | - |
realityEndTime | 实际结束日期 | string | - |
rangeBeginTime | 范围开始日期 - 自身以及子节点时的日期范围 | string | - |
rangeEndTime | 范围结束日期 - 自身以及子节点时的日期范围 | string | - |
milestone | 是否是里程碑 | boolean | - |
status | 节点状态,字段名称可由calendarConfig.statusKey定义 | string | - |
createFS/createSF/createFF createSS | 是否可关联不同的节点关系 | boolean | - |
FS/SF/FF/SS | 节点关系 | object[] | - |
disabled | 是否可编辑 | Boolean | - |
3、分组类型(type === i)
参数 | 说明 | 类型 | 默认值 |
---|
rangeBeginTime | 范围开始日期 - 自身以及子节点时的日期范围 | string | - |
rangeEndTime | 范围结束日期 - 自身以及子节点时的日期范围 | string | - |
配置相关
1、基础配置 - config
参数 | 说明 | 类型 | 默认值 |
---|
locale | 显示语言 - zh-CN、en-US、zh-TW | string | zh-CN |
mode | 视图类型 - year、halfYear、season、month、week、day | string | day |
format | 日期格式 | string | YYYY-MM-DD |
rowKey | 数据的唯一键值 | string | id |
showExpand | 是否可展开 | boolean | true |
expandedKeys | 展开的节点 | rowKey[] | [] |
collapse | 表格视图是否可收起 | boolean | true |
parentChild | 父子节点是否可关联 | boolean | false |
autoPairing | 是否开启自动编排,开启后, | boolean | false |
colWidth | 列宽 - 描述一天表示的宽度 | number | 32 |
rowHeight | 行高 - 描述数据行的高度 | number | 32 |
hasMore | 是否有更多数据 | boolean | false |
loadMore | 是否支持加载更多 | boolean | false |
loadMoreText | 显示文案 | string | 加载更多 |
grid | 表格视图配置项 | gridConfig | 详细配置 |
calendar | 日期视图配置项 | calendarConfig | 详细配置 |
link | 关联关系 | linkConfig | 详细配置 |
resizer | 列调节器 | resizerConfig | 详细配置 |
exportImg | 导出甘特图,可导出png图片。size为支持的图片大小,name导出图片的名称 | (size, name) => Promise<{url, name, …other}> | - |
onExpand | 展开收起子节点的回调 | (expandedKeys, row) => void | - |
onCollapse | 展开/收起表格视图的回调 | (collapse) => void | - |
onLoadMore | 点击加载更多是,加载数据的回调 | (record) => void | - |
onLoadData | 节点展开时,加载数据的回调 | (record) => void | - |
onItemClick | 点击行时的回调 | (record) => void | - |
onItemLinkChange | 关联关系发生变化时的回调, 第二个参数err,提供回调函数onError,当异步更新失败后,调用onError来重置数据状态 | (linkData, err) => void | - |
onItemChange | 数据发生变化时的回调, 第二个参数err,提供回调函数onError,当异步更新失败后,调用onError来重置数据状态 | (params, record, err) => void | - |
2、表格配置 - gridConfig
参数 | 说明 | 类型 | 默认值 |
---|
show | 是否显示表格 | boolean | true |
columns | 表格列,如果show为true,该值不能为空 | columnType[] | 详细配置 |
layout | 表格列是否可拖拽 | boolean | true |
width | 表格最大宽度。超出时,则支持滚动 | number | 400 |
defColW | 默认列宽 - 每列最小宽度 | number | 80 |
expandedWidthKey | 支持展开的列字段 | string | name |
collapseIndex | 收起时,显示列的位置 | number | 1 |
2.1 列配置 - columnType
参数 | 说明 | 类型 | 默认值 |
---|
name | 列名称 | string | - |
dataIndex | 列字段,唯一值 | string | - |
width | 自定义列宽 | number | 80 |
hidden | 列是否显示 | boolean | false |
render | 自定义渲染方法 | (text, record) => string |htmlElement | function | - |
render = (text, record) => {
return (node, callback) => {
Promise.resolve().then(() => {
node.appendChild(document.createElement('div'));
callback && callback();
});
};
}
3、日历配置 - calendarConfig
参数 | 说明 | 类型 | 默认值 |
---|
showYear | 是否显示年份 | boolean | true |
beginTime | 描述项目的开始日期,在视图上绘制起始线 | string | - |
endTime | 描述项目的结束日期,在视图上绘制截止线 | string | - |
statusKey | 视图色块对应的DataItem字段 | string | status |
statusMap | 不同状态,对应的颜色 | string[] | [“#16AD31”, “#B5C5CD”, “#4463ED”, “#1990FF”, “#DCDADD”, “#DCDADD”, “#DCDADD”, “#F6313B”, “#B5C5CD”, “#B5C5CD”, “#88AD8E”] |
showTimeline | 是否显示当前时间线 | boolean | true |
endTimePlaceholder | 超出结束日期的提示文案 | string | ‘’ |
getDisableDate | 获取非工作日期的方法 | (beginTime, endTime) => (YYYY-MM-DD)[] | 默认以周六、周日为节点日 |
4、列调节器 - resizerConfig
参数 | 说明 | 类型 | 默认值 |
---|
show | 是否显示调节器 | boolean | true |
width | 调节器占位宽度 | number | 20 |
5、关联关系配置 - linkConfig
参数 | 说明 | 类型 | 默认值 |
---|
type | 可关联的关系类型,默认为空,支持全部关系 | FS/FF/SF/SS | ‘’ |
typesMap | 不同关联关系类型对应的字段映射 | typeMap[] | 详细配置 |
show | 是否显示操作栏 | boolean | true |
delayConfig | 延迟项配置 | delayConfig | 详细配置 |
deleteConfig | 删除项配置 | deleteConfig | 详细配置 |
5.1 typeMap
参数 | 说明 | 类型 | 默认值 |
---|
type | 关联关系类型 | FS/FF/SF/SS | ‘’ |
field | 关联关系类型对应的字段 | string | FS/FF/SF/SS |
5.2 delayConfig
参数 | 说明 | 类型 | 默认值 |
---|
min | 延迟最小值 | number | 0 |
max | 延迟最大值 | number | 99 |
decimals | 延迟值的精确度 | number | 0 |
show | 是否显示延迟操作栏 | boolean | true |
5.3 deleteConfig
参数 | 说明 | 类型 | 默认值 |
---|
show | 是否显示删除栏 | boolean | true |
api 相关
destroy
const instance = new AntGantt('#app', { grid: { show: false } });
instance.destroy();
render
const instance = new AntGantt('#app', { grid: { show: false } });
const data = [];
const config = {};
instance.render(data, config);
refresh
const instance = new AntGantt('#app', { grid: { show: false } });
const data = [];
instance.refresh(data, { expandKeys: [] });
updateConfig
const instance = new AntGantt('#app', { grid: { show: false } });
const config = { showYear: false };
instance.updateConfig(config);
refreshConfig
const instance = new AntGantt('#app', { grid: { show: false } });
const config = { showYear: false };
const viewType = null;
instance.refreshConfig(config, viewType);