vue2实现任务流程图效果

我使用的是antvx6 1.34.6版本

官网地址:

https://x6.antv.vision/zh/docs/tutorial/getting-started

 1、安装插件
npm install @antv/x6@1.34.6  --save
npm install @antv/x6-vue-shape insert-css 
 2、创建一个method.js文件 封装一个方法,在页面上创建节点
import '@antv/x6-vue-shape'
import { Graph, Shape, Addon, FunctionExt } from '@antv/x6'

export const startDragToGraph = (graph, type, e) => {
  const node = graph.createNode({
    width: 180, //节点的宽
    height: 35, //节点的高
    attrs: {
      label: {
        text: type, //文本
        fill: '#000000',
        fontSize: 14,
        textWrap: {
          width: -10,
          height: -10,
          ellipsis: true,
        },
      },
      body: {
        stroke: '#ccc',
        strokeWidth: 1,
        fill: '#ffffff',
      },
    },
    ports: ports,
  })

  const dnd = new Addon.Dnd({ target: graph })
  dnd.start(node, e)
}
const ports = {
  groups: {
    // 输入链接桩群组定义
    // 可以连接线的点 元素的上下左右
    top: {
      position: 'top',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#2D8CF0',
          strokeWidth: 2,
          fill: '#fff',
        },
      },
    },
    // 输出链接桩群组定义
    bottom: {
      position: 'bottom',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#2D8CF0',
          strokeWidth: 2,
          fill: '#fff',
        },
      },
    },
    left: {
      position: 'left',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#2D8CF0',
          strokeWidth: 2,
          fill: '#fff',
        },
      },
    },
    right: {
      position: 'right',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#2D8CF0',
          strokeWidth: 2,
          fill: '#fff',
        },
      },
    },
  },
  items: [
    {
      id: 'port1',
      group: 'top',
    },
    {
      id: 'port2',
      group: 'bottom',
    },
    {
      id: 'port3',
      group: 'left',
    },
    {
      id: 'port4',
      group: 'right',
    },
  ],
}
 3、创建左侧元素

有的是在方法里创建,单独写一个比较好修改样式

list是元素列表

<li
    v-for="item in list"
    :key="item.value"
    @mousedown="startDrag(item.name, $event)"
>
    <p>{{ item.name }}</p>
</li>
4、创建容器
<div id="containerChart" class="containerChart"></div>
5、引入依赖 、封装的方法
import { Graph, Shape, Addon, FunctionExt, DataUri } from '@antv/x6'
import insertCss from 'insert-css'
import '@antv/x6-vue-shape'

