<template>
<div id="app">
<!-- <el-table
:data="tableData1"
style="width: 100%"
:span-method="objectSpanMethod"
border
cell-class-name="gantt-table-row"
>
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="80"> </el-table-column>
<el-table-column prop="address" label="地址" width="220"></el-table-column>
<el-table-column>
<template slot="header" slot-scope="scope">
<div>操作</div>
</template>
<template slot-scope="scope">
<div class="gantt-container">
</div>
</template>
</el-table-column>
</el-table> -->
<div class="gantt-box" ref="ganttRef">
<div class="gantt-row" v-for="(item,rowIndex) in data" :key="'row'+rowIndex">
<template v-if="item.list.length > 0">
<div class="gantt-col"
v-for="(itemBox,colIndex) in item.list"
:key="itemBox.id"
:style="{ background: getBgColors(),left: itemBox.x + 'px' ,top: itemBox.y + 'px',width: itemBox.x1 - itemBox.x +'px' }"
@mousedown="onMouseDown($event, colIndex, rowIndex)"
:data-id="itemBox.id"
:ref="itemBox.id"
>
{{itemBox.id}}
</div>
</template>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return {
tableData1: [{
id: 1,
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
id: 2,
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
id: 3,
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄',
hasChildren: true
}, {
id: 4,
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}],
data:[
{
id: 1,
list: [
{x: 0,y: 10,id: 1 ,x1: 80},
{x: 80,y: 10,id: 8 ,x1: 110},
{x: 120,y: 10,id: 2,x1: 170},
{x: 250,y: 10,id: 3,x1: 370}
]
},
{
id: 2,
list: [
{x: 30,y: 10,id: 4,x1:150},
{x: 150,y: 10,id: 5,x1: 350},
{x: 370,y: 10,id: 6,x1:460}
]
}
],
moveX: 0,
moveY: 0,
clientX: 0,
clientY: 0,
}
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }){
// console.log('columnIndex',columnIndex);
if (columnIndex === 3) {
return {
rowspan: this.tableData1.length,
colspan: 1
};
}
},
getBgColors(){
return `rgba(${Math.round(Math.random() * 255)},${Math.round(Math.random() * 255)},${Math.round(Math.random() * 255)},0.7)`
},
onMouseDown(ev,colIndex,rowIndex){
// 用box 移动,不采用 Doucment
const box = this.$refs.ganttRef;
const dom = ev.target;
this.clientX = ev.clientX;
this.clientY = ev.clientY;
// 算出鼠标相对元素的位置
const disL = dom.offsetLeft;
const disT = dom.offsetTop;
// 如果事件绑定在 dom上,那么一旦鼠标移动过快就会脱离掌控
console.log(disL,disT);
box.onmousemove = ee => {
// console.log('22222');
// 移动事件
this.onMouseMove(ee, disL, disT, dom);
};
window.onmouseup = ()=>{
box.onmousemove = null;
window.onmouseup = null;
this.onMouseUp(colIndex,rowIndex)
}
},
onMouseMove(ee,disL, disT, dom){
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
const { clientX , clientY } = this;
let left = (ee.clientX - clientX) + disL;
const top = (ee.clientY - clientY) + disT;
// console.log('left',left,'top',top);
if(left < 0){
left = 0;
}
this.moveX = left;
this.moveY = top;
dom.style.left = left + 'px';
dom.style.top = top + 'px';
},
onMouseUp(colIndex,rowIndex){
const { moveX ,moveY ,data} = this;
console.log(rowIndex,colIndex);
let suckIndex = Math.round((moveY - 10) / 60) + rowIndex;
if(suckIndex < 0){
suckIndex = 0
}else if(suckIndex > data.length-1){
suckIndex = data.length-1
}
//去掉该区块对应的位置
let nowRowObj = data[rowIndex];
const nowObj = nowRowObj.list[colIndex];
nowRowObj.list.splice(colIndex,1);
this.$set(this.data,rowIndex,nowRowObj)
const w = nowObj.x1 - nowObj.x;
//增加新区块的位置
let newRowObj = data[suckIndex];
// const refId = Math.round(Math.random()*10000);
const nowBoxObj = {x: moveX,y: 10,id: nowObj.id,x1:w + moveX };
console.log(JSON.stringify(nowBoxObj));
this.$nextTick(()=>{
// this.detectionOverlap(suckIndex)
this.detectionOverlap(newRowObj,suckIndex,nowBoxObj)
console.log(JSON.stringify(nowBoxObj));
})
},
detectionOverlap(newRowObj,index,obj){//检测是否叠加
let nowList = this._sort([...newRowObj.list,obj],'x')
let newList = this.changeSize(nowList);
console.log(222222,JSON.stringify(newList));
newRowObj.list = [...newList];
this.$set(this.data,index,newRowObj)
},
changeSize(dataList){
for (let k = 0; k < dataList.length; k++) {
const lastObj = dataList[k - 1];
const nowObj = dataList[k];
if(lastObj && lastObj.x1 > nowObj.x){
const diff = nowObj.x1 - nowObj.x;
if(lastObj.x1 > nowObj.x1){//覆盖 整体后移
const longDiff = lastObj.x1 - nowObj.x;
for(let j = k;j < dataList.length;j++){
const jNowObj = dataList[j];
if(lastObj.x1 < jNowObj.x){
break;
}
const jDiff = jNowObj.x1 - jNowObj.x;
jNowObj.x = jNowObj.x + longDiff;
jNowObj.x1 = jNowObj.x + jDiff;
this.changeSize(dataList);
break;
}
break;
}else{//相交
nowObj.x = lastObj.x1;
nowObj.x1 = lastObj.x1 + diff;
this.changeSize(dataList);
break;
}
}
}
return dataList
},
_sort(row,key) {
return row.sort((a, b) => {
return a[key] - b[key]
})
},
},
computed:{
},
mounted(){
// this.initData()
}
}
</script>
<style scoped>
::v-deep .el-table .el-table__cell{
padding: 0;
height: 60px;
}
.gantt-container{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.gantt-box{
position: relative;
}
.gantt-row{
position: relative;
height: 60px;
border-bottom: 1px solid #EBEEF5;
}
.gantt-col{
position: absolute;
/* width:100px; */
height: calc(100% - 20px);
top: 10px;
z-index: 3;
}
.gantt-col.trs{
transition: all 2s ease-in-out;
}
</style>
<style scoped >
/* .gantt-col{
width: +'px';
} */
</style>
甘特图简例
于 2023-10-30 14:56:46 首次发布