使用jQueryGantt实现进度甘特图

  由于项目需要,需要做一个进度甘特图。要求使用jQueryGantt来实现,在网上看了很多博客,终于找了几篇比较有用的。但是仅仅靠这几篇文章和一个demo无法满足项目的需求,所以研究了下jQueryGantt的源码,根据项目需求进行了一些改动。由于网上对于jQueryGantt的文章较少,很多都不完整,所以特此写下这篇文章进行记录,顺便分享有需要的人。

1.jQueryGantt下载

官方演示地址:http://taitems.github.io/jQuery.Gantt
我此次使用的是Github上一位网友发布的一个版本:https://github.com/ybx13579/jQuery.Gantt
这是他写的一份指南:https://blog.csdn.net/yangbingx/article/details/73470030
非常感谢,大家喜欢的记得给他一个star。

2.运行

这里的说明并不是很详细,具体参考test1文件夹中的index.html
将css,js,img放入工程项目中,并参考test1/index.html 中的引入。

注:如果需要甘特图中显示中文,则需要在js文件引用中加上charset特性并设置为GB2312,否则中文内容将显示为乱码。

之后在html页面上写一个div

   


    

复制相应的js方法


JQueryGantt需要的Json数据格式

[

                {
                    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。

灵魂画手已上线
使用jQueryGantt实现进度甘特图_第1张图片
image.png

看了看自己画的图,还是贴代码吧。。。

//SpringMvc Framwork
@RequestMapping(value = "ganttData", method = RequestMethod.POST)
    @ResponseBody
    public String ganttData(String id) throws Exception {
          //查询出需要的多条进度数据
            List scheduleDataList = scheduleMgrService.selectScheduleDataListByPid(pt);
            //用于保存整个数据集
            List dataList = new ArrayList<>();
            //循环遍历,对数据进行重新封装
            for (ScheduleData data : scheduleDataList) {
               //用于存放 name,desc,value三个对象
                Map planItemMap = new HashMap<>();
                planItemMap.put("name", data.getSd_process_name() + "(计划)");
                planItemMap.put("desc", data.getSd_plan_remark());
                //用于存放value中的from,to,label,customClass
                Map 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 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实现进度甘特图_第2张图片
jQueryGantt.jpg

3.修改jQueryGantt的核心文件来满足项目的需求

问题:

下载的Demo中的jQueryGantt是一个宽度为800px的甘特图,但是项目中需要将甘特图横向铺满,所以必须将宽度设置为100%。但是jQueryGantt顶部的时间刻度是根据数据的时间长度生成的,在数据时间比较短并且在横向铺满屏幕的情况下就会出现时间刻度不全的情况。


使用jQueryGantt实现进度甘特图_第3张图片
image.png

当我只修改了div的宽度为自动或者100%的时候出现了上述情况。

    
使用jQueryGantt实现进度甘特图_第4张图片

解决方法:

我不得不说,为了找到这个解决办法,我花了三个小时来阅读,调试,修改这个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;
            },

这时你再刷新一下页面就会发现空白部分的网格和时间刻度被填上了。像这个样子


使用jQueryGantt实现进度甘特图_第5张图片
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%;
}
使用jQueryGantt实现进度甘特图_第6张图片
修改完后的效果图

到此为止,我的问题基本上都解决了~

参考文章:
https://blog.csdn.net/yangbingx/article/details/73470030
https://github.com/ybx13579/jQuery.Gantt
https://blog.csdn.net/weixin_41916005/article/details/80851748
https://blog.csdn.net/weixin_41916005/article/details/80851748
https://www.cnblogs.com/marksfly/p/4561165.html
https://blog.csdn.net/l3922768721/article/details/79933327
http://taitems.github.io/jQuery.Gantt/?yyue=a21bo.50862.201879
https://github.com/ybx13579/jQuery.Gantt

转载请注明出处及作者,谢谢。

你可能感兴趣的:(使用jQueryGantt实现进度甘特图)