首页  ·  知识 ·  前端
JAVASCRIPT实现甘特图
佚名  http://www.kaiyuan8.org/Article/IAVTEnsTDnxzGLShYi  综合  编辑:dezai  图片来源:网络
笔者在开发一个基于Web的应用程序提供对人物和项目事件的管理。项目需要一个甘特图控件可视化表示任务列表,笔者尝试寻找自由可用的解决方案(因 为不想增加

笔者在开发一个基于Web的应用程序提供对人物和项目事件的管理。项目需要一个甘特图控件可视化表示任务列表,笔者尝试寻找自由可用的解决方案(因 为不想增加开销)。笔者找到了一些例子,不过并不满意。于是,决定创建一个自己的甘特图控件。此次是笔者工作的最初成果。这个SIcon的最初版本只做了 几个小时,所以仍会有些问题。尽管如此,笔者还是希望与各位分享,希望能帮助大家。

在新窗口查看图片

 

  1. /* --------- SICON GANTT CHART --------------------------------------------------------- 
  2. * AUTHOR        : Dathq - ICT Service Engineering Jsc, - dathq@ise.com.vn 
  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, 
  10. *                    not includes %) 
  11. *--------------------------------------------------------------------------------------*/ 
  12. function Task(from, to, task, resource, progress) 
  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, 
  20.         parseInt(dvArr[1], 10)); 
  21.     dvArr = to.split('/');  
  22.     _to.setFullYear(parseInt(dvArr[2], 10), parseInt(dvArr[0], 10) - 1, 
  23.         parseInt(dvArr[1], 10));         
  24.  
  25.     this.getFrom = function(){ return _from}; 
  26.     this.getTo = function(){ return _to}; 
  27.     this.getTask = function(){ return _task}; 
  28.     this.getResource = function(){ return _resource}; 
  29.     this.getProgress = function(){ return _progress}; 
  30.  
  31. function Gantt(gDiv) 
  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 = "'border-collapse:collapse'
  48.            '2' width='200px' style='width:200px;'
  49.            class='GTaskTitle' style='width:200px;'>Task