import { startDragToGraph } from './methods.js'
6、渲染画布 以及画布上的事件
mounted() {
   this.initX6()
},
initX6() {
      this.graph = new Graph({
        // 开启键盘事件
        keyboard: true,
        panning: true,
        container: document.getElementById('containerChart'),
        //画布
        grid: {
            size: 20, // 大小 10px
            visible: true, // 渲染背景
            type: 'dot',  //dot:点  mesh:网格
            args: { 
              color: '#D0D0D0',
              thickness: 2, // 网格线宽度/网格点大小
              factor: 10,
            },
        },
        //小地图 start
        scroller: {
          enabled: true,
        },
        minimap: {
          enabled: true,
          container: document.getElementById('containerChart'),
          graphOptions: {
            async: true,
          },
        },
        //end
        resizing: {
          //调整节点宽高
          enabled: true,
          orthogonal: false,
        },
        selecting: true, //可选
        snapline: true,
        interacting: {
          edgeLabelMovable: true,
        },
        connecting: {
          // 节点连接
          anchor: 'center',
          connectionPoint: 'anchor',
          allowBlank: false,
          snap: true,
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: '#1890ff',
                  strokeWidth: 2,
                  targetMarker: {
                    name: 'classic',
                    size: 8,
                  },
                  strokeDasharray: 0, //虚线
                  style: {
                    animation: 'ant-line 30s infinite linear',
                  },
                },
              },
              label: {
                text: '',
              },
              connector: 'normal',
              router: {
                name: '',
              },
              zIndex: 0,
            })
          },
        },
        highlighting: {
          magnetAvailable: {
            name: 'stroke',
            args: {
              padding: 4,
              attrs: {
                strokeWidth: 4,
                stroke: '#6a6c8a',
              },
            },
          },
        },
      })
      insertCss(`
              @keyframes ant-line {
              to {
                    stroke-dashoffset: -1000
                }
              }
            `)
      this.graph.fromJSON(data)
      this.graph.history.redo()
      this.graph.history.undo()
      // 给画布添加事件
      // 鼠标移入移出节点
      this.graph.on(
        'node:mouseenter',
        FunctionExt.debounce(() => {
          const container = document.getElementById('containerChart')
          const ports = container.querySelectorAll('.x6-port-body')
          this.showPorts(ports, true)
        }),
        500
      )
      this.graph.on('node:mouseleave', () => {
        const container = document.getElementById('containerChart')
        const ports = container.querySelectorAll('.x6-port-body')
        this.showPorts(ports, false)
      })
      this.graph.on('blank:click', () => {
        this.type = 'grid'
      })
      this.graph.on('cell:click', ({ cell }) => {
        this.type = cell.isNode() ? 'node' : 'edge'
      })
      this.graph.on('selection:changed', (args) => {
        args.added.forEach((cell) => {
          this.selectCell = cell
          if (cell.isEdge()) {
            cell.isEdge() && cell.attr('line/strokeDasharray', 5) //虚线蚂蚁线
            cell.addTools([
              {
                name: 'vertices',
                args: {
                  padding: 4,
                  attrs: {
                    strokeWidth: 0.1,
                    stroke: '#2d8cf0',
                    fill: '#ffffff',
                  },
                },
              },
            ])
          }
        })
        args.removed.forEach((cell) => {
          cell.isEdge() && cell.attr('line/strokeDasharray', 0) //正常线
          cell.removeTools()
        })
      })
      // 双击页面节点事件
      this.graph.on('cell:dblclick', ({ cell }) => {
      })
      //添加节点事件
      this.graph.on('node:added', (e) => {
      })
      // delete 键盘删除事件
      this.graph.bindKey(['backspace', 'delete'], () => {
        // 删除选中的元素
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.removeCells(cells)
        }
      })
},
// 拖拽
startDrag(type, e) {
    startDragToGraph(this.graph, type, e)
},
showPorts(ports, show) {
    for (let i = 0, len = ports.length; i < len; i = i + 1) {
        ports[i].style.visibility = show ? 'visible' : 'hidden'
    }
},

就可以得到一个示例啦!

还可以添加按钮,下载 、删除选择的节点,以及设置默认数据
<el-button
   type="primary"
   icon="el-icon-download"
   circle
   @click="saveToPNG"
></el-button>
<el-button
    type="primary"
    icon="el-icon-delete"
    circle
    @click="deleteNode"
></el-button>
下载和删除方法
//下载    
saveToPNG() {
      this.$nextTick(() => {
        this.graph.toPNG(
          (dataUri) => {
            // 下载
            DataUri.downloadDataUri(dataUri, '下载名称.png')
          },
          {
            backgroundColor: 'white',
            padding: {
              top: 50,
              right: 50,
              bottom: 50,
              left: 50,
            },
            quality: 1,
            copyStyles: false,
          }
        )
      })
},
 // 删除节点
deleteNode() {
      const cell = this.graph.getSelectedCells()
      if (cell.length) {
        this.graph.removeCells(cell)
      }
},
给流程图添加默认数据

ports数据就是method.js文件里ports数据,重新复制一份

数据多了可以封装一个方法

this.graph.addNode({
          width: 180,
          height: 35,
          id: '1',
          x: item.x,
          y: item.y,
          attrs: {
            label: {
              text: '文本',
              fill: '#000000',
              fontSize: 14,
              textWrap: {
                width: -10,
                height: -10,
                ellipsis: true,
              },
            },
            body: {
              stroke: '#ccc',
              strokeWidth: 1,
              fill: '#ffffff',
            },
          },
          ports: this.ports,
 })

