首先我们要明白:这个甘特图需要哪些动态数据。

(1)需要:id,tname,number,计划开始时间,开始时间,计划结束时间,结束时间,项目负责人,参与人,知情人id,计划时长(可以计算得出的,不必在数据库中);前置任务;项目进度,该任务属于哪个任务

(2)然后利用easycode插件生成实体类,映射类,服务类,ontcroller等

(3)利用bootstrap框架做出甘特图的样式,写好js。

<!doctype html>
<html xmlns:th="http://www.thymeleleaf.org">
<head>
<title>ganttu.html</title>
<meta name="keywords" content="keyword1,keyword2,keyword3" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="reason" content="甘特图的实际进度与计划进度可能不符,为了展示实际进度与计划进度的差异和方便统计,自己写了个甘特图框架" />
<meta name="mast" content="使用代码之前请留言,禁止转载..." />
<meta name="description" content="liuyuhang    的甘特图,当前版本1.0,2019-02-19" />
<meta name="description" content="时间日期格式:yyyy-mm-dd" />
<meta name="description" content="①计划进度与实际进度双重进度体系" />
<meta name="description" content="②有前置任务连接线" />
<meta name="description" content="③可修改图颜色" />
<meta name="description" content="④可隐藏与展示列" />
<meta name="description" content="⑤可隐藏域展示子项目" />
<meta name="description" content="⑥可跳转时间到当前时间" />
<meta name="description" content="⑦可从当前项目开始时间查看" />
<meta name="description" content="⑦可隐藏某时间之前的内容" />
<meta name="warning" content="⑧未做图拖拽,并不打算做..." />
<meta name="author" content="liuyuhang 13501043063" />
<!-- 只引用了这些,其余的并没有引用 -->
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="external nofollow"  rel="stylesheet" />
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style type="text/css">
#ganttu-head {
height: 70px;
background-color: #dddddd;
padding: 10px 20px;
}
#ganttu-body {
min-height: 780px;
background-color: #eeeeee;
padding: 10px 20px;
font-size: 20px;
}
#ganttu-index-projectname {
display: inline;
padding: 5px 15px;
background-image: linear-gradient(to left, #222222 0%, #222222 75%, #000000 100%);
color: white;
border-radius: 18px;
}
#ganttu-index-projectdesc {
display: inline;
padding: 5px 15px;
background-image: linear-gradient(to left, #777777 0%, #777777 75%, #333333 100%);
color: white;
border-radius: 18px;
}
td {
white-space: nowrap
}
</style>
</head>
<body>
<div id='ganttu-head' class='col-lg-12 col-md-12 col-sm-12 col-xs-12' style="height:100px" >
<div style='display: inline;font-size: 30px;font-weight: normal;padding: 5px 15px;'>甘特图面板</div>
<div id='ganttu-index-projectname'>此项目 名称...</div>
<div id='ganttu-index-projectdesc'>此项目描述...</div>
</div>
<div id='ganttu-body' class='col-lg-12 col-md-12 col-sm-12 col-xs-12' style=';overflow-x:scroll;font-size:14px;'>
<!-- 甘特图放到了这个div中 -->
<div id="lyh-ganttu" class='col-lg-12 col-md-12 col-sm-12 col-xs-12' style='position:relative;padding:0px;height:700px;'></div>
</div>
</body>
<script type="text/javascript" th:inline="javascript">
$(function() {
lyhganttuinit('lyh-ganttu'); //甘特图初始化
})
var lyhganttudata=[[${lyhganttudata}]];
/**
* 甘特图设置,变量名固定
*/
var lyhganttuconfig = {
start : '1900/01/01', //初始化开始时间配置    - 别在意
end : '1900/01/10', //初始化结束时间配置    - 别在意
planborder : '#1a8cff', //计划进度的border颜色
planbackground : '#80bfff', //计划进度的back颜色
border : '#ffaa00', //实际进度的border染颜色
background : '#ffcc66', //实际进度的back颜色
linecolor : 'green', //前置任务线颜色
//表格中的thead的题头设置,可按照格式任意添加或减少
labels : {
'projectname' : {
'name' : '         任务名         ',
'show' : true,
}, //任务名
'projectcode' : {
'name' : '编号',
'show' : true,
}, //编号
'planstartat' : {
'name' : '计划开始',
'show' : true,
}, //计划开始时间
'planendat' : {
'name' : '计划结束',
'show' : false,
}, //计划结束时间
'startat' : {
'name' : '实际开始',
'show' : false,
}, //实际开始时间
'endat' : {
'name' : '实际结束',
'show' : false,
}, //实际结束时间
'persent' : {
'name' : '完成比例',
'show' : true,
}, //完工百分比
'dur' : {
'name' : '时长',
'show' : true,
}, //持续时间
'resps' : {
'name' : '负责人',
'show' : true,
}, //负责人
'actors' : {
'name' : '参与人',
'show' : true,
}, //参与人
'insiders' : {
'name' : '知情人',
'show' : false,
}, //知情人
'before' : {
'name' : '前置任务',
'show' : false,
}, //前置任务
'operate' : {
'name' : "<button title='新建计划' class='btn btn-primary btn-xs'><span class='glyphicon glyphicon-plus' style='margin-right:0px'></span></button>",
'show' : true,
}, //修改按钮
}
}
/**
* 添加修改功能
*/
function lyhganttudatamodifybyoperate() {
var data = lyhganttudata.data;
for (var i = 0; i < data.length; i++) {
data[i]['operate'] = "<button title='修改此计划' class='btn btn-primary btn-xs'><span class='glyphicon glyphicon-edit' style='margin-right:0px'></span></button>";
}
}
//================
//以下为甘特图本身的绘图代码,调用lyhganttuinit,参数为要加载甘特图的id
//请使用谷歌浏览器,缩放倍数为100%
/**
* 甘特图初始化函数
*/
function lyhganttuinit(target) {
//重置日期设置缓存
lyhganttuconfig.start = '1900/01/01';
lyhganttuconfig.end = '1900/01/10';
lyhganttuconfigmodifybydate(); //过滤所有时间,获取时间长度
lyhganttudatamodifybyoperate(); //添加点修改或新增数据按钮
var table = lyhganttutable(target);
$('#' + target).html(table);
drawlink(target); //线条初始化
//提示工具初始化
$('#' + target).find('[title]').attr('data-toggle', 'tooltip').attr('data-placement', 'right');
$("[data-toggle='tooltip']").tooltip();
//标记today
var today = lyhganttudate(new date()); //今天的日期字符串
var todayin = $('#' + target + ' .table thead tr #date').find('[data-original-title=\'' + today + '\']');
if (todayin.length > 0) {
todayin.addclass('todaydiv').css('background-color', 'orange').append($('<div>').css({
'height' : parseint($('#' + target + ' .table').css('height').split('px')[0]) - 45 + 'px',
'position' : 'absolute',
'z-index' : 202,
'margin-top' : '-40px',
'margin-left' : '-10px',
'border-left' : '2px dashed red',
}).append($('<button>').addclass('btn btn-danger btn-xs todaybtn').css('margin-left', '3px').html(' today ')))
}
}
/**
* 绘制甘特图基础函数
*/
function lyhganttutable(target) {
var htr = $('<tr>').addclass('text-center');
var labels = lyhganttuconfig.labels; //head的标签json
var start = lyhganttuconfig.start; //总开始时间
var end = lyhganttuconfig.end; //总结束时间
var pborder = lyhganttuconfig.planborder;
var pbackground = lyhganttuconfig.planbackground;
var border = lyhganttuconfig.border;
var background = lyhganttuconfig.background;
var indexbtn = $('<button>').addclass('btn btn-success btn-xs').append("<span class='glyphicon glyphicon-chevron-down' style='margin-right:0px'></span><span class='glyphicon glyphicon-chevron-right' style='display:none;margin-right:0px'></span>");
indexbtn.click(function() { //展开或隐藏所以有任务卡点击函数
var me = $(this);
var indexbtndown = me.find('.glyphicon-chevron-down'); //转开状态
var indexbtnright = me.find('.glyphicon-chevron-right'); //隐藏状态
var metrs = $('#' + target + ' .table tr');
var metdshide = metrs.find('div[hideid]');
if (indexbtnright.is(':hidden')) { //若当前为展开状态,则隐藏,同时调整按钮
metdshide.parent().parent().hide(300);
indexbtnright.show();
indexbtndown.hide();
} else { //当前为隐藏状态,则展开
metdshide.parent().parent().show(300);
indexbtnright.hide();
indexbtndown.show();
}
settimeout(function() { //重新绘图
drawlink('lyh-ganttu');
}, 400)
})
var index = $('<td>').append(indexbtn);
htr.append(index); //添加index
//循环添加label
for (var label in labels) {
var htd = $('<td>').append($('<div>').attr('id', label).html(labels[label].name));
if (labels[label].show != true) {
htd.css('display', 'none');
}
htr.append(htd);
}
//添加甘特图的日期头
var datahtd = $('<td>').attr('id', 'date').css('width', '50%').css('padding', '0px');
var hdivs = lyhganttuheaddivs(target);
for (var i = 0; i < hdivs.length; i++) {
datahtd.append(hdivs[i]);
}
htr.append(datahtd);
//添加甘特图的数据内容
var tbody = $('<tbody>')
var data = lyhganttudata.data;
for (var i = 0; i < data.length; i++) {
//写入展开按钮
var btr = $('<tr>').addclass('text-center').css('max-height', '40px');
if (data[i].pid == 0) {
var plusbtn = $('<button>').append("<span class='glyphicon glyphicon-flag' style='margin-right:0px'></span>").addclass('btn btn-success btn-xs').attr('title', '展开/隐藏-计划').attr('id', data[i]['id']);
plusbtn.click(function() { //任务展开与隐藏按钮点击函数
var me = $(this);
var meid = me.attr('id');
var metrs = $('#' + target + ' .table tr');
var metdshide = metrs.find('div[hideid=' + meid + ']');
if (metdshide.is(':hidden')) { //已经隐藏
metdshide.parent().parent().show(300);
} else {
metdshide.parent().parent().hide(300);
}
settimeout(function() { //重新绘图
drawlink('lyh-ganttu');
}, 400)
})
var plus = $('<td>').css('padding', '5px').append(plusbtn)
} else {
var plus = $('<td>').css('padding', '5px').append($('<div>').attr('id', data[i]['id']).attr('hideid', data[i]['pid']).attr('title', '工作包').append("<span class='glyphicon glyphicon-tasks' style='margin-right:0px'></span>"));
}
btr.append(plus)
//写入数据
for (var label in labels) {
for (var key in data[i]) {
if (label == key) {
if (label.indexof('at') > -1) { //若是时间数据,则截取一下
var tda = $('<td>').css('padding', '5px').append($('<div>').addclass(key).html(data[i][key].substr(5, 5)).attr('title', data[i][key]))
} else if (label == 'resps' || label == 'actors' || label == 'insiders') { //负责人,参与人,知情人加载
var tda = $('<td>').css('padding', '5px').append($('<div>').addclass(key).html(data[i][key][0]).attr('title', data[i][key]));
} else if (label == 'before') { //前置任务
var befores = data[i][key];
var beforesnames = [];
if (befores.length > 0) {
for (var j = 0; j < data.length; j++) {
for (var k = 0; k < befores.length; k++) {
if (data[j].id == befores[k]) {
beforesnames.push(data[j].projectname);
}
}
}
} else {
beforesnames.push('无');
}
var tda = $('<td>').css('padding', '5px').append($('<div>').addclass(key).html(beforesnames[0]).attr('title', beforesnames));
} else { //其他信息加载
var tda = $('<td>').css('padding', '5px').append($('<div>').addclass(key).html(data[i][key]));
}
if (labels[label].show != true) { //该列是否展示
tda.hide();
}
if (label == 'planstartat') {
tda.css('cursor', 'pointer')
tda.click(function() { //对planstartat添加点击函数
var me = $(this);
var psatitle = me.find('div').attr('data-original-title');
var datedivs = $('#' + target + ' .table thead #date');
var datebtn = datedivs.find('div[data-original-title=\'' + psatitle + '\']').prev();
datebtn.click();
})
}
btr.append(tda);
break;
}
}
}
//写入图信息
var ps = data[i]['planstartat']; //计划开始时间
var pe = data[i]['planendat']; //计划结束时间
var dpss = lyhganttudatediff(start, ps) - 1; //计划开始时间和总开始时间的时间差
var dpse = lyhganttudatediff(ps, pe) + 1; //计划开始时间和计划结束时间的时间差
var dse = lyhganttudatediff(start, end); //总开始和总结束时间差
var as = data[i]['startat']; //实际开始时间
var ae = data[i]['endat']; //实际结束时间
var dass = lyhganttudatediff(start, as) - 1; //实际开始时间和总开始时间的时间差
var dase = lyhganttudatediff(as, ae) + 1; //实际开始时间和实际结束时间的时间差
var tdu = $('<td>').css('padding', '0px').css('max-height', '38px');
var d = $('<div>').css({ //计划的div
'display' : 'inline-block',
'width' : '55px',
'height' : '26px',
'margin-bottom' : '-5px',
'margin-top' : '3px',
'padding' : '-1px',
'z-index' : 200,
}).addclass('gout').append($('<div>').css({ //背景色的div,用于标注周末
'width' : '55px',
'height' : '30px',
'position' : 'absolute',
'margin-top' : '-2px',
'opacity' : 0.07,
}).addclass('weekend')).append($('<div>').css({ //实际的div
'width' : '55px',
'height' : '14px',
'position' : 'absolute',
'margin-top' : '7px',
'z-index' : 200,
}).addclass('gin'));
var weekday = new date(start).getday(); //获取初始日期是星期几 - - 0-6为星期日 -- 星期六
//甘特图绘图填色
for (var k = 0; k < dse; k++) { //在总开始和总结束之间做日期循环
var dc = d.clone();
if ((k + weekday) % 7 == 5 || (k + weekday) % 7 == 6) { //周末标识填充
dc.find('.weekend').css({
'background-color' : 'blue',
'border-left' : '1px inset #ddd',
})
}
if (k > dpss - 1 && k < dpss + dpse) { //计划内容填充
dc.css({
'background-color' : pbackground,
'border-top' : '1px inset ' + pborder,
'border-bottom' : '1px inset ' + pborder,
}).attr('title', '计划进度与实际进度');
if (k == dpss) { //左边界
dc.css('border-left', '1px inset ' + pborder);
dc.find('.gin').html('<div style="position:absolute;top:-3px;padding-left:10px">' + data[i]['persent'] + '</div>'); //完工百分比
dc.attr('sid', data[i]['id']); //标记为开始,查询sid,获取当前的计划的id
}
if (k == dpss + dpse - 1) { //右边界
dc.css('border-right', '1px inset ' + pborder);
dc.attr('eid', data[i]['id']); //标记为结束,查询eid,获取当前的计划的id
}
}
if (k > dass - 1 && k < dass + dase) { //实际内容填充
dc.find('.gin').css({
'background-color' : background,
'border-top' : '1px inset ' + border,
'border-bottom' : '1px inset ' + border,
}).attr('title', '实际进度与实际进度');
if (k == dass) { //左边界
dc.find('.gin').css('border-left', '1px inset ' + border);
}
if (k == dass + dase - 1) { //右边界
dc.find('.gin').css('border-right', '1px inset ' + border);
}
if (dc.css('border-top-width') != '1px') { //是否是只有实际进度,进行margin-top位置调整
dc.find('.gin').css('margin-top', '8px');
}
}
tdu.append(dc)
}
btr.append(tdu)
tbody.append(btr);
}
//写入table顶部工具栏,包括隐藏展示列功能
var optr = $('<tr>');
var hideresetbtn = $('<button>').addclass('btn btn-primary btn-sm').attr('title', '展示所有隐藏项').html('<span class="glyphicon glyphicon-transfer"></span>')
hideresetbtn.click(function() { //全部展示或隐藏的按钮点击函数
if (lyhganttuconfig.labels.planendat.show == false) {
for (var key in lyhganttuconfig.labels) {
if (key != 'projectname' && key != 'planstartat' && key != 'operate') {
lyhganttuconfig.labels[key].show = true;
}
}
} else {
for (var key in lyhganttuconfig.labels) {
if (key != 'projectname' && key != 'planstartat' && key != 'operate') {
lyhganttuconfig.labels[key].show = false;
}
}
}
lyhganttuinit(target); //重新绘图
})
var optdfirst = $('<td>').css('padding', '5px').append(hideresetbtn);
optr.append(optdfirst); //写入重置隐藏项按钮
for (var key in labels) {
if (key != 'projectname' && key != 'planstartat' && key != 'operate') {
var checkspan = $('<span>').addclass('glyphicon glyphicon-check'); //已选择span
var uncheckspan = $('<span>').addclass('glyphicon glyphicon-unchecked'); //未选择span
if (labels[key].show == true) { //该项目要显示,隐藏未选
uncheckspan.hide();
} else {
checkspan.hide();
}
var optbtn = $('<button>').addclass('btn btn-primary btn-sm').html('').append(checkspan).append(uncheckspan).append(labels[key].name)
.attr('title', '隐藏/展示-' + labels[key].name + '列').attr('id', key);
optbtn.click(function() { //表格列工具点击函数
var me = $(this);
var hidecolumid = me.attr('id');
if (lyhganttuconfig.labels[hidecolumid].show == true) { //隐藏
lyhganttuconfig.labels[hidecolumid].show = false;
} else {
lyhganttuconfig.labels[hidecolumid].show = true; //展示
}
lyhganttuinit(target); //重新绘图
})
var optd = $('<td>').css('padding', '5px 10px').append(optbtn);
optr.append(optd);
}
}
//当前进度按钮
var optbtntoday = $('<button>').addclass('btn btn-danger btn-sm').html('<span class="glyphicon glyphicon-pushpin"></span>今天进度').attr('id', key);
optbtntoday.click(function() { //跳转到今天的点击函数
var todaybtn = $('#' + target + ' .table thead tr #date').find('.todaydiv');
todaybtn.prev().prev().click();
})
optr.append($('<td>').css('padding', '5px 10px').append(optbtntoday));
var opt = $('<caption>').append(optr);
//组装table
var thead = $('<thead>').append(htr).css('background-color', '#cccccc');
var table = $('<table>').append(opt).append(thead).append(tbody).addclass('table table-bordered table-hover');
return table;
}
/**
* 根据甘特图生成canvas线条连接linked的函数
*/
function drawlink(target) {
var temp = $('#' + target);
var dw = parseint(temp.find('.table #date').css('width').split('px')[0]);
var offset = temp.find('.table #date').position().left;
var dh = parseint(temp.find('.table').css('height').split('px')[0]) - 80;
var data = lyhganttudata.data;
var canvas = $('<canvas>').css({
'position' : 'absolute',
'top' : '0px',
'left' : '0px',
'z-index' : 10,
'margin-top' : '95px', //高偏移量
'margin-left' : offset + 'px',
}).attr('width', dw + 'px').attr('height', dh + 'px');
//删除target下的所有的canvas
temp.find('canvas').remove()
for (var i = 0; i < data.length; i++) {
var before = data[i]['before'];
var id = data[i]['id'];
if (before.length > 0) {
for (var k = 0; k < before.length; k++) {
var ediv = $('#' + target).find('div[sid=' + id + ']')
var sdiv = $('#' + target).find('div[eid=' + before[k] + ']')
if (ediv.is(':hidden')) { //若已经被隐藏,则不绘制线条
break;
}
var sy = sdiv.position().top - 88; //设置高度偏移量
var sx = sdiv.position().left + 55 - offset; //设置宽度偏移量
var ey = ediv.position().top - 88;
var ex = ediv.position().left - offset;
var c = canvas.clone();
$('#' + target).append(c); //加载画布
var ctx = c[0].getcontext("2d"); //创建画布
//绘制连接线条
ctx.beginpath();
ctx.strokestyle = lyhganttuconfig.linecolor; //绿色线条
ctx.moveto(sx, sy); //起点
ctx.lineto(sx + 15, sy); //右移15
ctx.lineto(sx + 15, sy + 26); //下移32
ctx.lineto(sx - 15, sy + 26); //左移30
ctx.lineto(sx - 15, ey); //下移到终点行
ctx.lineto(ex, ey); //到终点
ctx.stroke(); //描边。stroke不会自动closepath()
//绘制起点球球
ctx.beginpath();
ctx.fillstyle = lyhganttuconfig.linecolor;
ctx.arc(sx, sy, 2, 0, 2 * math.pi, false); //x,y,半径,*,弧长,时针
ctx.fill(); //填充
//绘制终点箭头
ctx.beginpath();
ctx.strokestyle = lyhganttuconfig.linecolor;
ctx.moveto(ex - 7, ey - 3);
ctx.lineto(ex, ey);
ctx.lineto(ex - 7, ey + 3);
ctx.stroke(); //描边。stroke不会自动closepath()
}
}
}
}
var datelabelclickflag = null;
/**
* 以过滤后的日期制作head中的日期div
*/
function lyhganttuheaddivs(target) {
var start = lyhganttuconfig.start;
var end = lyhganttuconfig.end;
var diff = lyhganttudatediff(end, start); //获取时间差
var arr = [];
var temp = null;
for (var i = 0; i < diff; i++) {
if (null == temp) {
var next = lyhganttudateplus(start);
} else {
var next = lyhganttudateplus(temp);
}
temp = next;
var div = $('<div>').css({
'border-left' : '1px solid #ddd',
'display' : 'inline-block',
'padding' : '9px 9px',
'title' : next,
'cursor' : 'pointer',
}).attr('title', next).html(next.substr(5, 5));
div.click(function() { //date题头点击的函数,隐藏之前的所有内容
var me = $(this);
if (datelabelclickflag != me.attr('title')) { //检验第几次点击,第一次点击则隐藏,再次点击则展示之前内容
dateclickhide(target, me); //隐藏内容
datelabelclickflag = me.attr('title'); //更新flag
} else {
dateclickshow(target); //隐藏内容
datelabelclickflag = null; //更新flag
}
})
arr.push(div);
}
return arr; //写回div的jquery的对象的数组
}
/**
* 隐藏点击的日期之前的所有甘特图内容的函数
*/
function dateclickhide(target, me) {
var count = 0;
var temp = me.prev();
while (temp.length != 0) { //隐藏题头
var prev = temp;
temp.hide();
temp = temp.prev();
count++;
}
var trs = $('#' + target + ' tbody tr');
for (var i = 0; i < trs.length; i++) {
var td = $(trs[i]).children("td:last-child");
var divs = td.find('.gout');
for (var k = 0; k < count; k++) {
$(divs[k]).hide();
}
}
drawlink(target); //重新绘制
}
/**
* 展示点击的日期之前的所有甘特图的内容的函数
*/
function dateclickshow(target) {
$('#' + target + ' div').show();
drawlink(target); //重新绘制
}
/**
* 初始化日期,最早时间-5,最长时间+5
*/
function lyhganttuconfigmodifybydate() {
for (var i = 0; i < lyhganttudata.data.length; i++) {
if (lyhganttuconfig.start == '1900/01/01') {
lyhganttuconfig.start = lyhganttudata.data[i].planstartat;
}
if (lyhganttuconfig.end == '1900/01/10') {
lyhganttuconfig.end = lyhganttudata.data[i].planendat;
}
if (str2date(lyhganttuconfig.start, '/').gettime() > str2date(lyhganttudata.data[i].planstartat, '/').gettime()) {
lyhganttuconfig.start = lyhganttudata.data[i].planstartat;
}
if (str2date(lyhganttuconfig.start, '/').gettime() > str2date(lyhganttudata.data[i].startat, '/').gettime()) {
lyhganttuconfig.start = lyhganttudata.data[i].startat;
}
if (str2date(lyhganttuconfig.end, '/').gettime() < str2date(lyhganttudata.data[i].planendat, '/').gettime()) {
lyhganttuconfig.end = lyhganttudata.data[i].planendat;
}
if (str2date(lyhganttuconfig.end, '/').gettime() < str2date(lyhganttudata.data[i].endat, '/').gettime()) {
lyhganttuconfig.end = lyhganttudata.data[i].endat;
}
}
lyhganttuconfig.start = lyhganttudate(new date(str2date(lyhganttuconfig.start, '/').gettime() - (3 * 24 * 60 * 60 * 1000)))
lyhganttuconfig.end = lyhganttudate(new date(str2date(lyhganttuconfig.end, '/').gettime() + (8 * 24 * 60 * 60 * 1000)))
}
/**
* json date转换日期工具
*/
function lyhganttudatestr(datestr) {
var date = str2date(datestr, '-');
var year = date.getfullyear().tostring();
var month = (date.getmonth() + 1) <= 9 ? "0"
+ (date.getmonth() + 1) : (date.getmonth() + 1);
var day = date.getdate() <= 9 ? "0" + date.getdate() : date
.getdate();
return year + "/" + month + "/" + day;
}
/**
* json date转换日期工具    date 对象转化为固定格式/日期的函数
*/
function lyhganttudate(date) {
var year = date.getfullyear().tostring();
var month = (date.getmonth() + 1) <= 9 ? "0"
+ (date.getmonth() + 1) : (date.getmonth() + 1);
var day = date.getdate() <= 9 ? "0" + date.getdate() : date
.getdate();
return year + "/" + month + "/" + day;
}
/**
* 固定格式的字符串转换成date格式函数
*/
function str2date(datestr, separator) {
if (!separator) {
separator = "/";
}
var datearr = datestr.split(separator);
var year = parseint(datearr[0]);
var month;
//处理月份为04这样的情况
if (datearr[1].indexof("0") == 0) {
month = parseint(datearr[1].substring(1));
} else {
month = parseint(datearr[1]);
}
var day = parseint(datearr[2]);
var date = new date(year, month - 1, day);
return date;
}
/**
* 计算两个日期之间的天数
*/
function lyhganttudatediff(datestr1, datestr2) { //sdate1和sdate2是2006-12-18格式
var datespan,
tempdate,
idays;
datestr1 = date.parse(datestr1);
datestr2 = date.parse(datestr2);
datespan = datestr2 - datestr1;
datespan = math.abs(datespan);
idays = math.floor(datespan / (24 * 3600 * 1000));
return idays
}
/**
* 当前日期时间以原格式+1的函数
*/
function lyhganttudateplus(datestr, days) {
var date = str2date(datestr);
if (days == undefined || days == '') {
days = 1;
}
date.setdate(date.getdate() + days); //日期+1
var year = date.getfullyear().tostring();
var month = (date.getmonth() + 1) <= 9 ? "0"
+ (date.getmonth() + 1) : (date.getmonth() + 1);
var day = date.getdate() <= 9 ? "0" + date.getdate() : date
.getdate();
return year + "/" + month + "/" + day;
}
</script>
</html>

