使用jQueryGantt實現進度甘特圖

  因爲項目須要,須要作一個進度甘特圖。要求使用jQueryGantt來實現,在網上看了不少博客,終於找了幾篇比較有用的。可是僅僅靠這幾篇文章和一個demo沒法知足項目的需求,因此研究了下jQueryGantt的源碼,根據項目需求進行了一些改動。因爲網上對於jQueryGantt的文章較少,不少都不完整,因此特此寫下這篇文章進行記錄,順便分享有須要的人。javascript

1.jQueryGantt下載css

官方演示地址:taitems.github.io/jQuery.Gant… 我這次使用的是Github上一位網友發佈的一個版本:github.com/ybx13579/jQ… 這是他寫的一份指南:blog.csdn.net/yangbingx/a… 很是感謝,你們喜歡的記得給他一個star。html

2.運行前端

這裏的說明並非很詳細,具體參考test1文件夾中的index.html 將css,js,img放入工程項目中,並參考test1/index.html 中的引入。java

注:若是須要甘特圖中顯示中文,則須要在js文件引用中加上charset特性並設置爲GB2312,不然中文內容將顯示爲亂碼。
<script src="js/jquery.fn.gantt.js" charset ="GB2312"></script>
複製代碼

以後在html頁面上寫一個divjquery

<style type="text/css">
        body {
            font-family: Helvetica, Arial, sans-serif;
            font-size: 13px;
            padding: 0 0 50px 0;
        }

        .contain {
            width: 800px;
            margin: 0 auto;
        }
    </style>


    <div class="gantt_ot" style="width:800px; margin:100px auto;">
        <div class="gantt"></div>
    </div>
複製代碼

複製相應的js方法git

<script type="text/javascript">
    $(function () {
        var sourceData;
        $.ajax({
            url: "/test/getGanttData", //請求後臺,並返回甘特圖須要的json數據
            type: "post",
            dataType: "json",
            cache: false, //關閉AJAX緩存
            data: {"id": 1}, //傳入的查詢參數
            success: function (data) {

                //初始化gantt
                $(".gantt").gantt({
                    source: data,
                    navigate: 'scroll',//// 底部使用拖拽的刻度尺仍是按鈕:scroll和buttons
                    scale: "weeks",// 這裏是設置默認比例。這裏總共有四個參數:months  weeks days  hours.
                    maxScale: "months", // 這裏是設置最大比例。這裏總共有四個參數:months  weeks days  hours.
                    minScale: "days", // 這裏是設置最小比例。這裏總共有四個參數:months  weeks days  hours.
                    itemsPerPage: 20, //設置甘特圖每頁顯示多少條
                    onItemClick: function (data) {//有數據範圍內的點擊事件
                        // alert("Item clicked - show some details");
                    },
                    onAddClick: function (dt, rowId) {//無數據範圍內的點擊事件
                        // alert("Empty space clicked - add an item!");
                    },
                    onRender: function () {//渲染事件
                        if (window.console && typeof console.log === "function") {
                            // console.log("chart rendered");
                        }
                    }
                });
            }
        });

        /*  //彈窗功能
          $(".gantt").popover({
              selector: ".bar",
              title: "I'm a popover",
              content: "And I'm the content of said popover.",
              trigger: "hover",
              placement: "auto right"
          });*/

        //prettyPrint();
    });


</script>
複製代碼

JQueryGantt須要的Json數據格式github

[

                {
                    name: "task1",
                    desc: "",
                    values: [{
                        from: "/Date(1320192000000)/", //這裏須要的時間爲毫秒
            //。計算方式爲時間變量減去時間初始值(1970-1-1)的差值換算爲毫秒
                          to: "/Date(1320592000000)/",
                        label: "這是label",
                        customClass: "ganttRed" //這裏是這條記錄的在甘特圖上的顏色
                    }]
                }, {
                    name: "task2",
                    desc: "這是描述",
                    values: [{
                        from: "/Date(1322611200000)/",
                        to: "/Date(1323302400000)/",
                        label: "",
                        customClass: "ganttGreen"
                    }]
                }]
