jquery.gantt版甘特图实战使用教程附源码下载
日期:2020-01-03
来源:程序思维浏览:2265次
由于项目需要,需要做一个进度甘特图。要求使用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,否则中文内容将显示为乱码。
<script src="js/jquery.fn.gantt.js" charset ="GB2312"></script>
之后在html页面上写一个div
<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>
<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数据格式
[
{
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。
3.修改jQueryGantt的核心文件来满足项目的需求
当我只修改了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;
},
这时你再刷新一下页面就会发现空白部分的网格和时间刻度被填上了。像这个样子
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%;
}
好啦到这里问题都解决啦!
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,否则中文内容将显示为乱码。
<script src="js/jquery.fn.gantt.js" charset ="GB2312"></script>
之后在html页面上写一个div
<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>
<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数据格式
[
{
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。
3.修改jQueryGantt的核心文件来满足项目的需求
问题:
下载的Demo中的jQueryGantt是一个宽度为800px的甘特图,但是项目中需要将甘特图横向铺满,所以必须将宽度设置为100%。但是jQueryGantt顶部的时间刻度是根据数据的时间长度生成的,在数据时间比较短并且在横向铺满屏幕的情况下就会出现时间刻度不全的情况。当我只修改了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;
},
这时你再刷新一下页面就会发现空白部分的网格和时间刻度被填上了。像这个样子
4.小优化
虽然最麻烦的问题得以解决。但是用户体验上还存在一些可以优化的地方,例如:月份为英文,星期为英文,底部的控件没有居中,这样用户感觉不太好。接下来我们逐一解决这些问题。
1.修改英文月份和周为中文。
打开jquery.fn.gantt.js
找到var settings这个变量的定义的地方,这里是jQueryGantt初始化参数的位置。
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%;
}
好啦到这里问题都解决啦!
精品好课