亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

springboot+thymeleaf+mybatis實(shí)現(xiàn)甘特圖的詳細(xì)過(guò)程

瀏覽:77日期:2023-02-25 08:27:38

首先我們要明白:這個(gè)甘特圖需要哪些動(dòng)態(tài)數(shù)據(jù)。

(1)需要:ID,tName,number,計(jì)劃開(kāi)始時(shí)間,開(kāi)始時(shí)間,計(jì)劃結(jié)束時(shí)間,結(jié)束時(shí)間,項(xiàng)目負(fù)責(zé)人,參與人,知情人ID,計(jì)劃時(shí)長(zhǎng)(可以計(jì)算得出的,不必在數(shù)據(jù)庫(kù)中);前置任務(wù);項(xiàng)目進(jìn)度,該任務(wù)屬于哪個(gè)任務(wù)

springboot+thymeleaf+mybatis實(shí)現(xiàn)甘特圖的詳細(xì)過(guò)程

(2)然后利用easycode插件生成實(shí)體類(lèi),映射類(lèi),服務(wù)類(lèi),ontCroller等

(3)利用bootstrap框架做出甘特圖的樣式,寫(xiě)好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='甘特圖的實(shí)際進(jìn)度與計(jì)劃進(jìn)度可能不符,為了展示實(shí)際進(jìn)度與計(jì)劃進(jìn)度的差異和方便統(tǒng)計(jì),自己寫(xiě)了個(gè)甘特圖框架' /> <meta name='mast' content='使用代碼之前請(qǐng)留言,禁止轉(zhuǎn)載...' /> <meta name='description' content='liuyuhang 的甘特圖,當(dāng)前版本1.0,2019-02-19' /> <meta name='description' content='時(shí)間日期格式:yyyy-mm-dd' /> <meta name='description' content='①計(jì)劃進(jìn)度與實(shí)際進(jìn)度雙重進(jìn)度體系' /> <meta name='description' content='②有前置任務(wù)連接線' /> <meta name='description' content='③可修改圖顏色' /> <meta name='description' content='④可隱藏與展示列' /> <meta name='description' content='⑤可隱藏域展示子項(xiàng)目' /> <meta name='description' content='⑥可跳轉(zhuǎn)時(shí)間到當(dāng)前時(shí)間' /> <meta name='description' content='⑦可從當(dāng)前項(xiàng)目開(kāi)始時(shí)間查看' /> <meta name='description' content='⑦可隱藏某時(shí)間之前的內(nèi)容' /> <meta name='warning' content='⑧未做圖拖拽,并不打算做...' /> <meta name='author' content='liuyuhang 13501043063' /> <!-- 只引用了這些,其余的并沒(méi)有引用 --> <link 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’ > <div style=’display: inline;font-size: 30px;font-weight: normal;padding: 5px 15px;’>甘特圖面板</div> <div id=’ganttu-index-projectName’>此項(xiàng)目 名稱(chēng)...</div> <div id=’ganttu-index-projectDesc’>此項(xiàng)目描述...</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;’> <!-- 甘特圖放到了這個(gè)div中 --> <div 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}]];/** * 甘特圖設(shè)置,變量名固定 */ var lyhGanttuConfig = {start : ’1900/01/01’, //初始化開(kāi)始時(shí)間配置 - 別在意end : ’1900/01/10’, //初始化結(jié)束時(shí)間配置 - 別在意planBorder : ’#1a8cff’, //計(jì)劃進(jìn)度的border顏色planBackground : ’#80bfff’, //計(jì)劃進(jìn)度的back顏色border : ’#ffaa00’, //實(shí)際進(jìn)度的border染顏色background : ’#ffcc66’, //實(shí)際進(jìn)度的back顏色lineColor : ’green’, //前置任務(wù)線顏色//表格中的thead的題頭設(shè)置,可按照格式任意添加或減少labels : { ’projectName’ : {’name’ : ’ 任務(wù)名 ’,’show’ : true, }, //任務(wù)名 ’projectCode’ : {’name’ : ’編號(hào)’,’show’ : true, }, //編號(hào) ’planStartAt’ : {’name’ : ’計(jì)劃開(kāi)始’,’show’ : true, }, //計(jì)劃開(kāi)始時(shí)間 ’planEndAt’ : {’name’ : ’計(jì)劃結(jié)束’,’show’ : false, }, //計(jì)劃結(jié)束時(shí)間 ’startAt’ : {’name’ : ’實(shí)際開(kāi)始’,’show’ : false, }, //實(shí)際開(kāi)始時(shí)間 ’endAt’ : {’name’ : ’實(shí)際結(jié)束’,’show’ : false, }, //實(shí)際結(jié)束時(shí)間 ’persent’ : {’name’ : ’完成比例’,’show’ : true, }, //完工百分比 ’dur’ : {’name’ : ’時(shí)長(zhǎng)’,’show’ : true, }, //持續(xù)時(shí)間 ’resps’ : {’name’ : ’負(fù)責(zé)人’,’show’ : true, }, //負(fù)責(zé)人 ’actors’ : {’name’ : ’參與人’,’show’ : true, }, //參與人 ’insiders’ : {’name’ : ’知情人’,’show’ : false, }, //知情人 ’before’ : {’name’ : ’前置任務(wù)’,’show’ : false, }, //前置任務(wù) ’operate’ : {’name’ : '<button title=’新建計(jì)劃’ 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=’修改此計(jì)劃’ class=’btn btn-primary btn-xs’><span class=’glyphicon glyphicon-edit’ style=’margin-right:0px’></span></button>';} } //================ //以下為甘特圖本身的繪圖代碼,調(diào)用lyhGanttuInit,參數(shù)為要加載甘特圖的id //請(qǐng)使用谷歌瀏覽器,縮放倍數(shù)為100% /** * 甘特圖初始化函數(shù) */ function lyhGanttuInit(target) {//重置日期設(shè)置緩存lyhGanttuConfig.start = ’1900/01/01’;lyhGanttuConfig.end = ’1900/01/10’;lyhGanttuConfigModifyByDate(); //過(guò)濾所有時(shí)間,獲取時(shí)間長(zhǎng)度lyhGanttuDataModifyByOperate(); //添加點(diǎn)修改或新增數(shù)據(jù)按鈕var table = lyhGanttuTable(target);$(’#’ + target).html(table);drawLink(target); //線條初始化//提示工具初始化$(’#’ + target).find(’[title]’).attr(’data-toggle’, ’tooltip’).attr(’data-placement’, ’right’);$('[data-toggle=’tooltip’]').tooltip();//標(biāo)記todayvar 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 ’)))} } /** * 繪制甘特圖基礎(chǔ)函數(shù) */ function lyhGanttuTable(target) {var htr = $(’<tr>’).addClass(’text-center’);var labels = lyhGanttuConfig.labels; //head的標(biāo)簽jsonvar start = lyhGanttuConfig.start; //總開(kāi)始時(shí)間var end = lyhGanttuConfig.end; //總結(jié)束時(shí)間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() { //展開(kāi)或隱藏所以有任務(wù)卡點(diǎn)擊函數(shù) var me = $(this); var indexBtnDown = me.find(’.glyphicon-chevron-down’); //轉(zhuǎn)開(kāi)狀態(tài) var indexBtnRight = me.find(’.glyphicon-chevron-right’); //隱藏狀態(tài) var meTrs = $(’#’ + target + ’ .table tr’); var meTdsHide = meTrs.find(’div[hideId]’); if (indexBtnRight.is(’:hidden’)) { //若當(dāng)前為展開(kāi)狀態(tài),則隱藏,同時(shí)調(diào)整按鈕meTdsHide.parent().parent().hide(300);indexBtnRight.show();indexBtnDown.hide(); } else { //當(dāng)前為隱藏狀態(tài),則展開(kāi)meTdsHide.parent().parent().show(300);indexBtnRight.hide();indexBtnDown.show(); } setTimeout(function() { //重新繪圖drawLink(’lyh-ganttu’); }, 400)})var index = $(’<td>’).append(indexBtn);htr.append(index); //添加index//循環(huán)添加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);//添加甘特圖的數(shù)據(jù)內(nèi)容var tbody = $(’<tbody>’)var data = lyhGanttuData.data;for (var i = 0; i < data.length; i++) { //寫(xiě)入展開(kā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’, ’展開(kāi)/隱藏-計(jì)劃’).attr(’id’, data[i][’id’]);plusBtn.click(function() { //任務(wù)展開(kāi)與隱藏按鈕點(diǎn)擊函數(shù) var me = $(this); var meId = me.attr(’id’); var meTrs = $(’#’ + target + ’ .table tr’); var meTdsHide = meTrs.find(’div[hideId=’ + meId + ’]’); if (meTdsHide.is(’:hidden’)) { //已經(jīng)隱藏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) //寫(xiě)入數(shù)據(jù) for (var label in labels) {for (var key in data[i]) { if (label == key) {if (label.indexOf(’At’) > -1) { //若是時(shí)間數(shù)據(jù),則截取一下 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’) { //負(fù)責(zé)人,參與人,知情人加載 var tda = $(’<td>’).css(’padding’, ’5px’).append($(’<div>’).addClass(key).html(data[i][key][0]).attr(’title’, data[i][key]));} else if (label == ’before’) { //前置任務(wù) 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(’無(wú)’); } 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() { //對(duì)planStartAt添加點(diǎn)擊函數(shù)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; }} } //寫(xiě)入圖信息 var ps = data[i][’planStartAt’]; //計(jì)劃開(kāi)始時(shí)間 var pe = data[i][’planEndAt’]; //計(jì)劃結(jié)束時(shí)間 var dpss = lyhGanttuDateDiff(start, ps) - 1; //計(jì)劃開(kāi)始時(shí)間和總開(kāi)始時(shí)間的時(shí)間差 var dpse = lyhGanttuDateDiff(ps, pe) + 1; //計(jì)劃開(kāi)始時(shí)間和計(jì)劃結(jié)束時(shí)間的時(shí)間差 var dse = lyhGanttuDateDiff(start, end); //總開(kāi)始和總結(jié)束時(shí)間差 var as = data[i][’startAt’]; //實(shí)際開(kāi)始時(shí)間 var ae = data[i][’endAt’]; //實(shí)際結(jié)束時(shí)間 var dass = lyhGanttuDateDiff(start, as) - 1; //實(shí)際開(kāi)始時(shí)間和總開(kāi)始時(shí)間的時(shí)間差 var dase = lyhGanttuDateDiff(as, ae) + 1; //實(shí)際開(kāi)始時(shí)間和實(shí)際結(jié)束時(shí)間的時(shí)間差 var tdu = $(’<td>’).css(’padding’, ’0px’).css(’max-height’, ’38px’); var d = $(’<div>’).css({ //計(jì)劃的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,用于標(biāo)注周末’width’ : ’55px’,’height’ : ’30px’,’position’ : ’absolute’,’margin-top’ : ’-2px’,’opacity’ : 0.07, }).addClass(’weekend’)).append($(’<div>’).css({ //實(shí)際的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++) { //在總開(kāi)始和總結(jié)束之間做日期循環(huán)var dc = d.clone();if ((k + weekDay) % 7 == 5 || (k + weekDay) % 7 == 6) { //周末標(biāo)識(shí)填充 dc.find(’.weekend’).css({’background-color’ : ’blue’,’border-left’ : ’1px inset #ddd’, })}if (k > dpss - 1 && k < dpss + dpse) { //計(jì)劃內(nèi)容填充 dc.css({’background-color’ : pBackground,’border-top’ : ’1px inset ’ + pBorder,’border-bottom’ : ’1px inset ’ + pBorder, }).attr(’title’, ’計(jì)劃進(jìn)度與實(shí)際進(jìn)度’); 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’]); //標(biāo)記為開(kāi)始,查詢(xún)sid,獲取當(dāng)前的計(jì)劃的id } if (k == dpss + dpse - 1) { //右邊界dc.css(’border-right’, ’1px inset ’ + pBorder);dc.attr(’eId’, data[i][’id’]); //標(biāo)記為結(jié)束,查詢(xún)eid,獲取當(dāng)前的計(jì)劃的id }}if (k > dass - 1 && k < dass + dase) { //實(shí)際內(nèi)容填充 dc.find(’.Gin’).css({’background-color’ : background,’border-top’ : ’1px inset ’ + border,’border-bottom’ : ’1px inset ’ + border, }).attr(’title’, ’實(shí)際進(jìn)度與實(shí)際進(jìn)度’); 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’) { //是否是只有實(shí)際進(jìn)度,進(jìn)行margin-top位置調(diào)整dc.find(’.Gin’).css(’margin-top’, ’8px’); }}tdu.append(dc) } btr.append(tdu) tbody.append(btr);}//寫(xiě)入table頂部工具欄,包括隱藏展示列功能var optr = $(’<tr>’);var hideResetBtn = $(’<button>’).addClass(’btn btn-primary btn-sm’).attr(’title’, ’展示所有隱藏項(xiàng)’).html(’<span class='glyphicon glyphicon-transfer'></span>’)hideResetBtn.click(function() { //全部展示或隱藏的按鈕點(diǎn)擊函數(shù) 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); //寫(xiě)入重置隱藏項(xiàng)按鈕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) { //該項(xiàng)目要顯示,隱藏未選 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() { //表格列工具點(diǎn)擊函數(shù) 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); }}//當(dāng)前進(jìn)度按鈕var optBtnToday = $(’<button>’).addClass(’btn btn-danger btn-sm’).html(’<span class='glyphicon glyphicon-pushpin'></span>今天進(jìn)度’).attr(’id’, key);optBtnToday.click(function() { //跳轉(zhuǎn)到今天的點(diǎn)擊函數(shù) 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; } /** * 根據(jù)甘特圖生成canvas線條連接linked的函數(shù) */ 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’)) { //若已經(jīng)被隱藏,則不繪制線條break; } var sy = sDiv.position().top - 88; //設(shè)置高度偏移量 var sx = sDiv.position().left + 55 - offset; //設(shè)置寬度偏移量 var ey = eDiv.position().top - 88; var ex = eDiv.position().left - offset; var c = canvas.clone(); $(’#’ + target).append(c); //加載畫(huà)布 var ctx = c[0].getContext('2d'); //創(chuàng)建畫(huà)布 //繪制連接線條 ctx.beginPath(); ctx.strokeStyle = lyhGanttuConfig.lineColor; //綠色線條 ctx.moveTo(sx, sy); //起點(diǎn) 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); //下移到終點(diǎn)行 ctx.lineTo(ex, ey); //到終點(diǎn) ctx.stroke(); //描邊。stroke不會(huì)自動(dòng)closePath() //繪制起點(diǎn)球球 ctx.beginPath(); ctx.fillStyle = lyhGanttuConfig.lineColor; ctx.arc(sx, sy, 2, 0, 2 * Math.PI, false); //x,y,半徑,*,弧長(zhǎng),時(shí)針 ctx.fill(); //填充 //繪制終點(diǎn)箭頭 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不會(huì)自動(dòng)closePath()} }} } var dateLabelClickFlag = null; /** * 以過(guò)濾后的日期制作head中的日期div */ function lyhGanttuHeadDivs(target) {var start = lyhGanttuConfig.start;var end = lyhGanttuConfig.end;var diff = lyhGanttuDateDiff(end, start); //獲取時(shí)間差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題頭點(diǎn)擊的函數(shù),隱藏之前的所有內(nèi)容var me = $(this);if (dateLabelClickFlag != me.attr(’title’)) { //檢驗(yàn)第幾次點(diǎn)擊,第一次點(diǎn)擊則隱藏,再次點(diǎn)擊則展示之前內(nèi)容 dateClickHide(target, me); //隱藏內(nèi)容 dateLabelClickFlag = me.attr(’title’); //更新flag} else { dateClickShow(target); //隱藏內(nèi)容 dateLabelClickFlag = null; //更新flag} }) arr.push(div);}return arr; //寫(xiě)回div的jquery的對(duì)象的數(shù)組 } /** * 隱藏點(diǎn)擊的日期之前的所有甘特圖內(nèi)容的函數(shù) */ 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); //重新繪制 } /** * 展示點(diǎn)擊的日期之前的所有甘特圖的內(nèi)容的函數(shù) */ function dateClickShow(target) {$(’#’ + target + ’ div’).show();drawLink(target); //重新繪制 } /** * 初始化日期,最早時(shí)間-5,最長(zhǎng)時(shí)間+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轉(zhuǎn)換日期工具 */ 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轉(zhuǎn)換日期工具 date 對(duì)象轉(zhuǎn)化為固定格式/日期的函數(shù) */ 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; } /** * 固定格式的字符串轉(zhuǎn)換成date格式函數(shù) */ 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; } /** * 計(jì)算兩個(gè)日期之間的天數(shù) */ 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 } /** * 當(dāng)前日期時(shí)間以原格式+1的函數(shù) */ 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>

(4)在Controller層中利用Http請(qǐng)求傳參

@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)直接啟動(dòng)SpringBoot項(xiàng)目即可。

