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>

