Przeglądaj źródła

Merge remote-tracking branch 'origin/develop-cd' into aly_dev

guoxiaohuan 4 lat temu
rodzic
commit
c711221c12

+ 116 - 112
src/utils/ganttChart/GanttChart.js

@@ -3,7 +3,7 @@ import moment from 'moment';
  * 甘特图
  * @param {} options 
  */
-export function GanttChart(options) {
+export function GanttChartDay(options) {
   // 任务列表
   this.tasks = options.tasks || [];
   // AntVG Canvas
@@ -55,6 +55,8 @@ export function GanttChart(options) {
   this.todayTimeLineEl = null;
   // 点击回调事件
   this.callback = options.callback || null;
+  // 翻页时间回调
+  this.pageToCallback = options.pageToCallback || null;
 }
 
 
@@ -62,7 +64,7 @@ export function GanttChart(options) {
  * 设置数据
  * @param {*} _tasks 
  */
-GanttChart.prototype.changeTasks = function(_tasks){
+GanttChartDay.prototype.changeTasks = function(_tasks){
   this.tasks = _tasks
 }
 
@@ -70,7 +72,7 @@ GanttChart.prototype.changeTasks = function(_tasks){
  * 打开关闭分组
  */
 
-GanttChart.prototype.toggle = function(index) {
+GanttChartDay.prototype.toggle = function(index) {
   if (this.tasks[index].open) {
     this.tasks[index].open = false;
   } else {
@@ -83,7 +85,7 @@ GanttChart.prototype.toggle = function(index) {
 /**
  * 预处理数据
  */
-GanttChart.prototype.processData = function() {
+GanttChartDay.prototype.processData = function() {
   for (let i = 0; i < this.tasks.length; i++) {
     let currentTopTask = this.tasks[i];
     let lastTopTask = null;
@@ -112,7 +114,7 @@ GanttChart.prototype.processData = function() {
 /**
  * 强制清空图像,重绘
  */
-GanttChart.prototype.forceRefreshGraph = function() {
+GanttChartDay.prototype.forceRefreshGraph = function() {
   this.tasks.forEach((topTask) => {
     topTask.gGroup = null;
   });
@@ -124,7 +126,7 @@ GanttChart.prototype.forceRefreshGraph = function() {
 /**
  * 准备绘制,用于初始化和强制刷新
  */
-GanttChart.prototype.initDrawingReady = function() {
+GanttChartDay.prototype.initDrawingReady = function() {
   this.initCanvas();
   setTimeout(() => {
     this.initDragHandler();
@@ -138,7 +140,7 @@ GanttChart.prototype.initDrawingReady = function() {
 /**
  * 翻页
  */
-GanttChart.prototype.pageTo = function(dir = 'next') {
+GanttChartDay.prototype.pageTo = function(dir = 'next') {
   this.draging = false;
   this.endEvent = null;
   if (dir == 'next') {
@@ -151,6 +153,7 @@ GanttChart.prototype.pageTo = function(dir = 'next') {
     this.offsetDis = 2*this.viewWidth
   }
   this.endAt = moment(this.startAt).add(this.daysCount, 'days');
+  this.pageToCallback({dir: dir, startAt: this.startAt.format('YYYY-MM-DD'), endAt: this.endAt.format('YYYY-MM-DD')})
   console.log('已翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'), this.offsetDis);
   // offsetDis = viewWidth;
   this.forceRefreshGraph();
@@ -162,7 +165,7 @@ let lastClickAt = null;
  * 改变graphDiv 滚动距离
  * 到达边界距离后,刷新页面
  */
-GanttChart.prototype.doDrag = function(sEvent, eEvent) {  
+GanttChartDay.prototype.doDrag = function(sEvent, eEvent) {  
   if (sEvent == null) {
     sEvent = this.startEvent;
   }
@@ -192,7 +195,7 @@ GanttChart.prototype.doDrag = function(sEvent, eEvent) {
 /**
  * 初始化抓取拖动事件
  */
-GanttChart.prototype.initDragHandler = function() {
+GanttChartDay.prototype.initDragHandler = function() {
   this.graphDiv.scrollLeft = this.offsetDis;
   let _canvas = this._canvas
   _canvas.addEventListener('mousedown', (ev) => {
@@ -234,7 +237,7 @@ GanttChart.prototype.initDragHandler = function() {
  *
  */
 
-GanttChart.prototype.initCanvas = function() {
+GanttChartDay.prototype.initCanvas = function() {
   console.error('初始化画布...')
   this.gCanvas = new G.Canvas({
     container: this.chartContainer,
@@ -248,7 +251,7 @@ GanttChart.prototype.initCanvas = function() {
  * 绘制时间区域
  */
 
-GanttChart.prototype.drawTimeZone = function() {
+GanttChartDay.prototype.drawTimeZone = function() {
   console.log('时间段', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'));
   let start = moment(this.startAt);
   let timeGroup = this.gCanvas.addGroup();
@@ -331,7 +334,7 @@ GanttChart.prototype.drawTimeZone = function() {
 /**
  * 处理点击
  */
-GanttChart.prototype.handleClick = function(task, flag, ev) {
+GanttChartDay.prototype.handleClick = function(task, flag, ev) {
   // let detailDiv = document.getElementById('detailDiv')
   if(flag == 'enter'){
     // detailDiv.style.display = 'block'
@@ -356,7 +359,7 @@ GanttChart.prototype.handleClick = function(task, flag, ev) {
  * 根据任务状态区分颜色
  * 
  */
-GanttChart.prototype.statusColor =function(task) {
+GanttChartDay.prototype.statusColor =function(task) {
   switch (task.status) {
     case '按时完成':
       return 'aqua';
@@ -376,7 +379,7 @@ GanttChart.prototype.statusColor =function(task) {
  * 判断任务是否在视图内
  * 
  */ 
-GanttChart.prototype.isInView = function(task) {
+GanttChartDay.prototype.isInView = function(task) {
   let isLessThanEndAt = (task.endDate <= this.startAt.format('YYYY-MM-DD'))
   let isGreaterThanStartAt = task.startDate >= this.endAt.format('YYYY-MM-DD')
   return !(isLessThanEndAt || isGreaterThanStartAt)
@@ -385,7 +388,7 @@ GanttChart.prototype.isInView = function(task) {
 /**
  * 绘制完成之后的回调,用于某些工具缺陷的hack写法
  */
-GanttChart.prototype.postDrawTasksCallBack = function(){
+GanttChartDay.prototype.postDrawTasksCallBack = function(){
   // 画当前线条 TODO,放前面不行
   if(true){
     let todayAt = new Date()
@@ -426,110 +429,111 @@ GanttChart.prototype.postDrawTasksCallBack = function(){
  *
  */
 
-GanttChart.prototype.drawTasks = function() {
-  if (this.graphGroup) {
-    this.graphGroup.clear();
-  } else {
-    this.graphGroup = this.gCanvas.addGroup();
-    this.graphGroup._tname = 'graphGroup';
-  }
+GanttChartDay.prototype.drawTasks = function() {  
+  this.graphGroup = this.gCanvas.addGroup();
+  this.graphGroup._tname = 'graphGroup';
+  
   // 第一层循环,用于分组,例如,维保--xxxx
   this.tasks.forEach((topTask, topIndex) => {
-    if (topTask.open) {
-      let taskGroup = null;
-      taskGroup = this.graphGroup.addGroup();
-      taskGroup._tname = 'TaskGroup_' + topTask.id;
-      topTask.gGroup = taskGroup;
-
-      // 组名背景矩形
-      let TopGroupRectEl = taskGroup.addShape('rect', {
-        attrs: {
-          x: 0,
-          y: topTask.renderOptions.startY,
-          width: this.cWidth,
-          height: this.taskRowHeight,
-          fill: '#F5F6F7',
-          radius: [2, 4],
-        },
-      });
-      TopGroupRectEl.setZIndex(-1)
-      // 第二层循环,用于 区分具体多少任务,例如,维保-商管1/商管2...
-      topTask.dataList.forEach((taskP, index) => {
-        let taskPGroup = taskGroup.addGroup()
-        taskGroup.addGroup(taskPGroup);
-        // 任务背景矩形,主要用于Hover效果变更颜色
-        if(true){
-          let tempTaskContainerEl = taskPGroup.addShape('rect', {
-            attrs: {
-              x: 0,
-              y: topTask.renderOptions.startY + ((index+2)* (this.taskRowHeight + this.rowSpanDis))-5,
-              width: this.cWidth,
-              height: this.taskRowHeight+10,
-              fill: '#fff',
-              // stroke: 'black',
-              radius: [2, 4],
-            },
-          });
-          tempTaskContainerEl.setZIndex(1)
-          tempTaskContainerEl._pdata = taskP
-          tempTaskContainerEl.on('mouseenter',(ev)=>{
-            tempTaskContainerEl.attr({fill: '#F5F6F7'})
-            tempTaskContainerEl._pdata.tasks.forEach(_tempTask=>{
-              if(_tempTask._rectEl){
-                _tempTask._rectEl.setZIndex(5)
-              }
-            })
-          })
-          tempTaskContainerEl.on('mouseleave',(ev)=>{
-            tempTaskContainerEl.attr({fill: '#fff'})
-            tempTaskContainerEl._pdata.tasks.forEach(_tempTask=>{
-              if(_tempTask._rectEl){
-                _tempTask._rectEl.setZIndex(5)
-              }
-            })
-          })
-          taskP._containerEl = tempTaskContainerEl
-        }
-        // 第三层循环,用户区分每个子任务的执行时间段,例如:维保-商管1-2020.05-2020.06 / 2020.08- 2020.09
-        taskP.tasks.forEach((_taskItem, _index) => {
-          let _isInView = this.isInView(_taskItem)
-          // 在视图中才显示
-          if(_isInView){
-            let pos = this.calRectPos(_taskItem);
-            // console.log('render rect:', _taskItem, pos, topTask.renderOptions.startY + index * taskRowHeight);
-            let rectEl = taskPGroup.addShape('rect', {
+    try {      
+      if (topTask.open) {
+        let taskGroup = null;
+        taskGroup = this.graphGroup.addGroup();
+        taskGroup._tname = 'TaskGroup_' + topTask.id;
+        topTask.gGroup = taskGroup;
+  
+        // 组名背景矩形
+        let TopGroupRectEl = taskGroup.addShape('rect', {
+          attrs: {
+            x: 0,
+            y: topTask.renderOptions.startY,
+            width: this.cWidth,
+            height: this.taskRowHeight,
+            fill: '#F5F6F7',
+            radius: [2, 4],
+          },
+        });
+        TopGroupRectEl.setZIndex(-1)
+        // 第二层循环,用于 区分具体多少任务,例如,维保-商管1/商管2...
+        topTask.dataList.forEach((taskP, index) => {
+          let taskPGroup = taskGroup.addGroup()
+          taskGroup.addGroup(taskPGroup);
+          // 任务背景矩形,主要用于Hover效果变更颜色
+          if(true){
+            let tempTaskContainerEl = taskPGroup.addShape('rect', {
               attrs: {
-                x: pos.x,
-                y: topTask.renderOptions.startY + ((index + 1)* (this.taskRowHeight + this.rowSpanDis)),
-                width: pos.width,
-                height: this.taskRowHeight,
-                fill: this.statusColor(_taskItem),
-                stroke: 'black',
+                x: 0,
+                y: topTask.renderOptions.startY + ((index+2)* (this.taskRowHeight + this.rowSpanDis))-5,
+                width: this.cWidth,
+                height: this.taskRowHeight+10,
+                fill: '#fff',
+                // stroke: 'black',
                 radius: [2, 4],
               },
             });
-            rectEl.setZIndex(50)
-            rectEl._pdata = _taskItem;
-            _taskItem._rectEl = rectEl
-            rectEl.on('mouseover', (ev) => {
-              this.handleClick(ev.target, 'enter', ev);
-            });
-            rectEl.on('mouseleave', (ev) => {
-              this.handleClick(ev.target, 'leave', ev);
-            });
-            rectEl.on('click', (ev) => {
-              this.handleClick(ev.target, 'click', ev);
-            });
+            tempTaskContainerEl.setZIndex(1)
+            tempTaskContainerEl._pdata = taskP
+            tempTaskContainerEl.on('mouseenter',(ev)=>{
+              tempTaskContainerEl.attr({fill: '#F5F6F7'})
+              tempTaskContainerEl._pdata.tasks.forEach(_tempTask=>{
+                if(_tempTask._rectEl){
+                  _tempTask._rectEl.setZIndex(5)
+                }
+              })
+            })
+            tempTaskContainerEl.on('mouseleave',(ev)=>{
+              tempTaskContainerEl.attr({fill: '#fff'})
+              tempTaskContainerEl._pdata.tasks.forEach(_tempTask=>{
+                if(_tempTask._rectEl){
+                  _tempTask._rectEl.setZIndex(5)
+                }
+              })
+            })
+            taskP._containerEl = tempTaskContainerEl
           }
+          // 第三层循环,用户区分每个子任务的执行时间段,例如:维保-商管1-2020.05-2020.06 / 2020.08- 2020.09
+          taskP.tasks.forEach((_taskItem, _index) => {
+            let _isInView = this.isInView(_taskItem)
+            // 在视图中才显示
+            if(_isInView){
+              let pos = this.calRectPos(_taskItem);
+              // console.log('render rect:', _taskItem, pos, topTask.renderOptions.startY + index * taskRowHeight);
+              let rectEl = taskPGroup.addShape('rect', {
+                attrs: {
+                  x: pos.x,
+                  y: topTask.renderOptions.startY + ((index + 1)* (this.taskRowHeight + this.rowSpanDis)),
+                  width: pos.width,
+                  height: this.taskRowHeight,
+                  fill: this.statusColor(_taskItem),
+                  stroke: 'black',
+                  radius: [2, 4],
+                },
+              });
+              rectEl.setZIndex(50)
+              rectEl._pdata = _taskItem;
+              _taskItem._rectEl = rectEl
+              rectEl.on('mouseover', (ev) => {
+                this.handleClick(ev.target, 'enter', ev);
+              });
+              rectEl.on('mouseleave', (ev) => {
+                this.handleClick(ev.target, 'leave', ev);
+              });
+              rectEl.on('click', (ev) => {
+                this.handleClick(ev.target, 'click', ev);
+              });
+            }
+          });
         });
-      });
-
-      taskGroup.show();
-    } else {
-      if (topTask.gGroup) {
-        // topTask.gGroup.hide()
-        topTask.gGroup = null;
+  
+        taskGroup.show();
+      } else {
+        if (topTask.gGroup) {
+          // topTask.gGroup.hide()
+          topTask.gGroup = null;
+        }
       }
+    } catch (error) {
+      console.error('drawTasks error:', error)
     }
   });
 
@@ -540,7 +544,7 @@ GanttChart.prototype.drawTasks = function() {
  * 根据 Task 计算矩形位置
  *
  */
-GanttChart.prototype.calRectPos = function(taskItem) {
+GanttChartDay.prototype.calRectPos = function(taskItem) {
   let duraStartAt = new Date(taskItem.startDate) - new Date(this.startAt.format('YYYY-MM-DD'));
   let secondsStartAt = duraStartAt/1000
 
@@ -559,6 +563,6 @@ GanttChart.prototype.calRectPos = function(taskItem) {
  *
  */
 
-GanttChart.prototype.main = function() {  
+GanttChartDay.prototype.main = function() {  
   this.initDrawingReady();
 }

+ 574 - 0
src/utils/ganttChart/GanttChart_month.js

@@ -0,0 +1,574 @@
+import moment from 'moment';
+/**
+ * 甘特图
+ * @param {} options 
+ */
+export function GanttChartMonth(options) {
+  // 任务列表
+  this.tasks = options.tasks || [];
+  // AntVG Canvas
+  this.gCanvas = null;
+  // 视口宽度 800,可视区域
+  this.viewWidth = options['viewWidth'] || 800;
+  // 物理画布宽度 800
+  this.cWidth = options['cWidth'] || 2400;
+  this.cHeight = options['cHeight'] || 1600;
+  // 画布偏移位置
+  this.startPos = 0;
+  // 是否拖动中
+  this.draging = false;
+  // 开始拖动事件
+  this.startEvent = null;
+  // 结束拖动事件
+  this.endEvent = null;
+  // 拖动过程事件
+  this.dragingEvent = null;
+  // 拖动偏移量
+  this.offsetDis = (options['viewWidth']/2) || 800;
+  // 拖动定时器
+  this.dragTimer = null;
+  // 每天的间隔宽度
+  this.dayStep = parseInt(this.cWidth/365);
+  // 分组标题高度
+  this.groupTitleHeight = 18;
+  // 任务矩形高度
+  this.taskRowHeight = 16;
+  // 每行任务的纵向间距
+  this.rowSpanDis = 22;
+  // 总天数
+  this.daysCount = options['daysCount'] || 365;
+  // 任务图距离顶部高度
+  this.graphTopDis = 60
+  
+  // 每像素代表的小时数
+  this.timePerPix = this.cWidth/this.daysCount/24/3600
+  // 当前视图开始时间,向前推N天
+  this.startAt = moment().startOf('year')
+  this.endAt = moment().endOf('year')
+  this.graphDiv = document.getElementById(options['chartParentContainer']);
+  this.chartContainer = options['chartContainer']
+  // 图形容器组
+  this.graphGroup = null;
+  // 上一次拖动的事件
+  this.lastDragEv = null;
+  // 当日刻度线
+  this.todayTimeLineEl = null;
+  // 点击回调事件
+  this.callback = options.callback || null;
+  // 翻页时间回调
+  this.pageToCallback = options.pageToCallback || null;
+}
+
+
+/**
+ * 设置数据
+ * @param {*} _tasks 
+ */
+GanttChartMonth.prototype.changeTasks = function(_tasks){
+  this.tasks = _tasks
+}
+
+/**
+ * 打开关闭分组
+ */
+
+GanttChartMonth.prototype.toggle = function(index) {
+  if (this.tasks[index].open) {
+    this.tasks[index].open = false;
+  } else {
+    this.tasks[index].open = true;
+  }
+  this.processData();
+  this.drawTasks();
+}
+
+/**
+ * 预处理数据
+ */
+GanttChartMonth.prototype.processData = function() {
+  for (let i = 0; i < this.tasks.length; i++) {
+    let currentTopTask = this.tasks[i];
+    let lastTopTask = null;
+    currentTopTask.renderOptions = {};
+    // 设置StartY
+    if (i != 0) {
+      // 非0个,要补上前面的数据
+      lastTopTask = this.tasks[i - 1];
+      currentTopTask.renderOptions.startY = lastTopTask.renderOptions.endY + 20;
+    } else {
+      // 第一个
+      currentTopTask.renderOptions.startY = this.graphTopDis;
+    }
+    // 设置EndY
+    // 当有数据 且 打开时,
+    //     EndY = StartY + 标题上间距 + 标题 高度 + 任务个数 * (任务高度)
+    if (currentTopTask.dataList.length >0 && currentTopTask.open) {
+      currentTopTask.renderOptions.endY =
+        currentTopTask.renderOptions.startY  + this.groupTitleHeight + currentTopTask.dataList.length * 38;
+    } else {
+      currentTopTask.renderOptions.endY = currentTopTask.renderOptions.startY + this.groupTitleHeight;
+    }
+  }
+}
+
+/**
+ * 强制清空图像,重绘
+ */
+GanttChartMonth.prototype.forceRefreshGraph = function() {
+  this.tasks.forEach((topTask) => {
+    topTask.gGroup = null;
+  });
+  this.todayTimeLineEl = null
+  this.gCanvas.destroy();
+  this.initDrawingReady();
+}
+
+/**
+ * 准备绘制,用于初始化和强制刷新
+ */
+GanttChartMonth.prototype.initDrawingReady = function() {
+  this.initCanvas();
+  setTimeout(() => {
+    this.initDragHandler();
+    this.drawTimeZone();
+    this.processData();
+    this.drawTasks();
+    this.graphGroup = null
+  }, 200);
+}
+
+/**
+ * 翻页
+ */
+GanttChartMonth.prototype.pageTo = function(dir = 'next') {
+  this.draging = false;
+  this.endEvent = null;
+  if (dir == 'next') {
+    // 向后翻页`
+    this.startAt = this.startAt.add(this.daysCount, 'days');
+    this.offsetDis = 0
+  } else {
+    // 向前翻页
+    this.startAt = this.startAt.subtract(this.daysCount, 'days');
+    this.offsetDis = 2*this.viewWidth
+  }
+  this.endAt = moment(this.startAt).add(this.daysCount, 'days');
+  this.pageToCallback({dir: dir, startAt: this.startAt.format('YYYY-MM-DD'), endAt: this.endAt.format('YYYY-MM-DD')})
+  console.log('已翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'), this.offsetDis);
+  // offsetDis = viewWidth;
+  this.forceRefreshGraph();
+}
+// 上次点击时间,用于滚动时误触停止
+let lastClickAt = null;
+/**
+ * 执行拖动
+ * 改变graphDiv 滚动距离
+ * 到达边界距离后,刷新页面
+ */
+GanttChartMonth.prototype.doDrag = function(sEvent, eEvent) {  
+  if (sEvent == null) {
+    sEvent = this.startEvent;
+  }
+  let sPos = sEvent.clientX;
+  let cPos = eEvent.clientX;
+  // 滚动距离
+  let dis = cPos - sPos;
+  let tempDis = this.offsetDis
+  // console.log('offsetDis before:', this.offsetDis, dis)
+  this.offsetDis = this.offsetDis - dis / 2;
+  // console.log('draging...',tempDis, this.offsetDis, dis)
+  if (this.offsetDis <= -20) {
+    // 向前滑动,向前翻页
+    console.log('此处应该向前翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'),this.offsetDis);
+    this.offsetDis = this.viewWidth;
+    this.pageTo('prev');
+  }
+  if ((this.offsetDis - 20) >= this.viewWidth*2.2 ){ //cWidth - viewWidth) {
+    // 向后滑动,向后翻页
+    console.log('此处应该向后翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'),this.offsetDis);
+    this.offsetDis = this.viewWidth;
+    this.pageTo('next');
+  }
+  this.graphDiv.scrollLeft = this.offsetDis;
+}
+
+/**
+ * 初始化抓取拖动事件
+ */
+GanttChartMonth.prototype.initDragHandler = function() {
+  this.graphDiv.scrollLeft = this.offsetDis;
+  let _canvas = this._canvas
+  _canvas.addEventListener('mousedown', (ev) => {
+    this.draging = true;
+    this.startEvent = ev;
+    this.dragingEvent = null;
+    this.endEvent = null;
+    this.lastClickAt = new Date();
+    this.lastClickAt = ev;
+    this.lastDragEv = ev;
+  });
+
+
+  _canvas.addEventListener('mouseleave', (ev) => {
+    console.log('leave...恢复')
+    this.draging = false;
+    this.endEvent = ev;
+  });
+
+  _canvas.addEventListener('mouseup', (ev) => {
+    this.draging = false;
+    this.endEvent = ev;
+  });
+
+  _canvas.addEventListener('mousemove', (ev) => {
+    // console.log('this over', this)
+    if (this.draging) {
+      if (new Date() - this.lastClickAt < 20) {
+        return false;
+      }
+      this.dragingEvent = ev;
+      this.doDrag(this.lastDragEv, ev);
+      this.lastDragEv = ev;
+    }
+  });
+}
+/**
+ * 初始化画布
+ *
+ */
+
+GanttChartMonth.prototype.initCanvas = function() {
+  console.error('初始化画布...')
+  this.gCanvas = new G.Canvas({
+    container: this.chartContainer,
+    width: this.cWidth,
+    height: this.cHeight,
+  });
+  this._canvas = document.querySelector('#ganttContainer>canvas');
+}
+
+/**
+ * 绘制时间区域
+ */
+
+GanttChartMonth.prototype.drawTimeZone = function() {
+  console.log('时间段', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'));
+  let start = moment(this.startAt);
+  let timeGroup = this.gCanvas.addGroup();
+  this.timeGroupEl = timeGroup
+  timeGroup._tname = 'TimeGroup';
+  let startSecond = moment(this.startAt);
+
+  // 顶部底部边框
+  timeGroup.addShape('rect',{
+    attrs: {
+      x: 0,
+      y: 0,
+      width: this.cWidth,
+      height: 52,
+      fill: '#F8F9FA',
+      radius: [2, 4],
+    },
+  })
+  // 绘制第二级
+  let nowAtStr = moment().format('YYYY-MM-DD')
+  let year = this.startAt.format('YYYY')
+  this.timeZoneLineEls = []
+  for (let i = 1; i < 13; i++) {
+    let tempAt = moment(`${year}-${i}`)
+    let timeText = tempAt.format('MM');
+    if(timeText == '01'){
+      // 第一天,顶部需要绘制年月
+      timeGroup.addShape('text', {
+        attrs: {
+          x: this.dayStep * i,
+          y: 20,
+          fontSize: 12,
+          text: tempAt.format('YYYY'),
+          lineDash: [10, 10],
+          fill: '#8D9399',
+        },
+      });
+      
+    }
+    let isToday = nowAtStr == tempAt.format('YYYY-MM-DD')
+    if(isToday){
+      //是今日,需要画线
+      console.log('绘制 当日刻度线')
+      this.todayTimeLineOffsetPos = this.dayStep * i
+      timeGroup.addShape('rect',{
+        attrs: {
+          x: this.dayStep * i-10,
+          y: 25,
+          width: 30,
+          height: 16,
+          fill: '#0091FF',
+          radius: [2, 4],
+        },
+      })
+
+      this.todayTimeLineEl = this.gCanvas.addShape('rect',{
+        attrs: {
+          x: this.todayTimeLineOffsetPos,
+          y: 40,
+          width: 4,
+          height: this.cHeight,
+          fill: '#CDE9FF',
+          radius: [2, 4],
+        }
+      })
+      // this.todayTimeLineEl.setZIndex(3)
+    }
+
+    // 当月天数
+    let daysCount = moment(`${year}-${i}`).dayOfYear()
+    timeGroup.addShape('text', {
+      attrs: {
+        x: this.dayStep * daysCount,
+        y: 40,
+        fontSize: 10,
+        text: timeText,
+        lineDash: [10, 10],
+        fill: '#8D9399',
+      },
+    });
+  }
+}
+
+/**
+ * 处理点击
+ */
+GanttChartMonth.prototype.handleClick = function(task, flag, ev) {
+  // let detailDiv = document.getElementById('detailDiv')
+  if(flag == 'enter'){
+    // detailDiv.style.display = 'block'
+    // detailDiv.style.left = ev.clientX+'px';
+    // detailDiv.style.top = ev.clientY+'px';
+    // document.getElementById('detailTaskName').textContent = task._pdata.description
+    // document.getElementById('detailTaskStatus').textContent = task._pdata.status
+    // document.getElementById('detailTaskStartDate').textContent = task._pdata.startDate
+    // document.getElementById('detailTaskEndDate').textContent = task._pdata.endDate
+    console.log('show:', task);
+  } else if (flag === 'leave'){
+    // detailDiv.style.display = 'none'
+    console.log('hide:', task);
+  } else {
+    this.callback(task);
+    console.log('click:', task);
+  }
+}
+
+
+/**
+ * 根据任务状态区分颜色
+ * 
+ */
+GanttChartMonth.prototype.statusColor =function(task) {
+  switch (task.status) {
+    case '按时完成':
+      return 'aqua';
+      break;
+    case '计划批准':
+      return '#ff9800';
+      break;
+    case '已完成':
+      return '#19b720';
+      break;
+    default:
+      break;
+  }
+}
+
+/**
+ * 判断任务是否在视图内
+ * 
+ */ 
+GanttChartMonth.prototype.isInView = function(task) {
+  let isLessThanEndAt = (task.endDate <= this.startAt.format('YYYY-MM-DD'))
+  let isGreaterThanStartAt = task.startDate >= this.endAt.format('YYYY-MM-DD')
+  return !(isLessThanEndAt || isGreaterThanStartAt)
+}
+
+/**
+ * 绘制完成之后的回调,用于某些工具缺陷的hack写法
+ */
+GanttChartMonth.prototype.postDrawTasksCallBack = function(){
+  // 画当前线条 TODO,放前面不行
+  if(true){
+    let todayAt = new Date()
+    if(this.startAt < todayAt && this.endAt > todayAt){
+      this.todayTimeLineEl = this.gCanvas.addShape('rect',{
+        attrs: {
+          x: this.todayTimeLineOffsetPos,
+          y: 40,
+          width: 4,
+          height: this.cHeight,
+          fill: '#CDE9FF',
+          radius: [2, 4],
+        }
+      })
+      this.todayTimeLineEl.setZIndex(3)
+    }
+  }
+
+  if(true){
+    let year = this.startAt.format('YYYY')
+    for (let i = 1; i < 13; i++) {
+      // 当月天数
+    let daysCount = moment(`${year}-${i}`).dayOfYear()
+      let lineEl = this.timeGroupEl.addShape('rect', {
+        attrs: {
+          x: this.dayStep * daysCount,
+          y: 20,
+          width: 1,
+          height: this.cHeight,
+          fill: '#deebeb',
+          radius: [2, 4],
+        },
+      });
+      lineEl.setZIndex(200)
+    }
+  }
+}
+
+/**
+ * 分组绘制任务块
+ *
+ */
+
+GanttChartMonth.prototype.drawTasks = function() {  
+  this.graphGroup = this.gCanvas.addGroup();
+  this.graphGroup._tname = 'graphGroup';  
+  // 第一层循环,用于分组,例如,维保--xxxx
+  this.tasks.forEach((topTask, topIndex) => {
+    try {      
+      if (topTask.open) {
+        let taskGroup = null;
+        taskGroup = this.graphGroup.addGroup();
+        taskGroup._tname = 'TaskGroup_' + topTask.id;
+        topTask.gGroup = taskGroup;
+  
+        // 组名背景矩形
+        let TopGroupRectEl = taskGroup.addShape('rect', {
+          attrs: {
+            x: 0,
+            y: topTask.renderOptions.startY,
+            width: this.cWidth,
+            height: this.taskRowHeight,
+            fill: '#F5F6F7',
+            radius: [2, 4],
+          },
+        });
+        TopGroupRectEl.setZIndex(-1)
+        // 第二层循环,用于 区分具体多少任务,例如,维保-商管1/商管2...
+        topTask.dataList.forEach((taskP, index) => {
+          let taskPGroup = taskGroup.addGroup()
+          taskGroup.addGroup(taskPGroup);
+          // 任务背景矩形,主要用于Hover效果变更颜色
+          if(true){
+            let tempTaskContainerEl = taskPGroup.addShape('rect', {
+              attrs: {
+                x: 0,
+                y: topTask.renderOptions.startY + ((index+2)* (this.taskRowHeight + this.rowSpanDis))-5,
+                width: this.cWidth,
+                height: this.taskRowHeight+10,
+                fill: '#fff',
+                // stroke: 'black',
+                radius: [2, 4],
+              },
+            });
+            tempTaskContainerEl.setZIndex(1)
+            tempTaskContainerEl._pdata = taskP
+            tempTaskContainerEl.on('mouseenter',(ev)=>{
+              tempTaskContainerEl.attr({fill: '#F5F6F7'})
+              tempTaskContainerEl._pdata.tasks.forEach(_tempTask=>{
+                if(_tempTask._rectEl){
+                  _tempTask._rectEl.setZIndex(5)
+                }
+              })
+            })
+            tempTaskContainerEl.on('mouseleave',(ev)=>{
+              tempTaskContainerEl.attr({fill: '#fff'})
+              tempTaskContainerEl._pdata.tasks.forEach(_tempTask=>{
+                if(_tempTask._rectEl){
+                  _tempTask._rectEl.setZIndex(5)
+                }
+              })
+            })
+            taskP._containerEl = tempTaskContainerEl
+          }
+          // 第三层循环,用户区分每个子任务的执行时间段,例如:维保-商管1-2020.05-2020.06 / 2020.08- 2020.09
+          taskP.tasks.forEach((_taskItem, _index) => {
+            let _isInView = this.isInView(_taskItem)
+            // 在视图中才显示
+            if(_isInView){
+              let pos = this.calRectPos(_taskItem);
+              // console.log('render rect:', _taskItem, pos, topTask.renderOptions.startY + index * taskRowHeight);
+              let rectEl = taskPGroup.addShape('rect', {
+                attrs: {
+                  x: pos.x,
+                  y: topTask.renderOptions.startY + ((index + 1)* (this.taskRowHeight + this.rowSpanDis)),
+                  width: pos.width,
+                  height: this.taskRowHeight,
+                  fill: this.statusColor(_taskItem),
+                  stroke: 'black',
+                  radius: [2, 4],
+                },
+              });
+              rectEl.setZIndex(50)
+              rectEl._pdata = _taskItem;
+              _taskItem._rectEl = rectEl
+              rectEl.on('mouseover', (ev) => {
+                this.handleClick(ev.target, 'enter', ev);
+              });
+              rectEl.on('mouseleave', (ev) => {
+                this.handleClick(ev.target, 'leave', ev);
+              });
+              rectEl.on('click', (ev) => {
+                this.handleClick(ev.target, 'click', ev);
+              });
+            }
+          });
+        });
+  
+        taskGroup.show();
+      } else {
+        if (topTask.gGroup) {
+          // topTask.gGroup.hide()
+          topTask.gGroup = null;
+        }
+      }
+    } catch (error) {      
+      console.error('drawTasks error:', error)
+    }
+  });
+
+  this.postDrawTasksCallBack()
+}
+
+/**
+ * 根据 Task 计算矩形位置
+ *
+ */
+GanttChartMonth.prototype.calRectPos = function(taskItem) {
+  let duraStartAt = new Date(taskItem.startDate) - new Date(this.startAt.format('YYYY-MM-DD'));
+  let secondsStartAt = duraStartAt/1000
+
+  let duraEndAt = new Date(taskItem.endDate) - new Date(taskItem.startDate);
+  let secondsEndAt = duraEndAt/1000
+  return {
+    x: secondsStartAt * this.timePerPix,
+    y: 0,
+    width: secondsEndAt * this.timePerPix,
+    height: 0,
+  };
+}
+
+/**
+ * 主函数
+ *
+ */
+
+GanttChartMonth.prototype.main = function() {  
+  this.initDrawingReady();
+}

+ 0 - 438
src/utils/ganttChart/GanttChart_old.js

@@ -1,438 +0,0 @@
-import moment from 'moment';
-/**
- * 数据定义区域
- *
- */
-/**
- * 甘特图
- * @param {} options 
- */
-export function GanttChart(options) {
-  // 任务列表
-  this.tasks = options.tasks || [];
-  // AntVG Canvas
-  this.gCanvas = null;
-  // 视口宽度 800,可视区域
-  this.viewWidth = options['viewWidth'] || 800;
-  // 物理画布宽度 800
-  this.cWidth = options['cWidth'] || 2400;
-  this.cHeight = options['cHeight'] || 600;
-  // 画布偏移位置
-  this.startPos = 0;
-  // 是否拖动中
-  this.draging = false;
-  // 开始拖动事件
-  this.startEvent = null;
-  // 结束拖动事件
-  this.endEvent = null;
-  // 拖动过程事件
-  this.dragingEvent = null;
-  // 拖动偏移量
-  this.offsetDis = options['viewWidth'] || 800;
-  // 拖动定时器
-  this.dragTimer = null;
-  // 每天的间隔宽度
-  this.dayStep = 40;
-  // 分组标题高度
-  this.groupTitleHeight = 38;
-  // 任务矩形高度
-  this.taskRowHeight = 16;
-  // 每行任务的纵向间距
-  this.rowSpanDis = 22;
-  // 总天数
-  this.daysCount = options['daysCount'] || 60;
-  // 任务图距离顶部高度
-  this.graphTopDis = 20
-  
-  // 每像素代表的小时数
-  this.timePerPix = this.cWidth/this.daysCount/24/3600
-  // 当前视图开始时间,向前推N天
-  this.startAt = moment().subtract(this.daysCount / 3, 'days');
-  this.endAt = moment(this.startAt).add(this.daysCount, 'days');
-  this.graphDiv = document.getElementById(options['chartContainer']);
-  // 图形容器组
-  this.graphGroup = null;
-  // 上一次拖动的事件
-  this.lastDragEv = null;
-  // 回调事件
-  this.callback = options.callback || null;
-}
-
-
-/**
- * 设置数据
- * @param {*} _tasks 
- */
-GanttChart.prototype.changeTasks = function(_tasks){
-  this.tasks = _tasks
-}
-
-/**
- * 打开关闭分组
- */
-
-GanttChart.prototype.toggle = function(index) {
-  if (this.tasks[index].open) {
-    this.tasks[index].open = false;
-  } else {
-    this.tasks[index].open = true;
-  }
-  this.processData();
-  this.drawTasks();
-}
-
-/**
- * 预处理数据
- */
-GanttChart.prototype.processData = function() {
-  for (let i = 0; i < this.tasks.length; i++) {
-    let currentTopTask = this.tasks[i];
-    let lastTopTask = null;
-    currentTopTask.renderOptions = {};
-    if (i != 0) {
-      // 非0个,要补上前面的数据
-      lastTopTask = this.tasks[i - 1];
-      currentTopTask.renderOptions.startY = lastTopTask.renderOptions.endY + 20;
-    } else {
-      // 第一个
-      currentTopTask.renderOptions.startY = this.graphTopDis;
-    }
-    if (currentTopTask.open) {
-      currentTopTask.renderOptions.endY =
-        currentTopTask.renderOptions.startY + this.rowSpanDis + this.groupTitleHeight + currentTopTask.dataList.length * this.taskRowHeight;
-    } else {
-      currentTopTask.renderOptions.endY = currentTopTask.renderOptions.startY + this.groupTitleHeight;
-    }
-  }
-}
-
-/**
- * 强制清空图像,重绘
- */
-GanttChart.prototype.forceRefreshGraph = function() {
-  this.tasks.forEach((topTask) => {
-    topTask.gGroup = null;
-  });
-  this.gCanvas.destroy();
-  this.initDrawingReady();
-}
-
-/**
- * 准备绘制,用于初始化和强制刷新
- */
-GanttChart.prototype.initDrawingReady = function() {
-  this.initCanvas();
-  this.initDragHandler();
-  this.drawTimeZone();
-  this.processData();
-  this.drawTasks();
-  this.graphGroup = null
-}
-
-/**
- * 翻页
- */
-GanttChart.prototype.pageTo = function(dir = 'next') {
-  if (dir == 'next') {
-    // 向后翻页`
-    this.startAt = this.startAt.add(this.daysCount, 'days');
-    this.offsetDis = 0
-  } else {
-    // 向前翻页
-    this.startAt = this.startAt.subtract(this.daysCount, 'days');
-    this.offsetDis = 2*this.viewWidth
-  }
-  this.endAt = moment(this.startAt).add(this.daysCount, 'days');
-  console.log('已翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'), this.offsetDis);
-  // offsetDis = viewWidth;
-  this.forceRefreshGraph();
-}
-// 上次点击时间,用于滚动时误触停止
-let lastClickAt = null;
-/**
- * 执行拖动
- * 改变graphDiv 滚动距离
- * 到达边界距离后,刷新页面
- */
-GanttChart.prototype.doDrag = function(sEvent, eEvent) {
-  if (sEvent == null) {
-    sEvent = this.startEvent;
-  }
-  
-  let sPos = sEvent.clientX;
-  let cPos = eEvent.clientX;
-  // 滚动距离
-  let dis = cPos - sPos;
-  let tempDis = this.offsetDis
-  // console.log('offsetDis before:', this.offsetDis, dis)
-  this.offsetDis = this.offsetDis - dis / 2;
-  // console.log('draging...',tempDis, this.offsetDis, dis)
-  if (this.offsetDis <= -20) {
-    // 向前滑动,向前翻页
-    console.log('此处应该向前翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'),this.offsetDis);
-    this.offsetDis = this.viewWidth;
-    this.pageTo('prev');
-  }
-  if (this.offsetDis - 20 >= 2964 ){ //cWidth - viewWidth) {
-    // 向后滑动,向后翻页
-    console.log('此处应该向后翻页', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'),this.offsetDis);
-    this.offsetDis = this.viewWidth;
-    this.pageTo('next');
-  }
-  this.graphDiv.scrollLeft = this.offsetDis;
-}
-
-/**
- * 初始化抓取拖动事件
- */
-
-GanttChart.prototype.initDragHandler = function() {
-  this.graphDiv.scrollLeft = this.offsetDis;
-  let _canvas = document.querySelector('#ganttContainer>canvas');
-  _canvas.addEventListener('mousedown', (ev) => {
-    this.draging = true;
-    this.startEvent = ev;
-    this.dragingEvent = null;
-    this.endEvent = null;
-    this.lastClickAt = new Date();
-    this.lastClickAt = ev;
-    this.lastDragEv = ev;
-  });
-
-  _canvas.addEventListener('mouseup', (ev) => {
-    this.draging = false;
-    this.endEvent = ev;
-  });
-
-  _canvas.addEventListener('mousemove', (ev) => {
-    // console.log('this over', this)
-    if (this.draging) {
-      if (new Date() - this.lastClickAt < 20) {
-        return false;
-      }
-      this.dragingEvent = ev;
-      this.doDrag(this.lastDragEv, ev);
-      this.lastDragEv = ev;
-    }
-  });
-  _canvas.addEventListener('mouseleave', (ev) => {
-    console.log('leave...恢复')
-    this.draging = false;
-    this.endEvent = ev;
-  });
-}
-/**
- * 初始化画布
- *
- */
-
-GanttChart.prototype.initCanvas = function() {
-  this.gCanvas = new G.Canvas({
-    container: 'ganttContainer',
-    width: this.cWidth,
-    height: 800,
-  });
-}
-
-/**
- * 绘制时间区域
- */
-
-GanttChart.prototype.drawTimeZone = function() {
-  console.log('时间段', this.startAt.format('YYYY-MM-DD'),this.endAt.format('YYYY-MM-DD'));
-  let start = moment(this.startAt);
-  let timeGroup = this.gCanvas.addGroup();
-  timeGroup._tname = 'TimeGroup';
-  // 绘制第一级
-  timeGroup.addShape('text', {
-    attrs: {
-      x: 20,
-      y: 20,
-      fontSize: 12,
-      text: start.format('YYYY-MM'),
-      lineDash: [10, 10],
-      fill: '#8D9399',
-    },
-  });
-  timeGroup.addShape('text', {
-    attrs: {
-      x: 20 + this.viewWidth,
-      y: 20,
-      fontSize: 12,
-      text: start.add(this.daysCount / 3, 'days').format('YYYY-MM'),
-      lineDash: [10, 10],
-      fill: '#8D9399',
-    },
-  });
-  timeGroup.addShape('text', {
-    attrs: {
-      x: 20 + this.viewWidth * 2,
-      y: 20,
-      fontSize: 12,
-      text: start.add(this.daysCount / 3, 'days').format('YYYY-MM'),
-      lineDash: [10, 10],
-      fill: '#8D9399',
-    },
-  });
-  let startSecond = moment(this.startAt);
-  // 绘制第二级
-  for (let i = 0; i < this.daysCount; i++) {
-    let timeText = startSecond.add(1, 'days').format('DD');
-    timeGroup.addShape('text', {
-      attrs: {
-        x: 40 * i,
-        y: 40,
-        fontSize: 10,
-        text: timeText,
-        lineDash: [10, 10],
-        fill: '#8D9399',
-      },
-    });
-  }
-}
-
-/**
- * 处理点击
- */
-GanttChart.prototype.handleClick = function(task, flag, ev) {
-  // let detailDiv = document.getElementById('detailDiv')
-  if(flag == 'enter'){
-    // detailDiv.style.display = 'block'
-    // detailDiv.style.left = ev.clientX+'px';
-    // detailDiv.style.top = ev.clientY+'px';
-    // document.getElementById('detailTaskName').textContent = task._pdata.description
-    // document.getElementById('detailTaskStatus').textContent = task._pdata.status
-    // document.getElementById('detailTaskStartDate').textContent = task._pdata.startDate
-    // document.getElementById('detailTaskEndDate').textContent = task._pdata.endDate
-    console.log('show:', task);
-  } else if (flag === 'leave'){
-    // detailDiv.style.display = 'none'
-    console.log('hide:', task);
-  } else {
-    this.callback(task);
-    console.log('click:', task);
-  }
-}
-
-
-/**
- * 根据任务状态区分颜色
- * 
- */
-GanttChart.prototype.statusColor =function(task) {
-  switch (task.status) {
-    case '按时完成':
-      return 'aqua';
-      break;
-    case '计划批准':
-      return '#ff9800';
-      break;
-    case '已完成':
-      return '#19b720';
-      break;
-    default:
-      break;
-  }
-}
-
-/**
- * 判断任务是否在视图内
- * 
- */ 
-GanttChart.prototype.isInView = function(task) {
-  let isLessThanEndAt = (task.endDate <= this.startAt.format('YYYY-MM-DD'))
-  let isGreaterThanStartAt = task.startDate >= this.endAt.format('YYYY-MM-DD')
-  return !(isLessThanEndAt || isGreaterThanStartAt)
-}
-
-/**
- * 分组绘制任务块
- *
- */
-
-GanttChart.prototype.drawTasks = function() {
-  if (this.graphGroup) {
-    this.graphGroup.clear();
-  } else {
-    this.graphGroup = this.gCanvas.addGroup();
-    this.graphGroup._tname = 'graphGroup';
-  }
-  // 第一层循环,用于分组,例如,维保--xxxx
-  this.tasks.forEach((topTask, topIndex) => {
-    if (topTask.open) {
-      let taskGroup = null;
-      taskGroup = this.graphGroup.addGroup();
-      taskGroup._tname = 'TaskGroup_' + topTask.id;
-      topTask.gGroup = taskGroup;
-      // 第二层循环,用于 区分具体多少任务,例如,维保-商管1/商管2...    
-      topTask.dataList.forEach((taskP, index) => {                            
-        let taskPGroup = taskGroup.addGroup();
-        taskGroup.addGroup(taskPGroup);
-        // 第三层循环,用户区分每个子任务的执行时间段,例如:维保-商管1-2020.05-2020.06 / 2020.08- 2020.09
-        taskP.tasks.forEach((_taskItem, _index) => {
-          let _isInView = this.isInView(_taskItem)
-          // 在视图中才显示
-          if(_isInView){
-            let pos = this.calRectPos(_taskItem);
-            // console.log('render rect:', _taskItem, pos, topTask.renderOptions.startY + index * taskRowHeight);
-            let rectEl = taskPGroup.addShape('rect', {
-              attrs: {
-                x: pos.x,
-                y: topTask.renderOptions.startY + (index* (this.taskRowHeight + this.rowSpanDis)),
-                width: pos.width,
-                height: this.taskRowHeight,
-                fill: this.statusColor(_taskItem),
-                stroke: 'black',
-                radius: [2, 4],
-              },
-            });
-            rectEl._pdata = _taskItem;
-            rectEl.on('mouseover', (ev) => {
-              this.handleClick(ev.target, 'enter', ev);
-            });
-            rectEl.on('mouseleave', (ev) => {
-              this.handleClick(ev.target, 'leave', ev);
-            });
-            rectEl.on('click', (ev) => {
-              this.handleClick(ev.target, 'click', ev);
-            });
-          }
-        });
-      });
-
-      taskGroup.show();
-    } else {
-      if (topTask.gGroup) {
-        // topTask.gGroup.hide()
-        topTask.gGroup = null;
-      }
-    }
-  });
-}
-
-/**
- * 根据 Task 计算矩形位置
- *
- */
-GanttChart.prototype.calRectPos = function(taskItem) {
-  let duraStartAt = new Date(taskItem.startDate) - new Date(this.startAt.format('YYYY-MM-DD'));
-  let secondsStartAt = duraStartAt/1000
-
-  let duraEndAt = new Date(taskItem.endDate) - new Date(taskItem.startDate);        
-  let secondsEndAt = duraEndAt/1000
-  return {
-    x: secondsStartAt * this.timePerPix,
-    y: 0,
-    width: secondsEndAt * this.timePerPix,
-    height: 0,
-  };
-}
-
-/**
- * 主函数
- *
- */
-
-GanttChart.prototype.main = function() {  
-  this.initDrawingReady();
-}

+ 66 - 19
src/views/analysis/GanttChart.vue

@@ -11,7 +11,7 @@
         v-model="systemId"
         :selectdata="systemList"
         :placeholder="'请选择'"
-        @change="getGanttChartData"
+        @change="changeSystem"
       />
       <div class="legend-container">
         <div v-for="(item) in legends" :key="'key_' + item.id" class="item-legend">
@@ -19,7 +19,7 @@
           <div>{{item.text}}</div>
         </div>
         <div>
-          <el-radio-group v-model="timeType">
+          <el-radio-group v-model="timeType" @change="changeView">
             <el-radio style="line-height: 32px;margin-right: 16px;" label="month">月视图</el-radio>
             <el-radio style="line-height: 32px;" label="day">日视图</el-radio>
           </el-radio-group>
@@ -140,7 +140,8 @@ import { Tree } from "meri-design";
 import _ from "lodash";
 import moment from "moment";
 // import '../../utils/ganttChart/g.js';
-import { GanttChart } from "../../utils/ganttChart/GanttChart.js";
+import { GanttChartDay } from "../../utils/ganttChart/GanttChart_day.js";
+import { GanttChartMonth } from "../../utils/ganttChart/GanttChart_month.js";
 import { parse } from "path";
 import Task from "../../assets/svg/task.svg";
 import PlanTime from "../../assets/svg/plan_time.svg";
@@ -181,6 +182,8 @@ export default {
       ], // 图例
       timeType: "month", // 甘特图时间类型
       treeData: [], // 树结构数据
+      startTime: null, // 甘特图开始时间
+      endTime: null, // 甘特图结束时间
 
       // 弹窗相关
       showDetail: false, // 弹框显示状态
@@ -212,7 +215,7 @@ export default {
       ganttDetail: {}, // 甘特图明细
       tableData: [], // 表数据
 
-      showImgDetail: false // 查看更多图片弹框显示状态
+      showImgDetail: false, // 查看更多图片弹框显示状态
     };
   },
 
@@ -228,11 +231,21 @@ export default {
   computed: {},
 
   mounted() {
+    this.initChartTime();
     this.getSystemList();
   },
 
   methods: {
     /**
+     * 初始化甘特图请求时间
+     */
+    initChartTime() {
+      let endTime = new Date().getTime(),
+          startTime = endTime - 1000*60*60*24*365;
+      this.startTime = startTime;
+      this.endTime = endTime;
+    },
+    /**
      * 获取系统列表数据
      */
     getSystemList() {
@@ -279,6 +292,27 @@ export default {
       return [startTime, endTime];
     },
     /**
+     * 切换系统
+     */
+    changeSystem() {
+      if (window.gc) {
+        gc.gCanvas.destroy();
+        window.gc = null;
+      }
+      this.getGanttChartData();
+    },
+    /**
+     * 切换视图
+     */
+    changeView() {
+      console.log('timeType', this.timeType)
+      if (window.gc) {
+        gc.gCanvas.destroy();
+        window.gc = null;
+      }
+      this.getGanttChartData();
+    },
+    /**
      * 获取甘特图数据
      */
     getGanttChartData() {
@@ -286,8 +320,8 @@ export default {
       let param = {
         smsxt: this.systemId,
         plazaId: 1000423,
-        startDate: 20000101000000, // time[0]
-        endDate: 20200708000000 // time[1]
+        startDate: this.startTime, // time[0]
+        endDate: this.endTime // time[1]
       };
       queryGanttChart("/data/base/queryGanttChart", param).then(res => {
         const { dsfList, wbList, zwList, result } = res;
@@ -323,20 +357,33 @@ export default {
             };
           });
           console.log("taskData", taskData);
-          if (window.gc) {
-            gc.gCanvas.destroy();
+          if (!window.gc) {
+            let width = this.$refs.chartContainer.offsetWidth;
+            let handleFn = null;
+            if (this.timeType === 'month') {
+              handleFn = GanttChartMonth
+            } else {
+              handleFn = GanttChartDay
+            }
+            window.gc = new handleFn({
+              chartParentContainer: "chartContainer",
+              chartContainer: "ganttContainer",
+              viewWidth: width,
+              cWidth: 3 * width,
+              tasks: taskData,
+              daysCount: this.timeType === 'month'? 365 : parseInt((3 * width) / 40),
+              callback: this.showDialog,
+              pageToCallback: (data)=>{
+                const { startAt, endAt } = data;
+                this.startTime = new Date(startAt).getTime();
+                this.endTime = new Date(endAt).getTime();
+                this.getGanttChartData();
+              }
+            });
+            gc.main();
+          } else {
+            gc.changeTasks(taskData)
           }
-          let width = this.$refs.chartContainer.offsetWidth;
-          window.gc = new GanttChart({
-            chartParentContainer: "chartContainer",
-            chartContainer: "ganttContainer",
-            viewWidth: width,
-            cWidth: 3 * width,
-            tasks: taskData,
-            daysCount: parseInt((3 * width) / 40),
-            callback: this.showDialog
-          });
-          gc.main();
         }
       });
     },