免費JS甘特圖元件dhtmlxgantt

馬洪彪發表於2021-05-17

安裝

參考:https://docs.dhtmlx.com/gantt/desktop__install_with_bower.html

可使用NuGet、Bower、npm包管理器安裝(應用在asp.net、nodejs等專案上)。

Nuget

nuget install DHTMLX.Gantt

npm

npm install dhtmlx-gantt

或使用CDN、下載JS庫引入(簡單HTML應用)。

CDN

<link rel="stylesheet" href="http://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" 
    type="text/css"> 
<script src="http://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>

js

<script type="text/javascript" src="codebase/dhtmlxgantt.js"></script>  
<link rel="stylesheet" href="codebase/dhtmlxgantt.css">

初始化

https://docs.dhtmlx.com/gantt/desktop__initializing_gantt_chart.html

<!DOCTYPE html>
<html>
<head>
   <script src="codebase/dhtmlxgantt.js"></script>
   <link href="codebase/dhtmlxgantt.css" rel="stylesheet">
</head>
<body>
    <div id="gantt_here" style='width:1000px; height:400px;'></div>
    <script type="text/javascript">
        gantt.init("gantt_here");
    </script>
</body>
</html>

初始化步驟

  • 引入js
  • 引入css
  • 定義容器div
  • js呼叫gantt.init初始化

屬性、模板、配置

參考:https://docs.dhtmlx.com/gantt/desktop__common_configuration.html
自定義甘特圖,可實現自定義展示(通過config和templates),自定義互動(通過method和event)以及自定義元件佈局(layout)。
兩個配置檔案

  • gantt.config - 配置dates資料, scale刻度(年度、月度等), controls控制元件 等的選項
  • gantt.templates - 甘特圖中使用的dates資料 and labels標籤的格式化模板.

配置

API:https://docs.dhtmlx.com/gantt/api__refs__gantt_props.html

示例

在API中查詢到該屬性的各元素定義,參照使用。

gantt.scales = [
    { unit: "year", step: 1, format: "%Y" }
];
 
gantt.init("gantt_here");

注意事項

配置選項(gantt.xxx)要在初始化(gantt.init)前。

模板

API:https://docs.dhtmlx.com/gantt/api__refs__gantt_templates.html

示例

例如使用模板格式化任務名稱,首先查詢到其原型定義。

gantt.templates.task_text=function(start, end, task){
    return task.text;
};

然後參考原型方法,修改。

gantt.templates.task_text=function(start,end,task){
    return "<b>名稱:</b> "+task.text+",<b> 負責人:</b> "+task.users;
};
gantt.init("gantt_here");

注意事項:

模板的定義(gantt.templates.xxx)要在初始化(gantt.init)前。

自定義佈局

https://docs.dhtmlx.com/gantt/desktop__layout_config.html

5.0及以上支援該配置。
預設佈局為左側是任務資訊列表,右側是甘特圖時間線,自定義佈局可在右側、下方顯示更多資訊。
自定義佈局可顯示資源列表和資源的甘特圖時間線,但僅Pro版本可用。

預設佈局為:

gantt.config.layout = {
    css: "gantt_container",
    rows:[
        {
           cols: [
            {
              // 預設任務列表  
              view: "grid",  
              scrollX:"scrollHor", 
              scrollY:"scrollVer"
            },
            { resizer: true, width: 1 },
            {
              // 預設甘特圖(時間線)
              view: "timeline", 
              scrollX:"scrollHor", 
              scrollY:"scrollVer"
            },
            {
              view: "scrollbar", 
              id:"scrollVer"
            }
        ]},
        {
            view: "scrollbar", 
            id:"scrollHor"
        }
    ]
}

自定義佈局,修改gantt.config.layout即可。

  • grid - 定義甘特圖的表格,顯示任務的表格ID為grid;
  • timeline - 定義時間線,顯示任務時間線ID為"timeline";
  • scrollbar - 滾動條(表格和時間線).

事件處理

https://docs.dhtmlx.com/gantt/desktop__handling_events.html

使用者拖拽時間線、新增任務等事件的處理。
如果僅用作甘特圖的展示,則可忽略該部分,並且通過template、config配置遮蔽掉新增任務等功能。
但可以通過配置event,實現視覺化排程,在甘特圖時間線和任務grid中新增任務、新增任務連結、修改任務屬性,可拖拽來更新任務時間等。
在甘特圖上所做操作,需要通過event的相應方法,結合ajax提交到後臺更改資料,否則頁面重新整理後資料丟失。

