dojo甘特图插件扩展gantt cha…

最近几周,公司为了管理项目,要做甘特图,甘特图的插件,要不是很烂,要不是不完善,要不就是收费的,昭来找去,也就dojo的甘特图比较好,但是还是文档奇少,官方文档,给了个例子,也不做说明,他以为我就能看懂了,我去年买了表啊。
无图无真相,先上图,


      首先吐槽下,初始化甘特图的时候
  ganttChart = new GanttChart({
    readOnly: false,        // optional: determine if gantt chart iseditable
    dataFilePath:"gantt.json",     // optional:json data file path for load and save, default is"gantt_default.json"
//saveProgramPath:"",
    height: 400,            //optional: chart height in pixel, default is 400px
    width:  document.body.offsetWidth-50,             // optional: chart width inpixel, default is 600px
    withResource: true      //optional: display the resource chart or not
  }, "gantt");               //"gantt"is the node container id of gantt chart widget

  ganttChart.init();

dataFilePath的使用,这里只是写了json的文件名,一句注释,连json数据的格式都没说,不过如果拿到demo后,可以通过函数getJSONData然后转为字符串alert出来,但是把得到字符串放到json文件保存后,还是无法显示json数据,于是继续调试,原来是
loadJSONData:function(filename){
var _this = this;
_this.dataFilePath = filename ||_this.dataFilePath;
request.get(_this.dataFilePath,{
sync: true
}).then(function(response){
_this.loadJSONString( response);//此处原来是respons.text,但是get默认返回的就是text格式的字符串,所以去掉后,即可通过  ganttChart.loadJSONData("gantt.json");来加载数据
_this.buildUIContent();
console.log("Successfully! Loadeddata from: " + _this.dataFilePath);
}, function(){
console.log("Failed! Load error: " +_this.dataFilePath);
});
}

然后,在原来功能的基础上,公司测试部的老外说,需要加一个审批的功能,即在甘特图中加入的任务,新增的未审批任务需要以红色显示,审批后,才能显示绿色,于是乎,硬着头皮去修改,感谢dojo是开源的,有未压缩的代码。

首先在ganttTaskItem.js中,扩展一个属性: this.isApproval = configuration.isApproval ||"";

然后在tabmenu.js中的buildcontent方法下,加入一句
var taskSucAdd = this.createTab(11, "Add Successor Task", "t",true, this);
taskSucAdd.addItem(1, "Id", "id", true);
taskSucAdd.addItem(2, "Name", "name");
taskSucAdd.addItem(3, "Start Time", "startTime");
taskSucAdd.addItem(4, "Duration (hours)", "duration");
taskSucAdd.addItem(5, "Percent Complete (%)","percentage");
taskSucAdd.addItem(6, "Task Assignee", "taskOwner");
taskSucAdd.addItem(7, "Is Approval","isApproval");
taskSucAdd.addAction("addSuccessorTaskAction");

  根据createTab方法,
createTab: function(id, desc, type, showOInfo, menu,withDefaultValue){
var tab = new contextMenuTab(id, desc, type, showOInfo, menu,withDefaultValue, this.ganttChart);
this.arrTabs.push(tab);
return tab;
}

得知taskSucAdd是一个contextMenuTab对象,所以需要找到它的addItem方法,并且我们需要的是一个选择框,所以找到dojit的 Select控件,new一个出来
addItem: function(id, name, key, required){
var inputControl;
if(key == "startTime" || key == "startDate"){
inputControl = new DateTextBox({type:"text",constraints:{datePattern:"yyyy.M.d", strict:true}});
}else if(key == "percentage"){
inputControl = new NumberSpinner({ constraints:{ max:100,min:0 }});
}else if(key == "duration"){
inputControl = new NumberSpinner({ constraints:{ min:0}});
}else if(key =="isApproval"){
inputControl = new Select({name:"isApproval",options: [
{ label: "Yes", value: "yes"},
{ label: "No", value: "no", selected:true }]});
}else {
inputControl = new TextBox();
}
this.arrItems.push({
id: id,
name: name,
control: inputControl,
tab: this,
key: key,
required: required
});
},

