??由于項目需要,需要做一個進度甘特圖。要求使用jQueryGantt來實現啄刹,在網上看了很多博客忆嗜,終于找了幾篇比較有用的。但是僅僅靠這幾篇文章和一個demo無法滿足項目的需求淑玫,所以研究了下jQueryGantt的源碼巾腕,根據項目需求進行了一些改動。由于網上對于jQueryGantt的文章較少絮蒿,很多都不完整尊搬,所以特此寫下這篇文章進行記錄,順便分享有需要的人土涝。
1.jQueryGantt下載
官方演示地址:http://taitems.github.io/jQuery.Gantt
我此次使用的是Github上一位網友發(fā)布的一個版本: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>
復制相應的js方法
<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莺匠。
靈魂畫手已上線
看了看自己畫的圖金吗,還是貼代碼吧。。摇庙。
//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<>();
//循環(huán)遍歷旱物,對數據進行重新封裝
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();
}
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;
},
這時你再刷新一下頁面就會發(fā)現空白部分的網格和時間刻度被填上了礁竞。像這個樣子
4.小優(yōu)化
雖然最麻煩的問題得以解決糖荒。但是用戶體驗上還存在一些可以優(yōu)化的地方,例如:月份為英文模捂,星期為英文捶朵,底部的控件沒有居中,這樣用戶感覺不太好狂男。接下來我們逐一解決這些問題综看。
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%;
}
到此為止忠寻,我的問題基本上都解決了~
參考文章:
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