附加事件

gantt.attachEvent("onTaskClick", function(id, e) {
    alert("You've just clicked an item with id="+id);
});

移除

附加事件後返回事件ID,使用該ID可移除

//附加事件,返回事件ID
var eventId = gantt.attachEvent("onTaskClick", function(id, e) {
    alert("You've just clicked an item with id="+id);
});
//使用某個ID移除
gantt.detachEvent(eventId);

新增並移除所有

定義事件ID陣列,新增時記錄ID,移除時迴圈處理。

// save handler ids when attaching events
var events = [];
events.push(gantt.attachEvent("onTaskClick", function(id, e) {
    alert("You've just clicked an item with id="+id);
});
events.push(gantt.attachEvent("onTaskDblClick", function(id, e) {
    alert("You've just double clicked an item with id="+id);
});
 
// detach all saved events
while (events.length)
   gantt.detachEvent(events.pop());

檢查是否有事件響應

gantt.attachEvent("onTaskClick", function(id, e) {
    alert("You've just clicked a task with id="+id);
});
 
gantt.checkEvent("onTaskClick"); //returns 'true'

事件處理函式中取消事件響應

返回false,則中斷事件響應鏈。

gantt.attachEvent("onBeforeTaskChanged", function(id, mode, old_task){
    var task = gantt.getTask(id);
    if(mode == gantt.config.drag_mode.progress){
        if(task.progress < old_task.progress){
            dhtmlx.message(task.text + " progress can't be undone!");
            return false; 
        }
    }
    return true;
});

事件響應函式中訪問甘特圖物件

gantt.attachEvent("onTaskClick", function(id, e){
    parentId = this.getTask(id).parent;
});

this.getTask(id) 等方法參考方法API。
https://docs.dhtmlx.com/gantt/api__refs__gantt_methods.html

方法

https://docs.dhtmlx.com/gantt/api__refs__gantt_methods.html

其他

Ajax等。

ajax

i18N多語言

gantt.i18n.setLocale({
   labels: {
      gantt_save_btn: "New Label",
      gantt_cancel_btn: "New Label"
   }
});

屬性配置常用API

Ajax等。

autofit 表格列自適應

預設為false,若設定為true則平均分佈。
例如任務名稱列內容較多,設定為true後則可能顯示不全,設定為false後任務名稱列會寬一些。

gantt.config.autofit = true;
gantt.config.grid_width = 500;

autoscroll 操作的任務或連結超出螢幕後自動滾動到該位置

預設為true。

autoscroll_speed 自動滾動的速度

預設為30ms。

gantt.config.autoscroll = true;
gantt.config.autoscroll_speed = 50;
 
gantt.init("gantt_here");

autosize 自動調整甘特圖大小以適應螢幕

預設為false,即甘特圖可超出螢幕大小,超出後有滾動條可拖動。
如果設定為xy,則豎直內容不足螢幕,則皮膚將縮小至其高度,水平內容超過螢幕,則截斷無滾動條。

可賦值:"y" ( or true),"x", "xy"

gantt.config.autosize = "xy";
 
gantt.init("gantt_here");

autosize_min_width 水平自動縮放時的最小寬度

預設值0.

gantt.config.autosize = "xy";
gantt.config.autosize_min_width = 800;
 
gantt.init("gantt_here");

bar_height 時間線中的任務條的高度

預設值full。

gantt.config.bar_height = 30;
gantt.init("gantt_here");

buttons_left 任務詳情彈窗中左下角的按鈕定義

預設 ["gantt_save_btn", "gantt_cancel_btn"],儲存和取消

可自定義按鈕,並定義該按鈕的事件響應函式。

<style>
    .complete_button{
        margin-top: 2px;
        background-image:url("common/v_complete.png");
        width: 20px;
    }
</style>
<script>
    gantt.locale.labels["complete_button"] = "Complete";
    gantt.attachEvent("onGanttReady", function(){                               
        gantt.config.buttons_left = ["gantt_save_btn","gantt_cancel_btn",           
            "complete_button"];                                                 
    });                                                                         
    gantt.init("gantt_here");
 
    gantt.attachEvent("onLightboxButton", function(button_id, node, e){
        if(button_id == "complete_button"){
            var id = gantt.getState().lightbox;
            gantt.getTask(id).progress = 1;
            gantt.updateTask(id);
            gantt.hideLightbox();
        }
    });
</script>

也可修改預設的按鈕

gantt.locale.labels.icon_save = "New Label";
gantt.locale.labels.icon_cancel = "New Label";
 
gantt.init("gantt_here");

buttons_right 彈窗的右下角按鈕

預設值:["gantt_delete_btn"]; 刪除

calendar_property 任務繫結的日曆

cascade_delete 級聯刪除任務和關聯

預設值為true

gantt.config.cascade_delete = false;
gantt.init("gantt_here");

click_drag 啟用拖拽功能

gantt.config.click_drag = {
    callback: function(
        startPosition,
        endPosition,
        startDate,
        endDate,
        tasksBetween,
        rowsBetween
    ){
        var parentId = gantt.config.root_id;
        if(rowsBetween.length){
            parentId = rowsBetween[0].id;
        }
 
        gantt.createTask({
            text: "新任務",
            start_date: gantt.roundDate(startDate),
            end_date: gantt.roundDate(endDate)
        }, parentId);
 
    },
    singleRow: true
};

columns 配置任務表格的列

預設列定義為:

// default columns definition
gantt.config.columns=[
    {name:"text",       label:"任務名稱",  tree:true, width:'*' },
    {name:"start_date", label:"開始時間", align: "center" },
    {name:"duration",   label:"工期",   align: "center" },
    {name:"add",        label:"" }
];
gantt.init("gantt_here");

外掛

使用外掛可擴充套件甘特圖的基本功能。
使用時,先引入外掛,然後按照外掛的使用配置甘特圖(config屬性配置)。
https://docs.dhtmlx.com/gantt/api__gantt_plugins.html

gantt.plugins({
    quick_info: true,
    keyboard_navigation: true,
    undo: true
});
  • click_drag: true 通過拖拽來建立和選擇任務
  • auto_scheduling: true 自動排程,根據任務的連結自動排定時間
  • critical_path: true 最短路徑,Pro版支援
  • drag_timeline: true 拖拽時間線
  • overlay: true 在甘特圖上增加一個使用者自定義的層來顯示資訊
  • fullscreen: true 全屏
  • grouping: true 按任務的任何屬性來分組任務
  • keyboard_navigation: true 使用鍵盤快捷鍵來導航,建立任務、選中甘特圖等.
    gantt.config.keyboard_navigation_cells = true;
  • multiselect: true 允許選擇多個任務
  • quick_info: true 點選任務或時間線中的任務條後,顯示一個任務詳細並帶有刪除和編輯按鈕的浮窗
  • tooltip: true 提示
  • undo: true 取消、重做
  • marker: true 豎直標記線,高亮當前日期或特定日期

常見模板API

date_grid 任務表格的開始時間列的內容

gantt.templates.date_grid = function(date, task, column){
   if(task && gantt.isUnscheduled(task) && gantt.config.show_unscheduled){
        return gantt.templates.task_unscheduled_time(task);
    }else{
        return gantt.templates.grid_date_format(date);
   }
}
gantt.templates.drag_link = function(from, from_start, to, to_start) {
    from = gantt.getTask(from);
 
    var text = "From:<b> " +from.text + "</b> " +(from_start?"Start":"End")+"<br/>";
    if(to){
        to = gantt.getTask(to);
        text += "To:<b> " + to.text + "</b> "+ (to_start?"Start":"End")+"<br/>";
    }
    return text;
};
gantt.templates.drag_link_class = function(from, from_start, to, to_start) {
    var add = "";
    if(from && to){
        var allowed = gantt.isLinkAllowed(from, to, from_start, to_start);
        add = " " + (allowed ? "gantt_link_allow" : "gantt_link_deny");
    }
    return "gantt_link_tooltip" + add;
};

format_date 轉換日期物件為日期字串,以傳送給伺服器端

var dateToStr = gantt.date.date_to_str("%Y-%m-%d %H:%i");
gantt.templates.format_date = function(date){
    return dateToStr (date);
};

grid_blank 在樹形列中子項的自定義內容

gantt.templates.grid_blank = function(item) {
    return "<div class='gantt_tree_icon gantt_blank'></div>";
};

grid_file 設定樹形列的子項圖示

gantt.templates.grid_file = function(item) {
    return "<div class='gantt_tree_icon gantt_file'></div>";
};

grid_folder 設定樹形列的父項圖示


gantt.templates.link_class = function(link){
    return "";
};

progress_text 時間線上任務條的完成部分的文字

預設不顯示。預設盡在中部顯示任務名稱。

gantt.templates.progress_text=function(start, end, task){return "";};

修改增加在完成部分顯示完成的進度。

gantt.templates.progress_text = function (start, end, task) {
    return "<span style='text-align:left;'>" + Math.round(task.progress * 100) + "% </span>";
}; 

task_class 時間線任務條的CSS

gantt.templates.task_class = function(start, end, task){return "";};

task_unscheduled_time 未定義時間的任務


時間線任務條樣式自定義

https://docs.dhtmlx.com/gantt/samples/04_customization/04_task_styles.html

示例中定義了高中低三個優先順序的任務,根據不同的優先順序應用不同的樣式,優先順序高的應用為紅色。

也可以根據任務是否超期等應用不同的樣式,例如超期為紅色,普通為綠色。

時間線時間軸的縮放(通過按鈕或滑鼠滾輪)

適應螢幕、放大、縮小:
https://docs.dhtmlx.com/gantt/samples/03_scales/13_zoom_to_fit.html

滾動滑鼠縮放:
https://docs.dhtmlx.com/gantt/samples/03_scales/14_scale_zoom_by_wheelmouse.html

實現多語言(漢化)

https://docs.dhtmlx.com/gantt/desktop__localization.html

i18n 多語言 API:
https://docs.dhtmlx.com/gantt/api__gantt_i18n_other.html

方法一,直接設定

gantt.i18n.setLocale({
    labels: {
        new_task: "New task"
    }
});

方法二,定義然後設定

var localObject = {
    labels: {
        new_task: "New task"
    }
};
gantt.i18n.addLocale("lang", localeObject); 
gantt.i18n.setLocale("lang");

方法三,引入js後放置(推薦)

gantt.i18n.addLocale("lang", localeObject); 
gantt.i18n.setLocale("lang");

實現全屏切換

https://docs.dhtmlx.com/gantt/desktop__fullscreen_mode.html

使用全屏外掛

gantt.plugins({
    fullscreen: true
});

定義全屏按鈕並切換

  • gantt.expand(); 全屏模式
  • gantt.collapse(); 普通模式
<input id="fullscreen_button" type="button" value="全屏"/>
<script>
var button = document.getElementById("fullscreen_button");
    button.addEventListener("click", function(){
        if (!gantt.getState().fullscreen) { 
            gantt.expand();
        }
        else { 
            gantt.collapse();
        }
    }, false);
</script>

新增特定日期的時間線

例如標註當前日期,或標註某個特定日期(deadline)。

引入外掛

gantt.plugins({
		marker: true
	}); 

新增一條線

var dateToStr = gantt.date.date_to_str(gantt.config.task_date);
	var today = new Date();
	gantt.addMarker({
		start_date: today,
		css: "today",
		text: "今天",
		title: "今天: " + dateToStr(today)
	});

撤銷、重做

<input value="撤銷" type="button" onclick='gantt.undo()' style='margin:0 5px;'>
<input value="重做" type="button" onclick='gantt.redo()' style='margin:0 5px;'>

提示

參考:https://docs.dhtmlx.com/gantt/desktop__tooltips.html
點選任務grid或時間線中的任務條後,在任務條上彈出(懸掛)提示框。

啟用外掛

gantt.plugins({ 
        tooltip: true 
    });

使用template個性化內容

gantt.templates.tooltip_text = function(start,end,task){
		return "<b>任務:</b> "+task.text+"<br/><b>開始時間:</b> "+dateToStr(task.start_date)+"<br/><b>工期:</b> " + task.duration;
	};

任務grid分組

預設按照任務的層級分組,也可自定義按照任務的責任人、所屬類別等分組。

<input class="action" id="default" value="預設樹分組" type="button" onclick="showGroups()" style='margin:0 5px;'>
<input class="action" id="user" value="預設樹分組" type="button" onclick="showGroups('user')" style='margin:0 5px;'>

任務的三種型別

預設的三種任務型別:

  • 一般任務(預設值),可以理解為任務,專案的任務 type:gantt.config.types.task

  • 專案型任務,可以理解為專案或任務組 type:gantt.config.types.project

  • 里程碑 type:gantt.config.types.milestone

  • project,任務的開始或結束時間為自任務的最早開始時間和最晚結束時間,其自身定義的 start_date, end_date, duration 將被忽略。progress自定義,不由子任務決定。

  • milestone 里程碑,工期為0.

相關文章