ソースを参照

甘特图框架拖拽可滚动

yuhan 1 年間 前
コミット
6c0e7aae67
共有1 個のファイルを変更した108 個の追加20 個の削除を含む
  1. 108 20
      itdmWeb/src/components/module-iTDM/uGantt/index.vue

+ 108 - 20
itdmWeb/src/components/module-iTDM/uGantt/index.vue

@@ -42,6 +42,8 @@
           </template>
         </el-table>
       </div>
+      <!-- <div class="u-gantt-area" ref="uGantt"> -->
+      
       <div class="u-gantt" ref="uGantt">
         <div class="u-gantt-title u-flex" >
           <div v-for="(item, index) in uGanttColumns" :key="index" class="item-title">{{ item.label}}</div>
@@ -66,6 +68,7 @@
           </div>
         </div>
       </div>
+      <!-- </div> -->
     </div>
 
     <!-- 自定义内容:弹窗 -->
@@ -116,8 +119,10 @@
         })
         console.log(setTimeData[0].start_date)
         console.log(setTimeData[setTimeData.length - 1].end_date)
+        var start = this.addDate(setTimeData[0].start_date, -1)
         var end = this.addDate(setTimeData[setTimeData.length - 1].end_date, 2)
-        this.uGanttColumns = this.getBetweenDate(setTimeData[0].start_date, end)
+        this.uGanttColumns = this.getBetweenDate(start, end)
+        // this.uGanttColumns = this.getBetweenDate(setTimeData[0].start_date, end)
       },
       /**
        * 计算某个日期几天后的日期
@@ -238,47 +243,109 @@
       // 拖拽位移事件
       uGanttDrag(){
         var _this = this
+        // 当前甘特条可移动部分
         var uGanttDrag = this.$refs.uGanttDrag;
+        // 当前甘特条
         var uGanttTaskItem = this.$refs.uGanttTaskItem;
+        // 整个甘特图
+        var uGantt = this.$refs.uGantt
+        // console.log(this.$refs)
+        //当前甘特区域宽度 
         for (let i = 0; i < uGanttDrag.length; i++) {
           // 鼠标按下
           uGanttDrag[i].onmousedown = function (e) {
+            // 整个甘特图区域滚动宽度(非展示宽度,加上看不见的滚动区域)
+            var scrollWidth = uGantt.scrollWidth
+            const uGanttWidth = uGantt.offsetWidth // 放在down外值不对,不知道为啥
+            /**如果这些参数放在move设置就是会变的,放在down中就是固定值 */
+            // 当前甘特条距离左侧距离
             const offsetLeft = uGanttTaskItem[i].offsetLeft
+            // 当前甘特条宽度
             const offsetWidth = uGanttTaskItem[i].offsetWidth
+            // 设置上次移动结束滚动条位置,用来判断
+            const oldScrollLeft = uGantt.scrollLeft
+            // 甘特图距离窗口左侧的距离
+            var ganttWindowLeft = uGantt.getBoundingClientRect().left
+            // 鼠标按下位置-用于计算
             var startX = e.clientX;
-            var moveLen
+            var endX, moveLen
             // 向上取证获取当前是第几行
             var ganttIndex = Math.trunc(uGanttTaskItem[i].offsetTop/34)
