甘特图在Vue中的应用篇

注意:该插件只能在有外网上运行,内网不行,坑、坑、坑,重要的事情说三遍。

 

1、首先安装插件,由于官网上一些功能是收费的,所以我在github上发现一款还不错的插件,并有文档说明(全英)

npm i gantt-schedule-timeline-calendar

附上文档地址:https://gantt-schedule-timeline-calendar.neuronet.io/documentation/getting-started

Git项目地址:https://github.com/neuronetio/gantt-schedule-timeline-calendar#weekendhighlight-plugin

官方vue实例:https://github.com/neuronetio/vue-gantt-schedule-timeline-calendar

具体的Demo案例:https://github.com/neuronetio/vue-gantt-schedule-timeline-calendar-example

2、vue做甘特图,先大致介绍下核心功能:

(1)横轴、纵轴拖拽;

(2)自定义监听点击事件(双击、右键等)

(3)任务之间显示父子层级关系;

(4)左侧列表信息,右侧时间轴表示任务;

(5)每个任务可以订制样式,并且可以动态修改样式;

(6)自定义时间粒度显示(小时、天、星期、月、年);

(7)支持大批量数据渲染;

(8) 支持同行多节点渲染;

(9)支持选中,以及批量选中;

(9)优秀的扩展性,支持第三方插件。

等等还有其他的一些功能。这里先看一下效果图:

接下来会介绍用什么实现的,怎么使用,怎么添加拖拽、点击等各种功能,我以vue为例进行开发。

基础使用已经贴代码了,不做赘述,不清楚的查看官方示例,接下来主要说核心功能如何配置,这方面官方描述的不是很清楚,但是Git的 issues 好多问题都关闭了,基本大部分问题都可以查到。

1、基础展示,左侧多列表格展示

        

 

 

 这个主要配置config中的 list 属性,

  rows 代表左侧表格的行属性,key值是每行的id,多个key就有多行,通常都以数字做key值, 内部 具体属性是列信息。比如 order label line 等都是列信息,这个会一一对应到指定列。

    parentID 是父节点配置,一般配置了父节点,就会在 甘特图 中展示出父子层级来。

    expanded 是展开属性,默认false,父子层级是合上的,折叠隐藏子节点。如果想默认展示需要每个节点都加上这个属性。

  columns 代表左侧表格的列属性,key唯一就是列关键字。

    data 属性,是列,可以有多个属性,每个代表一列

      id 当前列的id

      data 列标识,和rows中每行的数据的字段唯一对应,比如  order、line 等

      isHTML 是否要展示HTML,默认false。  这个直接关系到content、html字段用哪个

      width 当前列宽度

      expander 是否显示层级,默认false不展示,设置为true,会展示出父子层级来,一般我们仅设置一列,当然设置多列也行。

      header 配置表头内容的

        content 表头想显示的内容

        html 写HTML,用来订制表头样式的,内容就是HTML,行内css

    percent 是左侧表格总宽度占甘特图的百分比,0就直接隐藏表格

    minWidth:是左侧表格的最小宽度

 list: {
          rows: {
            "1": {
              id: "1",
              order: '订单1',
              label: "压缩机",
              line: '线体1',
              expanded: true
            },
            "3": {
              id: "3",
              order: '订单3',
              label: "箱体",
              line: '线体3',
              parentId: '2',
            }
          },
          columns: {
            data: {
              id: {
                id: "id",
                data: "id",
                width: 50,
                expander: true,
                header: { content: "序号" }
              },
              order: {
                id: "order",
                data: "order",
                header: { content: "生产订单" }
              },
              label: {
                id: "label",
                data: "label",
                header: { content: "描述" }
              }
            }
          }
        }

2、右侧任务排列显示(包括订制样式)

      

 

这个主要配置config中的 chart 属性,

   time 配置时间轴

    from 左侧开始时间,填写毫秒数

    to 右侧结束时间,填写毫秒数

    zoom 显示层级,10-22,越大,时间粒度展示的越大,越小,显示越精细,最小到5分钟

  items 任务快配置,注意这个可以同行若干任务展示

    id 当前任务的id

    rowId 左侧表格 rows 的id,通过这个关联,渲染到某一行

    label 当前任务的名称,会默认展示在任务中

    time 任务的开始、结束时间

      start 开始时间,填写毫秒数

      end 结束时间, 填写毫秒数

    style 订制样式,是个对象,写过jsx写法,写过react 、vue jsx 的应该都不默认,这里举个简单的例子,订制任务div的背景色 圆角等样式  { background: 'red', borderRadius: '3px' }

chart: {
          time: {
            from: new Date().getTime() - 2 * 24 * 60 * 60 * 1000,
            to: new Date().getTime() + 8 * 24 * 60 * 60 * 1000,
            zoom: 22,    
          },
          items: {
            "1": {
              id: "1",
              rowId: "1",
              label: "Item 1",
              time: {
                start: new Date().getTime() + 1 * 24 * 60 * 60 * 1000,
                end: new Date().getTime() + 2 * 24 * 60 * 60 * 1000
              },
              style: {  // 每个块的样式
                background: 'blue'
              }
            },
            "21": {
              id: "21",
              rowId: "2",
              label: "Item 2-1",
              time: {
                start: new Date().getTime() + 2 * 24 * 60 * 60 * 1000,
                end: new Date().getTime() + 3 * 24 * 60 * 60 * 1000
              }
            }
          }
        }

