甘特图简例

<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>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值