前言:
本文基于在較為成熟完整的項目,進行甘特圖模塊開發(fā)的內(nèi)容。并不涉及node相關下載、安裝及vue的相關使用。
1 需安裝的模塊
npm install dhtmlx-gantt
npm install font-awesome
(1) dhtmlxgantt是進行甘特圖開發(fā)過程中所用到的插件庫,用于跨瀏覽器和跨平臺應用程序的功能較為齊全的Gantt圖表。其祖家組件為一個JavaScript庫,提供了一套完整的Ajax驅動的UI組件。
(2)font-awesome為圖標字體庫和css框架。提供了各類css樣式。
2 引入模塊
import { gantt } from 'dhtmlx-gantt';
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import 'font-awesome/css/font-awesome.min.css';
(1)引用dhtmlxgantt.css樣式,顯示插件界面;
(2)引用font-awesome.min.css圖標,為了顯示各種圖表插件。
3 設計頁面格式內(nèi)容
(1)前端展示界面設計:
//采用html5的el插件進行前端界面設計
<template>
//建立容器,在容器下存儲界面樣式與風格
<div class="app-container">
//容器下設計gantt-container,用以裝載甘特圖界面的顯示內(nèi)容
<div ref="gantt" class="gantt-container"></div>
//調用官方在線接口,設置摁鈕方式實現(xiàn)甘特圖導出(支持多種常見格式)
<input value="導出PDF" type="button" onclick="gantt.exportToPDF()"/>
<input value="導出Excel" type="button" onclick='gantt.exportToExcel()'/>
<input value="導出Png" type="button" onclick="gantt.exportToPNG()"/>
<input value="載入execl" type="button" onclick="gantt.load()"/>
//自動導入文件并解析為json格式,便于后續(xù)開發(fā)導入json數(shù)組自動生成甘特圖。
<form action="https://export.dhtmlx.com/gantt" method="post"
enctype="multipart/form-data">
<input type="file" name="file" />
<input type="" name="type" value="excel-parse"/>
<button type="submit">轉為json文件</button>
</form>
</div>
</template>
(2)甘特圖顯示設計(請參考官方文件(內(nèi)容很全只是為英文文檔):
界面示例,可在線編輯操作,便于學習:Gantt : Samples (dhtmlx.com)
官方學習文檔:Gantt API Gantt Docs (dhtmlx.com)
一個網(wǎng)址講解基本與官方文檔一致較為詳細:dhtmlxGantt使用教程:如何導出/導入Excel,導出到iCal-控件新聞-慧都網(wǎng) (evget.com)
一個官方博客,里面解決一些較為復雜的問題,并有示例代碼可在線編輯操作:
DHTMLX Blog - DHTMLX JavaScript Library - News, tips, and info.
<script>
import { gantt } from 'dhtmlx-gantt';
import "dhtmlx-gantt/codebase/dhtmlxgantt.js";
import "./api.js";
import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js";
import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js";
import "dhtmlx-gantt/codebase/locale/locale_cn.js";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import 'font-awesome/css/font-awesome.min.css';
export default {
name: "gantt",
data() {
return {
tasks: {
data: []
}
}
},
created() {
this.getList();
},
mounted() {
const than = this;
//自適應甘特圖的尺寸大小, 使得在不出現(xiàn)滾動條的情況下, 顯示全部任務
gantt.config.autosize = true;
//允許拖拽
gantt.config.drag_project = true;
//只讀模式
//gantt.config.readonly = true;
//是否顯示左側樹表格
gantt.config.show_grid = true;
//定義日期編輯器
var dateEditor = gantt.config.editor_types.date;
gantt.config.editor_types.end_date = gantt.mixin({
set_value: function(value, id, column, node){
var correctedValue = gantt.date.add(value, -1, "day");
return dateEditor.set_value.apply(this, [correctedValue, id, column, node]);
},
get_value: function(id, column, node) {
var selectedValue = dateEditor.get_value.apply(this, [id, column, node]);
return gantt.date.add(selectedValue, 1, "day");
},
}, dateEditor);
//定義各種編輯器及類型
var textEditor = {type: "text", map_to: "text"};
var colorEditor = {type: "color", map_to: "color"};
var progressEditor={type:"text",map_to:"progress"};
var startDateEditor = {type: "date", map_to: "start_date"};
var endDateEditor = {type: "date", map_to: "end_date"};
var priorityEditor={type: "select", map_to: "priority", options:gantt.serverList("priority")};
var durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
//設置甘特圖中各個列相關配置
gantt.config.columns = [
{
name: 'text',
/*height:'40',*/
label: '項目名稱',
editor: textEditor,
resize: true,
tree: true,
width: '230',
}
},
{
name: "add",
label:"",
width: 30
},
{
name:'priority',
align: "center",
label: "優(yōu)先級",
width:50,
editor: priorityEditor,
resize:true,
},
{
name: "color",
align: "center",
label: "顏色",
width:40,
editor: colorEditor,
resize:true,
},
{
name: 'start_date',
label: '項目開始時間',
align: "center",
editor: startDateEditor,
resize:true,
tree: false,
width: '100',
},
{
name: 'end_date',
label: '項目結束時間',
width:100,
align: 'center',
editor: endDateEditor,
resize: true,
},
{
name: 'sDuration',
label: '任務期',
align: "center",
editor: durationEditor,
resize:true,
tree: false,
width: '55',
template: function (obj) {
return obj.duration + '天'
},
hide: false
},
{
name: 'progress',
label: '項目進度',
align: "center",
tree: false,
editor: progressEditor,
resize:true,
width: '50',
},
]
//配置日期格式
gantt.templates.task_end_date = function(date){
return gantt.templates.task_date(new Date(date.valueOf() - 1));
};
var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
gantt.templates.grid_date_format = function(date, column){
if(column === "end_date"){
return gridDateToStr(new Date(date.valueOf() - 1));
}else{
return gridDateToStr(date);
}
}
//配置甘特圖容器中的行列滾動條
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.editor_types.color = {
show: function (id, column, config, placeholder) {
var html = "<div><input type='color' name=''" + column.name + "></div>";
placeholder.innerHTML = html;
},
hide: function () {
},
set_value: function (value, id, column, node) {
this.get_input(node).value = value;
},
get_value: function (id, column, node) {
return this.get_input(node).value || "";
},
is_changed: function (value, id, column, node) {
var input = this.get_input(node);
return input.value !== value;
},
get_input: function (node) {
return node.querySelector("input");
},
is_valid: function (value, id, column, node) {
var input = this.get_input(node);
return !!input.value;
},
focus: function (node) {
var input = this.get_input(node);
input.focus();
}
}
//配置時間規(guī)模,右上方日歷
gantt.config.subscales = [{
unit: "year",
step: 1,
format: "%Y",
template: weekScaleTemplate,
},
{
unit: "day",
step: 1,
format: "%D",
template:daysStyle,
}
];
// 初始化
gantt.init(this.$refs.gantt)
// 數(shù)據(jù)解析
gantt.parse(this.tasks)
//設置任務條進度內(nèi)容
gantt.templates.progress_text = function (start, end, task) {
return "<div style='text-align:left;color:#fff;padding-left:20px'>" + Math.round(task.progress) +
"% </div>";
};
//任務條顯示內(nèi)容
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圖任務懸浮窗位置
gantt.config.tooltip_offset_x = 10;
gantt.config.tooltip_offset_y = 30;
//激活列表展開、折疊功能
gantt.config.open_split_tasks = true;
//創(chuàng)建新事件通過點擊”+“打開燈箱
gantt.config.details_on_create = true;
//甘特圖圖表寬度自適應
gantt.config.autofit = true;
//用戶可以通過拖拽調整行高
gantt.config.resize_rows = true;
//圖標項目欄可以任意拖拽
gantt.config.order_branch = true;
gantt.config.order_branch_free = true;
//新增空白列后新增項目
gantt.config.placeholder_task = true;
//圖標刷新后位置不變
gantt.config.preserve_scroll = true;
gantt.config.round_dnd_dates = true;
//設置甘特圖表頭高度
gantt.config.scale_height = 100;
//是否顯示依賴連線(取消)
gantt.config.show_links = true;
//點擊表頭可排序
gantt.config.sort = true;
//允許拖放
gantt.config.drag_project = true;
// 初始化
gantt.init(this.$refs.gantt)
// 數(shù)據(jù)解析
gantt.parse(this.tasks)
gantt.exportToExcel({
name: "document.xlsx",
columns: [
{id: "text", header: "Title", width: 150},
{id: "start_date", header: "Start date", width: 250, type: "date"}
],
server: "https://myapp.com/myexport/gantt",
visual: true,
cellColors: true,
data: {},
date_format: "dddd d, mmmm yyyy"
});
gantt.exportToPNG({
name: "gantt.png",
locale: "cn",
data: {},
server: "https://export.dhtmlx.com/gantt",
raw: false,
callback: function (res) {
alert(res.gantt);
}
});
gantt.exportToPDF({
name: "gantt.pdf",
locale: "cn",
skin: 'terrace',
data: [],
server: "https://myapp.com/myexport/gantt",
raw: false,
callback: function (res) {
alert(res.data);
}
})
// 初始化
gantt.init(this.$refs.gantt)
// 數(shù)據(jù)解析
gantt.parse(this.tasks)
//表格列寬自適應
gantt.config.autofit=true;
//r任務或者連線拖拽到瀏覽器屏幕外時,自動觸發(fā)滾動效果
gantt.config.autoscroll=true;
//時間軸圖表中,任務條形圖的高度
gantt.config.task_height = 28
//時間軸圖表中,甘特圖的高度
gantt.config.row_height = 36
//時間軸圖表中,如果不設置,只有行邊框,區(qū)分上下的任務,設置之后帶有列的邊框,整個時間軸變成格子狀。
gantt.config.show_task_cells = true
//當task的長度改變時,自動調整圖表坐標軸區(qū)間用于適配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 = "sPend";
gantt.config.readonly = true;
// 初始化
gantt.init(this.$refs.gantt)
// 數(shù)據(jù)解析
gantt.parse(this.tasks)
gantt.i18n.setLocale('cn');
// 初始化
gantt.init(this.$refs.gantt)
// 數(shù)據(jù)解析
gantt.parse(this.tasks)
(3)關于css樣式渲染甘特圖界面
<style lang="scss">
.firstLevelTask {
border: none;
.gantt_task_content {
font-size: 13px;
}
}
.secondLevelTask {
border: none;
}
.weekend{
background: #f4f7f4 !important;
}
.gantt_selected .weekend{
background: #f7eb91 !important;
}
.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;
}
.task-color-cell{
margin:10%;
width:20px;
height:20px;
border:1px solid #cecece;
display:inline-block;
border-radius:20px;
}
.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;
}
.weekend{
background: #f4f7f4;
}
.gantt_selected .weekend{
background: #f7eb91;
}
</style>
最終實現(xiàn)風格如下:

其中支持文本字樣可編輯、日期點擊彈出日歷可選擇日期、不同任務選擇不同顏色,自動顯示進度,進度條總工期和當下進展用深淺色顯示。文章來源:http://www.zghlxwxcb.cn/news/detail-678036.html
同時支持png\pdf/execl/等文件導出。文章來源地址http://www.zghlxwxcb.cn/news/detail-678036.html
到了這里,關于一文搞定dhtmlx-gantt調度界面,vue下使用dhtmlxgantt進行項目甘特圖模塊設計開發(fā)(前端界面顯示篇(1))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!