source: Dev/branches/rest-dojo-ui/client/dojox/gantt/GanttResourceItem.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: 17.0 KB
Line 
1dojo.provide("dojox.gantt.GanttResourceItem");
2
3dojo.require("dojo.date.locale");
4
5dojo.declare("dojox.gantt.GanttResourceItem", null, {
6        constructor: function(ganttchart){
7                this.ganttChart = ganttchart;
8                this.ownerItem = [];
9                this.ownerNameItem = [];
10                this.ownerTaskNodeMapping = {};
11                this.ownerTaskNodeMapping_time = {};
12                this.resourceInfo = {};
13                this.ownerTimeConsume = {};
14        },
15        clearAll: function(){
16                this.clearData();
17                this.clearItems();
18        },
19        clearData: function(){
20                this.ownerItem = [];
21                this.ownerNameItem = [];
22                this.ownerTaskNodeMapping = {};
23                this.ownerTaskNodeMapping_time = {};
24                this.resourceInfo = {};
25                this.ownerTimeConsume = {};
26        },
27        clearItems: function(){
28                if(this.content.firstChild){
29                    dojo.destroy(this.content.firstChild);
30                }
31        },
32        buildResource: function(){
33                var resourceInfo = {};
34                dojo.forEach(this.ganttChart.arrProjects, function(project){
35                        dojo.forEach(project.arrTasks, function(task){
36                                task.buildResourceInfo(resourceInfo);
37                        }, this);
38                }, this);
39                return resourceInfo;
40        },
41        buildOwnerTimeConsume: function(){
42                var ownerTimeConsume = {};
43                for(var owner in this.resourceInfo){
44                        var tasks = this.resourceInfo[owner];
45                        //combine time zone  (startTime - this.startDate) / (60 * 60 * 1000) * this.pixelsPerHour;
46                        var timeZoom = {};
47                        for(var i = 0; i < tasks.length; i++){
48                                var task = tasks[i];
49                                var startTime = task.taskItem.startTime.getTime(), dur = task.taskItem.duration * 24 * 60 * 60 * 1000 / this.ganttChart.hsPerDay;
50                                timeZoom.min = timeZoom.min ? Math.min(timeZoom.min, startTime) : startTime;
51                                timeZoom.max = timeZoom.max ? Math.max(timeZoom.max, (startTime + dur)) : (startTime + dur);
52                        }
53                        timeZoom.dur = (timeZoom.max - timeZoom.min) * this.ganttChart.hsPerDay / (24 * 60 * 60 * 1000);
54                        timeZoom.min = new Date(timeZoom.min);
55                        timeZoom.max = new Date(timeZoom.max);
56                        ownerTimeConsume[owner] = timeZoom;
57                }
58                return ownerTimeConsume;
59        },
60        refresh: function(){
61                this.ownerTimeConsume = this.buildOwnerTimeConsume();
62                //resize outer div
63                this.contentData.firstChild.style.width = Math.max(1200, this.ganttChart.pixelsPerDay * this.ganttChart.totalDays) + "px";
64                for(var owner in this.resourceInfo){
65                        this.refreshOwnerEntry(owner);
66                }
67        },
68        reConstruct: function(){
69                this.clearAll();
70                this.resourceInfo = this.buildResource();
71                this.ownerTimeConsume = this.buildOwnerTimeConsume();
72                this.tableControl = dojo.create("table", {
73                        cellPadding: "0",
74                        cellSpacing: "0",
75                        className: "ganttResourceTableControl"
76                });
77                var newRowTblControl = this.tableControl.insertRow(this.tableControl.rows.length);
78                //Add to content Table
79                this.contentHeight = this.content.offsetHeight;
80                this.contentWidth = this.content.offsetWidth;
81                this.content.appendChild(this.tableControl);
82                //Creation panel contentData
83                this.contentData = dojo.create("div", {className: "ganttResourceContentDataContainer"});
84                this.contentData.appendChild(this.createPanelOwners());
85                dojo.style(this.contentData, "height", (this.contentHeight - this.ganttChart.panelTimeHeight) + "px");
86                //Creation panel of names
87                var newCellTblControl = dojo.create("td", {
88                        vAlign: "top"
89                });
90                this.panelNames = dojo.create("div", {className: "ganttResourcePanelNames"});
91                this.panelNames.appendChild(this.createPanelNamesOwners());
92                newCellTblControl.appendChild(this.panelNames);
93                newRowTblControl.appendChild(newCellTblControl);
94                //add to control contentData and contentDataTime
95                newCellTblControl = dojo.create("td", {
96                        vAlign: "top"
97                });
98                var divCell = dojo.create("div", {className: "ganttResourceDivCell"});
99                divCell.appendChild(this.contentData);
100                newCellTblControl.appendChild(divCell);
101                newRowTblControl.appendChild(newCellTblControl);
102                //Show panel of names
103                dojo.style(this.panelNames, {
104                        height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
105                        width: this.ganttChart.maxWidthPanelNames + "px"
106                });
107                this.contentData.style.width = (this.contentWidth - this.ganttChart.maxWidthPanelNames) + "px";
108                this.contentData.firstChild.style.width = this.ganttChart.pixelsPerDay * (this.ganttChart.panelTime.firstChild.firstChild.rows[3].cells.length) + "px";
109                var _this = this;
110                this.contentData.onscroll = function(){
111                        if(_this.panelNames){
112                                _this.panelNames.scrollTop = this.scrollTop;
113                        }
114                }
115                this.contentData.scrollLeft = this.ganttChart.contentData.scrollLeft;
116                for(var owner in this.resourceInfo){
117                        this.createOwnerEntry(owner);
118                }
119                this.postAdjustment();
120        },
121        create: function(){
122                var resourceHeader = dojo.create("div", {
123                        innerHTML: "Resource Chart:",
124                        className: "ganttResourceHeader"
125                }, this.ganttChart.content, "after");
126                dojo.style(resourceHeader, "width", this.ganttChart.contentWidth + "px");
127                var content = dojo.create("div", {className: "ganttResourceContent"}, resourceHeader, "after");
128                dojo.style(content, {
129                        width: this.ganttChart.contentWidth + "px",
130                        height: (this.ganttChart.resourceChartHeight || (this.ganttChart.contentHeight * 0.8)) + "px"
131                });
132                this.content = content || this.content;
133                //create Table
134                this.reConstruct();
135        },
136        postAdjustment: function(){
137                //contentData height
138                this.contentData.firstChild.style.height = (this.ownerItem.length * 23) + "px";
139                this.panelNames.firstChild.style.height = (this.ownerItem.length * 23) + "px";
140        },
141       
142        refreshOwnerEntry: function(owner){
143                this.refreshOwnerItem(owner);
144                dojo.forEach(this.resourceInfo[owner], function(task, i){
145                        var item = this.ownerTaskNodeMapping[owner].tasks[i][0];
146                        this.refreshDetailedTaskEntry(owner, item, task);
147                }, this);
148        },
149        createOwnerEntry: function(owner){
150                var containerOwner = this.contentData.firstChild;
151                var previousOwner = this.ownerItem[this.ownerItem.length - 1];
152                this.ownerTaskNodeMapping[owner] = {};
153                this.ownerTaskNodeMapping[owner][owner] = [];
154                //create nodes
155                var pos = dojo.position(containerOwner);
156                //creation arrTasks
157                var posY = (previousOwner ? parseInt(previousOwner.style.top) : (6 - 23)) + this.ganttChart.heightTaskItem + 11;
158                //creation task item
159                var oItem = this.createOwnerItem(owner, posY);
160                containerOwner.appendChild(oItem);
161                this.ownerItem.push(oItem);
162                this.ownerTaskNodeMapping[owner][owner].push(oItem);
163                if(this.panelNames){
164                        var oNameItem = this.createOwnerNameItem(owner, posY);
165                        this.panelNames.firstChild.appendChild(oNameItem);
166                        this.ownerNameItem.push(oNameItem);
167                        this.ownerTaskNodeMapping[owner][owner].push(oNameItem);
168                }
169                var currentOwnerNode = this.ownerItem[this.ownerNameItem.length - 1],
170                        currentOwnerNameNode = this.ownerNameItem[this.ownerNameItem.length - 1];
171                //adjust nodes
172                if(this.panelNames){
173                        this.checkWidthTaskNameItem(currentOwnerNameNode);
174                        var treeImg = this.createTreeImg(currentOwnerNameNode);
175                        this.panelNames.firstChild.appendChild(treeImg);
176                        this.ownerTaskNodeMapping[owner][owner].push(treeImg);
177                }
178                this.ownerTaskNodeMapping[owner]["taskCount"] = this.resourceInfo[owner].length;
179                this.ownerTaskNodeMapping[owner]["isOpen"] = false;
180                this.ownerTaskNodeMapping[owner]["tasks"] = [];
181                dojo.forEach(this.resourceInfo[owner], function(task){
182                        this.ownerTaskNodeMapping[owner]["tasks"].push(this.createDetailedTaskEntry(owner, currentOwnerNameNode, task));
183                }, this);
184                return this;
185        },
186        createOwnerNameItem: function(owner, posY){
187                var ownerName = dojo.create("div", {
188                        id: owner,
189                        title: owner,
190                        innerHTML: owner,
191                        className: "ganttOwnerNameItem"
192                });
193                dojo.style(ownerName, "top", posY + "px");
194                return ownerName;
195        },
196        refreshOwnerItem: function(owner){
197                var item = this.ownerTaskNodeMapping[owner][owner][0],
198                        start = this.ownerTimeConsume[owner].min, end = this.ownerTimeConsume[owner].max, dur = this.ownerTimeConsume[owner].dur,
199                        posX = this.ganttChart.getPosOnDate(start); // should be task start date
200                item.style.left = posX + "px";
201                item.style.width = dur * this.ganttChart.pixelsPerWorkHour + "px";
202                dojo.forEach(this.resourceInfo[owner], function(task, i){
203                        var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
204                        dojo.style(item.childNodes[i], {
205                                left: (tposX - posX) + "px",
206                                width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
207                        });
208                }, this);
209        },
210        createOwnerItem: function(owner, posY){
211                var start = this.ownerTimeConsume[owner].min, end = this.ownerTimeConsume[owner].max, dur = this.ownerTimeConsume[owner].dur;
212                var posX = this.ganttChart.getPosOnDate(start); // should be task start date
213                var ownerControl = dojo.create("div", {
214                        id: owner,
215                        owner: true,
216                        className: "ganttOwnerBar"
217                });
218                dojo.style(ownerControl, {
219                        left: posX + "px",
220                        top: posY + "px",
221                        width: dur * this.ganttChart.pixelsPerWorkHour + "px",
222                        height: this.ganttChart.heightTaskItem + "px"
223                });
224                dojo.forEach(this.resourceInfo[owner], function(task){
225                        var ownerTaskItem = dojo.create("div", {
226                                id: owner,
227                                className: "ganttOwnerTaskBar"
228                        }, ownerControl);
229                        var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
230                        dojo.style(ownerTaskItem, {
231                                left: (tposX - posX) + "px",
232                                width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px", // should be task duration
233                                height: this.ganttChart.heightTaskItem + "px"
234                        });
235                }, this);
236                return ownerControl;
237        },
238        refreshDetailedTaskEntry: function(owner, item, task){
239                this.refreshTaskItem(item, task);
240        },
241        createDetailedTaskEntry: function(owner, parentNode, task){
242                var taskItems = [];
243                var containerTasks = this.contentData.firstChild;
244                var posY = parseInt(parentNode.style.top);
245               
246                //creation task item
247                var taskItem = this.createTaskItem(task, posY);
248                taskItem.style.display = "none";
249                containerTasks.appendChild(taskItem);
250                this.ownerItem.push(taskItem);
251                taskItems.push(taskItem);
252                if(this.panelNames){
253                        var taskNameItem = this.createTaskNameItem(task.taskItem.name, posY);
254                        this.panelNames.firstChild.appendChild(taskNameItem);
255                        taskNameItem.style.display = "none";
256                        this.ownerNameItem.push(taskNameItem);
257                        taskItems.push(taskNameItem);
258                }
259                if(this.panelNames){
260                        this.ownerNameItem[this.ownerNameItem.length - 1].style.left = dojo.style(parentNode, "left") + 15 + "px";
261                        var arrConnectingLinesNames = this.createConnectingLinesPN(parentNode, this.ownerNameItem[this.ownerNameItem.length - 1]);
262                        dojo.forEach(arrConnectingLinesNames, function(lineName){
263                                lineName.style.display = "none";
264                        }, this);
265                        taskItems.push({
266                                "v": arrConnectingLinesNames[0],
267                                "h": arrConnectingLinesNames[1]
268                        });
269                        this.checkWidthTaskNameItem(this.ownerNameItem[this.ownerNameItem.length - 1]);
270                }
271                return taskItems;
272        },
273        createTaskNameItem: function(owner, posY){
274                var taskNameItem = dojo.create("div", {
275                        id: owner,
276                        className: "ganttTaskNameItem",
277                        title: owner,
278                        innerHTML: owner
279                });
280                dojo.style(taskNameItem, "top", posY + "px");
281                return taskNameItem;
282        },
283        refreshTaskItem: function(item, task){
284                var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
285                dojo.style(item, {
286                        left: posX + "px",
287                        width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
288                });
289        },
290        createTaskItem: function(task, posY){
291                var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
292                var itemControl = dojo.create("div", {
293                        id: task.taskItem.name,
294                        className: "ganttTaskBar"
295                });
296                dojo.style(itemControl, {
297                        left: posX + "px",
298                        top: posY + "px",
299                        width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
300                        height: this.ganttChart.heightTaskItem + "px"
301                });
302                return itemControl;
303        },
304        createConnectingLinesPN: function(parentNode, currentNode){
305                var arrConnectingLinesNames = [];
306                var lineVerticalLeft = dojo.create("div", {
307                        innerHTML: "&nbsp;",
308                        className: "ganttResourceLineVerticalLeft"
309                }, this.panelNames.firstChild);
310                lineVerticalLeft.cNode = currentNode;
311                lineVerticalLeft.pNode = parentNode;
312                var LineHorizontalLeft = dojo.create("div", {
313                        noShade: true,
314                        color: "#000",
315                        className: "ganttResourceLineHorizontalLeft"
316                }, this.panelNames.firstChild);
317                LineHorizontalLeft.cNode = currentNode;
318                LineHorizontalLeft.pNode = parentNode;
319                this.panelNames.firstChild.appendChild(LineHorizontalLeft);
320                arrConnectingLinesNames.push(lineVerticalLeft);
321                arrConnectingLinesNames.push(LineHorizontalLeft);
322                return arrConnectingLinesNames;
323        },
324        createTreeImg: function(ownerNameItem){
325                var treeImg = dojo.create("div", {
326                        id: ownerNameItem.id,
327                        className: "ganttImageTreeExpand"
328                });
329                dojo.attr(treeImg, "tabIndex", 0);
330                var currentItem = this.ownerTaskNodeMapping[ownerNameItem.id];
331                dojo.forEach(["onclick", "onkeydown"], function(e){
332                        this.ganttChart._events.push(
333                                dojo.connect(treeImg, e, this, function(evt){
334                                        var reachTarget = false, owner, ownerItem;
335                                        if(e == "onkeydown" && evt.keyCode != dojo.keys.ENTER){ return; }
336                                        //TODO: perhaps the following conditional can be collapsed?  Duplicate code.
337                                        if(currentItem.isOpen){
338                                                dojo.removeClass(treeImg, "ganttImageTreeCollapse");
339                                                dojo.addClass(treeImg, "ganttImageTreeExpand");
340                                                currentItem.isOpen = false;
341                                                //collapse
342                                                for(owner in this.ownerTaskNodeMapping){
343                                                        ownerItem = this.ownerTaskNodeMapping[owner];
344                                                        if(reachTarget){
345                                                                dojo.forEach(ownerItem[owner], function(tItem){
346                                                                        dojo.style(tItem, "top", dojo.style(tItem, "top") - currentItem.taskCount * 23 + "px");
347                                                                });
348                                                                dojo.forEach(ownerItem.tasks, function(tItems){
349                                                                        dojo.forEach(tItems, function(tItem){
350                                                                                var item = !tItem.v && !tItem.h ? [tItem] : [tItem.v, tItem.h];
351                                                                                dojo.forEach(item, function(t){
352                                                                                        dojo.style(t, "top", dojo.style(t, "top") - currentItem.taskCount * 23 + "px");
353                                                                                });
354                                                                        });
355                                                                });
356                                                        }else{
357                                                                if(owner == ownerNameItem.id){
358                                                                        reachTarget = true;
359                                                                        dojo.forEach(ownerItem.tasks, function(tItems, i){
360                                                                                dojo.forEach(tItems, function(tItem){
361                                                                                        this.styleOwnerItem(tItem, ownerItem[owner][0], "none", 0);
362                                                                                }, this);
363                                                                        }, this);
364                                                                }
365                                                        }
366                                                }
367                                        }else{
368                                                dojo.removeClass(treeImg, "ganttImageTreeExpand");
369                                                dojo.addClass(treeImg, "ganttImageTreeCollapse");
370                                                currentItem.isOpen = true;
371                                                //expand
372                                                for(owner in this.ownerTaskNodeMapping){
373                                                        ownerItem = this.ownerTaskNodeMapping[owner];
374                                                        if(reachTarget){
375                                                                dojo.forEach(ownerItem[owner], function(tItem){
376                                                                        dojo.style(tItem, "top", dojo.style(tItem, "top") + currentItem.taskCount * 23 + "px");
377                                                                });
378                                                                dojo.forEach(ownerItem.tasks, function(tItems){
379                                                                        dojo.forEach(tItems, function(tItem){
380                                                                                var item = !tItem.v && !tItem.h ? [tItem] : [tItem.v, tItem.h];
381                                                                                dojo.forEach(item, function(t){
382                                                                                        dojo.style(t, "top", dojo.style(t, "top") + currentItem.taskCount * 23 + "px");
383                                                                                });
384                                                                        });
385                                                                });
386                                                        }else{
387                                                                if(owner == ownerNameItem.id){
388                                                                        reachTarget = true;
389                                                                        dojo.forEach(ownerItem.tasks, function(tItems, i){
390                                                                                dojo.forEach(tItems, function(tItem){
391                                                                                        this.styleOwnerItem(tItem, ownerItem[owner][0], "inline", (i + 1) * 23);
392                                                                                }, this);
393                                                                        }, this);
394                                                                }
395                                                        }
396                                                }
397                                        }
398                                })
399                        );
400                }, this);
401                dojo.addClass(treeImg, "ganttResourceTreeImage");
402                dojo.style(treeImg, {
403                        left: (dojo.style(ownerNameItem, "left") - 12) + "px",
404                        top: (dojo.style(ownerNameItem, "top") + 3) + "px"
405                });
406                return treeImg;
407        },
408        styleOwnerItem: function(tItem, owner, displayType, topOffset){
409                if(tItem.v || tItem.h){
410                        dojo.style(tItem.v, {
411                                height: Math.max(1, (tItem.v.cNode.offsetTop - tItem.v.pNode.offsetTop)) + "px",
412                                top: (tItem.v.pNode.offsetTop + 5) + "px",
413                                left: (tItem.v.pNode.offsetLeft - 9) + "px",
414                                display: displayType
415                        });
416                        dojo.style(tItem.h, {
417                                width: Math.max(1, (tItem.h.cNode.offsetLeft - tItem.h.pNode.offsetLeft + 4)) + "px",
418                                top: (tItem.h.cNode.offsetTop + 5) + "px",
419                                left: (tItem.h.pNode.offsetLeft - 9) + "px",
420                                display: displayType
421                        });
422                }else{
423                        dojo.style(tItem, {
424                                display: displayType,
425                                top: parseInt(owner.style.top) + topOffset + "px"
426                        });
427                }
428        },
429        checkWidthTaskNameItem: function(taskNameItem){
430                if(taskNameItem && taskNameItem.offsetWidth + taskNameItem.offsetLeft > this.ganttChart.maxWidthPanelNames){
431                        var width = taskNameItem.offsetWidth + taskNameItem.offsetLeft - this.ganttChart.maxWidthPanelNames,
432                                countChar = Math.round(width / (taskNameItem.offsetWidth / taskNameItem.firstChild.length)),
433                                tName = taskNameItem.id.substring(0, taskNameItem.firstChild.length - countChar - 3);
434                        taskNameItem.innerHTML = tName + "...";
435                }
436        },
437        createPanelOwners: function(){
438                var panelOwner = dojo.create("div", {
439                        className: "ganttOwnerPanel"
440                });
441                dojo.style(panelOwner, {
442                        height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px"
443                });
444                return panelOwner;
445        },
446        createPanelNamesOwners: function(){
447                var panelNameOwner = dojo.create("div", {
448                        innerHTML: "&nbsp;",
449                        className: "ganttResourcePanelNamesOwners"
450                });
451                dojo.style(panelNameOwner, {
452                        height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
453                        width: this.ganttChart.maxWidthPanelNames + "px"
454                });
455                return panelNameOwner;
456        }
457});
Note: See TracBrowser for help on using the repository browser.