vue渲染甘特图

1,安装模块

	npm install dhtmlx-gantt
	npm install font-awesome

2,引入模块

	import { gantt } from 'dhtmlx-gantt';
	import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
	import 'font-awesome/css/font-awesome.min.css';

3,定义标签、数据容器、网格及进度条样式

<template>
  <div class="app-container">
    <div ref="gantt" class="gantt-container"></div>
  </div>
</template>
		 data() {
			return {
				...
					tasks: {
						data: []
					},
				...
			}
  mounted() {
    const than = this;
    //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
    gantt.config.autosize = true;
    //只读模式
    gantt.config.readonly = true;
    //是否显示左侧树表格
    gantt.config.show_grid = true;
    var colHeader = '<div class="gantt_grid_head_cell gantt_grid_head_add" onclick="gantt.AddTask()"></div>';

    gantt.AddTask = function(){
      than.handleAdd();
    };

    //表格列设置
    gantt.config.columns = [
      {
        name: 'text',
        label: '计划名称',
        tree: true,
        width: '280',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
          let style = node.getAttribute("style");
          switch (task.sStatus) {
            case "未开始":
              style += "color: #000000;"
              break;
            case "已开始":
              style += "color: #0033EE;"
              break;
            case "已完成":
              style += "color: #008000;"
              break;
            case "已逾期":
              style += "color: #FF0000;"
              break;
            case "已取消":
              style += "color: #808080;"
              break;
          }
          node.setAttribute("style", style);
        }
      },
      {
        name: "buttons",label: colHeader,width: 75,template: function (task) {
          return (
            '<i class="fa fa-pencil" data-action="edit"></i>' +
            '<i class="fa fa-plus" data-action="add"></i>' +
            '<i class="fa fa-times" data-action="delete"></i>'
            );
        }
      },
      {
        name: 'start_date',
        label: '计划开始',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sPend',
        label: '计划完成',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sRbegin',
        label: '实际开始',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sRend',
        label: '实际完成',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'id',
        label: '编号',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'text',
        label: '项目名称',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sType',
        label: '计划类型',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sStatus',
        label: '计划状态',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'progress',
        label: '完成度',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sAssignor',
        label: '分配人',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sExecutor',
        label: '执行人',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sReinspector',
        label: '复查人',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sVerifier',
        label: '核验人',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'nickName',
        label: '操作人',
        align: "center",
        tree: false,
        width: '100',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'jtaUpdateTime',
        label: '更新时间',
        align: "center",
        tree: false,
        width: '160',
        onrender: function (task, node) {
          node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
        }
      },
      {
        name: 'sDuration',
        label: '工期',
        align: "center",
        tree: false,
        width: '100',
        template: function (obj) {
          return obj.duration + '天'
        },
        hide: false
      },
      

    ];

    gantt.attachEvent("onTaskClick", function(id, e){
      var button = e.target.closest("[data-action]");
      if(button){
        var action = button.getAttribute("data-action");
        switch (action) {
          case "edit":
            than.handleUpdate({sId: id});
            break;
          case "add":
            than.handleAdd({sId: id});
            break;
          case "delete":
            than.handleDelete({sId: id});
            break;
        }
        return false;
      }
      return true;
    });

    var weekScaleTemplate = function (date) {
      var dateToStr = gantt.date.date_to_str("%m %d");
      var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
      var weekNum = gantt.date.date_to_str("第 %W 周");
      return weekNum(date)
    };
    var daysStyle = function (date) {
      var dateToStr = gantt.date.date_to_str("%D");
      if (dateToStr(date) == "六" || dateToStr(date) == "日") return "weekend";
      return "";
    };
    gantt.config.subscales = [{
      unit: "week",
      step: 1,
      template: weekScaleTemplate
    },
    {
      unit: "day",
      step: 1,
      format: "%d"
    }
    ];

    gantt.plugins({
      tooltip: true
    });
    gantt.attachEvent("onGanttReady", function () {
      var tooltips = gantt.ext.tooltips;
      gantt.templates.tooltip_text = function (start, end, task) {
        return task.toolTipsTxt + "<br/>" +
          "阶段:" + task.text + "<br/>" +
          gantt.templates.tooltip_date_format(start)
      };
    });


    //设置任务条进度内容
    gantt.templates.progress_text = function (start, end, task) {
      return "<div style='text-align:left;color:#fff;padding-left:20px'>" + Math.round(task.progress) +
        "% </div>";
    };

    //任务条显示内容
    gantt.templates.task_text = function (start, end, task) {
      return "<div style='text-align:center;color:#fff'>" + task.text + '(' + task.duration + '天)' +
        "</div>";
    }

    //任务条上的文字大小 以及取消border自带样式
    gantt.templates.task_class = function (start, end, item) {
      return item.$level == 0 ? 'firstLevelTask' : 'secondLevelTask'
    }

    gantt.config.layout = {
      css: "gantt_container",
      cols: [{
        width: 680,
        min_width: 680,
        rows: [{
          view: "grid",
          scrollX: "gridScroll",
          scrollable: true,
          scrollY: "scrollVer"
        },
        {
          view: "scrollbar",
          id: "gridScroll",
          group: "horizontal"
        }
        ]
      },
      {
        resizer: true,
        width: 1
      },
      {
        rows: [{
          view: "timeline",
          scrollX: "scrollHor",
          scrollY: "scrollVer"
        },
        {
          view: "scrollbar",
          id: "scrollHor",
          group: "horizontal"
        }
        ]
      },
      {
        view: "scrollbar",
        id: "scrollVer"
      }
      ]
    };

    //时间轴图表中,任务条形图的高度
    // gantt.config.task_height = 28
    //时间轴图表中,甘特图的高度
    // gantt.config.row_height = 36
    //时间轴图表中,如果不设置,只有行边框,区分上下的任务,设置之后带有列的边框,整个时间轴变成格子状。
    gantt.config.show_task_cells = true
    //当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度
    gantt.config.fit_tasks = true
    gantt.config.min_column_width = 40;
    gantt.config.auto_types = true;
    gantt.config.xml_date = "%Y-%m-%d";
    gantt.config.scale_unit = "month";
    gantt.config.step = 1;
    gantt.config.date_scale = "%Y年%M";
    gantt.config.start_on_monday = true;
    gantt.config.scale_height = 90;
    gantt.config.autoscroll = true;
    gantt.config.calendar_property = "start_date";
    gantt.config.calendar_property = "end_date";
    gantt.config.readonly = true;
    gantt.i18n.setLocale('cn');

    // 初始化
    gantt.init(this.$refs.gantt)
    // 数据解析
    gantt.parse(this.tasks)
  },