(4)在controller层中利用http请求传参

@requestmapping(value = "/gantee",method = requestmethod.get)
public string gantee(model model) throws jsonexception {
renwu renwu = renwuservice.querybyid(new integer("1"));
map jsondata = new hashmap();
list<map> jsonarray = new arraylist<>();
map jsonobject = new hashmap();
integer id = renwu.getprojectid();
integer  pid = renwu.getpid();
string projectname = renwu.getprojectname();
string projectcode = renwu.getprojectcode();
simpledateformat dateformat = new simpledateformat("yyyy/mm/dd");
date planstartdate = renwu.getplanstartat();
date planenddate = renwu.getplanendat();
date startdate = renwu.getstartat();
date enddate = renwu.getendat();
string planstartstr = dateformat.format(planstartdate);
string planendstr = dateformat.format(planenddate);
string startstr = dateformat.format(startdate);
string endstr = dateformat.format(enddate);
string persent = renwu.getpersent();
string resps = renwu.getresps();
string actors = renwu.getactors();
string insiders = renwu.getinsiders();
integer dur = renwu.getdur();
integer before = renwu.getbefore();
jsonobject.put("id",id);
jsonobject.put("pid",pid);
jsonobject.put("projectname",projectname);
jsonobject.put("projectcode",projectcode);
jsonobject.put("planstartat",planstartstr);
jsonobject.put("planendat",planendstr);
jsonobject.put("startat",startstr);
jsonobject.put("endat",endstr);
jsonobject.put("persent",persent);
jsonobject.put("resps",resps);
jsonobject.put("actors",actors);
jsonobject.put("insiders",insiders);
jsonobject.put("dur",dur);
jsonobject.put("before",new object[]{before});
jsonarray.add(jsonobject);
jsondata.put("data",jsonarray);
model.addattribute("lyhganttudata",jsondata);
return "ganttu";
}

(5)直接启动springboot项目即可。

这个是springboot项目,自然也是可以转到springcloud的子项目中。

  注意:html并不是我原创没我只是在其基础上改了一下js。在这个开放的时代,我觉得大家应该把学到的东西开放出来,不管多好或是很差。

到此这篇关于springboot+thymeleaf+mybatis实现甘特图的详细过程的文章就介绍到这了,更多相关springboot+thymeleaf+mybatis实现甘特图内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!