source: Dev/branches/rest-dojo-ui/client/dojox/gantt/GanttChart.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 43.9 KB
Line 
1dojo.provide("dojox.gantt.GanttChart");
2
3dojo.require("dijit.Tooltip");
4dojo.require("dojox.gantt.GanttProjectItem");
5dojo.require("dojox.gantt.GanttResourceItem");
6dojo.require("dojox.gantt.TabMenu");
7dojo.require("dojo.date.locale");
8
9(function(){
10        dojo.declare("dojox.gantt.GanttChart", null, {
11                constructor: function(configuration, node){
12                        this.resourceChartHeight = configuration.resourceChartHeight !== undefined ? configuration.resourceChartHeight : false;
13                        this.withResource = configuration.withResource !== undefined ? configuration.withResource : true;
14                        this.correctError = configuration.autoCorrectError !== undefined ? configuration.autoCorrectError : false;
15                        this.isShowConMenu = this.isContentEditable = !configuration.readOnly;
16                        this.withTaskId = configuration.withTaskId !== undefined ? configuration.withTaskId : !configuration.readOnly;
17                        this.animation = configuration.animation !== undefined ? configuration.animation : true;
18                        this.saveProgramPath = configuration.saveProgramPath  || "saveGanttData.php";
19                        this.dataFilePath = configuration.dataFilePath  || "gantt_default.json";
20                        this.contentHeight = configuration.height || 400;
21                        this.contentWidth = configuration.width || 600;
22                        this.content = dojo.byId(node);
23                        this.scrollBarWidth = 18;
24                        this.panelTimeHeight = 102;
25                        this.maxWidthPanelNames = 150;
26                        this.maxWidthTaskNames = 150;
27                        this.minWorkLength = 8;
28                        this.heightTaskItem = 12;
29                        this.heightTaskItemExtra = 11;
30                        this.pixelsPerDay = 24;//px
31                        this.hsPerDay = 8;
32                        this.pixelsPerWorkHour = this.pixelsPerDay / this.hsPerDay;//px
33                        this.pixelsPerHour = this.pixelsPerDay / 24;//px
34                        this.countDays = 0;
35                        this.totalDays = 0;
36                        this.startDate = null;
37                        this.initialPos = 0;
38                       
39                        this.contentDataHeight = 0;
40                        this.panelTimeExpandDelta = 20;
41                       
42                        this.divTimeInfo = null;
43                        this.panelNames = null;
44                        this.panelTime = null;
45                        this.contentData = null;
46                        this.tabMenu = null;
47                       
48                        this.project = [];
49                        this.arrProjects = [];
50                       
51                        this.xmlLoader = null;
52                        this.isMoving = false;
53                        this.isResizing = false;
54                        this.animationNodes = [];
55                        this.scale = 1;
56                        this.tempDayInPixels = 0;
57                        this.resource = null;
58                        this.months = dojo.date.locale.getNames("months", "wide");
59                        this._events = [];
60                },
61                getProject: function(id){
62                        return dojo.filter(this.arrProjects, function(proj){
63                                return proj.project.id == id;
64                        }, this)[0];
65                },
66                checkPosPreviousTask: function(predTask, task){
67                        var widthPred = this.getWidthOnDuration(predTask.duration);
68                        var posPred = this.getPosOnDate(predTask.startTime);
69                        var posChild = this.getPosOnDate(task.startTime);
70                        if((widthPred + posPred) > posChild){
71                                return false;
72                        }
73                        return true;
74                },
75                correctPosPreviousTask: function(predTask, ctask, ctaskObj){
76                        var newDate = new Date(predTask.startTime);
77                        newDate.setHours(newDate.getHours() + (predTask.duration / this.hsPerDay * 24))
78                        if(newDate.getHours() > 0){
79                                newDate.setHours(0);
80                                newDate.setDate(newDate.getDate() + 1);
81                        }
82                        ctaskObj ? (ctaskObj.setStartTime(newDate, true)) : (ctask.startTime = newDate);
83                        if(ctask.parentTask){
84                                if(!this.checkPosParentTask(ctask.parentTask, ctask)){
85                                        var newDate2 = new Date(ctask.parentTask.startTime);
86                                        newDate2.setHours(newDate2.getHours() + (ctask.parentTask.duration / this.hsPerDay * 24))
87                                        ctask.duration = parseInt((parseInt((newDate2 - ctask.startTime) / (1000 * 60 * 60))) * this.hsPerDay / 24);
88                                }
89                        }
90                },
91                correctPosParentTask: function(parentTask, ctask){
92                        if(!ctask.previousTask){
93                                if(parentTask.startTime > ctask.startTime){
94                                        ctask.startTime = new Date(parentTask.startTime);
95                                }
96                                if(!this.checkPosParentTask(parentTask, ctask)){
97                                        ctask.duration = parentTask.duration;
98                                }
99                        }else{
100                                this.correctPosPreviousTask(ctask.previousTask, ctask);
101                        }
102                },
103                checkPosParentTaskInTree: function(parentTask){
104                        var exception = false;
105                        for(var i = 0; i < parentTask.cldTasks.length; i++){
106                                var pcTask = parentTask.cldTasks[i];
107                                if(!this.checkPosParentTask(parentTask, pcTask)){
108                                        if(!this.correctError){
109                                                return true;
110                                        }else{
111                                                this.correctPosParentTask(parentTask, pcTask);
112                                        }
113                                }
114                                if(parentTask.startTime > pcTask.startTime){
115                                        if(!this.correctError){
116                                                return true;
117                                        }else{
118                                                this.correctPosParentTask(parentTask, pcTask);
119                                        }
120                                }
121                                if(pcTask.cldTasks.length > 0){
122                                        exception = this.checkPosParentTaskInTree(pcTask);
123                                }
124                        }
125                        return exception;
126                },
127                setPreviousTask: function(project){
128                        var exception = false;
129                        for(var i = 0; i < project.parentTasks.length; i++){
130                                var ppTask = project.parentTasks[i];
131                                if(ppTask.previousTaskId){
132                                        ppTask.previousTask = project.getTaskById(ppTask.previousTaskId);
133                                        if(!ppTask.previousTask){
134                                                if(!this.correctError){
135                                                        return true;
136                                                }
137                                        }
138                                        ppTask.previousTask.cldPreTasks.push(ppTask);
139                                }
140                                if(ppTask.previousTask){
141                                        if(!this.checkPosPreviousTask(ppTask.previousTask, ppTask)){
142                                                if(!this.correctError){
143                                                        return true;
144                                                }else{
145                                                        this.correctPosPreviousTask(ppTask.previousTask, ppTask);
146                                                }
147                                        }
148                                }
149                                exception = this.setPreviousTaskInTree(ppTask);
150                        }
151                        return exception;
152                },
153                setPreviousTaskInTree: function(parentTask){
154                        var exception = false;
155                        for(var i = 0; i < parentTask.cldTasks.length; i++){
156                                var pcTask = parentTask.cldTasks[i];
157                                if(pcTask.previousTaskId){
158                                        pcTask.previousTask = parentTask.project.getTaskById(pcTask.previousTaskId);
159                                        if(!pcTask.previousTask){
160                                                if(!this.correctError){
161                                                        return true;
162                                                }
163                                        }
164                                        if(!this.checkPosPreviousTask(pcTask.previousTask, pcTask)){
165                                                if(!this.correctError){
166                                                        return true;
167                                                }else{
168                                                        this.correctPosPreviousTask(pcTask.previousTask, pcTask);
169                                                }
170                                        }
171                                        pcTask.previousTask.cldPreTasks.push(pcTask);
172                                }
173                               
174                                if(pcTask.cldTasks.length > 0){
175                                        exception = this.setPreviousTaskInTree(pcTask);
176                                }
177                        }
178                        return exception;
179                },
180                checkPosParentTask: function(parentTask, task){
181                        var widthParent = this.getWidthOnDuration(parentTask.duration);
182                        var posParent = this.getPosOnDate(parentTask.startTime);
183                        var posChild = this.getPosOnDate(task.startTime);
184                        var widthChild = this.getWidthOnDuration(task.duration);
185                        return (widthParent + posParent) >= (posChild + widthChild);
186                },
187                addProject: function(projectItem){
188                        this.project.push(projectItem);
189                },
190                deleteProject: function(id){
191                        var project = this.getProject(id);
192                        if(project){
193                                if(project.arrTasks.length > 0){
194                                        while(project.arrTasks.length > 0){
195                                                project.deleteChildTask(project.arrTasks[0]);
196                                        }
197                                }
198                                var rowHeight = this.heightTaskItemExtra + this.heightTaskItem;
199                                project.nextProject && project.shiftNextProject(project, -rowHeight); //rowHeight: 23
200                                this.project = dojo.filter(this.project, function(proj){
201                                        return proj.id != project.project.id;
202                                }, this);
203                                if((project.previousProject) && (project.nextProject)){
204                                        var previousProject = project.previousProject;
205                                        previousProject.nextProject = project.nextProject;
206                                }
207                                if((project.previousProject) && !(project.nextProject)){
208                                        var previousProject = project.previousProject;
209                                        previousProject.nextProject = null;
210                                }
211                                if(!(project.previousProject) && (project.nextProject)){
212                                        var nextProject = project.nextProject;
213                                        nextProject.previousProject = null;
214                                }
215                                for(var i = 0; i < this.arrProjects.length; i++){
216                                        if(this.arrProjects[i].project.id == id){
217                                                this.arrProjects.splice(i, 1);
218                                        }
219                                }
220                                project.projectItem[0].parentNode.removeChild(project.projectItem[0]);
221                                project.descrProject.parentNode.removeChild(project.descrProject);
222                                project.projectNameItem.parentNode.removeChild(project.projectNameItem);
223                                this.contentDataHeight -= this.heightTaskItemExtra + this.heightTaskItem;
224                                if(this.project.length == 0){
225                                        var d = new Date(this.startDate);
226                                        var t = new Date(d.setDate(d.getDate() + 1));
227                                        var pi = new dojox.gantt.GanttProjectItem({
228                                                id: 1,
229                                                name: "New Project",
230                                                startDate: t
231                                        });
232                                        this.project.push(pi);
233                                        var project = new dojox.gantt.GanttProjectControl(this, pi);
234                                        project.create();
235                                        this.arrProjects.push(project);
236                                        this.contentDataHeight += this.heightTaskItemExtra + this.heightTaskItem;
237                                }
238                                this.checkPosition();
239                        }
240                },
241                insertProject: function(id, name, startDate){
242                        if(this.startDate >= startDate){
243                                return false;
244                        }
245                        if(this.getProject(id)){
246                                return false;
247                        }
248                        this.checkHeighPanelTasks();
249                        var project = new dojox.gantt.GanttProjectItem({
250                                id: id,
251                                name: name,
252                                startDate: startDate
253                        });
254                        this.project.push(project);
255                        var _project = new dojox.gantt.GanttProjectControl(this, project);
256                        for(var i = 0; i < this.arrProjects.length; i++){
257                                var curProject = this.arrProjects[i],
258                                        preProject = this.arrProjects[i-1],
259                                        nextProject = this.arrProjects[i+1];
260                                if(startDate < curProject.project.startDate){
261                                        this.arrProjects.splice(i, 0, _project);
262                                        if(i > 0){
263                                                _project.previousProject = preProject;
264                                                preProject.nextProject = _project;
265                                        }
266                                        if(i + 1 <= this.arrProjects.length){
267                                                _project.nextProject = nextProject;
268                                                nextProject.previousProject = _project;
269                                                var rowHeight = this.heightTaskItem + this.heightTaskItemExtra;
270                                                _project.shiftNextProject(_project, rowHeight);
271                                        }
272                                        _project.create();
273                                        _project.hideDescrProject();
274                                        this.checkPosition();
275                                        return _project;
276                                }
277                        }
278                        if(this.arrProjects.length > 0){
279                                this.arrProjects[this.arrProjects.length - 1].nextProject = _project;
280                                _project.previousProject = this.arrProjects[this.arrProjects.length - 1];
281                        }
282                        this.arrProjects.push(_project);
283                        _project.create();
284                        _project.hideDescrProject();
285                        this.checkPosition();
286                        return _project;
287                },
288                openTree: function(parentTask){
289                        var lastParentTask = this.getLastCloseParent(parentTask);
290                        this.openNode(lastParentTask);
291                        parentTask.taskItem.id != lastParentTask.taskItem.id && this.openTree(parentTask);
292                },
293                openNode: function(parentTask){
294                        if(!parentTask.isExpanded){
295                                dojo.removeClass(parentTask.cTaskNameItem[2], "ganttImageTreeExpand");
296                                dojo.addClass(parentTask.cTaskNameItem[2], "ganttImageTreeCollapse");
297                                parentTask.isExpanded = true;
298                                parentTask.shiftCurrentTasks(parentTask, parentTask.hideTasksHeight);
299                                parentTask.showChildTasks(parentTask, parentTask.isExpanded);
300                                parentTask.hideTasksHeight = 0;
301                        }
302                },
303                getLastCloseParent: function(task){
304                        if(task.parentTask){
305                                if((!task.parentTask.isExpanded) ||
306                                (task.parentTask.cTaskNameItem[2].style.display == "none")){
307                                        return this.getLastCloseParent(task.parentTask);
308                                }else{
309                                        return task;
310                                }
311                        }else{
312                                return task;
313                        }
314                },
315                getProjectItemById: function(id){
316                        return dojo.filter(this.project, function(proj){
317                                return proj.id == id;
318                        }, this)[0];
319                },
320                clearAll: function(){
321                        this.contentDataHeight = 0;
322                        this.startDate = null;
323                        this.clearData();
324                        this.clearItems();
325                        this.clearEvents();
326                },
327                clearEvents: function(){
328                        dojo.forEach(this._events, dojo.disconnect);
329                        this._events = [];
330                },
331                clearData: function(){
332                        this.project = [];
333                        this.arrProjects = [];
334                },
335                clearItems: function(){
336                        this.contentData.removeChild(this.contentData.firstChild);
337                        this.contentData.appendChild(this.createPanelTasks());
338                        this.panelNames.removeChild(this.panelNames.firstChild);
339                        this.panelNames.appendChild(this.createPanelNamesTasks());
340                        this.panelTime.removeChild(this.panelTime.firstChild);
341                },
342                buildUIContent: function(){
343                        this.project.sort(this.sortProjStartDate);
344                        this.startDate = this.getStartDate();
345                        this.panelTime.appendChild(this.createPanelTime());
346                        for(var i = 0; i < this.project.length; i++){
347                                var proj = this.project[i];
348                                for(var k = 0; k < proj.parentTasks.length; k++){
349                                        var ppTask = proj.parentTasks[k];
350                                        if(ppTask.startTime){
351                                                this.setStartTimeChild(ppTask);
352                                        }else{
353                                                return;
354                                        }
355                                        if(this.setPreviousTask(proj)){
356                                                return;
357                                        }
358                                }
359                                for(var k = 0; k < proj.parentTasks.length; k++){
360                                        var ppTask = proj.parentTasks[k];
361                                        if(ppTask.startTime < proj.startDate){
362                                                return;
363                                        }
364                                        if(this.checkPosParentTaskInTree(ppTask)) return;
365                                }
366                                this.sortTasksByStartTime(proj);
367                        }
368                       
369                        for(var i = 0; i < this.project.length; i++){
370                                var proj = this.project[i];
371                                var project = new dojox.gantt.GanttProjectControl(this, proj);
372                                if(this.arrProjects.length > 0){
373                                        var previousProject = this.arrProjects[this.arrProjects.length - 1];
374                                        project.previousProject = previousProject;
375                                        previousProject.nextProject = project;
376                                }
377                                project.create();
378                                this.checkHeighPanelTasks();
379                                this.arrProjects.push(project);
380                                this.createTasks(project);
381                        }
382                        this.resource && this.resource.reConstruct();
383                        this.postLoadData();
384                        this.postBindEvents();
385                },
386                loadJSONData: function(filename){
387                        var _this = this;
388                        _this.dataFilePath = filename || _this.dataFilePath;
389                        dojo.xhrGet({
390                                url: _this.dataFilePath,
391                                sync: true,
392                                load: function(text, ioArgs){
393                                        _this.loadJSONString(text);
394                                        _this.buildUIContent();
395                                        alert("Successfully! Loaded data from: " + _this.dataFilePath);
396                                },
397                                error: function(err, ioArgs){
398                                        alert("Failed! Load error: " + _this.dataFilePath);
399                                }
400                        });
401                },
402                loadJSONString: function(content){
403                        //load data
404                        if(!content){ return; }
405                        this.clearAll();
406                        var jsonObj = dojo.fromJson(content);
407                       
408                        var items = jsonObj.items;
409                        dojo.forEach(items, function(pItem){
410                                var startDate = pItem.startdate.split("-");
411                                var project = new dojox.gantt.GanttProjectItem({
412                                        id: pItem.id,
413                                        name: pItem.name,
414                                        startDate: new Date(startDate[0], (parseInt(startDate[1]) - 1), startDate[2])
415                                });
416                                var tItems = pItem.tasks;
417                                dojo.forEach(tItems, function(tItem){
418                                        var id = tItem.id,
419                                                name = tItem.name,
420                                                starttime = tItem.starttime.split("-");
421                                                duration = tItem.duration,
422                                                percentage = tItem.percentage,
423                                                previousTaskId = tItem.previousTaskId,
424                                                taskOwner = tItem.taskOwner;
425                                       
426                                        var task = new dojox.gantt.GanttTaskItem({
427                                                id: id,
428                                                name: name,
429                                                startTime: new Date(starttime[0], (parseInt(starttime[1]) - 1), starttime[2]),
430                                                duration: duration,
431                                                percentage: percentage,
432                                                previousTaskId: previousTaskId,
433                                                taskOwner: taskOwner
434                                        });
435                                        var ctItems = tItem.children;
436                                        if(ctItems.length != 0){
437                                                this.buildChildTasksData(task, ctItems);
438                                        }
439                                        project.addTask(task);
440                                }, this);
441                                this.addProject(project);
442                         }, this);
443                },
444                buildChildTasksData: function(parentTask, childTaskItems){
445                        childTaskItems && dojo.forEach(childTaskItems, function(ctItem){
446                                var id = ctItem.id,
447                                        name = ctItem.name,
448                                        starttime = ctItem.starttime.split("-"),
449                                        duration = ctItem.duration,
450                                        percentage = ctItem.percentage,
451                                        previousTaskId = ctItem.previousTaskId,
452                                        taskOwner = ctItem.taskOwner;
453                               
454                                var task = new dojox.gantt.GanttTaskItem({
455                                        id: id,
456                                        name: name,
457                                        startTime: new Date(starttime[0], (parseInt(starttime[1]) - 1), starttime[2]),
458                                        duration: duration,
459                                        percentage: percentage,
460                                        previousTaskId: previousTaskId,
461                                        taskOwner: taskOwner
462                                });
463                                task.parentTask = parentTask;
464                                parentTask.addChildTask(task);
465                               
466                                var ctItems = ctItem.children;
467                                if(ctItems.length != 0){
468                                        this.buildChildTasksData(task, ctItems);
469                                }
470                        }, this);
471                },
472                getJSONData: function(){
473                        var jsonObj = {identifier: 'id', items: []};
474                        dojo.forEach(this.project, function(proj){
475                                var project = {
476                                        id: proj.id,
477                                        name: proj.name,
478                                        startdate: proj.startDate.getFullYear() + '-' + (proj.startDate.getMonth() + 1) + '-' + proj.startDate.getDate(),
479                                        tasks: []
480                                };
481                                jsonObj.items.push(project);
482                                dojo.forEach(proj.parentTasks, function(pTask){
483                                        var task = {
484                                                id: pTask.id,
485                                                name: pTask.name,
486                                                starttime: pTask.startTime.getFullYear() + '-' + (pTask.startTime.getMonth() + 1) + '-' + pTask.startTime.getDate(),
487                                                duration: pTask.duration,
488                                                percentage: pTask.percentage,
489                                                previousTaskId: (pTask.previousTaskId || ''),
490                                                taskOwner: (pTask.taskOwner || ''),
491                                                children: this.getChildTasksData(pTask.cldTasks)
492                                        };
493                                        project.tasks.push(task);
494                                }, this);
495                        }, this);
496                        return jsonObj;
497                },
498                getChildTasksData: function(childTasks){
499                        var cTaskObj = [];
500                        childTasks && childTasks.length > 0 && dojo.forEach(childTasks, function(childTask){
501                                var ctask = {
502                                        id: childTask.id,
503                                        name: childTask.name,
504                                        starttime: childTask.startTime.getFullYear() + '-' + (childTask.startTime.getMonth() + 1) + '-' + childTask.startTime.getDate(),
505                                        duration: childTask.duration,
506                                        percentage: childTask.percentage,
507                                        previousTaskId: (childTask.previousTaskId || ''),
508                                        taskOwner: (childTask.taskOwner || ''),
509                                        children: this.getChildTasksData(childTask.cldTasks)
510                                };
511                                cTaskObj.push(ctask);
512                        }, this);
513                        return cTaskObj;
514                },
515                saveJSONData: function(fileName){
516                        var _this = this;
517                        _this.dataFilePath = (fileName && dojo.trim(fileName).length > 0) ? fileName : this.dataFilePath;
518                        try {
519                                var td = dojo.xhrPost({
520                                        url: _this.saveProgramPath,
521                                        content: {filename: _this.dataFilePath, data: dojo.toJson(_this.getJSONData())},
522                                        handle: function(res, ioArgs){
523                                                if((dojo._isDocumentOk(ioArgs.xhr))||
524                                                        (ioArgs.xhr.status == 405)
525                                                ){
526                                                        alert("Successfully! Saved data to " + _this.dataFilePath);
527                                                }else{
528                                                        alert("Failed! Saved error");
529                                                }
530                                        }
531                                });
532                        } catch (e){
533                                alert("exception: " + e.message);
534                        }
535                },
536                sortTaskStartTime: function(a, b){
537                        return a.startTime < b.startTime ? -1 : (a.startTime > b.startTime ? 1 : 0);
538                },
539                sortProjStartDate: function(a, b){
540                        return a.startDate < b.startDate ? -1 : (a.startDate > b.startDate ? 1 : 0);
541                },
542                setStartTimeChild: function(parentTask){
543                        dojo.forEach(parentTask.cldTasks, function(pcTask){
544                                if(!pcTask.startTime){
545                                        pcTask.startTime = parentTask.startTime;
546                                }
547                                if(pcTask.cldTasks.length != 0){
548                                        this.setStartTimeChild(pcTask);
549                                }
550                        }, this);
551                },
552                createPanelTasks: function(){
553                        var panelTask = dojo.create("div", {
554                                className: "ganttTaskPanel"
555                        });
556                        dojo.style(panelTask, {
557                                height: (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px"
558                        });
559                        return panelTask;
560                },
561                refreshParams: function(pixelsPerDay){
562                        this.pixelsPerDay = pixelsPerDay;
563                        this.pixelsPerWorkHour = this.pixelsPerDay / this.hsPerDay;
564                        this.pixelsPerHour = this.pixelsPerDay / 24;
565                },
566                createPanelNamesTasksHeader: function(){
567                        var _this = this;
568                        var panelHeader = dojo.create("div", {className: "ganttPanelHeader"});
569                        var tblHeader = dojo.create("table", {
570                                cellPadding: "0px",
571                                border: "0px",
572                                cellSpacing: "0px",
573                                bgColor: "#FFFFFF",
574                                className: "ganttToolbar"
575                        }, panelHeader);
576                        var firstRow = tblHeader.insertRow(tblHeader.rows.length);
577                        var secondRow = tblHeader.insertRow(tblHeader.rows.length);
578                        var thirdRow = tblHeader.insertRow(tblHeader.rows.length);
579                        var forthRow = tblHeader.insertRow(tblHeader.rows.length);
580                        var zoomIn = dojo.create("td", {
581                                align: "center",
582                                vAlign: "middle",
583                                className: "ganttToolbarZoomIn"
584                        }, firstRow);
585                        var zoomInFn = dojo.hitch(this, function(){
586                                if(this.scale * 2 > 5){return;}
587                                this.scale = this.scale * 2;
588                                this.switchTeleMicroView(this.pixelsPerDay * this.scale);
589                        });
590                        dojo.disconnect(this.zoomInClickEvent);
591                        this.zoomInClickEvent = dojo.connect(zoomIn, "onclick", this, zoomInFn);
592                        //a11y support
593                        dojo.disconnect(this.zoomInKeyEvent);
594                        this.zoomInKeyEvent = dojo.connect(zoomIn, "onkeydown", this, function(e){
595                                if(e.keyCode != dojo.keys.ENTER){return;}
596                                zoomInFn();
597                        });
598                        dojo.attr(zoomIn, "tabIndex", 0);
599                        var zoomOut = dojo.create("td", {
600                                align: "center",
601                                vAlign: "middle",
602                                className: "ganttToolbarZoomOut"
603                        }, firstRow);
604                        var zoomOutFn = dojo.hitch(this, function(){
605                                if(this.scale * 0.5 < 0.2){return;}
606                                this.scale = this.scale * 0.5;
607                                this.switchTeleMicroView(this.pixelsPerDay * this.scale);
608                        });
609                        dojo.disconnect(this.zoomOutClickEvent);
610                        this.zoomOutClickEvent = dojo.connect(zoomOut, "onclick", this, zoomOutFn);
611                        //a11y support
612                        dojo.disconnect(this.zoomOutKeyEvent);
613                        this.zoomOutKeyEvent = dojo.connect(zoomOut, "onkeydown", this, function(e){
614                                if(e.keyCode != dojo.keys.ENTER){return;}
615                                zoomOutFn();
616                        });
617                        dojo.attr(zoomOut, "tabIndex", 0);
618                        var micro = dojo.create("td", {
619                                align: "center",
620                                vAlign: "middle",
621                                className: "ganttToolbarMicro"
622                        }, secondRow);
623                        dojo.disconnect(this.microClickEvent);
624                        this.microClickEvent = dojo.connect(micro, "onclick", this, dojo.hitch(this, this.refresh, this.animation?15:1, 0, 2));
625                        //a11y support
626                        dojo.disconnect(this.microKeyEvent);
627                        this.microKeyEvent = dojo.connect(micro, "onkeydown", this, function(e){
628                                if(e.keyCode != dojo.keys.ENTER){return;}
629                                micro.blur();
630                                this.refresh(this.animation?15:1, 0, 2);
631                        });
632                        dojo.attr(micro, "tabIndex", 0);
633                        var tele = dojo.create("td", {
634                                align: "center",
635                                vAlign: "middle",
636                                className: "ganttToolbarTele"
637                        }, secondRow);
638                        dojo.disconnect(this.teleClickEvent);
639                        this.teleClickEvent = dojo.connect(tele, "onclick", this, dojo.hitch(this, this.refresh, this.animation?15:1, 0, 0.5));
640                        //a11y support
641                        dojo.disconnect(this.teleKeyEvent);
642                        this.teleKeyEvent = dojo.connect(tele, "onkeydown", this, function(e){
643                                if(e.keyCode != dojo.keys.ENTER){return;}
644                                tele.blur();
645                                this.refresh(this.animation?15:1, 0, 0.5);
646                        });
647                        dojo.attr(tele, "tabIndex", 0);
648                        var save = dojo.create("td", {
649                                align: "center",
650                                vAlign: "middle",
651                                className: "ganttToolbarSave"
652                        }, thirdRow);
653                        dojo.disconnect(this.saveClickEvent);
654                        this.saveClickEvent = dojo.connect(save, "onclick", this, dojo.hitch(this, this.saveJSONData, ""));
655                        //a11y support
656                        dojo.disconnect(this.saveKeyEvent);
657                        this.saveKeyEvent = dojo.connect(save, "onkeydown", this, function(e){
658                                if(e.keyCode != dojo.keys.ENTER){return;}
659                                this.saveJSONData("");
660                        });
661                        dojo.attr(save, "tabIndex", 0);
662                        var load = dojo.create("td", {
663                                align: "center",
664                                vAlign: "middle",
665                                className: "ganttToolbarLoad"
666                        }, thirdRow);
667                        dojo.disconnect(this.loadClickEvent);
668                        this.loadClickEvent = dojo.connect(load, "onclick", this, dojo.hitch(this, this.loadJSONData, ""));
669                        //a11y support
670                        dojo.disconnect(this.loadKeyEvent);
671                        this.loadKeyEvent = dojo.connect(load, "onkeydown", this, function(e){
672                                if(e.keyCode != dojo.keys.ENTER){return;}
673                                this.loadJSONData("");
674                        });
675                        dojo.attr(load, "tabIndex", 0);
676                        //action popup description
677                        var actions = [zoomIn, zoomOut, micro, tele, save, load],
678                                titles = ["Enlarge timeline", "Shrink timeline", "Zoom in time zone(microscope view)", "Zoom out time zone(telescope view)",
679                                                        "Save gantt data to json file", "Load gantt data from json file"];
680                        dojo.forEach(actions, function(action, i){
681                                var title = titles[i];
682                                var tooltipShow = function(){
683                                        dojo.addClass(action, "ganttToolbarActionHover");
684                                        dijit.showTooltip(title, action, ["above", "below"]);
685                                };
686                                action.onmouseover = tooltipShow;
687                                //a11y support
688                                action.onfocus = tooltipShow;
689                                var tooltipHide = function(){
690                                        dojo.removeClass(action, "ganttToolbarActionHover");
691                                        action && dijit.hideTooltip(action);
692                                };
693                                action.onmouseout = tooltipHide;
694                                action.onblur = tooltipHide;
695                        }, this);
696                        return panelHeader;
697                },
698                createPanelNamesTasks: function(){
699                        var panelNameTask = dojo.create("div", {
700                                innerHTML: "&nbsp;",
701                                className: "ganttPanelNames"
702                        });
703                        dojo.style(panelNameTask, {
704                                height: (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px",
705                                width: this.maxWidthPanelNames + "px"
706                        });
707                        return panelNameTask;
708                },
709                createPanelTime: function(){
710                        var panelTime = dojo.create("div", {className: "ganttPanelTime"});
711                        var tblTime = dojo.create("table", {
712                                cellPadding: "0px",
713                                border: "0px",
714                                cellSpacing: "0px",
715                                bgColor: "#FFFFFF",
716                                className: "ganttTblTime"
717                        }, panelTime);
718                        this.totalDays = this.countDays;
719                        //year
720                        var newYearRow = tblTime.insertRow(tblTime.rows.length), newYear = oldYear = new Date(this.startDate).getFullYear(), ycount = 0;
721                        for(var i = 0; i < this.countDays; i++, ycount++){
722                                var date = new Date(this.startDate);
723                                date.setDate(date.getDate() + i);
724                                newYear = date.getFullYear();
725                                if(newYear != oldYear){
726                                        this.addYearInPanelTime(newYearRow, ycount, oldYear);
727                                        ycount = 0;
728                                        oldYear = newYear;
729                                }
730                        }
731                        this.addYearInPanelTime(newYearRow, ycount, newYear);
732                        dojo.style(newYearRow, "display", "none");
733                        //month
734                        var newMonthRow = tblTime.insertRow(tblTime.rows.length), newMonth = oldMonth = new Date(this.startDate).getMonth(), mcount = 0, lastYear = 1970;
735                        for(var i = 0; i < this.countDays; i++, mcount++){
736                                var date = new Date(this.startDate);
737                                date.setDate(date.getDate() + i);
738                                newMonth = date.getMonth();
739                                lastYear = date.getFullYear();
740                                if(newMonth != oldMonth){
741                                        this.addMonthInPanelTime(newMonthRow, mcount, oldMonth, lastYear);
742                                        mcount = 0;
743                                        oldMonth = newMonth;
744                                }
745                        }
746                        this.addMonthInPanelTime(newMonthRow, mcount, newMonth, lastYear);
747                        //week
748                        var newWeekRow = tblTime.insertRow(tblTime.rows.length), newWeek = oldWeek = dojo.date.locale._getWeekOfYear(new Date(this.startDate)), mcount = 0;
749                        for(var i = 0; i < this.countDays; i++, mcount++){
750                                var date = new Date(this.startDate);
751                                date.setDate(date.getDate() + i);
752                                newWeek = dojo.date.locale._getWeekOfYear(date);
753                                if(newWeek != oldWeek){
754                                        this.addWeekInPanelTime(newWeekRow, mcount, oldWeek);
755                                        mcount = 0;
756                                        oldWeek = newWeek;
757                                }
758                        }
759                        this.addWeekInPanelTime(newWeekRow, mcount, newWeek);
760                        //day
761                        var newDayRow = tblTime.insertRow(tblTime.rows.length);
762                        for(var i = 0; i < this.countDays; i++){
763                                this.addDayInPanelTime(newDayRow);
764                        }
765                        //hour
766                        var newHourRow = tblTime.insertRow(tblTime.rows.length);
767                        for(var i = 0; i < this.countDays; i++){
768                                this.addHourInPanelTime(newHourRow);
769                        }
770                        dojo.style(newHourRow, "display", "none");
771                        return panelTime;
772                },
773                adjustPanelTime: function(width){
774                        var maxEndPos = dojo.map(this.arrProjects, function(project){
775                                return (parseInt(project.projectItem[0].style.left) + parseInt(project.projectItem[0].firstChild.style.width)
776                                        + project.descrProject.offsetWidth + this.panelTimeExpandDelta);
777                        }, this).sort(function(a,b){return b-a})[0];
778                        if(this.maxTaskEndPos != maxEndPos){
779                                //reset panel time
780                                var prows = this.panelTime.firstChild.firstChild.rows;
781                                for(var i = 0; i <= 4; i++){//prows.length
782                                        this.removeCell(prows[i]);
783                                };
784                                var countDays = Math.round((maxEndPos+this.panelTimeExpandDelta) / this.pixelsPerDay);
785                                this.totalDays = countDays;
786                                //year
787                                var newYear = oldYear = new Date(this.startDate).getFullYear(), ycount = 0;
788                                for(var i = 0; i < countDays; i++, ycount++){
789                                        var date = new Date(this.startDate);
790                                        date.setDate(date.getDate() + i);
791                                        newYear = date.getFullYear();
792                                        if(newYear != oldYear){
793                                                this.addYearInPanelTime(prows[0], ycount, oldYear);
794                                                ycount = 0;
795                                                oldYear = newYear;
796                                        }
797                                }
798                                this.addYearInPanelTime(prows[0], ycount, newYear);
799                                //month
800                                var newMonth = oldMonth = new Date(this.startDate).getMonth(), mcount = 0, lastYear = 1970;
801                                for(var i = 0; i < countDays; i++, mcount++){
802                                        var date = new Date(this.startDate);
803                                        date.setDate(date.getDate() + i);
804                                        newMonth = date.getMonth();
805                                        lastYear = date.getFullYear();
806                                        if(newMonth != oldMonth){
807                                                this.addMonthInPanelTime(prows[1], mcount, oldMonth, lastYear);
808                                                mcount = 0;
809                                                oldMonth = newMonth;
810                                        }
811                                }
812                                this.addMonthInPanelTime(prows[1], mcount, newMonth, lastYear);
813                                //week
814                                var newWeek = oldWeek = dojo.date.locale._getWeekOfYear(new Date(this.startDate)), mcount = 0;
815                                for(var i = 0; i < countDays; i++, mcount++){
816                                        var date = new Date(this.startDate);
817                                        date.setDate(date.getDate() + i);
818                                        newWeek = dojo.date.locale._getWeekOfYear(date);
819                                        if(newWeek != oldWeek){
820                                                this.addWeekInPanelTime(prows[2], mcount, oldWeek);
821                                                mcount = 0;
822                                                oldWeek = newWeek;
823                                        }
824                                }
825                                this.addWeekInPanelTime(prows[2], mcount, newWeek);
826                                //day
827                                for(var i = 0; i < countDays; i++){
828                                        this.addDayInPanelTime(prows[3]);
829                                }
830                                //hour
831                                for(var i = 0; i < countDays; i++){
832                                        this.addHourInPanelTime(prows[4]);
833                                }
834                                this.panelTime.firstChild.firstChild.style.width = this.pixelsPerDay * (prows[3].cells.length) + "px";
835                                this.contentData.firstChild.style.width = this.pixelsPerDay * (prows[3].cells.length) + "px";
836                                this.maxTaskEndPos = maxEndPos;
837                        }
838                },
839                addYearInPanelTime: function(row, count, year){
840                        var data = "Year   " + year;
841                        var newCell = dojo.create("td", {
842                                colSpan: count,
843                                align: "center",
844                                vAlign: "middle",
845                                className: "ganttYearNumber",
846                                innerHTML: this.pixelsPerDay * count > 20 ? data : "",
847                                innerHTMLData: data
848                        }, row);
849                        dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
850                },
851                addMonthInPanelTime: function(row, count, month, year){
852                        var data = this.months[month] + (year ? " of " + year : "");
853                        var newCell = dojo.create("td", {
854                                colSpan: count,
855                                align: "center",
856                                vAlign: "middle",
857                                className: "ganttMonthNumber",
858                                innerHTML: this.pixelsPerDay * count > 30 ? data : "",
859                                innerHTMLData: data
860                        }, row);
861                        dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
862                },
863                addWeekInPanelTime: function(row, count, week){
864                        var data = "Week   " + week;
865                        var newCell = dojo.create("td", {
866                                colSpan: count,
867                                align: "center",
868                                vAlign: "middle",
869                                className: "ganttWeekNumber",
870                                innerHTML: this.pixelsPerDay * count > 20 ? data : "",
871                                innerHTMLData: data
872                        }, row);
873                        dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
874                },
875                addDayInPanelTime: function(row){
876                        var date = new Date(this.startDate);
877                        date.setDate(date.getDate() + parseInt(row.cells.length));
878                        var newCell = dojo.create("td", {
879                                align: "center",
880                                vAlign: "middle",
881                                className: "ganttDayNumber",
882                                innerHTML: this.pixelsPerDay > 20 ? date.getDate() : "",
883                                innerHTMLData: String(date.getDate()),
884                                data: row.cells.length
885                        }, row);
886                        dojo.style(newCell, "width", this.pixelsPerDay + "px");
887                        (date.getDay() >= 5) && dojo.addClass(newCell, "ganttDayNumberWeekend");
888                        this._events.push(
889                                dojo.connect(newCell, "onmouseover", this, function(event){
890                                        var dayTime = event.target || event.srcElement;
891                                        var date = new Date(this.startDate.getTime());
892                                        date.setDate(date.getDate() + parseInt(dojo.attr(dayTime, "data")));
893                                        dijit.showTooltip(date.getFullYear() + "." + (date.getMonth() + 1) + "." + date.getDate(), newCell, ["above", "below"]);
894                                })
895                        );
896                        this._events.push(
897                                dojo.connect(newCell, "onmouseout", this, function(event){
898                                        var dayTime = event.target || event.srcElement;
899                                        dayTime && dijit.hideTooltip(dayTime);
900                                })
901                        );
902                },
903                addHourInPanelTime: function(row){
904                        var newCell = dojo.create("td", {
905                                align: "center",
906                                vAlign: "middle",
907                                className: "ganttHourNumber",
908                                data: row.cells.length
909                        }, row);
910                        dojo.style(newCell, "width", this.pixelsPerDay + "px");
911                       
912                        var hourTable = dojo.create("table", {
913                                cellPadding: "0",
914                                cellSpacing: "0"
915                        }, newCell);
916                        var newRow = hourTable.insertRow(hourTable.rows.length);
917                        for(var i = 0; i < this.hsPerDay; i++){
918                                var hourTD = dojo.create("td", {
919                                        className: "ganttHourClass"
920                                }, newRow);
921                                dojo.style(hourTD, "width", (this.pixelsPerDay / this.hsPerDay) + "px");
922                                dojo.attr(hourTD, "innerHTMLData", String(9 + i));
923                                if(this.pixelsPerDay / this.hsPerDay > 5){
924                                        dojo.attr(hourTD, "innerHTML", String(9 + i));
925                                }
926                                dojo.addClass(hourTD, i <= 3?"ganttHourNumberAM":"ganttHourNumberPM");
927                        }
928                },
929                incHeightPanelTasks: function(height){
930                        var containerTasks = this.contentData.firstChild;
931                        containerTasks.style.height = parseInt(containerTasks.style.height) + height + "px";
932                },
933                incHeightPanelNames: function(height){
934                        var containerNames = this.panelNames.firstChild;
935                        containerNames.style.height = parseInt(containerNames.style.height) + height + "px";
936                },
937                checkPosition: function(){
938                        dojo.forEach(this.arrProjects, function(project){
939                                dojo.forEach(project.arrTasks, function(task){
940                                        task.checkPosition();
941                                }, this);
942                        }, this);
943                },
944                checkHeighPanelTasks: function(){
945                        this.contentDataHeight += this.heightTaskItemExtra + this.heightTaskItem;
946                        if((parseInt(this.contentData.firstChild.style.height) <= this.contentDataHeight)){
947                                this.incHeightPanelTasks(this.heightTaskItem + this.heightTaskItemExtra);
948                                this.incHeightPanelNames(this.heightTaskItem + this.heightTaskItemExtra);
949                        }
950                },
951                sortTasksByStartTime: function(project){
952                        project.parentTasks.sort(this.sortTaskStartTime);
953                        for(var i = 0; i < project.parentTasks.length; i++){
954                                project.parentTasks[i] = this.sortChildTasks(project.parentTasks[i]);
955                        }
956                },
957                sortChildTasks: function(parenttask){
958                        parenttask.cldTasks.sort(this.sortTaskStartTime);
959                        for(var i = 0; i < parenttask.cldTasks.length; i++){
960                                if(parenttask.cldTasks[i].cldTasks.length > 0) this.sortChildTasks(parenttask.cldTasks[i]);
961                        }
962                        return parenttask;
963                },
964                refresh: function(count, current, multi){
965                        //return if no task items
966                        if(this.arrProjects.length <= 0){return;}
967                        if(this.arrProjects[0].arrTasks.length <= 0){return;}
968                        //Show panel of names
969                        if(!count || current > count){
970                                this.refreshController();
971                                if(this.resource){
972                                        this.resource.refresh();
973                                }
974                                this.tempDayInPixels = 0;
975                                this.panelNameHeadersCover && dojo.style(this.panelNameHeadersCover, "display", "none");
976                                return;
977                        }
978                        if(this.tempDayInPixels == 0){
979                                this.tempDayInPixels = this.pixelsPerDay;
980                        }
981                        this.panelNameHeadersCover && dojo.style(this.panelNameHeadersCover, "display", "");
982                        var dip = this.tempDayInPixels + this.tempDayInPixels * (multi - 1) * Math.pow((current / count), 2);
983                        this.refreshParams(dip);
984                        dojo.forEach(this.arrProjects, function(project){
985                                dojo.forEach(project.arrTasks, function(task){
986                                        task.refresh();
987                                }, this);
988                                project.refresh();
989                        }, this);
990                        setTimeout(dojo.hitch(this, function(){
991                                this.refresh(count, ++current, multi);
992                        }), 15);
993                },
994                switchTeleMicroView: function(dip){
995                        var plChild = this.panelTime.firstChild.firstChild;
996                        for(var i = 0; i < 5; i++){//0:Y 1:M 2:W 3:D 4:H
997                                if(dip > 40){
998                                        dojo.style(plChild.rows[i], "display", (i==0||i==1)?"none":"");
999                                }else if(dip < 20){
1000                                        dojo.style(plChild.rows[i], "display", (i==2||i==4)?"none":"");
1001                                }else{
1002                                        dojo.style(plChild.rows[i], "display", (i==0||i==4)?"none":"");
1003                                }
1004                        }
1005                },
1006                refreshController: function(){
1007                        this.contentData.firstChild.style.width = Math.max(1200, this.pixelsPerDay * this.totalDays) + "px";
1008                        this.panelTime.firstChild.style.width = this.pixelsPerDay * this.totalDays + "px";
1009                        this.panelTime.firstChild.firstChild.style.width = this.pixelsPerDay * this.totalDays + "px";
1010                        this.switchTeleMicroView(this.pixelsPerDay);
1011                        dojo.forEach(this.panelTime.firstChild.firstChild.rows, function(row){
1012                                dojo.forEach(row.childNodes, function(td){
1013                                        var cs = parseInt(dojo.attr(td, "colSpan") || 1);
1014                                        var idata = dojo.trim(dojo.attr(td, "innerHTMLData")||"");
1015                                        if(idata.length > 0){
1016                                                dojo.attr(td, "innerHTML", this.pixelsPerDay * cs < 20 ? "" : idata);
1017                                        }else{
1018                                                dojo.forEach(td.firstChild.rows[0].childNodes, function(td){
1019                                                        var sdata = dojo.trim(dojo.attr(td, "innerHTMLData")||"");
1020                                                        dojo.attr(td, "innerHTML", this.pixelsPerDay / this.hsPerDay > 10 ? sdata : "");
1021                                                }, this);
1022                                        }
1023                                        if(cs == 1){
1024                                                dojo.style(td, "width", (this.pixelsPerDay*cs) + "px");
1025                                                if(idata.length <= 0){
1026                                                        dojo.forEach(td.firstChild.rows[0].childNodes, function(td){
1027                                                                dojo.style(td, "width", (this.pixelsPerDay*cs / this.hsPerDay) + "px");
1028                                                        }, this);
1029                                                }
1030                                        }
1031                                }, this);
1032                        }, this);
1033                },
1034                init: function(){
1035                        this.startDate = this.getStartDate();
1036                        dojo.style(this.content, {
1037                                width: this.contentWidth + "px",
1038                                height: this.contentHeight + "px"
1039                        });
1040                        //create Table
1041                        this.tableControl = dojo.create("table", {
1042                                cellPadding: "0",
1043                                cellSpacing: "0",
1044                                className: "ganttTabelControl"
1045                        });
1046                        var newRowTblControl = this.tableControl.insertRow(this.tableControl.rows.length);
1047                        //Add to content Table
1048                        this.content.appendChild(this.tableControl);
1049                        this.countDays = this.getCountDays();
1050                        //Creation panel of time
1051                        this.panelTime = dojo.create("div", {className: "ganttPanelTimeContainer"});
1052                        dojo.style(this.panelTime, "height", this.panelTimeHeight + "px");
1053                        this.panelTime.appendChild(this.createPanelTime());
1054                        //Creation panel contentData
1055                        this.contentData = dojo.create("div", {className: "ganttContentDataContainer"});
1056                        dojo.style(this.contentData, "height", (this.contentHeight - this.panelTimeHeight) + "px");
1057                        this.contentData.appendChild(this.createPanelTasks());
1058                        //Creation panel of names
1059                        var newCellTblControl = dojo.create("td", {
1060                                vAlign: "top"
1061                        });
1062                        //Creation panel of task header
1063                        this.panelNameHeaders = dojo.create("div", {className: "ganttPanelNameHeaders"}, newCellTblControl);
1064                        dojo.style(this.panelNameHeaders, {
1065                                height: this.panelTimeHeight + "px",
1066                                width: this.maxWidthPanelNames + "px"
1067                        });
1068                        this.panelNameHeaders.appendChild(this.createPanelNamesTasksHeader());
1069                        this.panelNames = dojo.create("div", {className: "ganttPanelNamesContainer"}, newCellTblControl);
1070                        this.panelNames.appendChild(this.createPanelNamesTasks());
1071                        newRowTblControl.appendChild(newCellTblControl);
1072                        //add to control contentData and dataTime
1073                        newCellTblControl = dojo.create("td", {
1074                                vAlign: "top"
1075                        });
1076                        var divCell = dojo.create("div", {className: "ganttDivCell"});
1077                        divCell.appendChild(this.panelTime);
1078                        divCell.appendChild(this.contentData);
1079                        newCellTblControl.appendChild(divCell);
1080                        newRowTblControl.appendChild(newCellTblControl);
1081                        //Show panel of names
1082                        dojo.style(this.panelNames, "height", (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px");
1083                        dojo.style(this.panelNames, "width", this.maxWidthPanelNames + "px");
1084                        dojo.style(this.contentData, "width", (this.contentWidth - this.maxWidthPanelNames) + "px");
1085                        dojo.style(this.contentData.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
1086                        dojo.style(this.panelTime, "width", (this.contentWidth - this.maxWidthPanelNames - this.scrollBarWidth) + "px");
1087                        dojo.style(this.panelTime.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
1088                        if(this.isShowConMenu){
1089                                this.tabMenu = new dojox.gantt.TabMenu(this);
1090                        }
1091                        var _this = this;
1092                        this.contentData.onscroll = function(){
1093                                _this.panelTime.scrollLeft = this.scrollLeft;
1094                                if(_this.panelNames){
1095                                        _this.panelNames.scrollTop = this.scrollTop;
1096                                        if(_this.isShowConMenu){
1097                                                _this.tabMenu.hide();
1098                                        }
1099                                }
1100                                if(_this.resource){
1101                                        _this.resource.contentData.scrollLeft = this.scrollLeft;
1102                                }
1103                        }
1104                        this.project.sort(this.sortProjStartDate);
1105                        for(var i = 0; i < this.project.length; i++){
1106                                var proj = this.project[i];
1107                                for(var k = 0; k < proj.parentTasks.length; k++){
1108                                        var ppTask = proj.parentTasks[k];
1109                                        if(!ppTask.startTime){
1110                                                ppTask.startTime = proj.startDate;
1111                                        }
1112                                        this.setStartTimeChild(ppTask);
1113                                        if(this.setPreviousTask(proj)){
1114                                                return;
1115                                        }
1116                                }
1117                                for(var k = 0; k < proj.parentTasks.length; k++){
1118                                        var ppTask = proj.parentTasks[k];
1119                                        if(ppTask.startTime < proj.startDate){
1120                                                if(!this.correctError){
1121                                                        return;
1122                                                }else{
1123                                                        ppTask.startTime = proj.startDate;
1124                                                }
1125                                        }
1126                                        if(this.checkPosParentTaskInTree(ppTask)){
1127                                                return;
1128                                        }
1129                                }
1130                                this.sortTasksByStartTime(proj);
1131                        }
1132                        for(var i = 0; i < this.project.length; i++){
1133                                //creation project
1134                                var proj = this.project[i];
1135                                var project = new dojox.gantt.GanttProjectControl(this, proj);
1136                                if(this.arrProjects.length > 0){
1137                                        var previousProject = this.arrProjects[this.arrProjects.length - 1];
1138                                        project.previousProject = previousProject;
1139                                        previousProject.nextProject = project;
1140                                }
1141                                project.create();
1142                                this.checkHeighPanelTasks();
1143                                this.arrProjects.push(project);
1144                                this.createTasks(project);
1145                        }
1146                        if(this.withResource){
1147                                this.resource = new dojox.gantt.GanttResourceItem(this);
1148                                this.resource.create();
1149                        }
1150                        this.postLoadData();
1151                        this.postBindEvents();
1152                        return this;
1153                },
1154                postLoadData: function(){
1155                        dojo.forEach(this.arrProjects, function(project){
1156                                dojo.forEach(project.arrTasks, function(task){
1157                                        task.postLoadData();
1158                                }, this);
1159                                project.postLoadData();
1160                        }, this);
1161                        //toolbar cover div
1162                        var cpos = dojo.coords(this.panelNameHeaders);
1163                        if(!this.panelNameHeadersCover){
1164                                this.panelNameHeadersCover = dojo.create("div", {className: "ganttHeaderCover"}, this.panelNameHeaders.parentNode);
1165                                dojo.style(this.panelNameHeadersCover, {
1166                                        left: cpos.l+"px",
1167                                        top: cpos.t+"px",
1168                                        height: cpos.h+"px",
1169                                        width: cpos.w+"px",
1170                                        display: "none"
1171                                });
1172                        }
1173                },
1174                postBindEvents: function(){
1175                        //highlight row
1176                        var pos = dojo.position(this.tableControl, true);
1177                        !dojo.isIE && this._events.push(
1178                                dojo.connect(this.tableControl, "onmousemove", this, function(event){
1179                                        var elem = event.srcElement || event.target;
1180                                        if(elem == this.panelNames.firstChild || elem == this.contentData.firstChild){
1181                                                //23: this.heightTaskItem + this.heightTaskItemExtra
1182                                                var rowHeight = this.heightTaskItem + this.heightTaskItemExtra;
1183                                                var hlTop = parseInt(event.layerY / rowHeight) * rowHeight + this.panelTimeHeight - this.contentData.scrollTop;
1184                                                if(hlTop != this.oldHLTop && hlTop < (pos.h - 50)){
1185                                                        if(this.highLightDiv){
1186                                                                dojo.style(this.highLightDiv, "top", (pos.y + hlTop) + "px");
1187                                                        }else{
1188                                                                this.highLightDiv = dojo.create("div", {
1189                                                                        className: "ganttRowHighlight"
1190                                                                }, dojo.body());
1191                                                                dojo.style(this.highLightDiv, {
1192                                                                        top: (pos.y + hlTop) + "px",
1193                                                                        left: pos.x + "px",
1194                                                                        width: (pos.w - 20) + "px",
1195                                                                        height: rowHeight + "px"
1196                                                                });
1197                                                        }
1198                                                }
1199                                                this.oldHLTop = hlTop;
1200                                        }
1201                                })
1202                        );
1203                        //TODO: other event bindings
1204                },
1205                getStartDate: function(){
1206                        dojo.forEach(this.project, function(proj){
1207                                if(this.startDate){
1208                                        if(proj.startDate < this.startDate){
1209                                                this.startDate = new Date(proj.startDate);
1210                                        }
1211                                }else{
1212                                        this.startDate = new Date(proj.startDate);
1213                                }
1214                        }, this);
1215                        this.initialPos = 24 * this.pixelsPerHour;
1216                        return this.startDate ? new Date(this.startDate.setHours(this.startDate.getHours() - 24)) : new Date();
1217                },
1218                getCountDays: function(){
1219                        return parseInt((this.contentWidth - this.maxWidthPanelNames) / (this.pixelsPerHour * 24));
1220                },
1221                createTasks: function(project){
1222                        dojo.forEach(project.project.parentTasks, function(pppTask, i){
1223                                if(i > 0){
1224                                        project.project.parentTasks[i - 1].nextParentTask = pppTask;
1225                                        pppTask.previousParentTask = project.project.parentTasks[i - 1];
1226                                }
1227                                var task = new dojox.gantt.GanttTaskControl(pppTask, project, this);
1228                                project.arrTasks.push(task);
1229                                task.create();
1230                                this.checkHeighPanelTasks();
1231                                if(pppTask.cldTasks.length > 0){
1232                                        this.createChildItemControls(pppTask.cldTasks, project);
1233                                }
1234                        }, this);
1235                },
1236                createChildItemControls: function(arrChildTasks, project){
1237                        arrChildTasks && dojo.forEach(arrChildTasks, function(cTask, i){
1238                                if(i > 0){
1239                                        cTask.previousChildTask = arrChildTasks[i - 1];
1240                                        arrChildTasks[i - 1].nextChildTask = cTask;
1241                                }
1242                                var task = new dojox.gantt.GanttTaskControl(cTask, project, this);
1243                                task.create();
1244                                this.checkHeighPanelTasks();
1245                                if(cTask.cldTasks.length > 0){
1246                                        this.createChildItemControls(cTask.cldTasks, project);
1247                                }
1248                        }, this);
1249                },
1250                getPosOnDate: function(startTime){
1251                        return (startTime - this.startDate) / (60 * 60 * 1000) * this.pixelsPerHour;
1252                },
1253                getWidthOnDuration: function(duration){
1254                        return Math.round(this.pixelsPerWorkHour * duration);
1255                },
1256                getLastChildTask: function(task){
1257                        return task.childTask.length > 0 ? this.getLastChildTask(task.childTask[task.childTask.length - 1]) : task;
1258                },
1259                removeCell: function(row){
1260                        while(row.cells[0]){
1261                                row.deleteCell(row.cells[0]);
1262                        }
1263                }
1264        });
1265})();
Note: See TracBrowser for help on using the repository browser.