4,构造数据并设置进度条颜色

          let obj = {
            // 展开树
            open: true,
            // 鼠标悬停提示标题(项目名称)
            toolTipsTxt: element.projectInformation.piFullname,
            // 计划名称
            text: element.sName,
            // 计划开始
            start_date: element.sPbegin,
            // 计划完成
            sPend: element.sPend,
            // 实际开始
            sRbegin: element.sRbegin,
            // 实际完成
            sRend: element.sRend,
            // 编号
            id: element.sId,
            // 工期(天)
            duration: element.sDuration,
            // 父节点ID
            parent: element.sFid,
            // 计划类型
            sType: element.sType,
            // 计划状态
            sStatus: element.sStatus,
            // 更新时间
            jtaUpdateTime: element.jtaUpdateTime,
            // 分配人
            sAssignor: element.sAssignor,
            // 执行人
            sExecutor: element.sExecutor,
            // 复查人
            sReinspector: element.sReinspector,
            // 核验人
            sVerifier: element.sVerifier,
            // 操作人
            nickName: element.nickName,
            // 编号
            id: element.sId,
            // 完成度
            progress: element.sSchedule,
          }

          // #8579DD
          switch (obj.sType) {
            case "总计划":
              obj.color = '#5869C5';
              break;
            case "季度计划":
              obj.color = '#E57000';
              break;
            case "月计划":
              obj.color = '#8579DD';
              break;
            case "周计划":
              obj.color = '#008B8B';
              break;
            case "其他计划":
              obj.color = '#8A2BE2';
              break;
          }
          this.tasks.data.push(obj);
        }

        // 数据解析
        gantt.parse(this.tasks)
        // 刷新数据
        gantt.refreshData();

5,相关样式

</script>
<style lang="scss">
.firstLevelTask {
  border: none;

  .gantt_task_content {
    font-size: 13px;
  }
}

.secondLevelTask {
  border: none;
}

.thirdLevelTask {
  border: 2px solid #da645d;
  color: #da645d;
  background: #da645d;
}