this.graph.addNode({
          width: 180,
          height: 35,
          id: '2',
          x: item.x,
          y: item.y,
          attrs: {
            label: {
              text: '文本2',
              fill: '#000000',
              fontSize: 14,
              textWrap: {
                width: -10,
                height: -10,
                ellipsis: true,
              },
            },
            body: {
              stroke: '#ccc',
              strokeWidth: 1,
              fill: '#ffffff',
            },
          },
          ports: this.ports,
 })
给这两条数据添加线连接

source来源节点 target目标节点 

cell是节点的id

port是节点连接线的位置,有4个上下左右,和method.js里props的items数据对应

 // 设置默认连线数据
        this.graph.addEdge({
          source: { cell: '1', port: 'port2' },
          target: { cell: '2', port: 'port3' },
          attrs: {
            line: {
              stroke: '#1890ff',
              strokeWidth: 2,
              targetMarker: {
                name: 'classic',
                size: 8,
              },
              strokeDasharray: 0,
              style: {
                animation: 'ant-line 30s infinite linear',
              },
            },
          },
        })

### 回答1: 基于Vue的条形甘特图是通过使用Vue.js框架来实现的一种可视化工具,用于展示任务进度和时间表。在这种甘特图中,每个任务被表示为一条横向的条形,在整个工作流程中呈现顺序,代表任务的持续时间。 在Vue中,常用的条形甘特图插件有gantt-chart、VueGantt和vue2-gantt,它们通过简单的数据输入,即可自动生成甘特图。其中,gantt-chart可以在没有依赖关系的情况下直接使用,而VueGantt和vue2-gantt则提供了更多的数据和样式自定义选项。 条形甘特图可以用于跟踪项目计划的进度,管理资源和时间表,以及确定项目中存在的潜在问题。通过在Vue中使用条形甘特图,用户可以更轻松地处理大量数据,并在界面上动态地显示关键信息。 总之,基于Vue的条形甘特图是一种可视化工具,可帮助用户跟踪和管理项目任务进度和时间表,从而更好地规划和组织项目。在Vue中使用这种甘特图插件可以帮助用户更有效地处理数据和信息,并将其转化为具有意义的可视化展示。 ### 回答2: 基于Vue的条形甘特图是一个直观且动态的数据展示工具,使用Vue框架可以构建一个可复用的组件来实现该功能。 在这个组件中,首先需要定义一个数据格式,以便展示一个进度条,通常包含以下几个关键字段: - 名称:条形甘特图中每个任务或事件的名称; - 开始时间:任务或事件的开始时间; - 结束时间:任务或事件的结束时间; - 进度:当前任务或事件的完成进度。 在Vue组件中,可以使用v-for指令循环渲染所有的任务或事件,并根据数据中定义的时间段计算出每个任务或事件所在的位置和长度。同时,根据任务或事件的进度,可以添加不同颜色的进度条以表示当前任务或事件完成的程度。 除此之外,还可以根据需要添加更多的交互功能,例如:鼠标悬停时展示任务或事件的详细信息、点击某个任务或事件时跳转到相应的详情页等。 总之,基于Vue的条形甘特图是一个灵活、可定制且易于扩展的数据可视化工具,可以帮助用户有效展示项目进度和时间安排,提高工作效率和管理效果。 ### 回答3: 基于Vue的条形甘特图是一种新型的控件,它是Vue.js框架中的一种组件,可以快速、简便地构建出一个好看而且功能强大的甘特图。甘特图可以有效地帮助我们管理项目进度和时间,更好地规划和安排工作计划和资源,提高工作效率。Vue的条形甘特图将这种特性和优势添加到了Web应用程序中。 这种甘特图通过多个条形来表示不同的任务或进程的时间量,这些条形放置在时间轴上,可以更好地展示出项目的进度和时间,用户可以通过甘特图更好地了解项目进展情况,了解各个任务的完成程度,更好地规划和安排工作。基于Vue的条形甘特图还支持显示进度百分比,时间刻度可以自定义,可以添加标签和标题等,非常方便和实用。 总之,基于Vue的条形甘特图是一种非常方便和实用的控件,可以帮助开发人员更好地管理和规划项目进度和时间,提高工作效率和项目成功率,非常值得尝试和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值