
cobra
striver
-
个人空间
相册
- 性别:
- 来自:拼吾爱
- 积分:6811
- 帖子:6723
- 注册:
2007-04-09
|
甘特图(Javascript实现) - SIcon Gantt Chart
 附件: 您所在的用户组无法下载或查看附件简介 笔者在开发一个基于Web的应用程序提供对人物和项目事件的管理。项目需要一个甘特图控件可视化表示任务列表,笔者尝试寻找自由可用的解决方案(因为不想增加开销)。笔者找到了一些例子,不过并不满意。于是,决定创建一个自己的甘特图控件。此次是笔者工作的最初成果。这个SIcon的最初版本只做了几个小时,所以仍会有些问题。尽管如此,笔者还是希望与各位分享,希望能帮助大家。 SICon现在支持FireFox浏览器! 背景 掌握和使用这个示例需要Jscript和CSS知识。 使用代码 代码并不是很复杂,所以我在这里将展示全部: 脚本代码  Code
1 /* --------- SICON GANTT CHART ----------------------------------------------------------- 2 * AUTHOR : Dathq - ICT Service Engineering Jsc, - [email]dathq@ise.com.vn[/email] 3 * LICENSE : Free 4 * DESCRIPTION : Create a new task item with these info 5 * - from: start date (format: mm/dd/dddd) 6 * - to: deadline of task (format: mm/dd/dddd) 7 * - task: name of the task, what has to be solved (not includes ') 8 * - resource: who have to solve this task (not includes ') 9 * - progress: how is it going? (format: integer value from 0 to 100, not includes %) 10 *----------------------------------------------------------------------------------------*/ 11 function Task(from, to, task, resource, progress) 12 { 13 var _from = new Date(); 14 var _to = new Date(); 15 var _task = task; 16 var _resource = resource; 17 var _progress = progress; 18 var dvArr = from.split('/'); 19 _from.setFullYear(parseInt(dvArr[2], 10), parseInt(dvArr[0], 10) - 1, parseInt(dvArr[1], 10)); 20 dvArr = to.split('/'); 21 _to.setFullYear(parseInt(dvArr[2], 10), parseInt(dvArr[0], 10) - 1, parseInt(dvArr[1], 10)); 22 23 this.getFrom = function(){ return _from}; 24 this.getTo = function(){ return _to}; 25 this.getTask = function(){ return _task}; 26 this.getResource = function(){ return _resource}; 27 this.getProgress = function(){ return _progress}; 28 } 29 30 function Gantt(gDiv) 31 { 32 var _GanttDiv = gDiv; 33 var _taskList = new Array(); 34 this.AddTaskDetail = function(value) 35 { 36 _taskList.push(value); 37 38 } 39 this.Draw = function() 40 { 41 var _offSet = 0; 42 var _dateDiff = 0; 43 var _currentDate = new Date(); 44 var _maxDate = new Date(); 45 var _minDate = new Date(); 46 var _dTemp = new Date(); 47 var _firstRowStr = "<table border=1 style='border-collapse:collapse'><tr><td rowspan='2' width='200px' style='width:200px;'><div class='GTaskTitle' style='width:200px;'>Task</div></td>"; 48 var _thirdRow = ""; 49 var _gStr = ""; 50 var _colSpan = 0; 51 var counter = 0; 52 53 _currentDate.setFullYear(_currentDate.getFullYear(), _currentDate.getMonth(), _currentDate.getDate()); 54 if(_taskList.length > 0) 55 { 56 _maxDate.setFullYear(_taskList[0].getTo().getFullYear(), _taskList[0].getTo().getMonth(), _taskList[0].getTo().getDate()); 57 _minDate.setFullYear(_taskList[0].getFrom().getFullYear(), _taskList[0].getFrom().getMonth(), _taskList[0].getFrom().getDate()); 58 for(i = 0; i < _taskList.length; i++) 59 { 60 if(Date.parse(_taskList.getFrom()) < Date.parse(_minDate)) 61 _minDate.setFullYear(_taskList.getFrom().getFullYear(), _taskList.getFrom().getMonth(), _taskList.getFrom().getDate()); 62 if(Date.parse(_taskList.getTo()) > Date.parse(_maxDate)) 63 _maxDate.setFullYear(_taskList.getTo().getFullYear(), _taskList.getTo().getMonth(), _taskList.getTo().getDate()); 64 } 65 66 //---- Fix _maxDate value for better displaying----- 67 // Add at least 5 days 68 69 if(_maxDate.getMonth() == 11) //December 70 { 71 if(_maxDate.getDay() + 5 > getDaysInMonth(_maxDate.getMonth() + 1, _maxDate.getFullYear())) 72 _maxDate.setFullYear(_maxDate.getFullYear() + 1, 1, 5); //The fifth day of next month will be used 73 else 74 _maxDate.setFullYear(_maxDate.getFullYear(), _maxDate.getMonth(), _maxDate.getDate() + 5); //The fifth day of next month will be used 75 } 76 else 77 { 78 if(_maxDate.getDay() + 5 > getDaysInMonth(_maxDate.getMonth() + 1, _maxDate.getFullYear())) 79 _maxDate.setFullYear(_maxDate.getFullYear(), _maxDate.getMonth() + 1, 5); //The fifth day of next month will be used 80 else 81 _maxDate.setFullYear(_maxDate.getFullYear(), _maxDate.getMonth(), _maxDate.getDate() + 5); //The fifth day of next month will be used 82 } 83 84 //-------------------------------------------------- 85 86 _gStr = ""; 87 _gStr += "</tr><tr>"; 88 _thirdRow = "<tr><td> </td>"; 89 _dTemp.setFullYear(_minDate.getFullYear(), _minDate.getMonth(), _minDate.getDate()); 90 while(Date.parse(_dTemp) <= Date.parse(_maxDate)) 91 { 92 if(_dTemp.getDay() % 6 == 0) //Weekend 93 { 94 _gStr += "<td class='GWeekend'><div style='width:24px;'>" + _dTemp.getDate() + "</div></td>"; 95 if(Date.parse(_dTemp) == Date.parse(_currentDate)) 96 _thirdRow += "<td id='GC_" + (counter++) + "' class='GToDay' style='height:" + (_taskList.length * 21) + "'> </td>"; 97 else 98 _thirdRow += "<td id='GC_" + (counter++) + "' class='GWeekend' style='height:" + (_taskList.length * 21) + "'> </td>"; 99 } 100 else 101 { 102 _gStr += "<td class='GDay'><div style='width:24px;'>" + _dTemp.getDate() + "</div></td>"; 103 if(Date.parse(_dTemp) == Date.parse(_currentDate)) 104 _thirdRow += "<td id='GC_" + (counter++) + "' class='GToDay' style='height:" + (_taskList.length * 21) + "'> </td>"; 105 else 106 _thirdRow += "<td id='GC_" + (counter++) + "' class='GDay'> </td>"; 107 } 108 if(_dTemp.getDate() < getDaysInMonth(_dTemp.getMonth() + 1, _dTemp.getFullYear())) 109 { 110 if(Date.parse(_dTemp) == Date.parse(_maxDate)) 111 { 112 _firstRowStr += "<td class='GMonth' colspan='" + (_colSpan + 1) + "'>T" + (_dTemp.getMonth() + 1) + "/" + _dTemp.getFullYear() + "</td>"; 113 } 114 _dTemp.setDate(_dTemp.getDate() + 1); 115 _colSpan++; 116 } 117 else 118 { 119 _firstRowStr += "<td class='GMonth' colspan='" + (_colSpan + 1) + "'>T" + (_dTemp.getMonth() + 1) + "/" + _dTemp.getFullYear() + "</td>"; 120 _colSpan = 0; 121 if(_dTemp.getMonth() == 11) //December 122 { 123 _dTemp.setFullYear(_dTemp.getFullYear() + 1, 0, 1); 124 } 125 else 126 { 127 _dTemp.setFullYear(_dTemp.getFullYear(), _dTemp.getMonth() + 1, 1); 128 } 129 } 130 } 131 _thirdRow += "</tr>"; 132 _gStr += "</tr>" + _thirdRow; 133 _gStr += "</table>"; 134 _gStr = _firstRowStr + _gStr; 135 for(i = 0; i < _taskList.length; i++) 136 { 137 _offSet = (Date.parse(_taskList.getFrom()) - Date.parse(_minDate)) / (24 * 60 * 60 * 1000); 138 _dateDiff = (Date.parse(_taskList.getTo()) - Date.parse(_taskList.getFrom())) / (24 * 60 * 60 * 1000) + 1; 139 _gStr += "<div style='position:absolute; top:" + (20 * (i + 2)) + "; left:" + (_offSet * 27 + 204) + "; width:" + (27 * _dateDiff - 1 + 100) + "'><div title='" + _taskList.getTask() + "' class='GTask' style='float:left; width:" + (27 * _dateDiff - 1) + "px;'>" + getProgressDiv(_taskList.getProgress()) + "</div><div style='float:left; padding-left:3'>" + _taskList.getResource() + "</div></div>"; 140 _gStr += "<div style='position:absolute; top:" + (20 * (i + 2) + 1) + "; left:5px'>" + _taskList.getTask() + "</div>"; 141 } 142 _GanttDiv.innerHTML = _gStr; 143 } 144 } 145 } 146 147 function getProgressDiv(progress) 148 { 149 return "<div class='GProgress' style='width:" + progress + "%; overflow:hidden'></div>" 150 } 151 // GET NUMBER OF DAYS IN MONTH 152 function getDaysInMonth(month, year) 153 { 154 155 var days; 156 switch(month) 157 { 158 case 1: 159 case 3: 160 case 5: 161 case 7: 162 case 8: 163 case 10: 164 case 12: 165 days = 31; 166 break; 167 case 4: 168 case 6: 169 case 9: 170 case 11: 171 days = 30; 172 break; 173 case 2: 174 if (((year% 4)==0) && ((year% 100)!=0) || ((year% 400)==0)) 175 days = 29; 176 else 177 days = 28; 178 break; 179 } 180 return (days); 181 } 182 /*----- END OF MY CODE FOR Gantt CHART GENERATOR -----*/
如何使用这段脚本 在你的HTML, ASCX, ASPX或PHP文档的Body部分,把下面几行代码拷贝到你想表示甘特图的地方。  Code
1 <body> 2 <h3>Diagram</h3> 3 <div style="position:relative" class="Gantt" id="GanttChart"></div> 4 </body> 5 <script> 6 var g = new Gantt(document.all.GanttChart); 7 g.AddTaskDetail(new Task('2/11/2008', '2/12/2008', 8 '<b>Sample task 1 1</b>', 'Dathq', 50)); 9 g.AddTaskDetail(new Task('2/16/2008', '2/19/2008', 10 ' Sample task 1.1', 'Dathq, Thanhdd', 30)); 11 g.AddTaskDetail(new Task('2/12/2008', '3/4/2008', 'Sample task 2', 'Hanhnd', 60)); 12 g.AddTaskDetail(new Task('2/11/2008', '2/16/2008', 'Sample task 3', 'Dathq', 50)); 13 14 g.Draw(); 15 </script>
使用var g = new Gantt(document.all.GanttChart);语句指定你要显示的甘特图到命名为"GanttChart"的DIV元素(你可以在body中看到它)。 g.AddTaskDetail()方法添加任务到任务列表。你可以使用AJAX或任何你喜欢的方式来生成这些命令以添加任务的集合。 使用g.Draw()来渲染基于追加到甘特图对象的任务列表的甘特图。 如何改变组件外观 这里笔者定义了一些类用来自定义甘特图的样式,为此提供了全部代码。你可以定义更多的类并且更轻易地改变甘特图控件的外观。 通过改变样式表,并且在代码中添加属性到任务对象,你可以为你自己创建更加智能的甘特图。例如:为任务条设置不同的颜色,漂亮的背景图片,更好的图标提示等等。 样式表  Code
1 /*----- SICON GANTT CHART STYLE CLASSES -------------------------- 2 * DESCRIPTION : Theses class is required for SIcon Gantt Chart 3 * NOTE : Should change the color, the text style only 4 *----------------------------------------------------------------*/ 5 .Gantt 6 { 7 font-family:tahoma, arial, verdana; 8 font-size:11px; 9 } 10 11 .GTaskTitle 12 { 13 font-family:tahoma, arial, verdana; 14 font-size:11px; 15 font-weight:bold; 16 } 17 18 .GMonth 19 { 20 padding-left:5px; 21 font-family:tahoma, arial, verdana; 22 font-size:11px; 23 font-weight:bold; 24 } 25 26 .GToday 27 { 28 background-color: #FDFDE0; 29 } 30 31 .GWeekend 32 { 33 font-family:tahoma, arial, verdana; 34 font-size:11px; 35 background-color:#F5F5F5; 36 text-align:center; 37 } 38 39 .GDay 40 { 41 font-family:tahoma, arial, verdana; 42 font-size:11px; 43 text-align:center; 44 } 45 46 .GTask 47 { 48 border-top:1px solid #CACACA; 49 border-bottom:1px solid #CACACA; 50 height:14px; 51 background-color:yellow; 52 } 53 54 .GProgress 55 { 56 background-color:black; 57 height:2px; 58 overflow: hidden; 59 margin-top:5px; 60 }
图表 Code  Code
1 var g = new Gantt(document.all.GanttChart); 2 g.AddTaskDetail(new Task('2/11/2008', '2/19/2008', '<b>Sample task 1 1</b>', 'Dathq', 50)); 3 g.AddTaskDetail(new Task('2/16/2008', '2/19/2008', ' Sample task 1.1', 'Dathq, Thanhdo', 30)); 4 g.AddTaskDetail(new Task('2/12/2008', '3/2/2008', 'Sample task 2', 'Hanhnd', 60)); 5 g.AddTaskDetail(new Task('2/11/2008', '2/16/2008', '<i>Sample task 3<i>', 'Dathq', 50)); 6 g.AddTaskDetail(new Task('2/11/2008', '2/19/2008', '<b>Sample task 1 1</b>', 'Dathq', 50)); 7 g.AddTaskDetail(new Task('2/16/2008', '2/19/2008', ' Sample task 1.1', 'Dathq, Thanhdo', 30)); 8 g.AddTaskDetail(new Task('2/12/2008', '3/2/2008', 'Sample task 2', 'Hanhnd', 60)); 9 g.AddTaskDetail(new Task('2/11/2008', '2/16/2008', '<i>Sample task 3<i>', 'Dathq', 50)); 10 g.AddTaskDetail(new Task('2/11/2008', '2/19/2008', '<b>Sample task 1 1</b>', 'Dathq', 50)); 11 g.AddTaskDetail(new Task('2/16/2008', '2/19/2008', ' Sample task 1.1', 'Dathq, Thanhdo', 30)); 12 g.AddTaskDetail(new Task('2/12/2008', '3/2/2008', 'Sample task 2', 'Hanhnd', 60)); 13 g.AddTaskDetail(new Task('2/11/2008', '2/16/2008', '<i>Sample task 3<i>', 'Dathq', 50)); 14 15 g.AddTaskDetail(new Task('2/11/2008', '2/19/2008', '<b>Sample task 1 1</b>', 'Dathq', 50)); 16 g.AddTaskDetail(new Task('2/16/2008', '2/19/2008', ' Sample task 1.1', 'Dathq, Thanhdo', 30)); 17 g.AddTaskDetail(new Task('2/12/2008', '3/2/2008', 'Sample task 2', 'Hanhnd', 60)); 18 g.AddTaskDetail(new Task('5/11/2008', '5/16/2008', '<i>Sample task 3<i>', 'Dathq', 50)); 19 20 g.Draw();
兴趣点 你会先注意到图标运行起来速度很快。 SIcon甘特图是通过Javascript创建的,这意味着你可以在众多的Web开发环境中使用它。我比较喜欢ASP.NET,所以我会把此控件和ASP.NET一起使用。另外,你可以使用AJAX创建更酷的应用。你可以自定义CSS类得到更好看的甘特图。我将试图添加链接到任务用来描述他们的关系,并将显示一个父任务,就像我们在MS Project中看到的一样。 甘特图通过HTML显示,因为它使用的是轻量级结构,所以你可以添加更多的功能到图表。例如,提示、链接、图片等,在JScript中使用一些基本的变化就可以获得。 最后,它是全免费的,编码愉快! 程序下载:  附件: 您所在的用户组无法下载或查看附件原文地址: http://www.codeproject.com/KB/scripting/SIcon_Gantt_Chart.aspx(文/dathq 译/崔驰坤 出处/博客园) | 感谢原创者的辛勤劳动,希望对您有所帮助,转载请注明原出处。 |
|