当前位置:   article > 正文

vue渲染甘特图_vue甘特图

vue甘特图

1,安装模块

  1. npm install dhtmlx-gantt
  2. npm install font-awesome

2,引入模块

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

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

  1. <template>
  2. <div class="app-container">
  3. <div ref="gantt" class="gantt-container"></div>
  4. </div>
  5. </template>
  1. data() {
  2. return {
  3. ...
  4. tasks: {
  5. data: []
  6. },
  7. ...
  8. }
  1. mounted() {
  2. const than = this;
  3. //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
  4. gantt.config.autosize = true;
  5. //只读模式
  6. gantt.config.readonly = true;
  7. //是否显示左侧树表格
  8. gantt.config.show_grid = true;
  9. var colHeader = '<div class="gantt_grid_head_cell gantt_grid_head_add" onclick="gantt.AddTask()"></div>';
  10. gantt.AddTask = function(){
  11. than.handleAdd();
  12. };
  13. //表格列设置
  14. gantt.config.columns = [
  15. {
  16. name: 'text',
  17. label: '计划名称',
  18. tree: true,
  19. width: '280',
  20. onrender: function (task, node) {
  21. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  22. let style = node.getAttribute("style");
  23. switch (task.sStatus) {
  24. case "未开始":
  25. style += "color: #000000;"
  26. break;
  27. case "已开始":
  28. style += "color: #0033EE;"
  29. break;
  30. case "已完成":
  31. style += "color: #008000;"
  32. break;
  33. case "已逾期":
  34. style += "color: #FF0000;"
  35. break;
  36. case "已取消":
  37. style += "color: #808080;"
  38. break;
  39. }
  40. node.setAttribute("style", style);
  41. }
  42. },
  43. {
  44. name: "buttons",label: colHeader,width: 75,template: function (task) {
  45. return (
  46. '<i class="fa fa-pencil" data-action="edit"></i>' +
  47. '<i class="fa fa-plus" data-action="add"></i>' +
  48. '<i class="fa fa-times" data-action="delete"></i>'
  49. );
  50. }
  51. },
  52. {
  53. name: 'start_date',
  54. label: '计划开始',
  55. align: "center",
  56. tree: false,
  57. width: '100',
  58. onrender: function (task, node) {
  59. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  60. }
  61. },
  62. {
  63. name: 'sPend',
  64. label: '计划完成',
  65. align: "center",
  66. tree: false,
  67. width: '100',
  68. onrender: function (task, node) {
  69. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  70. }
  71. },
  72. {
  73. name: 'sRbegin',
  74. label: '实际开始',
  75. align: "center",
  76. tree: false,
  77. width: '100',
  78. onrender: function (task, node) {
  79. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  80. }
  81. },
  82. {
  83. name: 'sRend',
  84. label: '实际完成',
  85. align: "center",
  86. tree: false,
  87. width: '100',
  88. onrender: function (task, node) {
  89. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  90. }
  91. },
  92. {
  93. name: 'id',
  94. label: '编号',
  95. align: "center",
  96. tree: false,
  97. width: '100',
  98. onrender: function (task, node) {
  99. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  100. }
  101. },
  102. {
  103. name: 'text',
  104. label: '项目名称',
  105. align: "center",
  106. tree: false,
  107. width: '100',
  108. onrender: function (task, node) {
  109. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  110. }
  111. },
  112. {
  113. name: 'sType',
  114. label: '计划类型',
  115. align: "center",
  116. tree: false,
  117. width: '100',
  118. onrender: function (task, node) {
  119. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  120. }
  121. },
  122. {
  123. name: 'sStatus',
  124. label: '计划状态',
  125. align: "center",
  126. tree: false,
  127. width: '100',
  128. onrender: function (task, node) {
  129. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  130. }
  131. },
  132. {
  133. name: 'progress',
  134. label: '完成度',
  135. align: "center",
  136. tree: false,
  137. width: '100',
  138. onrender: function (task, node) {
  139. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  140. }
  141. },
  142. {
  143. name: 'sAssignor',
  144. label: '分配人',
  145. align: "center",
  146. tree: false,
  147. width: '100',
  148. onrender: function (task, node) {
  149. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  150. }
  151. },
  152. {
  153. name: 'sExecutor',
  154. label: '执行人',
  155. align: "center",
  156. tree: false,
  157. width: '100',
  158. onrender: function (task, node) {
  159. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  160. }
  161. },
  162. {
  163. name: 'sReinspector',
  164. label: '复查人',
  165. align: "center",
  166. tree: false,
  167. width: '100',
  168. onrender: function (task, node) {
  169. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  170. }
  171. },
  172. {
  173. name: 'sVerifier',
  174. label: '核验人',
  175. align: "center",
  176. tree: false,
  177. width: '100',
  178. onrender: function (task, node) {
  179. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  180. }
  181. },
  182. {
  183. name: 'nickName',
  184. label: '操作人',
  185. align: "center",
  186. tree: false,
  187. width: '100',
  188. onrender: function (task, node) {
  189. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  190. }
  191. },
  192. {
  193. name: 'jtaUpdateTime',
  194. label: '更新时间',
  195. align: "center",
  196. tree: false,
  197. width: '160',
  198. onrender: function (task, node) {
  199. node.setAttribute("class", "gantt_cell gantt_last_cell gantt_cell_tree " + task.sStatus);
  200. }
  201. },
  202. {
  203. name: 'sDuration',
  204. label: '工期',
  205. align: "center",
  206. tree: false,
  207. width: '100',
  208. template: function (obj) {
  209. return obj.duration + '天'
  210. },
  211. hide: false
  212. },
  213. ];
  214. gantt.attachEvent("onTaskClick", function(id, e){
  215. var button = e.target.closest("[data-action]");
  216. if(button){
  217. var action = button.getAttribute("data-action");
  218. switch (action) {
  219. case "edit":
  220. than.handleUpdate({sId: id});
  221. break;
  222. case "add":
  223. than.handleAdd({sId: id});
  224. break;
  225. case "delete":
  226. than.handleDelete({sId: id});
  227. break;
  228. }
  229. return false;
  230. }
  231. return true;
  232. });
  233. var weekScaleTemplate = function (date) {
  234. var dateToStr = gantt.date.date_to_str("%m %d");
  235. var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
  236. var weekNum = gantt.date.date_to_str("第 %W 周");
  237. return weekNum(date)
  238. };
  239. var daysStyle = function (date) {
  240. var dateToStr = gantt.date.date_to_str("%D");
  241. if (dateToStr(date) == "六" || dateToStr(date) == "日") return "weekend";
  242. return "";
  243. };
  244. gantt.config.subscales = [{
  245. unit: "week",
  246. step: 1,
  247. template: weekScaleTemplate
  248. },
  249. {
  250. unit: "day",
  251. step: 1,
  252. format: "%d"
  253. }
  254. ];
  255. gantt.plugins({
  256. tooltip: true
  257. });
  258. gantt.attachEvent("onGanttReady", function () {
  259. var tooltips = gantt.ext.tooltips;
  260. gantt.templates.tooltip_text = function (start, end, task) {
  261. return task.toolTipsTxt + "<br/>" +
  262. "阶段:" + task.text + "<br/>" +
  263. gantt.templates.tooltip_date_format(start)
  264. };
  265. });
  266. //设置任务条进度内容
  267. gantt.templates.progress_text = function (start, end, task) {
  268. return "<div style='text-align:left;color:#fff;padding-left:20px'>" + Math.round(task.progress) +
  269. "% </div>";
  270. };
  271. //任务条显示内容
  272. gantt.templates.task_text = function (start, end, task) {
  273. return "<div style='text-align:center;color:#fff'>" + task.text + '(' + task.duration + '天)' +
  274. "</div>";
  275. }
  276. //任务条上的文字大小 以及取消border自带样式
  277. gantt.templates.task_class = function (start, end, item) {
  278. return item.$level == 0 ? 'firstLevelTask' : 'secondLevelTask'
  279. }
  280. gantt.config.layout = {
  281. css: "gantt_container",
  282. cols: [{
  283. width: 680,
  284. min_width: 680,
  285. rows: [{
  286. view: "grid",
  287. scrollX: "gridScroll",
  288. scrollable: true,
  289. scrollY: "scrollVer"
  290. },
  291. {
  292. view: "scrollbar",
  293. id: "gridScroll",
  294. group: "horizontal"
  295. }
  296. ]
  297. },
  298. {
  299. resizer: true,
  300. width: 1
  301. },
  302. {
  303. rows: [{
  304. view: "timeline",
  305. scrollX: "scrollHor",
  306. scrollY: "scrollVer"
  307. },
  308. {
  309. view: "scrollbar",
  310. id: "scrollHor",
  311. group: "horizontal"
  312. }
  313. ]
  314. },
  315. {
  316. view: "scrollbar",
  317. id: "scrollVer"
  318. }
  319. ]
  320. };
  321. //时间轴图表中,任务条形图的高度
  322. // gantt.config.task_height = 28
  323. //时间轴图表中,甘特图的高度
  324. // gantt.config.row_height = 36
  325. //时间轴图表中,如果不设置,只有行边框,区分上下的任务,设置之后带有列的边框,整个时间轴变成格子状。
  326. gantt.config.show_task_cells = true
  327. //当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度
  328. gantt.config.fit_tasks = true
  329. gantt.config.min_column_width = 40;
  330. gantt.config.auto_types = true;
  331. gantt.config.xml_date = "%Y-%m-%d";
  332. gantt.config.scale_unit = "month";
  333. gantt.config.step = 1;
  334. gantt.config.date_scale = "%Y年%M";
  335. gantt.config.start_on_monday = true;
  336. gantt.config.scale_height = 90;
  337. gantt.config.autoscroll = true;
  338. gantt.config.calendar_property = "start_date";
  339. gantt.config.calendar_property = "end_date";
  340. gantt.config.readonly = true;
  341. gantt.i18n.setLocale('cn');
  342. // 初始化
  343. gantt.init(this.$refs.gantt)
  344. // 数据解析
  345. gantt.parse(this.tasks)
  346. },

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

  1. let obj = {
  2. // 展开树
  3. open: true,
  4. // 鼠标悬停提示标题(项目名称)
  5. toolTipsTxt: element.projectInformation.piFullname,
  6. // 计划名称
  7. text: element.sName,
  8. // 计划开始
  9. start_date: element.sPbegin,
  10. // 计划完成
  11. sPend: element.sPend,
  12. // 实际开始
  13. sRbegin: element.sRbegin,
  14. // 实际完成
  15. sRend: element.sRend,
  16. // 编号
  17. id: element.sId,
  18. // 工期(天)
  19. duration: element.sDuration,
  20. // 父节点ID
  21. parent: element.sFid,
  22. // 计划类型
  23. sType: element.sType,
  24. // 计划状态
  25. sStatus: element.sStatus,
  26. // 更新时间
  27. jtaUpdateTime: element.jtaUpdateTime,
  28. // 分配人
  29. sAssignor: element.sAssignor,
  30. // 执行人
  31. sExecutor: element.sExecutor,
  32. // 复查人
  33. sReinspector: element.sReinspector,
  34. // 核验人
  35. sVerifier: element.sVerifier,
  36. // 操作人
  37. nickName: element.nickName,
  38. // 编号
  39. id: element.sId,
  40. // 完成度
  41. progress: element.sSchedule,
  42. }
  43. // #8579DD
  44. switch (obj.sType) {
  45. case "总计划":
  46. obj.color = '#5869C5';
  47. break;
  48. case "季度计划":
  49. obj.color = '#E57000';
  50. break;
  51. case "月计划":
  52. obj.color = '#8579DD';
  53. break;
  54. case "周计划":
  55. obj.color = '#008B8B';
  56. break;
  57. case "其他计划":
  58. obj.color = '#8A2BE2';
  59. break;
  60. }
  61. this.tasks.data.push(obj);
  62. }
  63. // 数据解析
  64. gantt.parse(this.tasks)
  65. // 刷新数据
  66. gantt.refreshData();