+            // console.log(uGantt.scrollLeft)
+            // console.log(startX)
             // 移动事件
             document.onmousemove = function (e) {
-              var endX = e.clientX;
-              moveLen = offsetLeft + ( endX - startX )
+              endX = e.clientX;
               // 设置当前甘特条距离左侧的距离(使得左侧移动,而宽度不变,右侧对应向右移,产生移动效果)
+              // console.log(oldScrollLeft, uGantt.scrollLeft)
+              var distance
+              if(uGantt.scrollLeft === oldScrollLeft){
+                // 如果滚动条没有滚动
+                distance = offsetLeft + ( endX - startX )
+              } else {
+                // 如果滚动条滚动了
+                distance = offsetLeft + ( endX - startX ) + (uGantt.scrollLeft - oldScrollLeft)
+              }
+              // 判断超出左右距离时设置临界值
+              if(distance > (scrollWidth - offsetWidth)){
+                // 超出右边距离
+                moveLen = scrollWidth - offsetWidth
+              } else if(distance < 0) {
+                // 超出左边距离
+                moveLen = 0
+              } else {
+                moveLen = distance
+              }
               uGanttTaskItem[i].style.left = moveLen + 'px'
               // 移动过程鼠标变成拖拽形状
               uGanttDrag[i].style.cursor = 'move'
               
-              // 监听位置进行滚动条滚动--尚未完成
-              var uGantt = _this.$refs.uGantt
-              const offsetRight = uGantt.offsetWidth - (uGanttTaskItem[i].offsetLeft + uGanttTaskItem[i].offsetWidth)
-              // console.log(offsetRight)
-              if(offsetRight<0){
-                console.log(uGanttTaskItem[i].offsetWidth)
-                uGantt.scrollLeft ++
-                console.log(uGantt.offsetRight)
-                // uGantt.scrollLeft += uGanttTaskItem[i].offsetWidth
+              // 监听位置进行滚动条滚动
+              // 鼠标当前位置
+              var pointRight = ganttWindowLeft + uGanttWidth - endX
+              // console.log(document.documentElement.clientWidth)
+              
+              if(pointRight < 50){
+                uGantt.scrollLeft += 70
               }
+              // 鼠标当前位置位于左侧边缘
+              if(endX - ganttWindowLeft < 50){
+                uGantt.scrollLeft -= 70
+              }
+              // uGantt.scrollHeight // 滚动条的高度
             }
             document.onmouseup = function (evt) {
               // 同样:不能停在一段的中间位置,所以计算使其整段整段的形式显示
-              uGanttTaskItem[i].style.left = Math.round(moveLen/70) * 70 + 'px';
+              // console.log(uGanttTaskItem[i].offsetLeft)
+              // 移动到最后一列的时候:时间往前+1天
+              var StartLeft = Math.round(moveLen/70) * 70
+              // var startNum
+              if(StartLeft <= 0){
+                var currentStartData = _this.addDate(_this.uGanttColumns[0].name, -1)
+                _this.uGanttColumns = _this.getBetweenDate(currentStartData, _this.uGanttColumns[_this.uGanttColumns.length - 1].name)
+                uGanttTaskItem[i].style.left = (Math.round(moveLen/70) + 1) * 70 + 'px';
+                // startNum = (uGanttTaskItem[i].offsetLeft)/70
+              } else {
+                uGanttTaskItem[i].style.left = Math.round(moveLen/70) * 70 + 'px';
+              }
               // 获取最终左侧停在第几列
               var startNum = (uGanttTaskItem[i].offsetLeft)/70
+              // console.log(startNum)
+              // var StartNum0 = startNum === 0 ? startNum + 1 : startNum
+              // console.log(isStartNum)
               // 获取最终右侧停在第几列
               var endNum = (offsetWidth / 70) + startNum
               // 找到对应的时间强制赋值刷新
               _this.$set(_this.ganttLists[ganttIndex], 'start_date', _this.uGanttColumns[startNum].name)
               _this.$set(_this.ganttLists[ganttIndex], 'end_date', _this.uGanttColumns[endNum - 1].name)
+
+              // 移动到最后一列的时候:时间+2天
+              if(endNum >= _this.uGanttColumns.length){
+                var currentEndData = _this.addDate(_this.uGanttColumns[endNum - 1].name, 2)
+                _this.uGanttColumns = _this.getBetweenDate(_this.uGanttColumns[0].name, currentEndData)
+              }
+              
+              
               // 鼠标变回手型
               uGanttDrag[i].style.cursor = 'pointer'
               // 释放
@@ -344,6 +411,8 @@
         // 1.获取ref
         var resize = this.$refs.uGanttResizeR;
         var uGanttTaskItem = this.$refs.uGanttTaskItem;
+        // 整个甘特图
+        var uGantt = this.$refs.uGantt
         // 2.循环监听获取当前点击的事件
         // 上面设置onmousedown方法会出现第一次点击无法调用的问题,所以在mounted中写(不知道为什么有类似监听的效果)
         // 因为ref有好几个,获取的数组,所以这里要循环
@@ -352,17 +421,22 @@
           // 1.鼠标按下事件:
           // 用[resize[i].],而不是全局document监听,这样才能监听到是哪儿一个甘特条触发了事件
           resize[i].onmousedown = function (e) {
-            // 1.获取当前点击的甘特条是第几行的,也就是对应左侧项目组中的index
+            // 1.整个甘特图区域滚动宽度(非展示宽度,加上看不见的滚动区域)
+            var scrollWidth = uGantt.scrollWidth
+            const uGanttWidth = uGantt.offsetWidth
+            // 2.获取当前点击的甘特条是第几行的,也就是对应左侧项目组中的index
             var ganttIndex = Math.trunc(uGanttTaskItem[i].offsetTop/34)
-            // 2.获取按下位置距离
+            // 3.获取按下位置距离
             var startX = e.clientX;
-            // 3.获取当前右侧拖拽区域距离父元素左侧距离(也就是右侧拖拽区域距离甘特图左边的距离:注意父子关系)
+            // 4.获取当前右侧拖拽区域距离父元素左侧距离(也就是右侧拖拽区域距离甘特图左边的距离:注意父子关系)
             var offsetLeft = resize[i].offsetLeft;
             // 转言之:上面那个就是当前甘特条的宽度--也就可以写作下面的方式
             // var offsetLeft = uGanttTaskItem[i].offsetWidth;
-            // 4.定义拖拽参数--主要是为了onmouseup能调用
+            // 5.甘特图距离窗口左侧的距离
+            var ganttWindowLeft = uGantt.getBoundingClientRect().left
+            // 6.定义拖拽参数--主要是为了onmouseup能调用
             var moveLen
-            // 5.鼠标移动事件--注意:这里是document全局,这样就可以实现超出位置依旧可以控制拖拽
+            // 7.鼠标移动事件--注意:这里是document全局,这样就可以实现超出位置依旧可以控制拖拽
             document.onmousemove = function (e) {
               // 1.获取移动过程中实时位置
               var endX = e.clientX;
@@ -374,6 +448,14 @@
               // resize[i].style.left = moveLen;
               // 设置甘特条随move变化:即实时宽度也为moveLen即可
               uGanttTaskItem[i].style.width = moveLen + 'px';
+
+              // 4.监听位置进行滚动条滚动
+              // 鼠标当前位置
+              var pointRight = ganttWindowLeft + uGanttWidth - endX
+              // 如果位置靠右小于50,滚动条滚动
+              // if(pointRight < 50){
+              //   uGantt.scrollLeft += 70
+              // }
             }
             // 鼠标抬起事件
             document.onmouseup = function (evt) {
@@ -454,6 +536,8 @@
   // width: calc(100vw - 240px);
   .el-table{
     user-select: none;
+    // border-top: 1px solid #ebebeb;
+    // border-left: 1px solid #ebebeb;
     // width: auto;
     .u-table-cell{
       padding: 0 !important;
@@ -475,11 +559,15 @@
       color: #44c2e5;
     }
   }
+  .u-gantt-area{
+    flex: 1;
+    overflow: hidden;
+  }
   .u-gantt{
-    // width: calc(100% - 371px);
     flex: 1;
     border-top: 1px solid #ebebeb;
     border-left: 1px solid #ebebeb;
+    // width: calc(100% - 371px);
     overflow: auto;
   }
   .u-gantt-title{