1. 程式人生 > >vue專案中的elementui的表格中畫甘特圖

vue專案中的elementui的表格中畫甘特圖

最近的專案要求甘特圖在elementui中實現,在此做出總結。
效能限制,不能傳入太多的資料。
條件(時間):計劃開始時間、計劃結束時間、開始時間、結束時間、最大時間和最小時間。
思維:渲染表格頭、渲染天數、填充色塊。

  1. 實現簡單的表格
	<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>
  1. 兩個樣式
	.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;
	}
  1. 實現方法
    設:最小時間為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();
	}

缺點:日期範圍不能過大,不然表格載入緩慢!!!