"; 
  •         var _thirdRow = "";  
  •         var _gStr = "";         
  •         var _colSpan = 0; 
  •         var counter = 0; 
  •  
  •         _currentDate.setFullYear(_currentDate.getFullYear(), _currentDate.getMonth(), 
  •             _currentDate.getDate()); 
  •         if(_taskList.length > 0) 
  •         { 
  •             _maxDate.setFullYear(_taskList[0].getTo().getFullYear(), 
  •                 _taskList[0].getTo().getMonth(), _taskList[0].getTo().getDate()); 
  •             _minDate.setFullYear(_taskList[0].getFrom().getFullYear(), 
  •                 _taskList[0].getFrom().getMonth(), _taskList[0].getFrom().getDate()); 
  •             for(i = 0; i < _taskList.length; i++) 
  •             { 
  •                 if(Date.parse(_taskList[i].getFrom()) < Date.parse(_minDate)) 
  •                     _minDate.setFullYear(_taskList[i].getFrom().getFullYear(), 
  •                     _taskList[i].getFrom().getMonth(), _taskList[i].getFrom().getDate()); 
  •                 if(Date.parse(_taskList[i].getTo()) > Date.parse(_maxDate)) 
  •                     _maxDate.setFullYear(_taskList[i].getTo().getFullYear(), 
  •                     _taskList[i].getTo().getMonth(), _taskList[i].getTo().getDate());  
  •             } 
  •  
  •             //---- Fix _maxDate value for better displaying----- 
  •             // Add at least 5 days 
  •  
  •             if(_maxDate.getMonth() == 11) //December 
  •             { 
  •                 if(_maxDate.getDay() + 5 > getDaysInMonth(_maxDate.getMonth() + 1, 
  •                     _maxDate.getFullYear())) 
  •                     //The fifth day of next month will be used 
  •                     _maxDate.setFullYear(_maxDate.getFullYear() + 1, 1, 5);        
  •             else 
  •                     //The fifth day of next month will be used 
  •                     _maxDate.setFullYear(_maxDate.getFullYear(), _maxDate.getMonth(), 
  •                         _maxDate.getDate() + 5);            } 
  •             else 
  •             { 
  •                 if(_maxDate.getDay() + 5 > getDaysInMonth(_maxDate.getMonth() + 1, 
  •                     _maxDate.getFullYear())) 
  •                     //The fifth day of next month will be used 
  •                     _maxDate.setFullYear(_maxDate.getFullYear(), _maxDate.getMonth() + 1, 
  •                         5); 
  •                 else 
  •                     //The fifth day of next month will be used 
  •                     _maxDate.setFullYear(_maxDate.getFullYear(), _maxDate.getMonth(), 
  •                         _maxDate.getDate() + 5); 
  •             } 
  •  
  •             //-------------------------------------------------- 
  •  
  •             _gStr = ""
  •             _gStr += ""
  •             _thirdRow = " "
  •             _dTemp.setFullYear(_minDate.getFullYear(), _minDate.getMonth(), 
  •                 _minDate.getDate()); 
  •             while(Date.parse(_dTemp) <= Date.parse(_maxDate)) 
  •             {     
  •                 if(_dTemp.getDay() % 6 == 0) //Weekend 
  •                 { 
  •                     _gStr += "" + 
  •                         _dTemp.getDate() + "
  • "
  •                     if(Date.parse(_dTemp) == Date.parse(_currentDate))                    
  •                         _thirdRow += " + (counter++) +  
  •                         "' class='GToDay' style='height:" + 
  •                         (_taskList.length * 21) + "'> "
  •                     else 
  •                         _thirdRow += " + (counter++) + 
  •                         "' class='GWeekend' style='height:" + (_taskList.length * 21) + 
  •                         "'> "
  •                 } 
  •                 else 
  •                 { 
  •                     _gStr += "" + 
  •                         _dTemp.getDate() + "
  • "
  •                     if(Date.parse(_dTemp) == Date.parse(_currentDate))                    
  •                         _thirdRow += " + (counter++) + 
  •                         "' class='GToDay' style='height:" + (_taskList.length * 21) + 
  •                         "'> "
  •                     else 
  •                         _thirdRow += " + (counter++) +  
  •                        "' class='GDay'> "
  •                 } 
  •                 if(_dTemp.getDate() < getDaysInMonth(_dTemp.getMonth() + 1, 
  •                     _dTemp.getFullYear())) 
  •                 { 
  •                     if(Date.parse(_dTemp) == Date.parse(_maxDate)) 
  •                     {                             
  •                         _firstRowStr += " +  
  •                        (_colSpan + 1) + "'>T" + (_dTemp.getMonth() + 1) + "/" +  
  •                        _dTemp.getFullYear() + "";  
  •                     } 
  •                     _dTemp.setDate(_dTemp.getDate() + 1); 
  •                     _colSpan++; 
  •                 }                     
  •                 else  
  •                 { 
  •                     _firstRowStr += " + 
  •                         (_colSpan + 1) + "'>T" + (_dTemp.getMonth() + 1) + 
  •                         "/" + _dTemp.getFullYear() + ""
  •                     _colSpan = 0; 
  •                     if(_dTemp.getMonth() == 11) //December 
  •                     { 
  •                         _dTemp.setFullYear(_dTemp.getFullYear() + 1, 0, 1); 
  •                     } 
  •                     else 
  •                     { 
  •                         _dTemp.setFullYear(_dTemp.getFullYear(), 
  •                             _dTemp.getMonth() + 1, 1); 
  •                     } 
  •                 }                     
  •             } 
  •             _thirdRow += "";                  
  •             _gStr += "" + _thirdRow;                 
  •             _gStr += ""
  •             _gStr = _firstRowStr + _gStr;                 
  •             for(i = 0; i < _taskList.length; i++) 
  •             { 
  •                 _offSet = (Date.parse(_taskList[i].getFrom()) - Date.parse(_minDate)) / 
  •                     (24 * 60 * 60 * 1000); 
  •                 _dateDiff = (Date.parse(_taskList[i].getTo()) -  
  •                     Date.parse(_taskList[i].getFrom())) / (24 * 60 * 60 * 1000) + 1; 
  •                 _gStr += " + (20 * (i + 2)) +  
  •                 "; left:" + (_offSet * 27 + 204) + "; width:" +  
  •                 (27 * _dateDiff - 1 + 100) + "'> +  
  •                 _taskList[i].getTask() + "' class='GTask' style='float:left; width:" + 
  •                 (27 * _dateDiff - 1) + "px;'>" + 
  •                 getProgressDiv(_taskList[i].getProgress()) + 
  •                 "
  • " +  
  •                 _taskList[i].getResource() + ""
  •                 _gStr += " + 
  •                     (20 * (i + 2) + 1) + "; left:5px'>" + _taskList[i].getTask() + 
  •                     ""
  •             } 
  •             _GanttDiv.innerHTML = _gStr; 
  •         } 
  •     } 
  • }         
  •  
  • function getProgressDiv(progress) 
  •     return " + progress + 
  •        "%; overflow:hidden'>" 
  • // GET NUMBER OF DAYS IN MONTH 
  • function getDaysInMonth(month, year)   
  •  
  •     var days;         
  •     switch(month) 
  •     { 
  •     case 1: 
  •     case 3: 
  •     case 5: 
  •     case 7: 
  •     case 8: 
  •     case 10: 
  •     case 12: 
  •         days = 31; 
  •         break
  •     case 4: 
  •     case 6: 
  •     case 9: 
  •     case 11: 
  •         days = 30; 
  •         break
  •     case 2: 
  •         if (((year% 4)==0) && ((year% 100)!=0) || ((year% 400)==0))                 
  •             days = 29;                 
  •         else                                 
  •             days = 28;                 
  •         break
  •     } 
  •     return (days); 
  • }                 
  • /*----- END OF MY CODE FOR Gantt CHART GENERATOR -----*/ 
  •  

    在你的HTML, ASCX, ASPX或PHP文档的Body部分,把下面几行代码拷贝到你想表示甘特图的地方

     

    1. <body>     
    2.     <h3>Diagramh3>     
    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 1b>', '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()来渲染基于追加到甘特图对象的任务列表的甘特图。
    这里笔者定义了一些类用来自定义甘特图的样式,为此提供了全部代码。你可以定义更多的类并且更轻易地改变甘特图控件的外观。

    通过改变样式表,并且在代码中添加属性到任务对象,你可以为你自己创建更加智能的甘特图。例如:为任务条设置不同的颜色,漂亮的背景图片,更好的图标提示等等。

     

    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.     font-family:tahomaarialverdana
    7.     font-size:11px
    8.  
    9. .GTaskTitle 
    10.     font-family:tahomaarialverdana
    11.     font-size:11px
    12.     font-weight:bold
    13.  
    14. .GMonth 
    15.     padding-left:5px
    16.     font-family:tahomaarialverdana
    17.     font-size:11px
    18.     font-weight:bold;     
    19.  
    20. .GToday 
    21.     background-color#FDFDE0;     
    22.  
    23. .GWeekend 
    24.     font-family:tahomaarialverdana
    25.     font-size:11px
    26.     background-color:#F5F5F5
    27.     text-align:center
    28.  
    29. .GDay 
    30.     font-family:tahomaarialverdana
    31.     font-size:11px
    32.     text-align:center
    33.  
    34. .GTask 
    35.     border-top:1px solid #CACACA
    36.     border-bottom:1px solid #CACACA
    37.     height:14px
    38.     background-color:yellow; 
    39.  
    40. .GProgress 
    41.     background-color:black
    42.     height:2px
    43.     overflowhidden
    44.     margin-top:5px

     

    图表

    1. var g = new Gantt(document.all.GanttChart); 
    2. g.AddTaskDetail(new Task('2/11/2008''2/19/2008''Sample task 1 1''Dathq', 50)); 
    3. g.AddTaskDetail(new Task('2/16/2008''2/19/2008''... Sample task 1.1',  
    4.     'Dathq, Thanhdo', 30)); 
    5. g.AddTaskDetail(new Task('2/12/2008''3/2/2008''Sample task 2''Hanhnd', 60)); 
    6. g.AddTaskDetail(new Task('2/11/2008''2/16/2008''Sample task 3''Dathq', 50)); 
    7. g.AddTaskDetail(new Task('2/11/2008''2/19/2008''Sample task 1 1''Dathq', 50)); 
    8. g.AddTaskDetail(new Task('2/16/2008''2/19/2008''... Sample task 1.1'
    9.     'Dathq, Thanhdo', 30)); 
    10. g.AddTaskDetail(new Task('2/12/2008''3/2/2008''Sample task 2''Hanhnd', 60)); 
    11. g.AddTaskDetail(new Task('2/11/2008''2/16/2008''Sample task 3''Dathq', 50)); 
    12. g.AddTaskDetail(new Task('2/11/2008''2/19/2008''Sample task 1 1''Dathq', 50)); 
    13. g.AddTaskDetail(new Task('2/16/2008''2/19/2008''... Sample task 1.1'
    14.     'Dathq, Thanhdo', 30)); 
    15. g.AddTaskDetail(new Task('2/12/2008''3/2/2008''Sample task 2''Hanhnd', 60)); 
    16. g.AddTaskDetail(new Task('2/11/2008''2/16/2008''Sample task 3''Dathq', 50)); 
    17.  
    18. g.AddTaskDetail(new Task('2/11/2008''2/19/2008''Sample task 1 1''Dathq', 50)); 
    19. g.AddTaskDetail(new Task('2/16/2008''2/19/2008''... Sample task 1.1'
    20.      'Dathq, Thanhdo', 30)); 
    21. g.AddTaskDetail(new Task('2/12/2008''3/2/2008''Sample task 2''Hanhnd', 60)); 
    22. g.AddTaskDetail(new Task('5/11/2008''5/16/2008''Sample task 3''Dathq', 50)); 
    23.  
    24. 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
    文件下载: http://www.codeproject.com/KB/scripting/SIcon_Gantt_Chart/GanttChart.zip
    翻译: 崔驰坤(JOSHUA TSUEI, http://www.cnblogs.com/JOSHUATSUEI )

    点击下载此文件

    本文作者:佚名 来源:http://www.kaiyuan8.org/Article/IAVTEnsTDnxzGLShYi
    CIO之家 www.ciozj.com 微信公众号:imciow
       
    免责声明:本站转载此文章旨在分享信息,不代表对其内容的完全认同。文章来源已尽可能注明,若涉及版权问题,请及时与我们联系,我们将积极配合处理。同时,我们无法对文章内容的真实性、准确性及完整性进行完全保证,对于因文章内容而产生的任何后果,本账号不承担法律责任。转载仅出于传播目的,读者应自行对内容进行核实与判断。请谨慎参考文章信息,一切责任由读者自行承担。
    延伸阅读