轉帖|對比評測|編輯:楊鵬連|2020-07-20 09:34:52.730|閱讀 523 次
概述:本文記錄了我是為何棄用 echarts,轉而改用 dhtmlxGantt 完成甘特圖的過程,對一些功能的具體配置進行了詳細的介紹。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
dhtmlxGantt是用于跨瀏覽器和跨平臺應用程序的功能齊全的Gantt圖表。可滿足項目管理應用程序的所有需求,是最完善的甘特圖圖表庫。它允許你創建動態甘特圖,并以一個方便的圖形化方式可視化項目進度。有了dhtmlxGantt,你可以顯示活動之間的依賴關系,顯示具有完成百分比陰影的當前任務狀態以及組織活動到樹結構。
事情是這樣的
早些時候,我接到了一個需求,說要將項目里程碑用甘特圖展示,一臉懵逼的我先是搜一下什么是“甘特圖” :From 百度百科:甘特圖(Gantt chart)又稱為橫道圖、條狀圖(Bar chart)。其通過條狀圖來顯示項目,進度,和其他時間相關的系統進展的內在關系隨著時間進展的情況。
配合圖片感受 :
在 github 上一搜,甘特圖組件不算多,由于時間緊急,當時還沒發現只有413個 的真命天子(dhtmlxGantt),僅試用了前面4款 比較多的:
結果均是以失敗告終(不符合業務需求,改造難度大)。
調整一下心情,重新踏上甘特圖組件調研之路 ,終于,被我發現了 Top 5 : Best free jQuery and JavaScript Dynamic Gantt Charts for web applications 這個網站,真命天子 dhtmlxGantt 排名TOP1,于是我開始對其進行了試用及研究。
經過一番折騰,終于做出了符合業務方需求的甘特圖 :
有一說一,與 echarts 模擬的甘特圖一比,dhtmlxGantt 確實功能強大了許多,除了能實現對重要日期(如今日/項目開始時間/項目結束時間等)進行標示、tooltip、里程碑狀態區分等功能之外,最重要的是可以實現按時/日/月/年的切換。
由于 dhtmlxGantt 有免費版和付費版,一開始試用也不知道成不成功,所以我下載了免費版的源碼進行了一番研究,幸好最后的結果也是可以通過一些配置來實現需求,下面將介紹怎么實現。
通過配置 dhtmlxGantt 實現的功能
在 react 項目中使用
dhtmlxGantt 在 github 提供了在 Vue.js/Angular/React 項目中的使用方法入口,本文將對如何在 react 項目中使用進行介紹(經實踐)。
下載命令:
yarn add dhtmlx-gantt 復制代碼在組件中使用:
import 'dhtmlx-gantt'; import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'; import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js'; import 'dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js'; import 'dhtmlx-gantt/codebase/locale/locale_cn.js'; import * as React from 'react'; import { getGanttConfigByZoomValue } from '../../utils/milestone.lib'; import Toolbar from './components/Toolbar'; import * as styles from './index.module.less'; export default class Gantt extends React.Component根據 setConfig 和 setZoom 方法可以看到,我們可以通過對 gantt 實例進行操作來實現不同的功能。{ state = { currentZoom: 'Days', // 默認按日維度展示 isMount: false, }; private ganttContainer: any; componentWillReceiveProps (nextProps: any) { this.generateGantt(); this.setState({ isMount: true }); } handleZoomChange = (zoom: string) => { this.setState({ currentZoom: zoom }, () => { this.generateGantt(); }); } async generateGantt () { const { ganttData } = this.props; if (this.state.isMount) { // 若不加判斷,首次使用會報錯 gantt.clearAll(); // 移除所有任務,否則更新時任務會疊加 } this.setConfig(); // 添加配置 gantt.init(this.ganttContainer); // 初始化 dhtmlxGantt 到 ganttContainer 容器中 gantt.parse(ganttData); // 將數據注入到甘特圖 } setConfig () { ... } setZoom (value: string) { gantt.config = { ...gantt.config, ...getGanttConfigByZoomValue(value), // 根據維度展示不同的日期格式 }; } renderContent () { const { currentZoom } = this.state; return ( { this.ganttContainer = input; }} style={{ width: '100%', height: '100%' }} />); } render () { return ({this.renderContent()}); } } 復制代碼
只讀模式
在初始化 dhtmlxGantt 之前,通過將 gantt.config.readonly 設置為 true 來限制甘特圖為只讀模式:
gantt.config.readonly = true; gantt.init(this.ganttContainer); 復制代碼可以看到,盡管設置了只讀模式,表格行被選中后無法取消選中,同時,表格列最右邊仍有?號按鈕,雖然點了沒有反應:
解決表格行被選中后無法取消選中的問題,可以通過以下設置即可解決:
gantt.config.readonly = true; // 開啟只讀模式 select_task: false, // 禁止任務被選中, gantt.init(this.ganttContainer); 復制代碼至于表格列最右邊仍有?號按鈕的問題,可以通過自定義表格列來解決 。
自定義表格列
表格列設置如下:
gantt.config.columns = [ { name: 'text', label: '里程碑節點', width: 280, template: function (obj: any) { return `節點:${obj.text}`; // 通過 template 回調可以指定返回內容值 }, }, ]; gantt.init(this.ganttContainer); 復制代碼結果如下:
自定義tooltip
如果我們要自定義鼠標移動到任務上的 tooltip 提示,非常重要的一點是需要引入 dhtmlxgantt_tooltip.js,才可以使用通過 gantt.attachEvent 方法添加 tooltip,然后可以開始進行自定義:
// 自定義tooltip內容 gantt.templates.tooltip_text = function (start: Date, end: Date, task: any) { const t = gantt; const output = `里程碑:${task.text} 狀態:${ MILESTONE_STATE_MAP[task.state] } 計劃開始時間:${t.templates.tooltip_date_format( start, )} 計劃結束時間:${t.templates.tooltip_date_format(end)}`; return output; }, // 添加tooltip gantt.attachEvent('onGanttReady', function () { var tooltips = gantt.ext.tooltips; tooltips.tooltip.setViewport((gantt as any).$task_data); }); 復制代碼
當鼠標移動到項目上是,可以看到我們自定義的 tooltip 內容:
展示今日、項目開始和結束標示線
與 tooltip 功能類似,如果需要使用標示線的功能,需要引入 dhtmlxgantt_marker.js,這樣才能通過 gantt.addMarker 方法為一些重要日期的增加標示:
const { online_date, offline_date } = this.props; // 今日紅線 let today = new Date(`${getEndOfDate()}`); // getEndOfDate 為獲取今天結束時間的方法 gantt.addMarker({ start_date: today, css: 'today', text: '今日', }); // 項目開始時間 if (online_date) { gantt.addMarker({ start_date: online_date, css: 'projectStartDate', text: '項目開始', }); } // 項目結束時間 if (offline_date) { gantt.addMarker({ start_date: offline_date, css: 'projectEndDate', text: '項目結束', }); } 復制代碼
需要注意 ??:除了今日標示線已經有默認樣式以外,新增加的標示線需要指定css類名來增加樣式:
.projectStartDate, .projectEndDate { background: #00bcd4; } 復制代碼
結果:
自定義任務顏色
可以通過設置 gantt.templates.task_class 實現任務顏色自定義:task_class: function (start: Date, end: Date, task: any) { return `milestone-${task.state}`; // task.state值為default/unfinished/finished/canceled其中一種 }, 復制代碼
css:
.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; } 復制代碼
高亮周末日期顏色
由于公司周末不上班 ,可以將周末日期顏色進行高亮:
// 突出周末顏色 (gantt.templates as any).timeline_cell_class = function (item: any, date: Date): string { if (date.getDay() === 0 || date.getDay() === 6) { return 'weekend'; } return ''; }; 復制代碼
結果:
可以看到,由于按月和按年視圖展示,會用當前列的時間去做計算,這樣會導致整周/整月都被高亮,這明顯不是我們想要的結果,那就改造一下吧:
// 突出周末顏色 const disableHighlight = this.state.currentZoom === 'Years' || this.state.currentZoom === 'Months'; (gantt.templates as any).timeline_cell_class = function (item: any, date: Date): string { if (!disableHighlight && (date.getDay() === 0 || date.getDay() === 6)) { return 'weekend'; } return ''; }; 復制代碼
可以看到,三月這一列變正常了:
切換視圖
切換視圖的 Toolbar 組件在文檔中有詳細介紹,這里就不進行復述了,核心是getGanttConfigByZoomValue方法,用于設置不同視圖的具體時間格式,代碼如下:export function getGanttConfigByZoomValue (value: string) { switch (value) { case 'Hours': return { scale_unit: 'day', scale_height: 50, min_column_width: 30, date_scale: '%Y-%m-%d', subscales: [ { unit: 'hour', step: 1, date: '%H', }, ], }; case 'Days': return { scale_unit: 'week', scale_height: 50, min_column_width: 70, date_scale: '%Y年 %W周', subscales: [ { unit: 'day', step: 1, date: '%m-%d', }, ], }; case 'Months': return { scale_unit: 'month', scale_height: 50, min_column_width: 70, date_scale: '%Y-%m', subscales: [ { unit: 'week', step: 1, date: '%W周', }, ], }; case 'Years': return { scale_unit: 'year', scale_height: 50, min_column_width: 70, date_scale: '%Y年', subscales: [ { unit: 'month', step: 1, date: '%M', }, ], }; default: return {}; } } 復制代碼
通過上面介紹的配置,即可實現符合業務方需求的甘特圖 :
總結
本文記錄了我是為何棄用 echarts,轉而改用 dhtmlxGantt 完成甘特圖的過程,對一些功能的具體配置進行了詳細的介紹。
通過這次的需求我學到了很多,有時候應該轉換思路,先找找有沒有現成的開源庫,看看在原來已有的功能基礎上,能如何進行改造使其滿足需求,這樣能避免走很多彎路。正如牛頓所說:“如果說我看得比別人更遠些,那是因為我站在巨人的肩膀上。”如果您有興趣在Salesforce應用程序中實現我們的甘特圖庫,請隨時與我們聯系以獲取所有詳細信息和實時演示。
關產品推薦:
VARCHART XGantt:支持ActiveX、.Net等平臺的C#甘特圖控件
AnyGantt:構建復雜且內容豐富的甘特圖的理想工具
jQuery Gantt Package:基于HTML5 / jQuery的跨平臺jQuery Gantt包
phGantt Time Package:對任務和時間的分配管理的甘特圖
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: