十一、甘特图

简单甘特图

Highcharts.chart('container', {chart: {type: 'xrange'},title: {text: '简易甘特图'},xAxis: {type: 'datetime',dateTimeLabelFormats: {week: '%Y/%m/%d'}},yAxis: {title: {text: ''},categories: ['制作产品原型', '开发', '测试'],reversed: true},tooltip: {dateTimeLabelFormats: {day: '%Y/%m/%d'}},series: [{name: '项目1',// pointPadding: 0,// groupPadding: 0,borderColor: 'gray',pointWidth: 20,data: [{x: Date.UTC(2014, 10, 21),x2: Date.UTC(2014, 11, 2),y: 0,partialFill: 0.25}, {x: Date.UTC(2014, 11, 2),x2: Date.UTC(2014, 11, 5),y: 1}, {x: Date.UTC(2014, 11, 8),x2: Date.UTC(2014, 11, 9),y: 2}, {x: Date.UTC(2014, 11, 9),x2: Date.UTC(2014, 11, 19),y: 1}, {x: Date.UTC(2014, 11, 10),x2: Date.UTC(2014, 11, 23),y: 2}],dataLabels: {enabled: true}}]
});

代码:

<!DOCTYPE html>
<html>
<head>
<title>ganttu.html</title>
<meta name="keywords" content="keyword1,keyword2,keyword3">
<meta name="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="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'><div style='display: inline;font-size: 30px;font-weight: 430;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">$(function() {lyhGanttuInit('lyh-ganttu'); //甘特图初始化})/*** 甘特图数据,变量名固定*/var lyhGanttuData = {data : [{'id' : 1,'pid' : 0,'projectName' : '任务1','projectCode' : 'task01','planStartAt' : '2019/02/01','planEndAt' : '2019/02/11','startAt' : '2019/1/31','endAt' : '2019/02/12','persent' : '100%','resps' : [ '刘宇航' ],'actors' : [ '刘宇航a' ],'insiders' : [ '刘宇航i' ],'dur' : 3, //计划时间跨度'before' : [], //前置任务id},{'id' : 2,'pid' : 1,'projectName' : '任务2','projectCode' : 'task02','planStartAt' : '2019/02/01','planEndAt' : '2019/02/03','startAt' : '2019/1/31','endAt' : '2019/02/04','persent' : '100%','resps' : [ '刘宇航2' ],'actors' : [ '刘宇航b' ],'insiders' : [ '刘宇航j' ],'dur' : 4,'before' : [],},{'id' : 3,'pid' : 1,'projectName' : '任务3','projectCode' : 'task03','planStartAt' : '2019/02/04','planEndAt' : '2019/02/07','startAt' : '2019/02/05','endAt' : '2019/02/07','persent' : '100%','resps' : [ '张三', '李四', '王五' ],'actors' : [ '张三a', '李四b', '王五c' ],'insiders' : [ '刘宇航k', '刘宇航f' ],'dur' : 4,'before' : [ 2 ],},{'id' : 4,'pid' : 1,'projectName' : '任务4','projectCode' : 'task04','planStartAt' : '2019/02/08','planEndAt' : '2019/02/11','startAt' : '2019/02/08','endAt' : '2019/02/12','persent' : '100%','resps' : [ '李四', '王五' ],'actors' : [ '李四b', '王五c' ],'insiders' : [ '刘宇航k', '刘宇航f' ],'dur' : 4,'before' : [ 2, 3 ],},]}/*** 甘特图设置,变量名固定*/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' : '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;任务名&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;','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.datafor (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('&nbsp;today&nbsp;')))}}/*** 绘制甘特图基础函数*/function lyhGanttuTable(target) {var htr = $('<tr>').addClass('text-center');var labels = lyhGanttuConfig.labels; //head的标签jsonvar 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//循环添加labelfor (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'); //已选择spanvar uncheckSpan = $('<span>').addClass('glyphicon glyphicon-unchecked'); //未选择spanif (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);//组装tablevar 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下的所有的canvastemp.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); //右移15ctx.lineTo(sx + 15, sy + 26); //下移32ctx.lineTo(sx - 15, sy + 26); //左移30ctx.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); //日期+1var 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>

JS,统计图表大全--十一、甘特图相关推荐

  1. 强大js web甘特图制作之甘特图组件和数据对象

    引用CSS和JS 使用EdoGantt是一件简单轻松的事,首先我们在HTML页面内引用CSS和JS: <!--edo css--><link href="http://ww ...

  2. js通过开始时间和结束时间计算出中间的所有日期,并且转换为层级结构数组对象,用于甘特图头部日期数据

    写在前面: 先看下最终数据结构展示 time('2020-10-01', '2021-01-06') 需要根据一个开始日期和一个结束日期最后返回以下数组对象 [最外层数组里的每个对象代表了某一年的所有 ...

  3. 【Vue.JS】纯 Vue.js 制作甘特图

    效果图 在线预览 GitHub链接(包含 knockoutJS 版本与 Vue 版本) 推荐组合效果 推荐与双表头固定效果组合,实现如上例中横表头(日期)纵向固定,纵表头(类型)横向固定效果. 参照连 ...

  4. Highcharts Gantt JS 现代 Web 开发的甘特图

    Highcharts Gantt JS 现代 Web 开发的甘特图 现代 不要使用过时的专有桌面解决方案.Java Applet 或 Flash 来为您的项目带来甘特图功能.Highcharts Ga ...

  5. html5 统计图表曲线坐标,js统计图表FineReport多维度坐标轴图

    js统计图表FineReport多维度坐标轴图 1. 描述 多维度坐标轴图是指在图表中展示多个维度,不仅仅局限于2个维度(展示2个维度只能比较一个维度之间的数据),可以在同一张图表中同时比较2个或2个 ...

  6. 最优的JS甘特图插件【转载】

    甘特图(ant-gantt) 在项目管理中,甘特图的可视化操作界面,可以让项目规划与风险把控更便捷与清晰,同时该插件是一款基于HTML5.javasrcipt的一款js插件,支持在当前主流的前端框架中 ...

  7. 强大js web甘特图制作之甘特图的日历

    简单的项目日历 比如,有一个项目日历是这样的:星期1.星期3.星期5是工作日,其他是非工作日. 我们需要这样处理: //甘特图项目日历背景dataGantt.isWorkingDate = funct ...

  8. html 绘制甘特图,基于JS简单甘特图

    最近同事求助到一个小小的需求,写一个时间甘特图,主要想表现一个车在一天的不同的时间点里,停靠的站点, 先来看一下效果吧,这里的需求是从早上的5点为开始时间,到第二天到凌晨5点 前期准备 其实网上有很多 ...

  9. html 甘特图_甘特图该如何部署

    部署甘特图 在我们的安装中<install path="">Src文件夹下的文件通常应该在您的web页面中引用,并且也应该部署在您的服务器中.</install& ...

  10. 一起来了解React的四种优秀甘特图方案(下篇)

    接上篇!!! 3. DHTMLX Gantt(https://dhtmlx.com/docs/products/dhtmlxGantt/) 作为一款功能齐全的甘特图工具,DHTMLX Gantt能够实 ...

最新文章

  1. 自动化测试的优势和局限性有哪些
  2. k-近邻算法之距离度量
  3. Netty详解(六):Netty 编解码技术
  4. Java中如何生成jar(框架)
  5. hdu-2204 Eddy's爱好 nyoj 526
  6. java学习(4):第一个java程序
  7. C语言 局部变量 - C语言零基础入门教程
  8. python动物代码大全_python爬虫代码大全
  9. html 表格_HTML -- 表格结构
  10. python接口自动化 post请求,body 带headers参数
  11. Android Theme主题继承(SDK下主题和v7包下主题)
  12. Java-设计模式之调停者模式
  13. java写ansi_java实现utf8转换ansi
  14. 软件测试怎么测微信朋友圈,面试题:软件测试,如何测微信的朋友圈?
  15. 判断数是否为素数与素数输出
  16. 规则引擎 Drools:规则引擎概述
  17. [UWP]使用Acrylic(亚克力)
  18. Python基础知识:def创建函数
  19. MySQL的TIMESTAMP数据类型
  20. java实现日记本功能

热门文章

  1. HDUOJ---汉洛塔IX
  2. 记录每天背的单词,准备考研。(4月11日)
  3. 新赛季的中超和国安,荆棘中前行
  4. oracle failover mode,Oracle RAC FailOver配置
  5. 匹配 网络 Q值 带宽
  6. SAS逻辑回归之二分类
  7. java海贼王_Java 学以致用--为我的海贼王统一命名
  8. ssh-keygen命令详解
  9. 别人总结归纳很全的三方库
  10. 隔离太无聊!不如用Python实现愤怒的小鸟,看看能否通关!