.milestone-default {
  border: none;
  background: rgba(0, 0, 0, 0.45);
}

.milestone-unfinished {
  border: none;
  background: #5692f0;
}

.milestone-finished {
  border: none;
  background: #84bd54;
}

.milestone-canceled {
  border: none;
  background: #da645d;
}

html,
body {
  margin: 0px;
  padding: 0px;
  height: 100%;
  overflow: hidden;
}

.container {
  height: 100%;
  width: 100%;
  position: relative;

  .gantt_grid_head_cell {
    padding-left: 20px;
    text-align: left !important;
    font-size: 14px;
    color: #333;
  }

  .select-wrap {
    position: absolute;
    top: 25px;
    z-index: 99;
    width: 90px;
    left: 180px;

    .el-input__inner {
      border: none;
    }
  }

  .left-container {
    height: 100%;
  }

  .parent {
    .gantt_tree_icon {
      &.gantt_folder_open {
        // background-image: url(../../../../assets/icons/tree-table.svg) !important;
      }

      &.gantt_folder_closed {
        // background-image: url(../../../../assets/icons/documentation.svg) !important;
      }
    }
  }

  .green,
  .yellow,
  .pink,
  .popular {
    .gantt_tree_icon.gantt_file {
      background: none;
      position: relative;

      &::before {
        content: "";
        width: 10px;
        height: 10px;
        border-radius: 50%;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
    }
  }

  .green {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #84bd54;
      }
    }
  }

  .yellow {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #fcca02;
      }
    }
  }

  .pink {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #da645d;
      }
    }
  }

  .popular {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #d1a6ff;
      }
    }
  }

}

.left-container {
  height: 100%;
}

.gantt_task_content {
  text-align: left;
  padding-left: 10px;
}



#gantt_here{
  width: 100vw;  
  height: 100vh;
}


.fa {
  cursor: pointer;
  font-size: 14px;
  text-align: center;
  opacity: 0.2;
  padding: 5px;
}

.fa:hover {
  opacity: 1;
}

.fa-pencil {
  color: #ffa011;
}

.fa-plus {
  color: #328EA0;
}

.fa-times {
  color: red;
}



</style>

6,效果

参考:

gantthttps://docs.dhtmlx.com/gantt/

完整demo演示

http://61.134.65.198:9103/smartsite/login?redirect=%2Findexicon-default.png?t=M85Bhttp://61.134.65.198:9103/smartsite/login?redirect=%2Findex​​​​​​​备注:

数据载入基于数据库,分页查询、反向规划、表单校验等不赘述,可参考演示源码。

对不起,我之前提到的是一个基于Vue.js开发的通用甘特图组件,而非特定的库或插件。但是,如果你想在Vue.js中使用甘特图,你可以考虑使用dhtmlx-gantt库。 dhtmlx-gantt是一个功能强大的JavaScript甘特图库,它提供了丰富的功能和可定制选项。它可以与Vue.js框架很好地集成,让你可以在Vue.js项目中轻松地创建和管理甘特图。 要在Vue.js中使用dhtmlx-gantt,你需要先安装该库,并在你的Vue组件中引入和初始化甘特图。你可以使用npm或yarn等包管理工具安装dhtmlx-gantt,并在你的Vue组件中引入它。然后,你可以根据需要配置和定制甘特图的外观和行为。 以下是一个简单的示例代码,演示了如何在Vue.js中使用dhtmlx-gantt: ```vue <template> <div id="gantt-chart"></div> </template> <script> import "dhtmlx-gantt"; import "dhtmlx-gantt/codebase/dhtmlxgantt.css"; export default { mounted() { const tasks = [ { id: 1, text: "Task 1", start_date: "2022-01-01", duration: 5 }, { id: 2, text: "Task 2", start_date: "2022-01-06", duration: 3 }, // more tasks... ]; gantt.init("gantt-chart"); gantt.parse({ data: tasks }); } }; </script> <style> #gantt-chart { width: 100%; height: 500px; } </style> ``` 上面的代码演示了在Vue组件的mounted钩子函数中初始化和渲染甘特图。你可以根据自己的需求修改任务数据、甘特图容器的样式以及其他配置选项。 总的来说,dhtmlx-gantt是一个强大且易于使用的甘特图库,适用于在Vue.js项目中展示和管理甘特图。你可以根据该库的文档和示例进行进一步的学习和定制。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

外码斯迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值