複製代碼

若是你是使用的Java來編寫的話,我這裏提供一下後臺處理json數據的思路。 首先,最外層的是一個List集合。而後裏面的name,desc,values使用Map進行封裝。而values裏面又是一個集合,因此values整個呢誒容是一個List集合。而內部的from,to,label等參數又須要使用Map以[key,value]的形式保存。因此又要封裝一個Map。web

靈魂畫手已上線

image.png

看了看本身畫的圖,仍是貼代碼吧。。。ajax

//SpringMvc Framwork
@RequestMapping(value = "ganttData", method = RequestMethod.POST)
    @ResponseBody
    public String ganttData(String id) throws Exception {
          //查詢出須要的多條進度數據
            List<Project> scheduleDataList = scheduleMgrService.selectScheduleDataListByPid(pt);
            //用於保存整個數據集
            List<Object> dataList = new ArrayList<>();
            //循環遍歷,對數據進行從新封裝
            for (ScheduleData data : scheduleDataList) {
               //用於存放 name,desc,value三個對象
                Map<String, Object> planItemMap = new HashMap<>();
                planItemMap.put("name", data.getSd_process_name() + "(計劃)");
                planItemMap.put("desc", data.getSd_plan_remark());
                //用於存放value中的from,to,label,customClass
                Map<String, Object> valueMap = new HashMap<>();
                valueMap.put("from", "/Date(" + data.getSd_plan_start_date().getTime() + ")/");
                valueMap.put("to", "/Date(" + data.getSd_plan_end_date().getTime() + ")/");
                valueMap.put("label", "");
                valueMap.put("customClass", "ganttRed");
                //將封裝的value的map封裝到一個List集合中去
                List<Object> planValueList = new ArrayList<>();
                planValueList.add(valueMap);
                //將封裝的value List集合添加到保存整個數據集的List裏面去
                planItemMap.put("values", planValueList);
                dataList.add(planItemMap);
                }
          //將封裝的數據集轉換爲Json數組
           JSONArray array = JSONArray.fromObject(dataList);
            //將Json數組轉換爲字符串並返回給前端
            return array.toString();
}
複製代碼

jQueryGantt.jpg

3.修改jQueryGantt的核心文件來知足項目的需求

問題:

下載的Demo中的jQueryGantt是一個寬度爲800px的甘特圖,可是項目中須要將甘特圖橫向鋪滿,因此必須將寬度設置爲100%。可是jQueryGantt頂部的時間刻度是根據數據的時間長度生成的,在數據時間比較短而且在橫向鋪滿屏幕的狀況下就會出現時間刻度不全的狀況。

image.png

當我只修改了div的寬度爲自動或者100%的時候出現了上述狀況。

<div class="gantt_ot" style="width:auto; margin:100px auto;">
        <div class="gantt"></div>
    </div>
複製代碼

解決方法:

我不得不說,爲了找到這個解決辦法,花了點時間閱讀源碼,調試,修改這個jquery.fn.gantt.js來解決這個問題。(多是本身太菜了 2333333)。

(敲黑板) 重點來了~~ 思路:空出來的地方用一年的刻度時間應該能填滿,因此只要將jQueryGantt根據數據中的結束時間計算刻度尺長度的時間追加一年,就會多出一年的刻度時間出來。 打開jquery.fn.gantt.js 找到getMaxDate這個function 在全部的getFullYear()方法後面都追加一個 +1 maxDate.getFullYear()+1

貼出修改後的maxDate方法

