最近几周,公司为了管理项目,要做甘特图,甘特图的插件,要不是很烂,要不是不完善,要不就是收费的,昭来找去,也就dojo的甘特图比较好,但是还是文档奇少,官方文档,给了个例子,也不做说明,他以为我就能看懂了,我去年买了表啊。
@H_403_2@
无图无真相,先上图,
@H_403_2@
首先吐槽下,初始化甘特图的时候
@H_403_2@
ganttChart = new GanttChart({
@H_403_2@
readOnly: false,
// optional: determine if gantt chart iseditable
@H_403_2@
dataFilePath:"gantt.json",
// optional:json data file path for load and save,default is"gantt_default.json"
@H_403_2@
//saveProgramPath:"",@H_403_2@
height: 400,
//optional: chart height in pixel,default is 400px
@H_403_2@
width:
document.body.offsetWidth-50,
// optional: chart width inpixel,default is 600px
@H_403_2@
withResource: true
//optional: display the resource chart or not
@H_403_2@
},"gantt");
//"gantt"is the node container id of gantt chart widget
@H_403_2@
@H_403_2@
ganttChart.init();
@H_403_2@
@H_403_2@
@H_403_2@
@H_403_2@
dataFilePath的使用,这里只是写了json的文件名,一句注释,连json数据的格式都没说,不过如果拿到demo后,可以通过函数getJSONData然后转为字符串alert出来,但是把得到字符串放到json文件保存后,还是无法显示json数据,于是继续调试,原来是
@H_403_2@
loadJSONData:function(filename){
@H_403_2@
var _this = this;
@H_403_2@
_this.dataFilePath = filename ||_this.dataFilePath;
@H_403_2@
request.get(_this.dataFilePath,{
@H_403_2@
sync: true
@H_403_2@
}).then(function(response){
@H_403_2@
_this.loadJSONString(
response);//此处原来是respons.text,但是get默认返回的就是text格式的字符串,所以去掉后,即可通过
ganttChart.loadJSONData("gantt.json");来加载数据
@H_403_2@
_this.buildUIContent();
@H_403_2@
console.log("Successfully! Loadeddata from: " + _this.dataFilePath);
@H_403_2@
},function(){
@H_403_2@
console.log("Failed! Load error: " +_this.dataFilePath);
@H_403_2@
});
@H_403_2@
}
@H_403_2@
@H_403_2@
@H_403_2@
@H_403_2@
@H_403_2@
然后,在原来功能的基础上,公司测试部的老外说,需要加一个审批的功能,即在甘特图中加入的任务,新增的未审批任务需要以红色显示,审批后,才能显示绿色,于是乎,硬着头皮去修改,感谢dojo是开源的,有未压缩的代码。
@H_403_2@
@H_403_2@
@H_403_2@
首先在ganttTaskItem.js中,扩展一个属性:
this.isApproval = configuration.isApproval ||"";
@H_403_2@
@H_403_2@
@H_403_2@
然后在tabmenu.js中的buildcontent方法下,加入一句
@H_403_2@
var taskSucAdd = this.createTab(11,"Add Successor Task","t",true,this);
@H_403_2@
taskSucAdd.addItem(1,"Id","id",true);
@H_403_2@
taskSucAdd.addItem(2,"Name","name");
@H_403_2@
taskSucAdd.addItem(3,"Start Time","startTime");
@H_403_2@
taskSucAdd.addItem(4,"Duration (hours)","duration");
@H_403_2@
taskSucAdd.addItem(5,"Percent Complete (%)","percentage");
@H_403_2@
taskSucAdd.addItem(6,"Task Assignee","taskOwner");
@H_403_2@
taskSucAdd.addItem(7,"Is Approval","isApproval");
@H_403_2@
taskSucAdd.addAction("addSuccessorTaskAction");
@H_403_2@
@H_403_2@
@H_403_2@
根据createTab方法,
@H_403_2@
@H_403_2@
createTab: function(id,desc,type,showOInfo,menu,withDefaultValue){
@H_403_2@
var tab = new contextMenuTab(id,withDefaultValue,this.ganttChart);
@H_403_2@
this.arrTabs.push(tab);
@H_403_2@
return tab;
@H_403_2@
}
@H_403_2@
@H_403_2@
@H_403_2@
@H_403_2@
得知taskSucAdd是一个contextMenuTab对象,所以需要找到它的addItem方法,并且我们需要的是一个选择框,所以找到dojit的
Select控件,new一个出来
@H_403_2@
addItem: function(id,name,key,required){
@H_403_2@
var inputControl;
@H_403_2@
if(key == "startTime" || key == "startDate"){
@H_403_2@
inputControl = new DateTextBox({type:"text",constraints:{datePattern:"yyyy.M.d",strict:true}});
@H_403_2@
}else if(key == "percentage"){
@H_403_2@
inputControl = new NumberSpinner({ constraints:{ max:100,min:0 }});
@H_403_2@
}else if(key == "duration"){
@H_403_2@
inputControl = new NumberSpinner({ constraints:{ min:0}});
@H_403_2@
}else if(key =="isApproval"){
@H_403_2@
inputControl = new Select({name:"isApproval",options: [
@H_403_2@
{ label: "Yes",value: "yes"},
@H_403_2@
{ label: "No",value: "no",selected:true }]});
@H_403_2@
}else {
@H_403_2@
inputControl = new TextBox();
@H_403_2@
}
@H_403_2@
this.arrItems.push({
@H_403_2@
id: id,@H_403_2@
name: name,@H_403_2@
control: inputControl,@H_403_2@
tab: this,@H_403_2@
key: key,@H_403_2@
required: required
@H_403_2@
});
@H_403_2@
},@H_403_2@
@H_403_2@
@H_403_2@
@H_403_2@
在addItem后要执行,taskSucAdd.addAction("addSuccessorTaskAction");,所以还要找到addAction方法,此处没有修改,次方法只是把需要执行的方法名的到,即addSuccessorTaskAction,然后找到addSuccessorTaskAction,
@H_403_2@
addSuccessorTaskAction: function(){
@H_403_2@
if(!this.preValueValidation(this.arrItems)){
@H_403_2@
return;
@H_403_2@
}
@H_403_2@
var pr = this.object.project,@H_403_2@
id = this.arrItems[0].control.textBox.value,@H_403_2@
name = this.arrItems[1].control.textBox.value,@H_403_2@
startTime =this.decodeDate(this.arrItems[2].control.textBox.value),@H_403_2@
duration = this.arrItems[3].control.textBox.value,@H_403_2@
pc = this.arrItems[4].control.textBox.value,@H_403_2@
owner = this.arrItems[5].control.textBox.value,@H_403_2@
isApproval =this.arrItems[6].control.get('value');
@H_403_2@
if(lang.trim(id).length <= 0){
@H_403_2@
return;
@H_403_2@
}
@H_403_2@
var parentTaskId = !this.object.parentTask ? "" :this.object.parentTask.taskItem.id;
@H_403_2@
var predTaskId = this.object.taskItem.id;
@H_403_2@
if(pr.insertTask(id,startTime,duration,pc,predTaskId,owner,parentTaskId,isApproval)){
@H_403_2@
this.hide();
@H_403_2@
}else{
@H_403_2@
alert("Please adjust your Customization");
@H_403_2@
return;
@H_403_2@
}
@H_403_2@
this.tabMenu.ganttChart.resource &&this.tabMenu.ganttChart.resource.reConstruct();
@H_403_2@
},@H_403_2@
@H_403_2@
@H_403_2@
@H_403_2@
可以看到,如果要执行成功,还要修改
insertTask方法,在ganttProjectControl.js中找到insertTask方法,
@H_403_2@
insertTask: function(id,percentage,prevIoUsTaskId,taskOwner,isApproval){
@H_403_2@
var task = null;
@H_403_2@
var _task = null;
@H_403_2@
if(this.project.getTaskById(id)){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
if((!duration) || (duration <this.ganttChart.minWorkLength)){
@H_403_2@
duration = this.ganttChart.minWorkLength;
@H_403_2@
}
@H_403_2@
if((!name) || (name == "")){
@H_403_2@
name = id;
@H_403_2@
}
@H_403_2@
if((!percentage) || (percentage == "")){
@H_403_2@
percentage = 0;
@H_403_2@
}else{
@H_403_2@
percentage = parseInt(percentage);
@H_403_2@
if(percentage < 0 || percentage > 100){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
}
@H_403_2@
var sortrequired = false;
@H_403_2@
if((parentTaskId) && (parentTaskId != "")){
@H_403_2@
var parentTask = this.project.getTaskById(parentTaskId);
@H_403_2@
if(!parentTask){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
startTime = startTime || parentTask.startTime;
@H_403_2@
if(startTime < parentTask.startTime){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
task = new GanttTaskItem({
@H_403_2@
id: id,@H_403_2@
startTime: startTime,@H_403_2@
duration: duration,@H_403_2@
percentage: percentage,@H_403_2@
prevIoUsTaskId: prevIoUsTaskId,@H_403_2@
taskOwner: taskOwner,@H_403_2@
isApproval: isApproval
@H_403_2@
});
@H_403_2@
if(!this.ganttChart.checkPosParentTask(parentTask,task)){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
task.parentTask = parentTask;
@H_403_2@
var _parentTask = this.getTaskById(parentTask.id);
@H_403_2@
var isHide = false;
@H_403_2@
if(_parentTask.cTaskItem[0].style.display == "none"){
@H_403_2@
isHide = true;
@H_403_2@
}else if(_parentTask.cTaskNameItem[2]){
@H_403_2@
if(!_parentTask.isExpanded){
@H_403_2@
isHide = true;
@H_403_2@
}
@H_403_2@
}
@H_403_2@
if(isHide){
@H_403_2@
if(_parentTask.childTask.length == 0){
@H_403_2@
this.ganttChart.openTree(_parentTask.parentTask);
@H_403_2@
}else{
@H_403_2@
this.ganttChart.openTree(_parentTask);
@H_403_2@
}
@H_403_2@
}
@H_403_2@
if(prevIoUsTaskId != ""){
@H_403_2@
var predTask = this.project.getTaskById(prevIoUsTaskId);
@H_403_2@
if(!predTask){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
if(predTask.parentTask){
@H_403_2@
if(predTask.parentTask.id != task.parentTask.id){
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
}else{
@H_403_2@
return false;
@H_403_2@
}
@H_403_2@
if(!this.ganttChart.checkPosPrevIoUsTask(predTask,task)){
@H_403_2@
this.ganttChart.correctPosPrevIoUsTask(predTask,task);
@H_403_2@
}
@H_403_2@
task.prevIoUsTask = predTask;
@H_403_2@
}
@H_403_2@
var isAdd = false;
@H_403_2@