GanttProjectItem.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.gantt.GanttProjectItem"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.gantt.GanttProjectItem"] = true;
  8. dojo.provide("dojox.gantt.GanttProjectItem");
  9. dojo.require("dojox.gantt.GanttTaskItem");
  10. dojo.require("dojo.date.locale");
  11. dojo.declare("dojox.gantt.GanttProjectControl", null, {
  12. constructor: function(ganttChart, projectItem){
  13. this.project = projectItem;
  14. this.ganttChart = ganttChart;
  15. this.descrProject = null;
  16. this.projectItem = null;
  17. this.projectNameItem = null;
  18. this.posY = 0;
  19. this.posX = 0;
  20. this.nextProject = null;
  21. this.previousProject = null;
  22. this.arrTasks = [];
  23. this.percentage = 0;
  24. this.duration = 0;
  25. },
  26. checkWidthProjectNameItem: function(){
  27. if(this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft > this.ganttChart.maxWidthTaskNames){
  28. var width = this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft - this.ganttChart.maxWidthTaskNames;
  29. var countChar = Math.round(width / (this.projectNameItem.offsetWidth / this.projectNameItem.firstChild.length));
  30. var pName = this.project.name.substring(0, this.projectNameItem.firstChild.length - countChar - 3);
  31. pName += "...";
  32. this.projectNameItem.innerHTML = pName;
  33. }
  34. },
  35. refreshProjectItem: function(projectItem){
  36. this.percentage = this.getPercentCompleted();
  37. dojo.style(projectItem, {
  38. "left": this.posX + "px",
  39. "width": this.duration * this.ganttChart.pixelsPerWorkHour + "px"
  40. });
  41. var tblProjectItem = projectItem.firstChild;
  42. var width = this.duration * this.ganttChart.pixelsPerWorkHour;
  43. tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
  44. tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
  45. var rowprojectItem = tblProjectItem.rows[0];
  46. if(this.percentage != -1){
  47. if(this.percentage != 0){
  48. var cellprojectItem = rowprojectItem.firstChild;
  49. cellprojectItem.width = this.percentage + "%";
  50. var imageProgress = cellprojectItem.firstChild;
  51. dojo.style(imageProgress, {
  52. width: (!this.duration ? 1 : (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
  53. height: this.ganttChart.heightTaskItem + "px"
  54. })
  55. }
  56. if(this.percentage != 100){
  57. var cellprojectItem = rowprojectItem.lastChild;
  58. cellprojectItem.width = (100 - this.percentage) + "%";
  59. var imageProgress = cellprojectItem.firstChild;
  60. dojo.style(imageProgress, {
  61. width: (!this.duration ? 1 : ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
  62. height: this.ganttChart.heightTaskItem + "px"
  63. })
  64. }
  65. }else{
  66. var cellprojectItem = rowprojectItem.firstChild;
  67. cellprojectItem.width = "1px";
  68. var imageProgress = cellprojectItem.firstChild;
  69. dojo.style(imageProgress, {
  70. width: "1px",
  71. height: this.ganttChart.heightTaskItem + "px"
  72. })
  73. }
  74. var divTaskInfo = projectItem.lastChild;
  75. var tblTaskInfo = divTaskInfo.firstChild;
  76. dojo.style(tblTaskInfo, {
  77. height: this.ganttChart.heightTaskItem + "px",
  78. width: (!this.duration ? 1 : (this.duration * this.ganttChart.pixelsPerWorkHour)) + "px"
  79. });
  80. var rowTaskInfo = tblTaskInfo.rows[0];
  81. var cellTaskInfo = rowTaskInfo.firstChild;
  82. cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
  83. if(this.project.parentTasks.length == 0){
  84. projectItem.style.display = "none";
  85. }
  86. return projectItem;
  87. },
  88. refreshDescrProject: function(divDesc){
  89. var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
  90. dojo.style(divDesc, {
  91. "left": posX + "px"
  92. });
  93. if(this.project.parentTasks.length == 0){
  94. this.descrProject.style.visibility = 'hidden';
  95. }
  96. return divDesc;
  97. },
  98. postLoadData: function(){
  99. //TODO e.g. project relative info...
  100. },
  101. refresh: function(){
  102. var containerTasks = this.ganttChart.contentData.firstChild;
  103. this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
  104. this.refreshProjectItem(this.projectItem[0]);
  105. this.refreshDescrProject(this.projectItem[0].nextSibling);
  106. return this;
  107. },
  108. create: function(){
  109. var containerTasks = this.ganttChart.contentData.firstChild;
  110. this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
  111. if(this.previousProject){
  112. if(this.previousProject.arrTasks.length > 0){
  113. var lastChildTask = this.ganttChart.getLastChildTask(this.previousProject.arrTasks[this.previousProject.arrTasks.length - 1]);
  114. this.posY = parseInt(lastChildTask.cTaskItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  115. }else{
  116. this.posY = parseInt(this.previousProject.projectItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  117. }
  118. }else{
  119. this.posY = 6;
  120. }
  121. var containerNames = this.ganttChart.panelNames.firstChild;
  122. this.projectNameItem = this.createProjectNameItem();
  123. containerNames.appendChild(this.projectNameItem);
  124. this.checkWidthProjectNameItem();
  125. this.projectItem = [this.createProjectItem(), []];
  126. containerTasks.appendChild(this.projectItem[0]);
  127. containerTasks.appendChild(this.createDescrProject());
  128. this.adjustPanelTime();
  129. },
  130. getTaskById: function(id){
  131. for(var i = 0; i < this.arrTasks.length; i++){
  132. var aTask = this.arrTasks[i];
  133. var task = this.searchTaskInTree(aTask, id);
  134. if(task){
  135. return task;
  136. }
  137. }
  138. return null;
  139. },
  140. searchTaskInTree: function(task, id){
  141. if(task.taskItem.id == id){
  142. return task;
  143. }else{
  144. for(var i = 0; i < task.childTask.length; i++){
  145. var cTask = task.childTask[i];
  146. if(cTask.taskItem.id == id){
  147. return cTask;
  148. }else{
  149. if(cTask.childTask.length > 0){
  150. var cTask = this.searchTaskInTree(cTask, id);
  151. if(cTask){
  152. return cTask;
  153. }
  154. }
  155. }
  156. }
  157. }
  158. return null;
  159. },
  160. shiftProjectItem: function(){
  161. var posItemL = null;
  162. var posItemR = null;
  163. var posProjectItemL = parseInt(this.projectItem[0].style.left);
  164. var posProjectItemR = parseInt(this.projectItem[0].firstChild.style.width) + parseInt(this.projectItem[0].style.left);
  165. var widthProjectItem = parseInt(this.projectItem[0].firstChild.style.width);
  166. for(var i = 0; i < this.arrTasks.length; i++){
  167. var aTask = this.arrTasks[i];
  168. var tmpPosItemL = parseInt(aTask.cTaskItem[0].style.left);
  169. var tmpPosItemR = parseInt(aTask.cTaskItem[0].style.left) + parseInt(aTask.cTaskItem[0].firstChild.firstChild.width);
  170. if(!posItemL){
  171. posItemL = tmpPosItemL;
  172. }
  173. if(!posItemR){
  174. posItemR = tmpPosItemR;
  175. }
  176. if(posItemL > tmpPosItemL){
  177. posItemL = tmpPosItemL;
  178. }
  179. if(posItemR < tmpPosItemR){
  180. posItemR = tmpPosItemR;
  181. }
  182. }
  183. if(posItemL != posProjectItemL){
  184. this.project.startDate = new Date(this.ganttChart.startDate);
  185. this.project.startDate.setHours(this.project.startDate.getHours() + (posItemL / this.ganttChart.pixelsPerHour));
  186. }
  187. this.projectItem[0].style.left = posItemL + "px";
  188. this.resizeProjectItem(posItemR - posItemL);
  189. this.duration = Math.round(parseInt(this.projectItem[0].firstChild.width) / (this.ganttChart.pixelsPerWorkHour));
  190. this.shiftDescrProject();
  191. this.adjustPanelTime();
  192. },
  193. adjustPanelTime: function(){
  194. var projectItem = this.projectItem[0];
  195. var width = parseInt(projectItem.style.left) + parseInt(projectItem.firstChild.style.width) + this.ganttChart.panelTimeExpandDelta;
  196. width += this.descrProject.offsetWidth;
  197. this.ganttChart.adjustPanelTime(width);
  198. },
  199. resizeProjectItem: function(width){
  200. var percentage = this.percentage,
  201. pItem = this.projectItem[0];
  202. if(percentage > 0 && percentage < 100){
  203. pItem.firstChild.style.width = width + "px";
  204. pItem.firstChild.width = width + "px";
  205. pItem.style.width = width + "px";
  206. var firstRow = pItem.firstChild.rows[0];
  207. firstRow.cells[0].firstChild.style.width = Math.round(width * percentage / 100) + "px";
  208. firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
  209. firstRow.cells[1].firstChild.style.width = Math.round(width * (100 - percentage) / 100) + "px";
  210. firstRow.cells[1].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
  211. pItem.lastChild.firstChild.width = width + "px";
  212. }else if(percentage == 0 || percentage == 100){
  213. pItem.firstChild.style.width = width + "px";
  214. pItem.firstChild.width = width + "px";
  215. pItem.style.width = width + "px";
  216. var firstRow = pItem.firstChild.rows[0];
  217. firstRow.cells[0].firstChild.style.width = width + "px";
  218. firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
  219. pItem.lastChild.firstChild.width = width + "px";
  220. }
  221. },
  222. shiftDescrProject: function(){
  223. var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
  224. this.descrProject.style.left = posX + "px";
  225. this.descrProject.innerHTML = this.getDescStr();
  226. },
  227. showDescrProject: function(){
  228. var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
  229. this.descrProject.style.left = posX + "px";
  230. this.descrProject.style.visibility = 'visible';
  231. this.descrProject.innerHTML = this.getDescStr();
  232. },
  233. hideDescrProject: function(){
  234. this.descrProject.style.visibility = 'hidden';
  235. },
  236. getDescStr: function(){
  237. return this.duration/this.ganttChart.hsPerDay + " days, " + this.duration + " hours";
  238. },
  239. createDescrProject: function(){
  240. var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
  241. var divDesc = dojo.create("div", {
  242. innerHTML: this.getDescStr(),
  243. className: "ganttDescProject"
  244. });
  245. dojo.style(divDesc, {
  246. left: posX + "px",
  247. top: this.posY + "px"
  248. });
  249. this.descrProject = divDesc;
  250. if(this.project.parentTasks.length == 0){
  251. this.descrProject.style.visibility = 'hidden';
  252. }
  253. return divDesc;
  254. },
  255. createProjectItem: function(){
  256. this.percentage = this.getPercentCompleted();
  257. this.duration = this.getDuration();
  258. var projectItem = dojo.create("div", {
  259. id: this.project.id,
  260. className: "ganttProjectItem"
  261. });
  262. dojo.style(projectItem, {
  263. left: this.posX + "px",
  264. top: this.posY + "px",
  265. width: this.duration * this.ganttChart.pixelsPerWorkHour + "px"
  266. });
  267. var tblProjectItem = dojo.create("table", {
  268. cellPadding: "0",
  269. cellSpacing: "0",
  270. className: "ganttTblProjectItem"
  271. }, projectItem);
  272. var width = this.duration * this.ganttChart.pixelsPerWorkHour;
  273. tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
  274. tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
  275. var rowprojectItem = tblProjectItem.insertRow(tblProjectItem.rows.length);
  276. if(this.percentage != -1){
  277. if(this.percentage != 0){
  278. var cellprojectItem = dojo.create("td", {
  279. width: this.percentage + "%"
  280. }, rowprojectItem);
  281. cellprojectItem.style.lineHeight = "1px";
  282. var imageProgress = dojo.create("div", {
  283. className: "ganttImageProgressFilled"
  284. }, cellprojectItem);
  285. dojo.style(imageProgress, {
  286. width: (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  287. height: this.ganttChart.heightTaskItem + "px"
  288. });
  289. }
  290. if(this.percentage != 100){
  291. var cellprojectItem = dojo.create("td", {
  292. width: (100 - this.percentage) + "%"
  293. }, rowprojectItem);
  294. cellprojectItem.style.lineHeight = "1px";
  295. var imageProgress = dojo.create("div", {
  296. className: "ganttImageProgressBg"
  297. }, cellprojectItem);
  298. dojo.style(imageProgress, {
  299. width: ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  300. height: this.ganttChart.heightTaskItem + "px"
  301. });
  302. }
  303. }else{
  304. var cellprojectItem = dojo.create("td", {
  305. width: "1px"
  306. }, rowprojectItem);
  307. cellprojectItem.style.lineHeight = "1px";
  308. var imageProgress = dojo.create("div", {
  309. className: "ganttImageProgressBg"
  310. }, cellprojectItem);
  311. dojo.style(imageProgress, {
  312. width: "1px",
  313. height: this.ganttChart.heightTaskItem + "px"
  314. });
  315. }
  316. var divTaskInfo = dojo.create("div", {className: "ganttDivTaskInfo"});
  317. var tblTaskInfo = dojo.create("table", {
  318. cellPadding: "0",
  319. cellSpacing: "0",
  320. height: this.ganttChart.heightTaskItem + "px",
  321. width: ((this.duration * this.ganttChart.pixelsPerWorkHour == 0) ? 1 : this.duration * this.ganttChart.pixelsPerWorkHour) + "px"
  322. }, divTaskInfo);
  323. var rowTaskInfo = tblTaskInfo.insertRow(0);
  324. var cellTaskInfo = dojo.create("td", {
  325. align: "center",
  326. vAlign: "top",
  327. height: this.ganttChart.heightTaskItem + "px",
  328. className: "ganttMoveInfo"
  329. }, rowTaskInfo);
  330. projectItem.appendChild(divTaskInfo);
  331. if(this.project.parentTasks.length == 0){
  332. projectItem.style.display = "none";
  333. }
  334. return projectItem;
  335. },
  336. createProjectNameItem: function(){
  337. var divName = dojo.create("div", {
  338. className: "ganttProjectNameItem",
  339. innerHTML: this.project.name,
  340. title: this.project.name
  341. });
  342. dojo.style(divName, {
  343. left: "5px",
  344. top: this.posY + "px"
  345. });
  346. dojo.attr(divName, "tabIndex", 0);
  347. if(this.ganttChart.isShowConMenu){
  348. this.ganttChart._events.push(
  349. dojo.connect(divName, "onmouseover", this, function(event){
  350. dojo.addClass(divName, "ganttProjectNameItemHover");
  351. clearTimeout(this.ganttChart.menuTimer);
  352. this.ganttChart.tabMenu.clear();
  353. this.ganttChart.tabMenu.show(event.target, this);
  354. })
  355. );
  356. this.ganttChart._events.push(
  357. dojo.connect(divName, "onkeydown", this, function(event){
  358. if(event.keyCode == dojo.keys.ENTER){
  359. this.ganttChart.tabMenu.clear();
  360. this.ganttChart.tabMenu.show(event.target, this);
  361. }
  362. if(this.ganttChart.tabMenu.isShow && (event.keyCode == dojo.keys.LEFT_ARROW || event.keyCode == dojo.keys.RIGHT_ARROW)){
  363. dijit.focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
  364. }
  365. if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
  366. this.ganttChart.tabMenu.hide();
  367. }
  368. })
  369. );
  370. this.ganttChart._events.push(
  371. dojo.connect(divName, "onmouseout", this, function(){
  372. dojo.removeClass(divName, "ganttProjectNameItemHover");
  373. clearTimeout(this.ganttChart.menuTimer);
  374. this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
  375. this.ganttChart.tabMenu.hide();
  376. }), 200);
  377. })
  378. );
  379. this.ganttChart._events.push(
  380. dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseover", this, function(){
  381. clearTimeout(this.ganttChart.menuTimer);
  382. })
  383. );
  384. this.ganttChart._events.push(
  385. dojo.connect(this.ganttChart.tabMenu.menuPanel, "onkeydown", this, function(event){
  386. if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
  387. this.ganttChart.tabMenu.hide();
  388. }
  389. })
  390. );
  391. this.ganttChart._events.push(
  392. dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseout", this, function(){
  393. clearTimeout(this.ganttChart.menuTimer);
  394. this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
  395. this.ganttChart.tabMenu.hide();
  396. }), 200);
  397. })
  398. );
  399. }
  400. return divName;
  401. },
  402. getPercentCompleted: function(){
  403. var sum = 0, percentage = 0;
  404. dojo.forEach(this.project.parentTasks, function(ppTask){
  405. sum += parseInt(ppTask.percentage);
  406. }, this);
  407. if(this.project.parentTasks.length != 0){
  408. return percentage = Math.round(sum / this.project.parentTasks.length);
  409. }else{
  410. return percentage = -1;
  411. }
  412. },
  413. getDuration: function(){
  414. var duration = 0, tmpDuration = 0;
  415. if(this.project.parentTasks.length > 0){
  416. dojo.forEach(this.project.parentTasks, function(ppTask){
  417. tmpDuration = ppTask.duration * 24 / this.ganttChart.hsPerDay + (ppTask.startTime - this.ganttChart.startDate) / (60 * 60 * 1000);
  418. if(tmpDuration > duration){
  419. duration = tmpDuration;
  420. }
  421. }, this);
  422. return ((duration - this.posX) / 24) * this.ganttChart.hsPerDay;
  423. }else{
  424. return 0;
  425. }
  426. },
  427. deleteTask: function(id){
  428. var task = this.getTaskById(id);
  429. if(task){
  430. this.deleteChildTask(task);
  431. this.ganttChart.checkPosition();
  432. }
  433. },
  434. setName: function(name){
  435. if(name){
  436. this.project.name = name;
  437. this.projectNameItem.innerHTML = name;
  438. this.projectNameItem.title = name;
  439. this.checkWidthProjectNameItem();
  440. this.descrProject.innerHTML = this.getDescStr();
  441. this.adjustPanelTime();
  442. }
  443. },
  444. setPercentCompleted: function(percentage){
  445. percentage = parseInt(percentage);
  446. if(isNaN(percentage) || percentage > 100 || percentage < 0){
  447. return false;
  448. }
  449. var prow = this.projectItem[0].firstChild.rows[0],
  450. rc0 = prow.cells[0], rc1 = prow.cells[1];
  451. if((percentage > 0) && (percentage < 100) && (this.percentage > 0) && (this.percentage < 100)){
  452. rc0.width = parseInt(percentage) + "%";
  453. rc0.firstChild.style.width = (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
  454. rc1.width = (100 - parseInt(percentage)) + "%";
  455. rc1.firstChild.style.width = ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
  456. }else if(((percentage == 0) || (percentage == 100)) && (this.percentage > 0) && (this.percentage < 100)){
  457. if(percentage == 0){
  458. rc0.parentNode.removeChild(rc0);
  459. rc1.width = 100 + "%";
  460. rc1.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
  461. }else if(percentage == 100){
  462. rc1.parentNode.removeChild(rc1);
  463. rc0.width = 100 + "%";
  464. rc0.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
  465. }
  466. }else if(((percentage == 0) || (percentage == 100)) && ((this.percentage == 0) || (this.percentage == 100))){
  467. if((percentage == 0) && (this.percentage == 100)){
  468. dojo.removeClass(rc0.firstChild, "ganttImageProgressFilled");
  469. dojo.addClass(rc0.firstChild, "ganttImageProgressBg");
  470. }else if((percentage == 100) && (this.percentage == 0)){
  471. dojo.removeClass(rc0.firstChild, "ganttImageProgressBg");
  472. dojo.addClass(rc0.firstChild, "ganttImageProgressFilled");
  473. }
  474. }else if(((percentage > 0) || (percentage < 100)) && ((this.percentage == 0) || (this.percentage == 100))){
  475. rc0.parentNode.removeChild(rc0);
  476. var cellprojectItem = dojo.create("td", {
  477. width: percentage + "%"
  478. }, prow);
  479. cellprojectItem.style.lineHeight = "1px";
  480. var imageProgress = dojo.create("div", {
  481. className: "ganttImageProgressFilled"
  482. }, cellprojectItem);
  483. dojo.style(imageProgress, {
  484. width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  485. height: this.ganttChart.heightTaskItem + "px"
  486. });
  487. cellprojectItem = dojo.create("td", {
  488. width: (100 - percentage) + "%"
  489. }, prow);
  490. cellprojectItem.style.lineHeight = "1px";
  491. imageProgress = dojo.create("div", {
  492. className: "ganttImageProgressBg"
  493. }, cellprojectItem);
  494. dojo.style(imageProgress, {
  495. width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  496. height: this.ganttChart.heightTaskItem + "px"
  497. });
  498. }else if(this.percentage == -1){
  499. if(percentage == 100){
  500. dojo.removeClass(rc0.firstChild, "ganttImageProgressBg");
  501. dojo.addClass(rc0.firstChild, "ganttImageProgressFilled");
  502. }else if(percentage < 100 && percentage > 0){
  503. rc0.parentNode.removeChild(rc0);
  504. var cellprojectItem = dojo.create("td", {
  505. width: percentage + "%"
  506. }, prow);
  507. cellprojectItem.style.lineHeight = "1px";
  508. imageProgress = dojo.create("div", {
  509. className: "ganttImageProgressFilled"
  510. }, cellprojectItem);
  511. dojo.style(imageProgress, {
  512. width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  513. height: this.ganttChart.heightTaskItem + "px"
  514. });
  515. cellprojectItem = dojo.create("td", {
  516. width: (100 - percentage) + "%"
  517. }, prow);
  518. cellprojectItem.style.lineHeight = "1px";
  519. imageProgress = dojo.create("div", {
  520. className: "ganttImageProgressBg"
  521. }, cellprojectItem);
  522. dojo.style(imageProgress, {
  523. width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
  524. height: this.ganttChart.heightTaskItem + "px"
  525. });
  526. }
  527. }
  528. this.percentage = percentage;
  529. this.descrProject.innerHTML = this.getDescStr();
  530. return true;
  531. },
  532. deleteChildTask: function(task){
  533. if(task){
  534. var tItem0 = task.cTaskItem[0], tNameItem0 = task.cTaskNameItem[0],
  535. tItem1 = task.cTaskItem[1], tNameItem1 = task.cTaskNameItem[1],
  536. tItem2 = task.cTaskItem[2], tNameItem2 = task.cTaskNameItem[2];
  537. if(tItem0.style.display == "none"){
  538. this.ganttChart.openTree(task.parentTask);
  539. }
  540. //delete of connecting lines
  541. if(task.childPredTask.length > 0){
  542. for(var i = 0; i < task.childPredTask.length; i++){
  543. var cpTask = task.childPredTask[i];
  544. for(var t = 0; t < cpTask.cTaskItem[1].length; t++){
  545. cpTask.cTaskItem[1][t].parentNode.removeChild(cpTask.cTaskItem[1][t]);
  546. }
  547. cpTask.cTaskItem[1] = [];
  548. cpTask.predTask = null;
  549. }
  550. }
  551. //delete child task
  552. if(task.childTask.length > 0){
  553. while(task.childTask.length > 0){
  554. this.deleteChildTask(task.childTask[0]);
  555. }
  556. }
  557. //shift tasks
  558. var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  559. if(tItem0.style.display != "none"){
  560. task.shiftCurrentTasks(task, -rowHeight);
  561. }
  562. //delete object task
  563. this.project.deleteTask(task.taskItem.id);
  564. //delete div and connecting lines from contentData
  565. if(tItem0){
  566. tItem0.parentNode.removeChild(tItem0);
  567. }
  568. task.descrTask.parentNode.removeChild(task.descrTask);
  569. if(tItem1.length > 0){
  570. for(var j = 0; j < tItem1.length; j++){
  571. tItem1[j].parentNode.removeChild(tItem1[j]);
  572. }
  573. }
  574. //delete div and connecting lines from panelName
  575. if(tNameItem0){
  576. tNameItem0.parentNode.removeChild(tNameItem0);
  577. }
  578. if(task.cTaskNameItem[1]){
  579. for(var j = 0; j < tNameItem1.length; j++){
  580. tNameItem1[j].parentNode.removeChild(tNameItem1[j]);
  581. }
  582. }
  583. if(tNameItem2 && tNameItem2.parentNode){
  584. tNameItem2.parentNode.removeChild(tNameItem2);
  585. }
  586. if(task.taskIdentifier){
  587. task.taskIdentifier.parentNode.removeChild(task.taskIdentifier);
  588. task.taskIdentifier = null;
  589. }
  590. //delete object task
  591. if(task.parentTask){
  592. if(task.previousChildTask){
  593. if(task.nextChildTask){
  594. task.previousChildTask.nextChildTask = task.nextChildTask;
  595. }else{
  596. task.previousChildTask.nextChildTask = null;
  597. }
  598. }
  599. var parentTask = task.parentTask;
  600. for(var i = 0; i < parentTask.childTask.length; i++){
  601. if(parentTask.childTask[i].taskItem.id == task.taskItem.id){
  602. parentTask.childTask[i] = null;
  603. parentTask.childTask.splice(i, 1);
  604. break;
  605. }
  606. }
  607. if(parentTask.childTask.length == 0){
  608. if(parentTask.cTaskNameItem[2]){
  609. parentTask.cTaskNameItem[2].parentNode.removeChild(parentTask.cTaskNameItem[2]);
  610. parentTask.cTaskNameItem[2] = null;
  611. }
  612. }
  613. }else{
  614. if(task.previousParentTask){
  615. if(task.nextParentTask){
  616. task.previousParentTask.nextParentTask = task.nextParentTask;
  617. }else{
  618. task.previousParentTask.nextParentTask = null;
  619. }
  620. }
  621. var project = task.project;
  622. for(var i = 0; i < project.arrTasks.length; i++){
  623. if(project.arrTasks[i].taskItem.id == task.taskItem.id){
  624. project.arrTasks.splice(i, 1);
  625. }
  626. }
  627. }
  628. if(task.predTask){
  629. var predTask = task.predTask;
  630. for(var i = 0; i < predTask.childPredTask.length; i++){
  631. if(predTask.childPredTask[i].taskItem.id == task.taskItem.id){
  632. predTask.childPredTask[i] = null;
  633. predTask.childPredTask.splice(i, 1);
  634. }
  635. }
  636. }
  637. if(task.project.arrTasks.length != 0){
  638. task.project.shiftProjectItem();
  639. }else{
  640. task.project.projectItem[0].style.display = "none";
  641. this.hideDescrProject();
  642. }
  643. this.ganttChart.contentDataHeight -= this.ganttChart.heightTaskItemExtra + this.ganttChart.heightTaskItem;
  644. }
  645. },
  646. insertTask: function(id, name, startTime, duration, percentage, previousTaskId, taskOwner, parentTaskId){
  647. var task = null;
  648. var _task = null;
  649. if(this.project.getTaskById(id)){
  650. return false;
  651. }
  652. if((!duration) || (duration < this.ganttChart.minWorkLength)){
  653. duration = this.ganttChart.minWorkLength;
  654. }
  655. if((!name) || (name == "")){
  656. name = id;
  657. }
  658. if((!percentage) || (percentage == "")){
  659. percentage = 0;
  660. }else{
  661. percentage = parseInt(percentage);
  662. if(percentage < 0 || percentage > 100){
  663. return false;
  664. }
  665. }
  666. var sortRequired = false;
  667. if((parentTaskId) && (parentTaskId != "")){
  668. var parentTask = this.project.getTaskById(parentTaskId);
  669. if(!parentTask){
  670. return false;
  671. }
  672. startTime = startTime || parentTask.startTime;
  673. if(startTime < parentTask.startTime){
  674. return false;
  675. }
  676. task = new dojox.gantt.GanttTaskItem({
  677. id: id,
  678. name: name,
  679. startTime: startTime,
  680. duration: duration,
  681. percentage: percentage,
  682. previousTaskId: previousTaskId,
  683. taskOwner: taskOwner
  684. });
  685. if(!this.ganttChart.checkPosParentTask(parentTask, task)){
  686. return false;
  687. }
  688. task.parentTask = parentTask;
  689. var _parentTask = this.getTaskById(parentTask.id);
  690. var isHide = false;
  691. if(_parentTask.cTaskItem[0].style.display == "none"){
  692. isHide = true;
  693. }else if(_parentTask.cTaskNameItem[2]){
  694. if(!_parentTask.isExpanded){
  695. isHide = true;
  696. }
  697. }
  698. if(isHide){
  699. if(_parentTask.childTask.length == 0){
  700. this.ganttChart.openTree(_parentTask.parentTask);
  701. }else{
  702. this.ganttChart.openTree(_parentTask);
  703. }
  704. }
  705. if(previousTaskId != ""){
  706. var predTask = this.project.getTaskById(previousTaskId);
  707. if(!predTask){
  708. return false;
  709. }
  710. if(predTask.parentTask){
  711. if(predTask.parentTask.id != task.parentTask.id){
  712. return false;
  713. }
  714. }else{
  715. return false;
  716. }
  717. if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
  718. this.ganttChart.correctPosPreviousTask(predTask, task);
  719. }
  720. task.previousTask = predTask;
  721. }
  722. var isAdd = false;
  723. if(sortRequired) for(var i = 0; i < parentTask.cldTasks.length; i++){
  724. if(task.startTime < parentTask.cldTasks[i].startTime){
  725. parentTask.cldTasks.splice(i, 0, task);
  726. if(i > 0){
  727. parentTask.cldTasks[i - 1].nextChildTask = parentTask.cldTasks[i];
  728. parentTask.cldTasks[i].previousChildTask = parentTask.cldTasks[i - 1];
  729. }
  730. if(parentTask.cldTasks[i + 1]){
  731. parentTask.cldTasks[i + 1].previousChildTask = parentTask.cldTasks[i];
  732. parentTask.cldTasks[i].nextChildTask = parentTask.cldTasks[i + 1];
  733. }
  734. isAdd = true;
  735. break;
  736. }
  737. }
  738. if(!isAdd){
  739. if(parentTask.cldTasks.length > 0){
  740. parentTask.cldTasks[parentTask.cldTasks.length - 1].nextChildTask = task;
  741. task.previousChildTask = parentTask.cldTasks[parentTask.cldTasks.length - 1];
  742. }
  743. parentTask.cldTasks.push(task);
  744. }
  745. if(parentTask.cldTasks.length == 1){
  746. var treeImg = _parentTask.createTreeImg();
  747. _parentTask.cTaskNameItem[2] = treeImg;
  748. }
  749. _task = new dojox.gantt.GanttTaskControl(task, this, this.ganttChart);
  750. _task.create();
  751. if(task.nextChildTask) _task.nextChildTask = _task.project.getTaskById(task.nextChildTask.id);
  752. _task.adjustPanelTime();
  753. var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  754. _task.shiftCurrentTasks(_task, rowHeight);//23
  755. }else{
  756. startTime = startTime || this.project.startDate;
  757. task = new dojox.gantt.GanttTaskItem({
  758. id: id,
  759. name: name,
  760. startTime: startTime,
  761. duration: duration,
  762. percentage: percentage,
  763. previousTaskId: previousTaskId,
  764. taskOwner: taskOwner
  765. });
  766. if(task.startTime <= this.ganttChart.startDate){
  767. return false;
  768. }
  769. if(previousTaskId != ""){
  770. var predTask = this.project.getTaskById(previousTaskId);
  771. if(!predTask){
  772. return false;
  773. }
  774. if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
  775. this.ganttChart.correctPosPreviousTask(predTask, task);
  776. }
  777. if(predTask.parentTask){
  778. return false;
  779. }
  780. task.previousTask = predTask;
  781. }
  782. var isAdd = false;
  783. if(sortRequired){
  784. for(var i = 0; i < this.project.parentTasks.length; i++){
  785. var ppTask = this.project.parentTasks[i];
  786. if(startTime < ppTask.startTime){
  787. this.project.parentTasks.splice(i, 0, task);
  788. if(i > 0){
  789. this.project.parentTasks[i - 1].nextParentTask = task;
  790. task.previousParentTask = this.project.parentTasks[i - 1];
  791. }
  792. if(this.project.parentTasks[i + 1]){
  793. this.project.parentTasks[i + 1].previousParentTask = task;
  794. task.nextParentTask = this.project.parentTasks[i + 1];
  795. }
  796. isAdd = true;
  797. break;
  798. }
  799. }
  800. }
  801. if(!isAdd){
  802. if(this.project.parentTasks.length > 0){
  803. this.project.parentTasks[this.project.parentTasks.length - 1].nextParentTask = task;
  804. task.previousParentTask = this.project.parentTasks[this.project.parentTasks.length - 1];
  805. }
  806. this.project.parentTasks.push(task);
  807. }
  808. _task = new dojox.gantt.GanttTaskControl(task, this, this.ganttChart);
  809. _task.create();
  810. if(task.nextParentTask) _task.nextParentTask = _task.project.getTaskById(task.nextParentTask.id);
  811. _task.adjustPanelTime();
  812. this.arrTasks.push(_task);
  813. var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
  814. _task.shiftCurrentTasks(_task, rowHeight);
  815. this.projectItem[0].style.display = "inline";
  816. this.setPercentCompleted(this.getPercentCompleted());
  817. this.shiftProjectItem();
  818. this.showDescrProject();
  819. }
  820. this.ganttChart.checkHeighPanelTasks();
  821. this.ganttChart.checkPosition();
  822. return _task;
  823. },
  824. shiftNextProject: function(project, height){
  825. if(project.nextProject){
  826. project.nextProject.shiftProject(height);
  827. this.shiftNextProject(project.nextProject, height);
  828. }
  829. },
  830. shiftProject: function(height){
  831. this.posY = this.posY + height;
  832. this.projectItem[0].style.top = parseInt(this.projectItem[0].style.top) + height + "px";
  833. this.descrProject.style.top = parseInt(this.descrProject.style.top) + height + "px";
  834. this.projectNameItem.style.top = parseInt(this.projectNameItem.style.top) + height + "px";
  835. if(this.arrTasks.length > 0){
  836. this.shiftNextParentTask(this.arrTasks[0], height);
  837. }
  838. },
  839. shiftTask: function(task, height){
  840. task.posY = task.posY + height;
  841. var tNameItem0 = task.cTaskNameItem[0], tNameItem1 = task.cTaskNameItem[1], tNameItem2 = task.cTaskNameItem[2],
  842. tItem0 = task.cTaskItem[0], tItem1 = task.cTaskItem[1], tItem2 = task.cTaskItem[2];
  843. tNameItem0.style.top = parseInt(tNameItem0.style.top) + height + "px";
  844. if(tNameItem2){
  845. tNameItem2.style.top = parseInt(tNameItem2.style.top) + height + "px";
  846. }
  847. if(task.parentTask){
  848. tNameItem1[0].style.top = parseInt(tNameItem1[0].style.top) + height + "px";
  849. tNameItem1[1].style.top = parseInt(tNameItem1[1].style.top) + height + "px";
  850. }
  851. task.cTaskItem[0].style.top = parseInt(task.cTaskItem[0].style.top) + height + "px";
  852. task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
  853. if(tItem1[0]){
  854. tItem1[0].style.top = parseInt(tItem1[0].style.top) + height + "px";
  855. tItem1[1].style.top = parseInt(tItem1[1].style.top) + height + "px";
  856. tItem1[2].style.top = parseInt(tItem1[2].style.top) + height + "px";
  857. }
  858. },
  859. shiftNextParentTask: function(task, height){
  860. this.shiftTask(task, height);
  861. this.shiftChildTasks(task, height);
  862. if(task.nextParentTask){
  863. this.shiftNextParentTask(task.nextParentTask, height);
  864. }
  865. },
  866. shiftChildTasks: function(task, height){
  867. dojo.forEach(task.childTask, function(cTask){
  868. this.shiftTask(cTask, height);
  869. if(cTask.childTask.length > 0){
  870. this.shiftChildTasks(cTask, height);
  871. }
  872. }, this);
  873. }
  874. });
  875. dojo.declare("dojox.gantt.GanttProjectItem", null, {
  876. constructor: function(configuration){
  877. //id is required
  878. this.id = configuration.id;
  879. this.name = configuration.name || this.id;
  880. this.startDate = configuration.startDate || new Date();
  881. this.parentTasks = [];
  882. },
  883. getTaskById: function(id){
  884. for(var i = 0; i < this.parentTasks.length; i++){
  885. var pTask = this.parentTasks[i];
  886. var task = this.getTaskByIdInTree(pTask, id);
  887. if(task){
  888. return task;
  889. }
  890. }
  891. return null;
  892. },
  893. getTaskByIdInTree: function(parentTask, id){
  894. if(parentTask.id == id){
  895. return parentTask;
  896. }else{
  897. for(var i = 0; i < parentTask.cldTasks.length; i++){
  898. var pcTask = parentTask.cldTasks[i];
  899. if(pcTask.id == id){
  900. return pcTask;
  901. }
  902. if(pcTask.cldTasks.length > 0){
  903. if(pcTask.cldTasks.length > 0){
  904. var cTask = this.getTaskByIdInTree(pcTask, id);
  905. if(cTask){
  906. return cTask;
  907. }
  908. }
  909. }
  910. }
  911. }
  912. return null;
  913. },
  914. addTask: function(task){
  915. this.parentTasks.push(task);
  916. task.setProject(this);
  917. },
  918. deleteTask: function(id){
  919. var task = this.getTaskById(id);
  920. if(!task){return;}
  921. if(!task.parentTask){
  922. for(var i = 0; i < this.parentTasks.length; i++){
  923. var pTask = this.parentTasks[i];
  924. if(pTask.id == id){
  925. if(pTask.nextParentTask){
  926. if(pTask.previousParentTask){
  927. pTask.previousParentTask.nextParentTask = pTask.nextParentTask;
  928. pTask.nextParentTask.previousParentTask = pTask.previousParentTask;
  929. }else{
  930. pTask.nextParentTask.previousParentTask = null;
  931. }
  932. }else{
  933. if(pTask.previousParentTask){
  934. pTask.previousParentTask.nextParentTask = null;
  935. }
  936. }
  937. pTask = null;
  938. this.parentTasks.splice(i, 1);
  939. break;
  940. }
  941. }
  942. }else{
  943. var parentTask = task.parentTask;
  944. for(var i = 0; i < parentTask.cldTasks.length; i++){
  945. var pcTask = parentTask.cldTasks[i];
  946. if(pcTask.id == id){
  947. if(pcTask.nextChildTask){
  948. if(pcTask.previousChildTask){
  949. pcTask.previousChildTask.nextChildTask = pcTask.nextChildTask;
  950. pcTask.nextChildTask.previousChildTask = pcTask.previousChildTask;
  951. }else{
  952. pcTask.nextChildTask.previousChildTask = null;
  953. }
  954. }else{
  955. if(pcTask.previousChildTask){
  956. pcTask.previousChildTask.nextChildTask = null;
  957. }
  958. }
  959. pcTask = null;
  960. parentTask.cldTasks.splice(i, 1);
  961. break;
  962. }
  963. }
  964. }
  965. }
  966. });
  967. }