最近几周,公司为了管理项目,要做甘特图,甘特图的插件,要不是很烂,要不是不完善,要不就是收费的,昭来找去,也就dojo的甘特图比较好,但是还是文档奇少,官方文档,给了个例子,也不做说明,他以为我就能看懂了,我去年买了表啊。
无图无真相,先上图,
//saveProgramPath:"",
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: function(id,desc,type,showOInfo,menu,withDefaultValue){
var tab = new contextMenuTab(id,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,
});
},
在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,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: function(id,percentage,prevIoUsTaskId,taskOwner,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,
startTime: startTime,
duration: duration,
percentage: percentage,
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,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,
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);
}
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,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.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了。在现实对话框的时候,又涉及到了一些赋值操作等一些地方需要小修小补的,代码不贴了,太多。
reapprovalTaskAction: function(){
var isApproval = this.arrItems[0].control.get('value');
//alert('isApproval---'+isApproval);
this.object.
setIsApproval(isApproval);
this.hide();
},
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");
}
},
最后,说了这么多,也贴了这么多代码,相信没人看得懂了,我自己以后也未必看得懂,
插件扩展gantt 插件扩展gantt