先看看圖的效果
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]); } } }