5,相关样式

  1. </script>
  2. <style lang="scss">
  3. .firstLevelTask {
  4. border: none;
  5. .gantt_task_content {
  6. font-size: 13px;
  7. }
  8. }
  9. .secondLevelTask {
  10. border: none;
  11. }
  12. .thirdLevelTask {
  13. border: 2px solid #da645d;
  14. color: #da645d;
  15. background: #da645d;
  16. }
  17. .milestone-default {
  18. border: none;
  19. background: rgba(0, 0, 0, 0.45);
  20. }
  21. .milestone-unfinished {
  22. border: none;
  23. background: #5692f0;
  24. }
  25. .milestone-finished {
  26. border: none;
  27. background: #84bd54;
  28. }
  29. .milestone-canceled {
  30. border: none;
  31. background: #da645d;
  32. }
  33. html,
  34. body {
  35. margin: 0px;
  36. padding: 0px;
  37. height: 100%;
  38. overflow: hidden;
  39. }
  40. .container {
  41. height: 100%;
  42. width: 100%;
  43. position: relative;
  44. .gantt_grid_head_cell {
  45. padding-left: 20px;
  46. text-align: left !important;
  47. font-size: 14px;
  48. color: #333;
  49. }
  50. .select-wrap {
  51. position: absolute;
  52. top: 25px;
  53. z-index: 99;
  54. width: 90px;
  55. left: 180px;
  56. .el-input__inner {
  57. border: none;
  58. }
  59. }
  60. .left-container {
  61. height: 100%;
  62. }
  63. .parent {
  64. .gantt_tree_icon {
  65. &.gantt_folder_open {
  66. // background-image: url(../../../../assets/icons/tree-table.svg) !important;
  67. }
  68. &.gantt_folder_closed {
  69. // background-image: url(../../../../assets/icons/documentation.svg) !important;
  70. }
  71. }
  72. }
  73. .green,
  74. .yellow,
  75. .pink,
  76. .popular {
  77. .gantt_tree_icon.gantt_file {
  78. background: none;
  79. position: relative;
  80. &::before {
  81. content: "";
  82. width: 10px;
  83. height: 10px;
  84. border-radius: 50%;
  85. position: absolute;
  86. left: 50%;
  87. top: 50%;
  88. transform: translate(-50%, -50%);
  89. }
  90. }
  91. }
  92. .green {
  93. .gantt_tree_icon.gantt_file {
  94. &::before {
  95. background: #84bd54;
  96. }
  97. }
  98. }
  99. .yellow {
  100. .gantt_tree_icon.gantt_file {
  101. &::before {
  102. background: #fcca02;
  103. }
  104. }
  105. }
  106. .pink {
  107. .gantt_tree_icon.gantt_file {
  108. &::before {
  109. background: #da645d;
  110. }
  111. }
  112. }
  113. .popular {
  114. .gantt_tree_icon.gantt_file {
  115. &::before {
  116. background: #d1a6ff;
  117. }
  118. }
  119. }
  120. }
  121. .left-container {
  122. height: 100%;
  123. }
  124. .gantt_task_content {
  125. text-align: left;
  126. padding-left: 10px;
  127. }
  128. #gantt_here{
  129. width: 100vw;
  130. height: 100vh;
  131. }
  132. .fa {
  133. cursor: pointer;
  134. font-size: 14px;
  135. text-align: center;
  136. opacity: 0.2;
  137. padding: 5px;
  138. }
  139. .fa:hover {
  140. opacity: 1;
  141. }
  142. .fa-pencil {
  143. color: #ffa011;
  144. }
  145. .fa-plus {
  146. color: #328EA0;
  147. }
  148. .fa-times {
  149. color: red;
  150. }
  151. </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​​​​​​​备注:

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/499548
推荐阅读
相关标签
  

闽ICP备14008679号