vue專案中的elementui的表格中畫甘特圖
阿新 • • 發佈:2019-01-24
最近的專案要求甘特圖在elementui中實現,在此做出總結。
效能限制,不能傳入太多的資料。
條件(時間):計劃開始時間、計劃結束時間、開始時間、結束時間、最大時間和最小時間。
思維:渲染表格頭、渲染天數、填充色塊。
- 實現簡單的表格
<el-table :data = "tableData" border > <el-table-column label="序號" type="index" align="center" width="40" ></el-table-column> <el-table-column label="計劃開始時間" prop="planned_start" align="center" width="110" > <template slot-scope="scope"> <span>{{ scope.row.planned_start }}</span> </template> </el-table-column> <el-table-column label="計劃結束之間" prop="planned_end" align="center" width="100" > <template slot-scope="scope"> <span>{{ scope.row.planned_end }}</span> </template> </el-table-column> <el-table-column label="實際開始時間" prop="start_date" align="center" width="110" > <template slot-scope="scope"> <span>{{ scope.row.start_datet }}</span> </template> </el-table-column> <el-table-column label="實際結束時間" prop="end_date" align="center" width="110" > <template slot-scope="scope"> <span>{{ scope.row.end_date }}</span> </template> </el-table-column> <el-table-column v-for="(item, index) in showMonths" :label="item.month" // 渲染月份 prop="showMonths" align="center" :key="index" > <el-table-column v-for="(it, index1) in item.daysArr" :label="it.day" width="20" style="padding: 0; margin: 0;" align="center" :key="index1" > <template slot-scope="scope1" class="progressCon"> <div :class="scope1.row['s-' + item.str + '-' + it.day] ? 'progressUpon' : '' "></div> <div :class="scope1.row['t-' + item.str + '-' + it.day] ? 'progressDownon' : '' "></div> </template> </el-table-column> </el-table-column> </el-table>
- 兩個樣式
.el-table--enable-row-transition .el-table__body td{ position: relative; } .progressCon{ padding: 0; margin: 0; position: relative; } ,progressUpon{ background: rgb(38, 84, 124); height: 10px; width: 20px; z-index: 3; position: absolute; top: 8px; } ,progressDownon{ background: rgb(255,209,102); height: 10px; width: 20px; z-index: 3; position: absolute; top: 25px; left: 0px; }
- 實現方法
設:最小時間為startDate、最大時間為endDate、表格資料為tableData;
// 渲染表格頭,首先是年月,如2018年11月 getChartTitle(startDate, endDate){ var chartTable = this.tableDate; for(var i = 0; i < chartTable.length; i++){ var planStartDate = chartTable[i].planned_start; var planEndDate = chartTable[i].planned_end; var realStartDate = chartTable[i].start_date; var realEndDate = chartTable[i].end_date; var mainObj = chartTable[i]; var allPlanArr = this.getAll(planStartDate, planEndDate); // 獲取兩段時間中的所有日期,新增到資料的表格中 if(allPlanArr){ for(var j = 0; i < allPlanArr.length; j++){ var objIndex = "s-" + allPlanArr[j]' mainObj[objIndex] = true; } } var all RealArr = this.getAll(realStartDate, realEndDate); if(allRealArr){ for(var j = 0; j < allRealArr.length; j++){ var objIndex = "t-" + allRealArr[j]; mainObj[objIndex] = true; } } } // 以下操作把資料放到表格中 var dateArr = this.getAll(startDate, endDate); // 表格上方的標題和日期 this.getYearArr(dateArr); //獲取並拼接我們需要的年月資訊。 var allYearArr = this.getYearArr(dateArr); var allMonths = []' for(var i = 0; i < allYearArr.length; i++){ for(var j = 0; j < allYearArr[i]/days.length; j++){ allMonths.push(allYearArr[i].days[j]); } } this.showMonths = allMonths; // 渲染表格上部的標題 } // 獲取時間陣列的函式 getAll(begin, end){ // 開始時間和結束時間有不存在的 if(!begin || !end){ return false; } // 獲取兩個日期之間的所有日期 Date.prototype.format = function(){ var s = ""; var month = this.getMonth() + 1; var day = this.getDate(); s += this.getFullYear() + '-'; s += month + '-'; s += day; return s; // 返回可以prop進表格的資料如:'s-2018-11-19' } var ab = begin.split('-'); var ae = end.split('-'); var db = new Date(); db.setUTCFullYear(ab[0], ab[1] - 1, ab[2]); var de = new Date(); de.setUTCFullYear(ae[0], ae[1] - 1, ae[2]); var unixDb = db.getTime(); var unixDe = de.getTime(); var arr = []; for(var k = unixDb, k <= unixDe; ){ // 開始的時間戳,結束的時間戳 arr.push(new Date(parseInt(k)).format()); k = k + 24 * 60 * 60 * 1000; } return arr; } // 獲取我們需要的格式的年月日資訊 getYearArr(dateArr){ // 獲取我們需要格式的年月資訊 var yearArr = []; var arr1 = []; // 存年 for(var i = 0; i < dateArr.length; i++){ var fullYear = new Date(dateArr[i]).getFullYear(); if(arr1.indexOf(fullYear) >= 0){ // 有這一年,繼續 continue; }else{ arr1.push(fullYear); // 沒有就新增 } } for(var i = 0; i < arr1.length; i++){ var yearObj = { year: "", months: [], // 放月的陣列 days: [ { strs: "", month: "", daysArr: [ day: "", a: "", b: "" ] } ] }; yearArr.push(yearObj); yearArr[i].year = arr1[i]; // 賦值年 } for(var i = 0; i < arr1.length; i++){ // 遍歷擁有的年 yearArr[i].months = []; for(var j = 0; j < dateArr.length; j++){ // 遍歷日期 獲得這一年,依據這一年獲取月份 var fullYear = new Date(dateArr[j]).getFullYear(); if(arr1[1] == fullYear){ // 當陣列中的年和日期的年相等時,獲取月份 var fullYear = new Date(dateArr[j]).getFullMonth() + 1; if(yearAll[i].months.indexOf(fullMonth) >= 0){ // 這一年的月中有這個月 continue; }else{ // 沒有這個月,新增這個月,並且,獲取這個月的天數,並新增 yearArr[i].months.push(fullMonth); } } } } for(var i = 0; i < yearArr.length; i++){ // 遍歷年 for(var j = 0; j < yearArr[i].months.length; j++){ // 遍歷月,根據年月獲取當前月的天數 var monthsDays = this.getLastDay(yearArr[i].year, yearArr[i].months[j]); yearArr[i].days[j] = {}; yearArr[i].days[j].str = yearArr[i].year + "-" + yearArr[i].months[j]; // 賦值月 yearArr[i].days[j].month = yearArr[i].year + "年" + yearArr[i].months[j] + "月"; // 賦值月 yearArr[i].days[j].daysArr = []; for(var k = 1; k <= monthsDays; k++){ // 賦值天 var dayObj = { day: "" }; yearArr[i].days[j].daysArr.push(dayObj); yearArr[i].days[j].daysArr[k-1].day = k + ""; } }; } return yearArr; } // 獲取月的最後一天 getLastDay(myyear, mymonth){ var new_date = new Date(myyear, mymonth, 0); return new_date.getDate(); }
缺點:日期範圍不能過大,不然表格載入緩慢!!!