springboot+thymeleaf+mybatis實(shí)現(xiàn)甘特圖的詳細(xì)過(guò)程

這個(gè)是Springboot項(xiàng)目,自然也是可以轉(zhuǎn)到SpringCloud的子項(xiàng)目中。

注意:HTML并不是我原創(chuàng)沒(méi)我只是在其基礎(chǔ)上改了一下JS。在這個(gè)開(kāi)放的時(shí)代,我覺(jué)得大家應(yīng)該把學(xué)到的東西開(kāi)放出來(lái),不管多好或是很差。

到此這篇關(guān)于springboot+thymeleaf+mybatis實(shí)現(xiàn)甘特圖的詳細(xì)過(guò)程的文章就介紹到這了,更多相關(guān)springboot+thymeleaf+mybatis實(shí)現(xiàn)甘特圖內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 免费一级美国片在线观看 | 九九精品视频在线播放8 | 成年片免费网址网站 | 日本欧美大码aⅴ在线播放 日本欧美不卡一区二区三区在线 | 精字窝地址二永久2021 | 久久婷婷色综合老司机 | 在线观看黄色 | 青青操夜夜操 | 亚洲三级久久 | 美女亚洲综合 | 久久精品视 | 国产福利一区二区在线精品 | 亚洲人和日本人jizz | 国产视频资源在线观看 | 免费vip影院 | 亚洲99久久无色码中文字幕 | 小蝌蚪亚洲精品国产 | 亚洲一二区视频 | 永久免费视频v片www | 欧美一区二区三区视频 | 微拍秒拍99福利精品小视频 | 香蕉视频免费在线 | 大学生久久香蕉国产线看观看 | 草草在线影院 | 亚洲国产精品综合福利专区 | 国产三级在线播放不卡 | 中文字幕黄色片 | 久久综合九九亚洲一区 | 日韩国产| 黄片毛片视频 | 2020阿v天堂网手机版 | 国产成人www | 激情五月色婷婷色综合 | 精品毛片视频 | 国产黄视频在线观看 | 国产在线视频精品视频免费看 | 一本一本久久a久久精品综合麻豆 | 国产精品污视频 | 奇米影视大全 | 麻豆视频在线免费 | 91在线网站|