普加甘特图使用
先看看图的效果
PlusGantt(普加甘特图)是使用Javascript开发的、基于Web网页的甘特图控件。可广泛应用于项目管理系统、 ERP 系统、MES系统或其它的任务资源分配相关领域。基于WEB网页显示,无需安装任何插件。 显示为左侧任务表格、右侧时间轴刻度条形图的甘特图界面。 支持跟踪甘特图视图。可对比“计划任务”与“实际任务”的区别。 支持分级加载,不一次性加载全部数据。这样可以支持大数据量显示。 支持年/月/日/时/分/秒等不同时间刻度单位。 支持表格列、条形图外观、ToolTip提示信息、右键菜单等任意自定义。 跨所有浏览器显示,如IE(1.5+)、FireFox、Chrome、Opera、Safari等。 跨任意服务端平台,如ASP.NET、ASP、PHP、JSP、ColdFusion、Ruby on Rails等都可以使用。 语言本地化。包括英语、中文、日文和其他任意的语言。 PlusGantt只需要您提供一个简单的数据结构,就能在WEB网页上显示一个漂亮的甘特图。 您可以轻松修改它任意部位的外观,比如单元格、条形图、提示信息等。
甘特图数据结构
1.列表结构(UID、ParentTaskUID):
[{ "UID": "1", "Name": "项目范围规划", "Duration": 8, "Start": "2007-01-01T00:00:00", "Finish": "2007-01-10T00:00:00", "PercentComplete": 0, "Summary": 1, "Critical": 0, "Milestone": 0, "PredecessorLink": [], "ParentTaskUID": -1 }, { "UID": "2", "Name": "确定项目范围", "Duration": 1, "Start": "2007-01-01T00:00:00", "Finish": "2007-01-01T23:23:59", "PercentComplete": 0, "Summary": 0, "Critical": 0, "Milestone": 0, "PredecessorLink": [], "ParentTaskUID": "1" }, { "UID": "3", "Name": "获得项目所需资金", "Duration": 2, "Start": "2007-01-02T00:00:00", "Finish": "2007-01-03T23:23:59", "PercentComplete": 0, "Summary": 0, "Critical": 0, "Milestone": 0, "PredecessorLink": [{ "Type": 1, "PredecessorUID": "2" }], "ParentTaskUID": "1" }, ... ]
2.树形结构(children):
[ { UID: "1", //任务唯一标识符 Name: "项目范围规划", //任务名称 Duration: 4, //工期 Start: "2007-01-01T00:00:00", //开始日期 Finish: "2007-01-04T23:59:59", //完成日期 PercentComplete: 14, //完成百分比 Summary: 1, //摘要任务 Critical: 1, //关键任务 Milestone: 0, //里程碑 PredecessorLink: [], //前置任务 children: [ { UID: "2", Duration: 4, Start: "2007-01-01T08:00:00", Finish: "2007-01-01T12:00:00", PercentComplete: 100, Summary: 0, Critical: 1, Name: "确定项目范围", Milestone: 0, PredecessorLink: [] }, { UID: "3", Duration: 8, Start: "2007-01-01T13:00:00", Finish: "2007-01-02T12:00:00", PercentComplete: 0, Summary: 0, Critical: 1, Name: "获得项目所需资金", Milestone: 0, PredecessorLink: [ //前置任务 { PredecessorUID: "2", Type": 1 } ] }, ....//更多子任务 ] }, .... //更多任务 ]
任务属性描述如下: UID:必须。String。唯一标识符。是一个任意的字符串或数字,确保任务UID不重复。 Name:必须。String。任务名称。 Start:必须。Date。开始日期。 Finish:必须。Date。完成日期。 Duration:必须。Number。工期。 PercentComplete:必须。Number(0~100)。完成百分比。显示为上下居中的进度条。 PredecessorLink:Array。前置任务。 四种任务关系Type:完成-完成(FF) 0,完成-开始(FS) 1,开始-完成(SF) 2,开始-开始(SS) 3。 Summary:Number(0或1)。摘要任务。当一个任务下有子任务的时候,这个任务就是摘要任务,当Summary为1时,此任务会两端黑色箭头显示。 Critical:Number(0或1)。关键任务。当Critical为1时,显示一个红色条形图。 Milestone:Number(0或1)。里程碑。当Milestone为1时,显示一个菱形图标。
对页面的操作基于原始Dom元素的。 所以,你可以不用做任何额外的处理,按PlusProject正常的例子,把项目甘特图对象加入到页面元素就可以了。 其次,对于ExtJS这样封装度很高的框架,可以从Ext对象找到它的dom,然后render加入即可。使用代码如下: //获取ext控件对象 var extControl = Ext.get(id); //设置尺寸为100%自适应 gantt.setStyle("width:100%;height:100%"); //把project加入到ext控件对象的dom属性中 gantt.render(extControl.dom);
只需要这样设置后,PlusProject就能在Ext的布局面板中自动调整尺寸大小,看上去跟Ext原生的控件一样了。
语言本地化 如果要显示他语言界面,只需要引用locale文件夹下资源js文件即可,例如英文资源包使用如下: <script src="../scripts/miniui/locale/en_US.js" type="text/javascript"></script>
PlusGantt ( API )
属性可以从对象直接读取,但是不能进行赋值操作。如果想对属性进行赋值,必须使用提供的方法。
var gantt = new PlusGantt(); var visible= gantt.visible; //正确 gantt.visible= true; //错误!!! gantt.setVisible(true); //正确
属性 | 类型 | 描述 |
readOnly | Boolean | 是否只读。 |
visible | Boolean | 是否显示。 |
style | String | 样式。 |
width | Number | 宽度。 |
height | Number | 高度。 |
showTableView | Boolean | 是否显示任务表格。 |
showGanttView | Boolean | 是否显示条形图。 |
showLinkLines | Boolean | 是否显示箭头连线。 |
showCritical | Boolean | 是否显示关键路径 |
showGridLines | Boolean | 是否条形图表格线。 |
timeLines | Array | 时间线数组。[ {date: new Date(2007, 0, 3), text: "时间线"}, {date: new Date(2007, 0, 5), text: "时间线2", style: "width:2px;background:red;"} ] |
rowHeight | Number | 行高。 |
allowDragDrop | Boolean | 是否允许任务行拖拽。 |
multiSelect | Boolean | 是否允许多选任务。 |
allowResize | Boolean | 是否允许拖拽调整甘特图。 |
方法 | 参数类型 | 描述 |
setStyle(String) | 设置样式,比如:gantt.setStyle("width:100%;height:400px")。 | |
loadTasks(Array) | 加载任务集合(树形)。 | |
getTaskTree() | 返回任务树形集合。 | |
getTaskList() | 返回任务列表集合。 | |
getRemovedTasks() | 返回被删除的任务集合。 | |
acceptChanges() | 恢复任务状态(撤销任务增加、删除、修改标记)。 | |
setColumns( Array ) | 设置表格列集合。 | |
setTreeColumn( String ) | 设置树形节点列。 | |
findTasks(field, value) | field:String。如"Duration"。 value:Object。属性值。 |
返回符合条件的任务集合。 |
getTask(taskUID) | 根据任务UID,获取任务。 | |
getTaskByID(taskID) | 根据任务ID,获取任务。project.filter(function(task){ if(task.Duration == 2) return true; else return false; }); |
|
clearFilter() | 取消过滤任务 | |
getSelected() | 获取选中的任务。 | |
getSelecteds() | 获取选中的任务集合。 | |
isSelected(task) | 判断是否选中任务。 | |
select(task) | 选中任务。 | |
deselect(task) | 取消选中任务。 | |
selects(Array) | 选中多个任务。 | |
deselects(Array) | 取消选中多个任务。 | |
selectAll() | 选中所有任务。 | |
deselectAll() | 取消选中所有任务。 | |
getParentTask(task) | 获取父任务对象。 | |
getChildTasks(task) //下一级任务 | 获取子任务数组。 | |
getAllChildTasks(task) | 获取所有子任务数组。 | |
getAncestorTasks(task) | 获取父级任务数组。 | |
isAncestor(parentTask, task) | 判断两任务之间是否有父子关系。 | |
eachChild(task, fn, scope) | 遍历下一级子节点。 | |
cascadeChild(task, fn, scope) | 遍历所有子节点。 | |
bubbleParent(task, fn, scope) | 遍历父级子节点。 | |
addTask(task) addTask(task, index) addTask(task, action, parentTask) |
task:Object。新任务对象。 index:Number。加入的索引位置。 action:String。加入的方式,before/after/add。 parentTask:父任务。 |
新增任务。 |
removeTask(task) | 删除任务。 | |
updateTask(task, property, value) updateTask(task, keyValues) |
property:String。任务属性名,如"Start"。 value:Object。属性值。 keyValues:Object。键值对,如{Name:'测试完成', PercentComplete: 0} |
更新任务属性。 |
moveTask(task, targetTask, action) | action:String。"before"/"after"/"add" targetTask:目标任务 action:移动方式 |
移动任务。 |
upgradeTask(task) | 升级任务。 | |
downgradeTask(task) | 降级任务。 | |
addTasks(tasks, index, parentTasks) addTasks(tasks, action, parentTasks) | tasks:Array。新任务数组。 index:Number/"before"/"after"/"add"。加入方式。 parentTasks:Array。父任务数组。 |
批量新增任务。 |
removeTasks(tasks) | 批量删除任务。 | |
updateTasks(tasks, keyValues) | tasks:Array。任务数组。 keyValues:Object。键值对,如{Name:'测试完成', PercentComplete: 0} |
批量修改任务。 |
collapseAll ( ) | 折叠所有任务。 | |
expandAll ( ) | 展开所有任务。 | |
collapseLevel( Number ) | 折叠某层级任务。 | |
expandLevel( Number ) | 展开某层级任务。 | |
collapse(task) | 折叠任务。 | |
expand(task) | 展开任务。 | |
setShowTableView( Boolean ) | 设置表格是否显示。 | |
setShowGanttView( Boolean ) | 设置条形图是否显示。 | |
setTableViewExpanded( Boolean ) | 设置表格折叠。 | |
setGanttViewExpanded( Boolean ) | 设置条形图折叠。 | |
setTableViewWidth( Number ) | 设置表格宽度。 | |
setGanttViewWidth( Number ) | 设置条形图宽度。 | |
setShowLinkLines( Boolean ) | 设置是否显示箭头连线。 | |
setShowCritical( Boolean ) | 设置是否显示关键路径 | |
setShowGridLines( Boolean ) | 设置是否显示条形图背景表格线。 | |
setTimeLines( Array ) | 设置项目时间线。 | |
setRowHeight( Number ) | 设置行高。 | |
setMultiSelect( Boolean ) | 设置是否多选任务。 | |
setAllowDragDrop( Boolean ) | 设置是否允许任务行拖拽。 | |
setTopTimeScale( String ) | String:时间刻度。 "year/halfyear/quarter/month/week/day/hour" |
设置顶层时间刻度。 |
setBottomTimeScale( String ) |
同上 |
设置底层时间刻度。(底层必须比顶层要小) |
zoomIn( ) | 放大时间刻度 | |
zoomOut( ) | 缩小时间刻度 | |
scrollIntoView(task) | 定位显示任务。 |
事件 通过如下方式监听事件:
functon onTaskDblClick(e){ var project = e.source; var task = e.task; //e是事件对象, 具体请看每个事件的"参数类型" } gantt.on('taskdblclick', onTaskDblClick);
事件名称 | 事件对象 | 描述 |
drawcell |
{ source: Object, //甘特图对象 record: Object, //任务对象 column: Object, //列对象 field: String, //属性名 value: Object, //单元格值 cellHtml: Stirng//单元格内容HTML } |
绘制单元格时发生。 |
drawitem |
{ source: Object, //甘特图对象 item: Object, //条形图,任务对象 itemBox: Object, //条形图的坐标尺寸 itemHtml: Stirng//单元格内容HTML } |
绘制条形图时发生。 |
taskclick |
{ source: Object, //甘特图对象 task: Object //任务对象 } |
单击任务时发生。 |
taskdblclick |
{ source: Object, //甘特图对象 task: Object //任务对象 } |
双击任务时发生。 |
taskdragdrop |
{ source: Object, //甘特图对象 tasks: Array, //被拖拽的任务集合 targetTask: Object, //目标任务 action: String, //投放方式:before,after,append cancel: Boolean //是否取消操作 } |
拖拽行释放时发生。 |
cellbeginedit |
{ source: Object, //甘特图对象 record: Object, //任务对象 column: Object, //列对象 field: String, //属性名 value: Object, //单元格值 cancel: Boolean //是否取消操作 } |
单元格开始编辑时发生 |
CellCommitEdit |
{ source: Object, //甘特图对象 record: Object, //任务对象 column: Object, //列对象 field: String, //属性名 value: Object, //单元格值 cancel: Boolean //是否取消操作 } |
单元格提交编辑值时发生 |
itemdragstart |
{ source: Object, //甘特图对象 item: Object, //任务对象 action: String, //拖拽操作: |
条形图开始拖拽时发生。 |
itemdragcomplete |
{ source: Object, //甘特图对象 item: Object, //任务对象 action: String, //拖拽操作: |
条形图完成拖拽时发生。 |
常见问题
自定义列
开发者可以根据自己扩展的任务属性类型,来创建自己的列。
具体请参考"自定义列示例"。
自定义单元格
通过监听处理"drawcell"事件,可以根据任务信息,设置行、单元格样式,以及自定义单元格Html内容。
gantt.on("drawcell", function (e) { var task = e.record, column = e.column, field = e.field; //单元格样式 if (column.name == "Name") { e.cellCls = "mycellcls"; } //行样式 if (task.Summary == 1) { e.rowCls = "myrowcls"; } ////自定义单元格Html。如果是工期列, 并且工期大与5天, 显示红色 if (field == "Name" && task.Duration > 5) { e.cellHtml = '<b style="color:red;">' + task.Name + '</b>'; } if (field == "Name" && task.Duration <= 2) { e.cellHtml = '<span style="color:blue;">' + task.Name + '</span>'; } if (task.Duration == 0) { e.rowCls = "deletetask"; } });
自定义条形图外观
开发者可以控制右侧条形图的HTML外观,达到任意的条形图效果:
//1)自定义条形图外观显示 gantt.on("drawitem", function (e) { var item = e.item; var left = e.itemBox.left, top = e.itemBox.top, width = e.itemBox.width, height = e.itemBox.height; if (!item.Summary && !item.Milestone) { var percentWidth = width * (item.PercentComplete / 100); e.itemHtml = '<div id="' + item._id + '" class="myitem" style="left:' + left + 'px;top:' + top + 'px;width:' + width + 'px;height:' + (height) + 'px;">'; e.itemHtml += '<div style="width:' + (percentWidth) + 'px;" class="percentcomplete"></div>'; e.itemHtml += '</div>'; //e.ItemHtml = '<a href="http://www.baidu.com" style="left:'+left+'px;top:'+top+'px;width:'+width+'px;height:'+(height-2)+'px;" class="myitem">111</a>'; } }); //2)自定义条形图提示信息 gantt.on('itemtooltipneeded', function (e) { var task = e.task; e.tooltip = "<div>任务:" + task.Name + "</div>" // + "<div ><div style='float:left;'>进度:<b>"+task.PercentComplete + "%</b></div>" // + "<div style='float:right;'>工期:"+task.Duration + "日</div></div>" + "<div style='clear:both;'>开始日期:" + mini.formatDate(task.Start, 'yyyy-MM-dd') + "</div>" + "<div>完成日期:" + mini.formatDate(task.Finish, 'yyyy-MM-dd') + "</div>"; });
自定义单元格可编辑
通过监听表格的"cellbeginedit"事件,可以控制每个行、每个单元格是否可编辑。
//控制单元格是否可编辑 gantt.on("cellbeginedit", function (e) { var task = e.record, column = e.column, field = e.field; if (task.Summary == 1) { e.cancel = true; } if (field == 'Duration') { e.cancel = true; } });
悬停显示内容
/2)自定义条形图提示信息 gantt.on('itemtooltipneeded', function (e) { var task = e.task; e.tooltip = "<div>任务:" + task.Name + "</div>" // + "<div ><div style='float:left;'>进度:<b>"+task.PercentComplete + "%</b></div>" // + "<div style='float:right;'>工期:"+task.Duration + "日</div></div>" + "<div style='clear:both;'>开始日期:" + mini.formatDate(task.Start, 'yyyy-MM-dd') + "</div>" + "<div>完成日期:" + mini.formatDate(task.Finish, 'yyyy-MM-dd') + "</div>"; });
改变ID,成为树形序号
var gantt_arr = gantt.data.Tasks; for(var i = 0 ; i < gantt_arr.length;i++){ gantt_arr[i].ID = i+1; } var children = e.task; if(!(children.children)){ }else{ if (children.children) { for (var i = 0; i < children.children.length; i++) { children.children[i].ID=children.ID+'.'+(i+1); getChildren(children.children[i]); } } }