普加甘特图(PlusGantt) V3.0 开发文档

更新时间:2017-03-01

上海普加软件有限公司

目录

  1. PlusGantt
  2. 如何使用?
  3. 甘特图数据结构
  4. 集成到第三方JS框架(jQuery、Ext等)
  5. 语言本地化
  6. PlusGantt API参考
  7. 常见问题
  8. 历史更新
  9. 获得支持

PlusGantt

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网页上显示一个漂亮的甘特图。
您可以轻松修改它任意部位的外观,比如单元格、条形图、提示信息等。

如何使用?

PlusGantt是一个Javascript控件,运行在WEB浏览器中。与服务端平台和数据库无关。

使用者需要用Ajax从服务端获取甘特图数据,是一个简单的树形结构。

甘特图数据到达页面后,使用PlusGantt的loadTasks方法,加载显示甘特图界面。

然后,使用者可以做如下自定义处理:

  1. 扩展表格列,比如扩展部门、负责人、权重等列。
  2. 外观自定义:单元格、条形图和任务提示框等。
  3. 其他。如右键菜单、时间刻度、条形图生成、分级加载、语言本地化等处理。

普加甘特图能很好完成在WEB上显示甘特图的功能。
但是如果您需要在WEB上实现一个类似微软Project功能逻辑的控件,请查看普加项目管理控件PlusProject

甘特图数据结构

PlusGantt数据是一个树形结构的任务数据。这里是JSON格式的数据。
下一级子任务由"children"属性体现。
前置任务由"PredecessorLink"属性体现。

列表结构(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"
},
...
]
树形结构(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
                    }
                ]
            },
            ....//更多子任务
        ]
    },
    .... //更多任务
]

任务属性描述如下:

集成到第三方JS框架(jQuery、Ext等)

首先,对于jQuery, YUI, Prototype.js等框架来说,它们对页面的操作基于原始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,     //拖拽操作:
move, start, finish, percentcomplete cancel: Boolean //是否取消操作 }
条形图开始拖拽时发生。
itemdragcomplete
{
    source: Object,     //甘特图对象    
    item: Object,       //任务对象
    action: String,     //拖拽操作:
move, start, finish, percentcomplete value: Object //拖拽调节的值。日期Date或者数字Number类型。 }
条形图完成拖拽时发生。

常见问题

自定义列

开发者可以根据自己扩展的任务属性类型,来创建自己的列。

具体请参考"自定义列示例"。

自定义单元格

通过监听处理"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;
    }
});

示例请参考"控制单元格可编辑"