在addItem后要执行,taskSucAdd.addAction("addSuccessorTaskAction");,所以还要找到addAction方法,此处没有修改,次方法只是把需要执行的方法名的到,即addSuccessorTaskAction,然后找到addSuccessorTaskAction,
addSuccessorTaskAction: function(){
if(!this.preValueValidation(this.arrItems)){
return;
}
var pr = this.object.project,
id = this.arrItems[0].control.textbox.value,
name = this.arrItems[1].control.textbox.value,
startTime =this.decodeDate(this.arrItems[2].control.textbox.value),
duration = this.arrItems[3].control.textbox.value,
pc = this.arrItems[4].control.textbox.value,
owner = this.arrItems[5].control.textbox.value,
isApproval =this.arrItems[6].control.get('value');
if(lang.trim(id).length <= 0){
return;
}
var parentTaskId = !this.object.parentTask ? "" :this.object.parentTask.taskItem.id;
var predTaskId = this.object.taskItem.id;
if(pr.insertTask(id, name, startTime,duration, pc, predTaskId, owner, parentTaskId,isApproval)){
this.hide();
}else{
alert("Please adjust your Customization");
return;
}
this.tabMenu.ganttChart.resource &&this.tabMenu.ganttChart.resource.reConstruct();
},

可以看到,如果要执行成功,还要修改 insertTask方法,在ganttProjectControl.js中找到insertTask方法,
insertTask: function(id, name, startTime, duration,percentage, previousTaskId, taskOwner, parentTaskId,isApproval){
var task = null;
var _task = null;
if(this.project.getTaskById(id)){
return false;
}
if((!duration) || (duration <this.ganttChart.minWorkLength)){
duration = this.ganttChart.minWorkLength;
}
if((!name) || (name == "")){
name = id;
}
if((!percentage) || (percentage == "")){
percentage = 0;
}else{
percentage = parseInt(percentage);
if(percentage < 0 || percentage > 100){
return false;
}
}
var sortRequired = false;
if((parentTaskId) && (parentTaskId != "")){
var parentTask = this.project.getTaskById(parentTaskId);
if(!parentTask){
return false;
}
startTime = startTime || parentTask.startTime;
if(startTime < parentTask.startTime){
return false;
}
task = new GanttTaskItem({
id: id,
name: name,
startTime: startTime,
duration: duration,
percentage: percentage,
previousTaskId: previousTaskId,
taskOwner: taskOwner,
isApproval: isApproval
});
if(!this.ganttChart.checkPosParentTask(parentTask,task)){
return false;
}
task.parentTask = parentTask;
var _parentTask = this.getTaskById(parentTask.id);
var isHide = false;
if(_parentTask.cTaskItem[0].style.display == "none"){
isHide = true;
}else if(_parentTask.cTaskNameItem[2]){
if(!_parentTask.isExpanded){
isHide = true;
}
}
if(isHide){
if(_parentTask.childTask.length == 0){
this.ganttChart.openTree(_parentTask.parentTask);
}else{
this.ganttChart.openTree(_parentTask);
}
}
if(previousTaskId != ""){
var predTask = this.project.getTaskById(previousTaskId);
if(!predTask){
return false;
}
if(predTask.parentTask){
if(predTask.parentTask.id != task.parentTask.id){
return false;
}
}else{
return false;
}
if(!this.ganttChart.checkPosPreviousTask(predTask,task)){
this.ganttChart.correctPosPreviousTask(predTask, task);
}
task.previousTask = predTask;
}
var isAdd = false;
if(sortRequired) for(var i = 0; i <parentTask.cldTasks.length; i++){
if(task.startTime <parentTask.cldTasks[i].startTime){
parentTask.cldTasks.splice(i, 0, task);
if(i > 0){
parentTask.cldTasks[i - 1].nextChildTask =parentTask.cldTasks[i];
parentTask.cldTasks[i].previousChildTask =parentTask.cldTasks[i - 1];
}
if(parentTask.cldTasks[i + 1]){
parentTask.cldTasks[i + 1].previousChildTask =parentTask.cldTasks[i];
parentTask.cldTasks[i].nextChildTask = parentTask.cldTasks[i +1];
}
isAdd = true;
break;
}
}
if(!isAdd){
if(parentTask.cldTasks.length > 0){
parentTask.cldTasks[parentTask.cldTasks.length -1].nextChildTask = task;
task.previousChildTask =parentTask.cldTasks[parentTask.cldTasks.length - 1];
}
parentTask.cldTasks.push(task);
}
if(parentTask.cldTasks.length == 1){
_parentTask.cTaskNameItem[2] =_parentTask.createTreeImg();
}
_task = new GanttTaskControl(task, this,this.ganttChart);
_task.create();
if(task.nextChildTask) _task.nextChildTask =_task.project.getTaskById(task.nextChildTask.id);
_task.adjustPanelTime();
var rowHeight = this.ganttChart.heightTaskItem +this.ganttChart.heightTaskItemExtra;
_task.shiftCurrentTasks(_task, rowHeight);//23
}else{
startTime = startTime || this.project.startDate;
task = new GanttTaskItem({
id: id,
name: name,
startTime: startTime,
duration: duration,
percentage: percentage,
previousTaskId: previousTaskId,
taskOwner: taskOwner,
isApproval: isApproval
});
if(task.startTime <= this.ganttChart.startDate){
return false;
}
if(previousTaskId != ""){
var predTask = this.project.getTaskById(previousTaskId);
if(!predTask){
return false;
}
if(!this.ganttChart.checkPosPreviousTask(predTask,task)){
this.ganttChart.correctPosPreviousTask(predTask, task);
}
if(predTask.parentTask){
return false;
}
task.previousTask = predTask;
}
var isAdd = false;
if(sortRequired){
for(var i = 0; i < this.project.parentTasks.length;i++){
var ppTask = this.project.parentTasks[i];
if(startTime < ppTask.startTime){
this.project.parentTasks.splice(i, 0, task);
if(i > 0){
this.project.parentTasks[i - 1].nextParentTask = task;
task.previousParentTask = this.project.parentTasks[i -1];
}
if(this.project.parentTasks[i + 1]){
this.project.parentTasks[i + 1].previousParentTask =task;
task.nextParentTask = this.project.parentTasks[i + 1];
}
isAdd = true;
break;
}
}
}
if(!isAdd){
if(this.project.parentTasks.length > 0){
this.project.parentTasks[this.project.parentTasks.length -1].nextParentTask = task;
task.previousParentTask =this.project.parentTasks[this.project.parentTasks.length -1];
}
this.project.parentTasks.push(task);
}
_task = new GanttTaskControl(task, this,this.ganttChart);
_task.create();
if(task.nextParentTask) _task.nextParentTask =_task.project.getTaskById(task.nextParentTask.id);
_task.adjustPanelTime();
this.arrTasks.push(_task);
var rowHeight = this.ganttChart.heightTaskItem +this.ganttChart.heightTaskItemExtra;
_task.shiftCurrentTasks(_task, rowHeight);
this.projectItem[0].style.display = "inline";
this.setPercentCompleted(this.getPercentCompleted());
this.shiftProjectItem();
this.showDescrProject();
}
this.ganttChart.checkHeighPanelTasks();
this.ganttChart.checkPosition();
return _task;
},

