1、首先把 gantt 官网下载的相关文件放入 resource 文件中。
2、在html文件中引入

3、创建一个gantt components,此框架是vue3 + ts + ant design。
1 <template> 2 <div ref="ganttRef"></div> 3 </template>
1 <script> 2 import { defineComponent, ref, computed, unref, toRaw, onMounted, render } from 'vue'; 3 import { useMessage } from '/@/hooks/web/useMessage'; 4 export default defineComponent({ 5 name: 'Gantt', 6 props: { 7 tasks: { 8 type: Object, 9 default() { 10 return { data: [], links: [] }; 11 }, 12 }, 13 columns: { 14 type: Array, 15 default() { 16 return []; 17 }, 18 }, 19 }, 20 emits: [], 21 setup(props, { attrs, emit, slots }) { 22 const ganttRef = ref(null); 23 const { createMessage, notification } = useMessage(); 24 onMounted(() => { 25 console.log('渲染===================>'); 26 initGanttEvents(); 27 // gantt.config.readonly = true; // 激活甘特图的只读模式 28 // gantt.config.cascade_delete = false; // 嵌套任务的级联删除 29 // gantt.config.keep_grid_width = true; // 要在调整列大小期间保留网格的大小,请将keep_grid_width选项设置为true 30 gantt.config.drag_resize = true; //允许用户通过拖拽任务的条形图的两端来改变工期 31 gantt.config.drag_move = true; //允许用户拖动条形图来改变位置 32 gantt.config.drag_progress = true; // 允许用户推拽条形图上用来调整进度百分比的小按钮 33 gantt.config.xml_date = '%Y-%m-%d'; 34 // gantt.config.columns = props.columns; 35 // 重绘操作 36 // gantt.refreshData(); 37 gantt.config.duration_unit = 'day'; //工期计算的基本单位 hour 38 gantt.config.duration_step = 1; //工期计算的倍数 39 gantt.config.work_time = true; // 允许在工作时间而不是日历时间计算任务的持续时间 40 // gantt.config.scale_height = 28 * 3; //设置甘特图的表头高度 41 // 改变布局 42 setLayoutConfig('gridAndTimeLine'); 43 // 改变时间 44 setScaleConfig('day'); 45 gantt.config.row_height = 44; 46 gantt.config.show_links = true; //允许显示鼠标移动到进度条上时显示前后两个小圆点(是否显示依赖连线) 47 gantt.i18n.setLocale('cn'); //本地化 48 gantt.config.redo = true; // 重做功能 49 gantt.config.undo = true; // 撤销功能 50 gantt.config.multiselect = true; // 多选 51 /** 52 * https://docs.dhtmlx.com/gantt/desktop__undo_redo.html 53 * 想要撤回在甘特图中做出的修改,调用undo方法即可: gantt.undo(); 54 * 获取储存的undo命令,使用getUndoStack方法即可:var stack = gantt.getUndoStack(); 返回值都是命令对象的数组 55 * 56 * 想要重做在甘特图中做出的修改,调用redo方法即可:gantt.redo(); 57 * 获取储存的redo命令,使用getRedoStack方法即可:var stack = gantt.getRedoStack(); 返回值都是命令对象的数组 58 */ 59 gantt.plugins({ 60 // 启用全屏插件 61 fullscreen: true, 62 // 启用撤销插件 63 undo: true, 64 // 启用tooltip 65 // tooltip: true, 66 multiselect: true, 67 // 标记 68 marker: true, 69 // 自动调度 70 // auto_scheduling: true, 71 }); 72 // gantt.config.auto_scheduling = true; 73 // gantt.config.auto_scheduling_strict = true; 74 // gantt.config.auto_scheduling_compatibility = true; 75 // 允许在出现意外行为时显示错误警报 76 gantt.config.show_errors = false; 77 // 自动扩展时间刻度以适应所有显示的任务 78 gantt.config.fit_tasks = true; 79 // 双击task时,弹出lightbox弹出框 80 gantt.config.details_on_dblclick = false; 81 // 设置工具提示隐藏之前的时间长度,以毫秒为单位 82 // gantt.config.tooltip_hide_timeout = 5000; 83 // 指定将应用于时间轴区域行的 CSS 类 84 gantt.templates.task_row_class = function (start, end, task) { 85 // console.log('task_row_class', task); 86 let style = ''; 87 if (task.type == 'project') { 88 style = 'row_project'; 89 } else { 90 style = 'row_task'; 91 } 92 return 'gantt_row_demo ' + style; 93 }; 94 // 指定将应用于用户拖动链接时出现的弹出窗口的 CSS 类 95 gantt.templates.drag_link_class = function (from, from_start, to, to_start) { 96 // console.log(from, from_start, to, to_start); 97 let add = ''; 98 if (from && to) { 99 let allowed = gantt.isLinkAllowed(from, to, from_start, to_start); 100 add = ' ' + (allowed ? 'gantt_link_allow' : 'gantt_link_deny'); 101 } 102 return 'gantt_link_tooltip' + add; 103 }; 104 // 指定将应用于链接的 CSS 类 105 gantt.templates.link_class = function (link) { 106 // console.log('link_class', link); 107 return 'line_task_tofflon'; 108 }; 109 // gantt.config.undo_actions = { 110 // update: 'update', 111 // remove: 'remove', // remove an item from datastore 112 // add: 'add', 113 // }; 114 gantt.config.undo_steps = 10; //要定义可以还原的步骤数 115 /*gantt.templates.timeline_cell_class = function (item, date) { 116 if (date.getDay() == 0 || date.getDay() == 6) { 117 return 'weekend'; 118 } 119 };*/ 120 // gantt.clearAll(); //清空数据 121 // gantt.render(); 122 gantt.init(unref(ganttRef)); 123 initDataProcessor(); 124 }); 125 126 // 动态修改布局 127 function setLayoutConfig(level) { 128 console.log(level); 129 switch (level) { 130 case 'gridAndTimeLine': 131 // 布局 132 //展示配置滚动条 133 gantt.config.layout = { 134 css: 'gantt_container', 135 cols: [ 136 { 137 width: 720, 138 rows: [ 139 { 140 view: 'grid', 141 scrollX: 'gridScroll', 142 // scrollable: true, 143 scrollY: 'scrollVer', 144 }, 145 { view: 'scrollbar', id: 'gridScroll', group: 'horizontal' }, 146 ], 147 // gravity: 2 148 }, 149 { resizer: true, width: 1 }, 150 { 151 rows: [ 152 { view: 'timeline', scrollX: 'scrollHor', scrollY: 'scrollVer' }, 153 { view: 'scrollbar', id: 'scrollHor', group: 'horizontal' }, 154 ], 155 }, 156 { view: 'scrollbar', id: 'scrollVer' }, 157 ], 158 }; 159 gantt.resetLayout(); 160 gantt.render(); 161 break; 162 case 'grid': 163 // 布局 164 gantt.config.layout = { 165 css: 'gantt_container', 166 rows: [ 167 { 168 cols: [ 169 { 170 // 默认任务列表 171 view: 'grid', 172 scrollX: 'scrollHor', 173 scrollY: 'scrollVer', 174 }, 175 { 176 view: 'scrollbar', 177 id: 'scrollVer', 178 }, 179 ], 180 }, 181 { 182 view: 'scrollbar', 183 id: 'scrollHor', 184 }, 185 ], 186 }; 187 gantt.resetLayout(); 188 gantt.render(); 189 break; 190 case 'timeLine': 191 // 布局 192 gantt.config.layout = { 193 css: 'gantt_container', 194 rows: [ 195 { 196 cols: [ 197 { 198 // 默认甘特图(时间线) 199 view: 'timeline', 200 scrollX: 'scrollHor', 201 scrollY: 'scrollVer', 202 }, 203 { 204 view: 'scrollbar', 205 id: 'scrollVer', 206 }, 207 ], 208 }, 209 { 210 view: 'scrollbar', 211 id: 'scrollHor', 212 }, 213 ], 214 }; 215 gantt.resetLayout(); 216 gantt.render(); 217 break; 218 } 219 } 220 221 // 动态设置Scale 222 function setScaleConfig(level) { 223 console.log(level); 224 const weekScaleTemplate = function (date) { 225 const dateToStr = gantt.date.date_to_str('%M-%d日'); 226 const weekNum = gantt.date.date_to_str('(%W周)'); 227 const endDate = gantt.date.add(gantt.date.add(date, 1, 'week'), -1, 'day'); 228 return dateToStr(date) + '~' + dateToStr(endDate) + '' + weekNum(date); 229 }; 230 switch (level) { 231 case 'day': 232 gantt.config.scale_height = 28 * 4; 233 gantt.config.subscales = [ 234 { 235 unit: 'year', 236 step: 1, 237 date: '%Y年', 238 }, 239 { 240 unit: 'month', 241 step: 1, 242 date: '%F', 243 }, 244 { 245 unit: 'week', 246 step: 1, 247 template: weekScaleTemplate, 248 }, 249 ]; 250 gantt.config.scale_unit = 'day'; 251 gantt.config.date_scale = '周%D,%d日'; 252 gantt.render(); 253 break; 254 case 'week': 255 gantt.config.subscales = [ 256 { 257 unit: 'year', 258 step: 1, 259 date: '%Y年', 260 }, 261 { 262 unit: 'week', 263 step: 1, 264 template: weekScaleTemplate, 265 }, 266 ]; 267 gantt.config.scale_height = 28 * 3; 268 gantt.config.scale_unit = 'month'; 269 gantt.config.date_scale = '%F'; 270 gantt.render(); 271 break; 272 case 'month': 273 gantt.config.subscales = [ 274 { 275 unit: 'year', 276 step: 1, 277 date: '%Y年', 278 }, 279 ]; 280 gantt.config.scale_unit = 'month'; 281 gantt.config.date_scale = '%F'; 282 gantt.config.scale_height = 28 * 2; 283 gantt.render(); 284 break; 285 case 'year': 286 gantt.config.subscales = []; 287 gantt.config.scale_unit = 'year'; 288 gantt.config.date_scale = '%Y年'; 289 gantt.config.scale_height = 28 * 2; 290 gantt.render(); 291 break; 292 } 293 } 294 295 function initGanttEvents() { 296 console.log(gantt.$_eventsInitialized); 297 if (!gantt.$_eventsInitialized) { 298 // 当用户双击链接时触发 299 gantt.attachEvent('onLinkDblClick', function (id, e) { 300 console.log('onLinkDblClick', id, e); 301 //any custom logic here 302 return true; 303 }); 304 305 // 在用户删除链接前触发 306 gantt.attachEvent('onBeforeLinkDelete', function (id, item) { 307 return true; 308 }); 309 gantt.$_eventsInitialized = true; 310 } 311 } 312 313 function initDataProcessor() { 314 if (!gantt.$_dataProcessorInitialized) { 315 gantt.$_dataProcessorInitialized = true; 316 } 317 } 318 319 return { ganttRef, gantt, setScaleConfig, setLayoutConfig }; 320 }, 321 }); 322 </script>

