当前位置:   article > 正文

超多功能的免费甘特图 适用(vue)_甘特图插件vue

甘特图插件vue

使用的插件:dhtmlx-gantt

下载方式:npm i dhtmlx-gantt

插件官网:Gantt API Gantt Docs (dhtmlx.com)

作品展示

直接上全部代码

  1. <template>
  2. <div class="card">
  3. <el-card>
  4. <div class="ard">
  5. <el-radio-group v-model="radio2">
  6. <el-radio-button label="全部" />
  7. <el-radio-button label="进行中" />
  8. <el-radio-button label="已超时" />
  9. <el-radio-button label="已完成" />
  10. </el-radio-group>
  11. <div class="asd">
  12. <p>开始时间:</p>
  13. <el-date-picker v-model="value1" type="date" placeholder="点击选择时间" :size="size" />
  14. </div>
  15. <div class="asd">
  16. <p>结束时间:</p>
  17. <el-date-picker v-model="value1" type="date" placeholder="点击选择时间" :size="size" />
  18. </div>
  19. <div class="asd">
  20. <p>选择任务类型:</p>
  21. <el-select v-model="value" class="m-2" placeholder="下拉选择" style="width: 170px">
  22. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
  23. </el-select>
  24. </div>
  25. <el-button style="margin-left: 10px;" type="primary" :icon="Filter">筛选</el-button>
  26. <el-button type="primary" :icon="Plus">新增</el-button>
  27. </div>
  28. </el-card>
  29. <el-card class="box-card">
  30. <div class="cardtop">
  31. <div class="margins">
  32. <p><el-color-picker v-model="objs.asd1" show-alpha />攻击组</p>
  33. <p><el-color-picker v-model="objs.asd2" show-alpha />防御组</p>
  34. <p><el-color-picker v-model="objs.asd3" show-alpha />目标组</p>
  35. </div>
  36. <el-radio-group v-model="radio1" size="small">
  37. <el-radio-button label="年" />
  38. <el-radio-button label="月" />
  39. <el-radio-button label="日" />
  40. </el-radio-group>
  41. </div>
  42. <div id="gantt_here" style="margin-top: 10px;" class="gantt-container"></div>
  43. </el-card>
  44. </div>
  45. </template>
  46. <script setup>
  47. import { reactive, toRefs, ref, onBeforeMount, onMounted, watchEffect, defineExpose } from 'vue'
  48. import { gantt } from 'dhtmlx-gantt'
  49. import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'
  50. import { Plus, Filter } from '@element-plus/icons-vue'
  51. const data = reactive({})
  52. const radio1 = ref('年')
  53. const radio2 = ref('全部')
  54. const value1 = ref('')
  55. const value = ref('')
  56. let objs = reactive({
  57. asd1: '#f2e6c2',
  58. asd2: '#b5e09b',
  59. asd3: '#baefe2'
  60. })
  61. let dialogVisible = ref(false)
  62. //初始化甘特图
  63. const initGantt = () => {
  64. var tasks = {
  65. data: [
  66. {
  67. id: 1,
  68. taskname: '明天吃烩菜',
  69. parent: 0,
  70. start_date: "01-04-2018",
  71. progress: 0.3,
  72. duration: 1,
  73. types: 1,
  74. text: '李大厨',
  75. color: objs.asd1,
  76. tsakrank: 0,
  77. },
  78. {
  79. id: 2,
  80. taskname: '明天吃鱼肉',
  81. parent: 0,
  82. start_date: "01-04-2018",
  83. progress: 0.42,
  84. duration: 5,
  85. types: 2,
  86. color: objs.asd2,
  87. text: '王大厨',
  88. tsakrank: 1,
  89. },
  90. {
  91. id: 3,
  92. taskname: '明天吃西餐',
  93. parent: 0,
  94. start_date: "01-04-2018",
  95. progress: 0.65,
  96. duration: 5,
  97. types: 3,
  98. text: '赵大厨',
  99. color: objs.asd3,
  100. tsakrank: 2,
  101. },
  102. {
  103. id: 4,
  104. taskname: '购买水军发动舆论偏差',
  105. parent: 1,
  106. start_date: "01-04-2018",
  107. progress: 0.1,
  108. duration: 1,
  109. types: 1,
  110. text: '李大厨',
  111. color: objs.asd1
  112. },
  113. {
  114. id: 5,
  115. taskname: '编辑一边有效证据的文章',
  116. parent: 2,
  117. start_date: "01-04-2018",
  118. progress: 0.1,
  119. duration: 3,
  120. types: 2,
  121. text: '王大厨',
  122. color: objs.asd2
  123. },
  124. {
  125. id: 6,
  126. taskname: '寻找目标人物关键证据',
  127. parent: 3,
  128. start_date: "01-04-2018",
  129. progress: 0.1,
  130. duration: 3,
  131. types: 3,
  132. text: '赵大厨',
  133. color: objs.asd3
  134. },
  135. {
  136. id: 7,
  137. taskname: '发布目标任务黑料',
  138. parent: 1,
  139. start_date: "03-04-2018",
  140. progress: 0.2,
  141. duration: 2,
  142. types: 1,
  143. text: '李大厨',
  144. color: objs.asd1
  145. },
  146. {
  147. id: 8,
  148. taskname: '打造慈善公益效果',
  149. parent: 2,
  150. start_date: "04-04-2018",
  151. progress: 0.1,
  152. duration: 3,
  153. types: 2,
  154. text: '王大厨',
  155. color: objs.asd2
  156. },
  157. {
  158. id: 9,
  159. taskname: '查看目标亲朋好友博客',
  160. parent: 3,
  161. start_date: "02-04-2018",
  162. progress: 0.1,
  163. duration: 6,
  164. types: 3,
  165. text: '赵大厨',
  166. color: objs.asd3
  167. },
  168. ],
  169. // links: [
  170. // { id: 1, source: 1, target: 2, type: "1" },
  171. // { id: 2, source: 2, target: 3, type: "0" },
  172. // { id: 3, source: 3, target: 4, type: "1" },
  173. // { id: 4, source: 4, target: 5, type: "0" },
  174. // ]
  175. };
  176. gantt.config.grid_width = 350
  177. gantt.config.add_column = false //添加符号
  178. gantt.config.autosize = true//自适应尺寸
  179. gantt.config.autofit = true// 表格列宽自适应
  180. gantt.config.autoscroll = true// 把任务或者连线拖拽到浏览器屏幕外时,自动触发滚动效果
  181. gantt.config.drag_progress = false//取消任务进度条进度拖动
  182. gantt.config.scale_height = 60
  183. gantt.config.row_height = 60
  184. gantt.config.bar_height = 34
  185. gantt.config.fit_tasks = true //自动延长时间刻度,以适应所有显示的任务
  186. gantt.config.auto_types = true //将包含子任务的任务转换为项目,将没有子任务的项目转换回任务
  187. gantt.i18n.setLocale('cn') //设置语言
  188. //时间栏配置
  189. gantt.config.scales = [
  190. { unit: 'month', step: 1, format: '%Y年%m月' },
  191. { unit: 'day', step: 1, format: '%m/%d' },
  192. ]
  193. //左侧列表配置
  194. gantt.config.columns = [
  195. { name: "taskname", label: "任务名称", align: 'left', tree: true, width: 140 },
  196. {
  197. name: "progress", label: "任务优先", align: 'center', width: 80, template: function (task) {
  198. let obj = {
  199. color: task.tsakrank === 0 ? '#ff2b00' : task.tsakrank === 1 ? '#ffab00' : '#409eff',
  200. icon: task.tsakrank === 0 ? 'icon-youxianjiP0' : task.tsakrank === 1 ? 'icon-youxianjiP1' : 'icon-youxianjiP2',
  201. }
  202. return `<div class="jindu" style="color:${obj.color};"><i style="font-size:24px;" class="iconfont ${obj.icon}"></i></div>`
  203. }
  204. },
  205. {
  206. name: "type", label: "任务类别", align: 'center', width: 100, template: function (task) {
  207. let obj = {
  208. color: task.types === 1 ? '#f29d38' : task.types === 2 ? '#65c16f' : '#1890ff',
  209. icon: task.types === 1 ? 'icon-gongji' : task.types === 2 ? 'icon-kaiqifangyu' : 'icon-icon--mubiaoku',
  210. text: task.types === 1 ? '攻击' : task.types === 2 ? '防御' : '目标'
  211. }
  212. return `<div class="tasktype" style="color:${obj.color};font-size:14px;">
  213. <i class="iconfont ${obj.icon}"></i>
  214. <span style="margin-left:3px;"> ${obj.text}</span>
  215. </div>`
  216. }
  217. },
  218. {
  219. name: "progress", label: "任务进度", align: 'center', width: 80, template: function (task) {
  220. return `<div class="jindu" style="width:100%;height:30px;padding-left:10px;font-size:13px;color:black;"><span>${(task.progress * 100).toFixed(0) + "%"}</span></div>`;
  221. }
  222. },
  223. ]
  224. //鼠标移入弹框
  225. // gantt.templates.tooltip_text = function (start, end, task) {
  226. // return `
  227. // <div style="width: 200px;height: 200px;">
  228. // <p>任务名称:这是一个任务</p>
  229. // <p>任务策划:张三</p>
  230. // <p>当前状态:进行中</p>
  231. // <p>任务类别:攻击</p>
  232. // <p>开始时间:2020-12-11</p>
  233. // <p>结束时间:2021-04-13</p>
  234. // </div>
  235. // `
  236. // };
  237. //更改父项图标
  238. gantt.templates.grid_folder = (item) => {
  239. return ""
  240. }
  241. gantt.plugins({
  242. marker: true
  243. });
  244. var date_to_str = gantt.date.date_to_str(gantt.config.task_date);
  245. var today = new Date();
  246. gantt.addMarker({
  247. start_date: today,
  248. css: "today",
  249. text: "今天",
  250. title: "今天: " + date_to_str(today)
  251. });
  252. //更改子项图标
  253. gantt.templates.grid_file = (item) => {
  254. return ""
  255. }
  256. //任务条显示内容
  257. gantt.templates.task_text = function (start, end, task) {
  258. return `
  259. <div style="color:#454545;font-size:14px;font-weight:700;">执行:${task.text}</div>
  260. `
  261. }
  262. //任务条左侧配置
  263. // gantt.templates.leftside_text = function (start, end, task) {
  264. // return `<div class="jindu" style="width:100%;height:30px;background-color:#e6f4ff;padding-left:10px;font-size:13px;color:#629eff;"><span>当前进度${(task.progress * 100).toFixed(0) + "%"}</span></div>`;
  265. // };
  266. //展开树图标
  267. gantt.templates.grid_open = function (item) {
  268. return `<i style="font-size:14px;background:none; color:#1890ff; padding-left:10px;" class="gantt_tree_icon gantt_${item.$open ? "close" : "open"} iconfont ${item.$open ? 'icon-zhankaishousuo' : 'icon-zhankaishousuo1'}"></i>`
  269. };
  270. gantt.init('gantt_here') //初始化
  271. gantt.parse(tasks) //填充数据
  272. //双击事件
  273. gantt.attachEvent("onTaskDblClick", function (id, e) {
  274. // 在这里编写处理双击事件的代码
  275. console.log("双击了任务:" + id);
  276. dialogVisible.value = true
  277. });
  278. }
  279. onBeforeMount(() => { })
  280. onMounted(() => {
  281. initGantt()
  282. })
  283. watchEffect(() => { })
  284. defineExpose({
  285. ...toRefs(data)
  286. })
  287. </script>
  288. <style scoped lang="scss">
  289. ::-webkit-scrollbar {
  290. width: 10px;
  291. }
  292. ::-webkit-scrollbar-track {
  293. background-color: #f1f1f1;
  294. }
  295. ::-webkit-scrollbar-thumb {
  296. background-color: #888;
  297. border-radius: 5px;
  298. }
  299. ::-webkit-scrollbar-thumb:hover {
  300. background-color: #555;
  301. }
  302. .renwus {
  303. width: 100%;
  304. height: 200px;
  305. display: flex;
  306. align-items: center;
  307. justify-content: space-around;
  308. flex-wrap: wrap;
  309. overflow: auto;
  310. }
  311. .renwu {
  312. width: 100%;
  313. height: 200px;
  314. display: flex;
  315. align-items: center;
  316. justify-content: space-around;
  317. flex-wrap: wrap;
  318. }
  319. :deep(.el-progress-circle) {
  320. width: 100px !important;
  321. height: 80px !important;
  322. }
  323. .ps {
  324. padding: 0;
  325. margin: 0;
  326. }
  327. .percentage-value {
  328. display: block;
  329. margin-top: 10px;
  330. font-size: 28px;
  331. }
  332. .percentage-label {
  333. display: block;
  334. margin-top: 10px;
  335. font-size: 12px;
  336. }
  337. .demo-progress .el-progress--line {
  338. margin-bottom: 15px;
  339. width: 350px;
  340. }
  341. .demo-progress .el-progress--circle {
  342. margin-right: 15px;
  343. }
  344. .cardtop {
  345. width: 100%;
  346. height: 100%;
  347. display: flex;
  348. justify-content: space-between;
  349. align-items: center;
  350. .margins {
  351. display: flex;
  352. font-size: 12px;
  353. p {
  354. margin-left: 10px;
  355. :deep(.el-color-picker .el-color-picker__icon) {
  356. opacity: 0;
  357. }
  358. :deep(.el-color-picker__trigger) {
  359. border: none;
  360. width: 25px;
  361. height: 25px;
  362. }
  363. }
  364. }
  365. }
  366. .box-card {
  367. margin-top: 20px;
  368. }
  369. .card {
  370. width: 1500px;
  371. height: 1000px;
  372. margin: 0 auto;
  373. .ard {
  374. width: 100%;
  375. height: 40px;
  376. display: flex;
  377. align-items: center;
  378. }
  379. .icons {
  380. width: 80px;
  381. height: 30px;
  382. display: flex;
  383. align-items: center;
  384. justify-content: center;
  385. border: 1px solid #a0cfff;
  386. color: #46a2ff;
  387. margin-right: 10px;
  388. border-radius: 7px;
  389. background-color: #ecf5ff;
  390. i {
  391. color: #1890ff;
  392. font-size: 14px;
  393. margin-right: 5px;
  394. }
  395. }
  396. }
  397. .asd {
  398. width: 300px;
  399. height: 33px;
  400. border-radius: 5px;
  401. border: 1px dotted #ccc;
  402. margin-left: 20px;
  403. display: flex;
  404. align-items: center;
  405. p {
  406. color: #606266;
  407. margin-left: 5px;
  408. }
  409. :deep(.el-input__wrapper) {
  410. border: none;
  411. box-shadow: none !important;
  412. }
  413. :deep(.el-date-editor.el-input) {
  414. width: 200px !important;
  415. }
  416. :deep(.el-select__wrapper) {
  417. border: none;
  418. box-shadow: none !important;
  419. }
  420. }
  421. :deep(.gantt_layout_cell) {
  422. border-radius: 7px;
  423. }
  424. :deep(.gantt_tree_indent) {
  425. opacity: 0;
  426. }
  427. :deep(.gantt_grid_scale .gantt_grid_head_cell) {
  428. color: #606266;
  429. font-size: 15px;
  430. font-weight: 700;
  431. border-right: 1px solid #ccc !important;
  432. }
  433. :deep(.gantt_scale_cell) {
  434. color: #454545 !important;
  435. }
  436. :deep(.gantt_grid_data .gantt_cell) {
  437. border-right: 1px solid #ccc !important;
  438. padding: 0;
  439. }
  440. :deep(.gantt_task_progress_wrapper) {
  441. border-radius: 5px;
  442. }
  443. :deep(.gantt_task_line.gantt_project) {
  444. border-radius: 5px;
  445. border: none;
  446. }
  447. :deep(.gantt_data_area div) {
  448. border-radius: 5px;
  449. // border:none;
  450. }
  451. :deep(.gantt_tree_content) {
  452. display: flex;
  453. align-items: center;
  454. .jindu {
  455. width: 100%;
  456. display: flex;
  457. justify-content: center;
  458. align-items: center;
  459. color: #4482e3;
  460. border-radius: 10px;
  461. }
  462. .tasktype {
  463. width: 100%;
  464. height: 100%;
  465. display: flex;
  466. justify-content: center;
  467. align-items: center;
  468. }
  469. }
  470. :deep(.gantt_task_line) {
  471. border: none;
  472. }
  473. :deep(.gantt_link_point) {
  474. display: none !important;
  475. }
  476. :deep(.gantt_task_progress) {
  477. height: 100%;
  478. }
  479. .toppingTask {
  480. width: 200px;
  481. height: 200px;
  482. background-color: #1890ff;
  483. }
  484. </style>

不懂的直接区官网查看就好 什么api都有

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

闽ICP备14008679号