最好用的 Angular 甘特图组件 ngx-gantt

964 阅读4分钟

作者/PingCode前端工程师 张文

一句话介绍

ngx-gantt 是一款基于 Angular 框架的甘特图组件,支持多种视图展示并支持多种高级的特性,能快速的帮助开发者搭建自己的甘特图应用。

什么是甘特图

甘特图又名横道图,是项目管理中比较流行的一种工具。在图表的左侧显示任务列表,顶部显示合适的时间刻度,每个任务由一个条形表示,条形的位置和长度反映了任务的开始日期、持续时间和结束日期,使项目管理者一目了然。

image.png

最初基于Excel制作的甘特图的样子

传统的甘特图工具都是基于客户端的,ngx-gantt 把甘特图直观、高效的特性引入到 Web 端,方便更多的 Web 端用户快速构建自己的甘特图工具。

特性

  • 5 种视图(日、周、月、季、年)

  • 任务分组展示

  • 树形结构数据展示并支持异步加载

  • 任务前后置依赖关联及展示

  • 任务拖拽更改时间

  • 表格自定义

  • 滚动加载数据

  • 导出为图片

  • 可定制化开发

动机

2020年,PingCode 准备做一款项目集管理的产品 Plan,Plan 这款产品包含多项目路线图管理,进度管理,资源跟踪以及里程碑管理,其中涉及到路线图,里程碑等功能都需要基于甘特图来实现,随后我们开始调研Github中开源的一些甘特图的组件,最终都因为不能满足我们的需求而pass,其中主要的原因有以下几点:

  • 不能很好的支持 Angular

  • 有一些功能强大的库依旧依赖 JQuery

  • 不支持多层级展示

  • 默认支持的视图不满足我们的场景

  • 不够灵活

基于上述原因,我们决定自己造轮子,做一款基于 Angular 的甘特图组件。

展示效果

话不多说,先上效果

ngx-gantt 的特点

更灵活的表格

表格和甘特图一起展示是一种更好的方式,我们支持灵活的表格。具体的实现方式是结合 Angular 的模板 ng-template 来使用,这样就可以在模板中使用任何组件,指令等等,从而更灵活的自定义表格内容。除此之外,我们还支持自定义表格列宽,表格中的每一列和整个表格都是可以拖拽修改宽度的。

示例:



具体使用:

<ngx-gantt>
  <ngx-gantt-table>
    <ngx-gantt-column name="工作项" width="120px">
      <ng-template #cell let-item="item">
        <app-work-item [workItem]="item"></app-work-item>
      </ng-template>
    </ngx-gantt-column>
    <ngx-gantt-column name="负责人" width="120px">
      ...
    </ngx-gantt-column>
  </ngx-gantt-table>
</ngx-gantt>

树形结构数据展示

树形结构能明确的展示出任务的父子关系,方便我们用甘特图管理复杂的任务。考虑到性能问题,我们同时支持了异步加载子数据。默认层级是两层,你可以通过 maxLevel 参数设置自己需要的层级数。

示例:

任务依赖

在甘特图组件中,依赖关系的展示也尤为的重要,ngx-gantt 支持通过拖拽关联任务,展示任务依赖关系。一般来说,任务之间的依赖关系主要有以下四种:

  • Finish to Start (FS)​ — 结束到开始,即A任务必须先结束,B任务才能开始。这是最常见的一种依赖关系。

  • Start to Start (SS) — 开始到开始,即A任务必须先开始,B任务才能开始。

  • Finish to Finish (FF) — 结束到结束,即A任务必须先结束,B任务才能结束。

  • Start to Finish (SF) — 开始到结束,即A任务必须先结束,B任务才能结束。

ngx-gantt 组件中依赖关系线的绘制是由SVG中的path 元素完成的,拖拽一个任务至另外一个任务会在两个任务之间生成一段贝塞尔曲线,然后绘制到页面上,来展示两个任务之间的依赖关系。

具体使用:

<ngx-gantt 
  [linkable]="true"
  (linkDragStarted)="linkDragStarted($event)"
  (linkDragEnded)="linkDragEnded($event)"
  (lineClick)="lineClick($event)"
>
  ...
</ngx-gantt>

导出为图片

集成 htm​l2can​​vas 导出图片。

gantt-example (1).png

导出的图片示例

强大的自定义能力

ngx-gantt 支持了甘特图的基本特性及一些高级的特性,但是我们依旧不能保证能满足大部分使用者的场景,所以我们提供了一些基础的组件可以让使用者基于基础的组件去开发自己的应用。

示例:

截屏2021-07-15 下午4.41.17.png

具体使用:

<ngx-gantt-root [sideWidth]="300">
  <ng-template #sideTemplate>
    ...
  </ng-template>
  <ng-template #mainTemplate>
    ...
  </ng-template>
</ngx-gantt-root>

快速开始

安装

$ npm i @worktile/gantt --save
# or
$ yarn add @worktile/gantt

使用

模块导入

import { NgModule } from '@angular/core';
import { NgxGanttModule } from '@worktile/gantt';

@NgModule({
  ...
  imports: [ NgxGanttModule, ... ]
  ...
})
export class AppModule {

}

组件使用

<ngx-gantt start="1514736000" end="1609430400">
  <ngx-gantt-table>
    <ngx-gantt-column></ngx-gantt-column>
  </ngx-gantt-table>
</ngx-gantt>

Github:github.com/worktile/ng…

Demo :gantt.ngnice.com/

总结

ngx-gantt 已经在 智能化研发管理工具PingCode企业级项目协作与目标管理工具Worktile 中使用了一年多了,目前稳定迭代中。之前由于文档不完善、测试覆盖率比较低,一直没有向大家介绍,但是我们的代码是早就公开了的。截止到目前,我们已经完善了文档,提升了测试覆盖率,大家可以放心使用。

最后,ngx-gantt 还有一些需要完善的地方,我们正在考虑加入虚拟滚动进一步提升性能。同时我们也希望有更多的 Angular 用户使用并反馈,和我们一起去完善它。