3、配置右侧横轴的时间显示

     

 

 这个主要配置config中的 locale 属性,时间的语言环境配置,这里看文档详细些,下面只详说2个属性,

  weekdays 配置 每周显示的文案   主要是做国际化用的

  months 配置月的,也是做国际化的

  locale: {
          name: "zh",
          Now: "Now",
          weekdays:["周日","周一","周二","周三","周四","周五","周六"],
          months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
        }

4、监听鼠标右击事件

      

 

 这个主要配置config中的 actions 属性,他是对象,以下是他所有能监听dom,很多,这篇博客就只介绍人物块的事件监听,其他的不做一一赘述了

  • main
  • list
  • list-column
  • list-column-header
  • list-column-header-resizer
  • list-column-header-resizer-dots
  • list-column-row
  • list-column-row-expander
  • list-column-row-expander-toggle
  • list-toggle
  • chart
  • chart-calendar
  • chart-calendar-date
  • chart-timeline
  • chart-timeline-grid
  • chart-timeline-grid-row
  • chart-timeline-grid-row-block
  • chart-timeline-items
  • chart-timeline-items-row
  • chart-timeline-items-row-item

  这个监听函数会接收2个参数,element  和 data ,一个是dom,另一个是 任务节点的数据。根据官方要求,监听函数必须返回一个对象,此对象必须包含 update  destroy 2个方法,分别是位置更新和销毁时需要执行的方法。具体写法请见如下代码:

actions: {
      'chart-timeline-items-row-item': [this.addListenClick] // 监听右击事件
}

methods:{
    addListenClick(element, data) {
      const onClick = (e) => {
        e.preventDefault()
        // console.log(data)
        this.modal = {
          visible: true,
          title: data.item.label,
          data
        }
        return false
      }
      element.addEventListener('contextmenu', onClick);
      return {
        update(element, newData) {
          data = newData;
        },
        destroy(element, data) {
          element.removeEventListener('click', onClick);
        }
      };
    },
    closeModal() {
      this.modal = {
        visible: false,
        title: '',
        data: {}
      }
    }
  },

5、任务的横轴、纵轴拖动

       

 

这个主要配置config中的 plugins 属性,

  ItemMovement 插件,这个是官方开发的用来拖拽任务的插件。这个包的插件系统做的很好,官方提供了几种不错的插件,同时还支持其他的第三方插件,有兴趣的可以自己试试,这里先介绍拖拽插件,

     moveable 拖拽的方向, x 支持横轴拖拽;   y 支持纵轴拖拽;  true 横轴、纵轴都可以拖拽; false 禁止拖拽

    resizeable 是否可以拖拽,true开启拖拽

    resizerContent 拖拽的图标,直接写HTML,可以自己定制拖拽图标的样式

    collisionDetection: 拖拽过程中是否允许元素重叠, true 不允许重叠

    ghostNode  false 不展示重影节点

    snapStart 拖拽开始时间点回调,这个比较机制特殊,拖拽位置的时候触发这个方法,参数接收开始时间  时间变化 当前节点数据,默认是毫秒级的刷新,会卡,我们做if判断1小时拖拽

    snapEnd 拖拽结束时间点回调,这个是拖动任务块大小时触发,接收结束时间 时间段。用法同上。具体请看如下代码:

 plugins: [
          // 拖动 x 横向, y 纵向
          ItemMovement({
            moveable: 'x',
            resizerContent: '<div class="resizer">-></div>',
            ghostNode: false,
            snapStart(time, diff, item) {
              if(Math.abs(diff) > 14400000) {
                return time + diff
              }
              return time
            },
            snapEnd(time, diff, item) {
              if(Math.abs(diff) > 14400000) {
                return time + diff
              }
              return time
            }
          })
        ]

6、选中任务

      

 

这个主要配置config中的 plugins 属性,

  Selection插件,单个选中、批量选中插件。

    grid 能否选中单元格

    items  能否选中任务

    rows  能否选中行

    rectStyle 矩形样式

    selected 选中的回调

    deselected  取消选中的回调

    canSelected  可选中的的回调,用来过滤哪些可以选中

    canDeselected 可取消选中的回调,用来过滤哪些可以取消选中

 plugins: [
          Selection({
            items: false,
            rows: false,
            grid: true,
            rectStyle: { opacity: '0.0' }, 
            canSelect(type, currentlySelecting) {
              if (type === 'chart-timeline-grid-row-block') {
                return currentlySelecting.filter(selected => {
                  if (!selected.row.canSelect) return false;
                  for (const item of selected.row._internal.items) {
                    if (
                      (item.time.start >= selected.time.leftGlobal && item.time.start <= selected.time.rightGlobal) ||
                      (item.time.end >= selected.time.leftGlobal && item.time.end <= selected.time.rightGlobal) ||
                      (item.time.start <= selected.time.leftGlobal && item.time.end >= selected.time.rightGlobal)
                    ) {
                      return false;
                    }
                  }
                  return true;
                });
              }
              return currentlySelecting;
            },
            canDeselect(type, currently, all) {
              if (type === 'chart-timeline-grid-row-blocks') {
                return all.selecting['chart-timeline-grid-row-blocks'].length ? [] : currently;
              }
              return [];
            }
          })
        ]

 

小结:

  以上就是整个甘特图的使用了,这是我用过最符合项目需求的甘特图,他的开发团队也在持续的维护这个项目,很赞。

感谢大佬的教程,很赞,附上链接:https://www.cnblogs.com/pengfei-nie/p/13092159.html

 

 

 

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值