乱七八糟的一大坨,基本看不懂,应该是一些验证的东西,好在我只是加个属性,不需要验证日期是否过期什么的,所以,加上标红的两句,ok了。在现实对话框的时候,又涉及到了一些赋值操作等一些地方需要小修小补的,代码不贴了,太多。
contextMenuTab.js中新增 reapprovalTaskAction函数,设置修改后的审批值
reapprovalTaskAction: function(){
var isApproval = this.arrItems[0].control.get('value');
//alert('isApproval---'+isApproval);
this.object. setIsApproval(isApproval);
this.hide();
},
所以还要一个setIsApproval函数,在ganttTaskControl.js中新增次函数
setIsApproval: function(isApproval){// reapproval function byHu Wei
this.taskItem.isApproval = isApproval;
//get the percentage node rc0, consult the functionsetPercentCompleted :by Hu Wei
var trow =this.cTaskItem[0].childNodes[0].firstChild.rows[0],
rc0 = trow.cells[0], rc1 = trow.cells[1];
if(isApproval=='no'){
domClass.replace(rc0.firstChild,"ganttImageTaskProgressFi lledNo","ganttImageTaskProgressFi lled");
}else {
domClass.replace(rc0.firstChild,"ganttImageTaskProgressFi lled","ganttImageTaskProgressFi lledNo");
}
},
这样就基本ok了,后面还要求新增task的时候,id要实现自动话,其实就是遍历整个json数据,取最大值了,只是人家插件本来的初衷是id可以是非数字的,所以这个功能有点奇怪,暂不贴出来。
最后,说了这么多,也贴了这么多代码,相信没人看得懂了,我自己以后也未必看得懂, dojo甘特图插件扩展gantt <wbr>chart(一) ,所以还是献上demo的好,没找到上传附件的功能,想要附件的,请评论并留下邮箱,我会发给你的。嘿嘿,突然想起,曾经在eoe也这样搞过,最后有200多条回复,发邮件差点累死,而且最后还有个学弟拿了我的代码去做毕业设计,最后还混了顿饭,这次有可能也混顿饭吃吗?dojo甘特图插件扩展gantt <wbr>chart(一)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值