// Return the maximum available date in data depending on the scale
//根據比例返回數據中的最大可用日期。
    getMaxDate: function (element) {
                var maxDate = null;
                $.each(element.data, function (i, entry) {
                    $.each(entry.values, function (i, date) {
                        maxDate = maxDate < tools.dateDeserialize(date.to) ? tools.dateDeserialize(date.to) : maxDate;
                    });
                });
                maxDate = maxDate || new Date();
                var bd;
                switch (settings.scale) {
                    case "hours":
                        maxDate.setHours(Math.ceil((maxDate.getHours()) / element.scaleStep) * element.scaleStep);
                        maxDate.setHours(maxDate.getHours() + element.scaleStep * 3);
                        break;
                    case "weeks":
                        // wtf is happening here?
                        bd = new Date(maxDate.getTime());
                        bd = new Date(bd.setDate(bd.getDate() + 3 * 7));
                        var md = Math.floor(bd.getDate() / 7) * 7;
                        maxDate = new Date(bd.getFullYear() + 1, bd.getMonth(), md === 0 ? 4 : md - 3);
                        break;
                    case "months":
                        bd = new Date(maxDate.getFullYear() + 1, maxDate.getMonth(), 1);
                        bd.setMonth(bd.getMonth() + 2);
                        maxDate = new Date(bd.getFullYear() + 1, bd.getMonth(), 1);
                        break;
                    case "days":
                    /* falls through */
                    default:
                        maxDate.setHours(0);
                        maxDate.setDate(maxDate.getDate() + 3);
                }
                return maxDate;
            },
複製代碼

這時你再刷新一下頁面就會發現空白部分的網格和時間刻度被填上了。像這個樣子

image.png

4.小優化

雖然最麻煩的問題得以解決。可是用戶體驗上還存在一些能夠優化的地方,例如:月份爲英文,星期爲英文,底部的控件沒有居中,這樣用戶感受不太好。接下來咱們逐一解決這些問題。

1.修改英文月份和周爲中文。

打開jquery.fn.gantt.js 找到var settings這個變量的定義的地方,這裏是jQueryGantt初始化參數的位置。

//Default settings 默認設置
var settings = {
            source: [],
            holidays: [],
            // 默認的頁數
            itemsPerPage: 7,
            // localisation
            // dow: ["S", "M", "T", "W", "T", "F", "S"],
            //面板上的星期,只能爲一個字,兩個字會被擠出來
            dow: ["日", "一", "二", "三", "四", "五", "六"],
            //面板上的月份
            months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
          //甘特圖在渲染的時候顯示的提示文字
            waitText: "加載中,請稍候...",
            // 底部使用拖拽的刻度尺仍是按鈕:scroll和buttons
            navigate: "buttons",
            //網格加載完畢後是否自動滾動到今天,true爲是 false爲不須要
            scrollToToday: false,
            // cookie options
            useCookie: false,
            cookieKey: "jquery.fn.gantt",
            // scale parameters
            scale: "days",
            maxScale: "months",
            minScale: "hours",
            // callbacks
            onItemClick: function (data) {
                return;
            },
            onAddClick: function (dt, rowId) {
                return;
            },
            onRender: $.noop
        };
複製代碼
2.底部的控件居中

打開jQueryGantt的style.css

.gantt {
    width: 100%;
    margin: 0 auto; //清除掉上下間距
    border: 14px solid #ddd;
    position: relative;
    -webkit-border-radius: 6px;
   -moz-border-radius: 6px;
        border-radius: 6px;
  -webkit-box-sizing: border-box;
   -moz-box-sizing: border-box;
        box-sizing: border-box;
}

//設置底部控件位置(前端技術有限,就這樣簡單的處理了一下)
.nav-slider {
    margin-left: 20%;
}
複製代碼

修改完後的效果圖

參考文章:

blog.csdn.net/yangbingx/a… github.com/ybx13579/jQ… blog.csdn.net/weixin_4191… blog.csdn.net/weixin_4191… www.cnblogs.com/marksfly/p/… blog.csdn.net/l3922768721… taitems.github.io/jQuery.Gant… github.com/ybx13579/jQ…

轉載請註明出處及做者,謝謝。Create By Hiseico

掘金我的主頁

相關文章
相關標籤/搜索