Pratik Vyas | c1e6e4c | 2011-06-08 14:37:15 +0530 | [diff] [blame] | 1 | pscript.queries_bg_dict = { |
| 2 | 'Urgent':'RED', |
| 3 | 'High':'ORANGE', |
| 4 | 'Low':'BLUE', |
| 5 | 'Closed':'GREEN', |
| 6 | 'Pending Review':'YELLOW' |
| 7 | } |
| 8 | |
| 9 | pscript.onload_Projects = function() { |
| 10 | var d = $i('projects_div'); |
| 11 | |
| 12 | new PageHeader(d, 'Gantt Chart'); |
| 13 | new GanttChart($a(d, 'div', '', { margin:'16px'})); |
| 14 | } |
| 15 | |
| 16 | |
| 17 | // Gantt Chart |
| 18 | // ========================================================================== |
| 19 | |
| 20 | GanttChart = function(parent) { |
| 21 | this.wrapper = $a(parent, 'div'); |
| 22 | //this.head = new PageHeader(this.wrapper, 'Gantt Chart'); |
| 23 | |
| 24 | this.toolbar_area = $a(this.wrapper, 'div','',{padding:'16px', border:'1px solid #AAF', }); $bg(this.toolbar_area, '#EEF'); $br(this.toolbar_area, '3px'); |
| 25 | this.toolbar_tab = make_table(this.toolbar_area, 1, 4, '100%', ['25%', '25%','25%', '25%']); |
| 26 | this.grid_area = $a(this.wrapper, 'div', '', {margin: '16px 0px'}); |
| 27 | this.no_task_message = $a(this.wrapper, 'div', 'help_box', |
| 28 | {textAign:'center', fontSize:'14px'}, 'Select your criteria and click on "Make" to show the Gantt Chart') |
| 29 | |
| 30 | this.get_init_data(); |
| 31 | //this.make_grid(); |
| 32 | } |
| 33 | |
| 34 | GanttChart.prototype.get_init_data = function() { |
| 35 | var me = this; |
| 36 | var callback = function(r,rt) { |
| 37 | me.pl = r.message.pl.sort(); |
| 38 | me.rl = r.message.rl.sort(); |
| 39 | |
| 40 | me.make_toolbar(); |
| 41 | } |
| 42 | $c_obj('Project Control','get_init_data','', callback); |
| 43 | } |
| 44 | |
| 45 | GanttChart.prototype.make_filter = function(label, idx) { |
| 46 | var w = $a($td(this.toolbar_tab,0,idx), 'div','',{marginBottom:'8px'}); |
| 47 | var l = $a(w, 'div','',{fontSize:'11px'}); l.innerHTML = label; |
| 48 | return w; |
| 49 | } |
| 50 | |
| 51 | GanttChart.prototype.make_select = function(label, options,idx) { |
| 52 | var w = this.make_filter(label,idx); |
| 53 | var s = $a(w, 'select','',{width:'100px'}); add_sel_options(s, add_lists(['All'],options)); |
| 54 | return s; |
| 55 | } |
| 56 | |
| 57 | GanttChart.prototype.make_date = function(label,idx) { |
| 58 | var w = this.make_filter(label,idx); |
| 59 | var i = $a(w, 'input'); |
| 60 | |
| 61 | var user_fmt = locals['Control Panel']['Control Panel'].date_format; |
| 62 | if(!this.user_fmt)this.user_fmt = 'dd-mm-yy'; |
| 63 | |
| 64 | $(i).datepicker({ |
| 65 | dateFormat: user_fmt.replace('yyyy','yy'), |
| 66 | altFormat:'yy-mm-dd', |
| 67 | changeYear: true |
| 68 | }); |
| 69 | |
| 70 | return i; |
| 71 | } |
| 72 | |
| 73 | GanttChart.prototype.make_toolbar = function() { |
| 74 | |
| 75 | // resource / project |
| 76 | this.r_sel = this.make_select('Resource', this.rl, 0); |
| 77 | this.p_sel = this.make_select('Project', this.pl, 1); |
| 78 | |
| 79 | // start / end |
| 80 | this.s_date = this.make_date('Start Date', 2); this.s_date.value = date.str_to_user(date.month_start()); |
| 81 | this.e_date = this.make_date('End Date', 3); this.e_date.value = date.str_to_user(date.month_end()); |
| 82 | |
| 83 | // button |
| 84 | var me = this; |
| 85 | $btn(this.toolbar_area, 'Make', function() { me.refresh(); }, null, 'green', 1); |
| 86 | this.print_btn = $btn(this.toolbar_area, 'Print', function() { me.print(); }, {display:'none'},null); |
| 87 | } |
| 88 | |
| 89 | GanttChart.prototype.print = function() { |
| 90 | $(this.grid_area).printElement(); |
| 91 | } |
| 92 | |
| 93 | GanttChart.prototype.get_data = function() { |
| 94 | var me = this; |
| 95 | var callback = function(r, rt) { |
| 96 | me.tasks = r.message; |
| 97 | if(me.tasks.length) { |
| 98 | $dh(me.no_task_message); |
| 99 | $ds(me.grid_area); |
| 100 | me.show_tasks(); |
| 101 | $di(me.print_btn); |
| 102 | } else { |
| 103 | // nothign to show |
| 104 | $dh(me.grid_area); |
| 105 | $ds(me.no_task_message); |
| 106 | $dh(me.print_btn); |
| 107 | me.no_task_message.innerHTML = 'Nothing allocated for the above criteria' |
| 108 | } |
| 109 | } |
| 110 | $c_obj('Project Control','get_tasks', |
| 111 | [date.user_to_str(this.s_date.value), |
| 112 | date.user_to_str(this.e_date.value), |
| 113 | sel_val(this.p_sel), |
| 114 | sel_val(this.r_sel)].join('~~~') |
| 115 | , callback) |
| 116 | } |
| 117 | |
| 118 | GanttChart.prototype.make_grid = function() { |
| 119 | // clear earlier chart |
| 120 | this.grid_area.innerHTML = ''; |
| 121 | this.grid = new GanttGrid(this, this.s_date.value, this.e_date.value); |
| 122 | } |
| 123 | |
| 124 | GanttChart.prototype.refresh = function() { |
| 125 | this.get_data(); |
| 126 | } |
| 127 | |
| 128 | GanttChart.prototype.show_tasks = function() { |
| 129 | this.make_grid(); |
| 130 | for(var i=0; i<this.tasks.length; i++) { |
| 131 | new GanttTask(this.grid, this.tasks[i], i) |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // ========================================================================== |
| 136 | |
| 137 | GanttGrid = function(chart, s_date, e_date) { |
| 138 | this.chart = chart; |
| 139 | this.s_date = s_date; |
| 140 | |
| 141 | this.wrapper = $a(chart.grid_area, 'div'); |
| 142 | this.start_date = date.str_to_obj(date.user_to_str(s_date)); |
| 143 | this.end_date = date.str_to_obj(date.user_to_str(e_date)); |
| 144 | |
| 145 | this.n_days = date.get_diff(this.end_date, this.start_date) + 1; |
| 146 | this.g_width = 100 / this.n_days + '%'; |
| 147 | |
| 148 | this.make(); |
| 149 | } |
| 150 | |
| 151 | GanttGrid.prototype.make_grid = function() { |
| 152 | // grid ----------- |
| 153 | var ht = this.chart.tasks.length * 40 + 'px'; |
| 154 | this.grid = $a($td(this.body, 0, 1), 'div', '', {border:'2px solid #888', height: ht, position:'relative'}); |
| 155 | |
| 156 | this.grid_tab = make_table(this.grid, 1, this.n_days, '100%', [], {width:this.g_width, borderLeft:'1px solid #DDD', height: ht}); |
| 157 | $y(this.grid_tab,{tableLayout:'fixed'}); |
| 158 | |
| 159 | this.task_area = $a(this.grid, 'div', '', {position:'absolute', height:ht, width: '100%', top:'0px'}); |
| 160 | } |
| 161 | |
| 162 | GanttGrid.prototype.make_labels = function() { |
| 163 | // labels ------------ |
| 164 | this.x_labels = $a($td(this.body, 0, 1), 'div', '', {marginTop:'8px'}); |
| 165 | this.x_lab_tab = make_table(this.x_labels, 1, this.n_days, '100%', [], {width:this.g_width, fontSize:'10px'}); |
| 166 | $y(this.x_lab_tab,{tableLayout:'fixed'}); |
| 167 | |
| 168 | var d = this.start_date; |
| 169 | var today = new Date(); |
| 170 | for(var i=0; i<this.n_days; i++) { |
| 171 | if(d.getDay()==0) { |
| 172 | $td(this.x_lab_tab,0,i).innerHTML = d.getDate() + '-' + month_list[d.getMonth()]; |
| 173 | $y($td(this.grid_tab,0,i),{borderLeft:'1px solid RED'}) |
| 174 | } |
| 175 | if(d.getDate()==today.getDate() && d.getMonth()==today.getMonth() && d.getYear() == today.getYear()) { |
| 176 | $y($td(this.grid_tab,0,i),{borderLeft:'2px solid #000'}) |
| 177 | } |
| 178 | var d = date.add_days(this.start_date, 1); |
| 179 | } |
| 180 | this.start_date = date.str_to_obj(date.user_to_str(this.s_date)); |
| 181 | } |
| 182 | |
| 183 | GanttGrid.prototype.make = function() { |
| 184 | this.body = make_table(this.wrapper, 1, 2, '100%', ['30%','70%']); |
| 185 | this.make_grid(); |
| 186 | this.make_labels(); |
| 187 | this.y_labels = $a($td(this.body, 0, 0), 'div', '', {marginTop:'2px', position:'relative'}); |
| 188 | } |
| 189 | |
| 190 | GanttGrid.prototype.get_x = function(dt) { |
| 191 | var d = date.str_to_obj(dt); // convert to obj |
| 192 | return flt(date.get_diff(d, this.start_date)+1) / flt(date.get_diff(this.end_date, this.start_date)+1) * 100; |
| 193 | } |
| 194 | |
| 195 | // ========================================================================== |
| 196 | |
| 197 | GanttTask = function(grid, data, idx) { |
| 198 | // start_date, end_date, name, status |
| 199 | this.start_date = data[3]; |
| 200 | this.end_date = data[4]; |
| 201 | |
| 202 | // label |
| 203 | this.label = $a(grid.y_labels, 'div', '', {'top':(idx*40) + 'px', overflow:'hidden', position:'absolute', 'width':'100%', height: '40px'}); |
| 204 | var l1 = $a($a(this.label, 'div'), 'span', 'link_type'); l1.innerHTML = data[0]; l1.dn = data[7]; l1.onclick = function() { loaddoc('Ticket', this.dn) }; |
| 205 | var l2 = $a(this.label, 'div', '', {fontSize:'10px'}); l2.innerHTML = data[1]; |
| 206 | |
| 207 | // bar |
| 208 | var col = pscript.queries_bg_dict[data[5]]; |
| 209 | if(data[6]!='Open') col = pscript.queries_bg_dict[data[6]]; |
| 210 | if(!col) col = 'BLUE'; |
| 211 | |
| 212 | this.body = $a(grid.task_area, 'div','',{backgroundColor:col, height:'12px', position:'absolute'}); |
| 213 | |
| 214 | //bar info |
| 215 | this.body_info = $a(this.body, 'div','',{backgroundColor:'#CCC', position:'absolute', zIndex:20}); |
| 216 | |
| 217 | var x1 = grid.get_x(this.start_date); |
| 218 | var x2 = grid.get_x(this.end_date); |
| 219 | |
| 220 | if(x1<=0)x1=0; |
| 221 | else x1 -=100/flt(date.get_diff(grid.end_date, grid.start_date)+1); |
| 222 | if(x2>=100)x2=100; |
| 223 | // else x2+=100/flt(date.get_diff(grid.end_date, grid.start_date)+1); |
| 224 | |
| 225 | $y(this.body, { |
| 226 | top: idx * 40 + 14 + 'px', |
| 227 | left: x1 + '%', |
| 228 | width: (x2-x1) + '%', |
| 229 | zIndex: 1, |
| 230 | cursor:'pointer' |
| 231 | }) |
| 232 | |
| 233 | // divider |
| 234 | if(idx) { |
| 235 | var d1 = $a(grid.task_area, 'div','',{borderBottom: '1px solid #AAA', position:'absolute', width:'100%', top:(idx*40) + 'px'}); |
| 236 | var d2 = $a(grid.y_labels, 'div','',{borderBottom: '1px solid #AAA', position:'absolute', width:'100%', top:(idx*40) + 'px'}); |
| 237 | } |
| 238 | |
| 239 | this.make_tooltip(data); |
| 240 | } |
| 241 | |
| 242 | GanttTask.prototype.make_tooltip = function(d) { |
| 243 | var t = '<div>'; |
| 244 | if(d[0]) t += '<b>Task: </b>' + d[0]; |
| 245 | if(d[5]) t += '<br><b>Priority: </b>' + d[5]; |
| 246 | if(d[6]) t += '<br><b>Status: </b>' + d[6]; |
| 247 | if(d[1]) t += '<br><b>Allocated To: </b>' + d[1]; |
| 248 | if(d[2]) t += '<br><b>Project: </b>' + d[2]; |
| 249 | if(d[3]) t += '<br><b>From: </b>' + date.str_to_user(d[3]); |
| 250 | if(d[4]) t += '<br><b>To: </b>' + date.str_to_user(d[4]); |
| 251 | t += '</div>'; |
| 252 | |
| 253 | $(this.body).qtip({ |
| 254 | content:t, |
| 255 | position:{ |
| 256 | corner:{ |
| 257 | tooltip: 'topMiddle', // Use the corner... |
| 258 | target: 'bottomMiddle' // ...and opposite corner |
| 259 | } |
| 260 | }, |
| 261 | style:{ |
| 262 | border: { |
| 263 | width: 5, |
| 264 | radius: 10 |
| 265 | }, |
| 266 | padding: 10, |
| 267 | tip: true, // Give it a speech bubble tip with automatic corner detection |
| 268 | name: 'green' // Style it according to the preset 'cream' style |
| 269 | } |
| 270 | }) |
| 271 | |
| 272 | } |
| 273 | |
| 274 | |
| 275 | |
| 276 | |