vue中使用antv/g6绘制树图

参考http://t.csdn.cn/VYezb此篇文章跟方便理解配置项

Step 1: 使用命令行在项目目录下执行以下命令:

npm install --save @antv/g6

Step 2: 在需要用的 G6 的 JS 文件中导入:

import G6 from '@antv/g6';
import insertCss from 'insert-css'
Step1:创建一个容器
<div id="container"></div>
Step2:绘制树状图函数
showChart() {
      insertCss(`
          .g6-component-tooltip {
            background-color: rgba(0,0,0, 0.65);
            padding: 10px;
            box-shadow: rgb(174, 174, 174) 0px 0px 10px;
            width: fit-content;
            color: #fff;
            border-radius = 4px;
          }
        `)
      document.getElementById('container')
      const defaultConfig = {
        width: 1600,
        height: 600,
        modes: {
          default: ['zoom-canvas', 'drag-canvas']
        },
        animate: true,
        defaultNode: {
          type: 'flow-rect'
        },
        defaultEdge: {
          type: 'cubic-horizontal',
          style: {
            stroke: '#CED4D9'
          }
        },
        layout: {
          type: 'indented',
          direction: 'LR',
          dropCap: false,
          indent: 450,
          center: [800, 300],
          getHeight: () => {
            return 60
          }
        }
      }
      const colors = {
        1: '#F46649',
        2: '#BBB7B7',
        3: '#5BD8A6'
      }
      // 自定义节点、边
      const registerFn = () => {
        /**
           * 自定义节点
           */
        G6.registerNode(
          'flow-rect',
          {
            shapeType: 'flow-rect',
            draw(cfg, group) {
              const {
                name = '',
                files,
                projectId,
                branchName,
                confirmPerson,
                confirmTime,
                whiteString,
                command,
                subsystem,
                isHighRiskCommandAlarms,
                highRiskCommandAlarmNum,
                whiteStringNum,
                controllableParameters,
                functionName,
                children,
                collapsed,
                called,
                status,
                calls,
                fuid,
                tracingContext
              } = cfg
              const grey = '#CED4D9'
              // 逻辑不应该在这里判断
              const rectConfig = {
                width: 200,
                height: 60,
                lineWidth: 1,
                fontSize: 12,
                fill: '#fff',
                radius: 4,
                stroke: grey,
                opacity: 1
              }

              const nodeOrigin = {
                x: rectConfig.width / 2,
                y: rectConfig.height / 2
              }

              const textConfig = {
                textAlign: 'left',
                textBaseline: 'bottom'
              }

              const rect = group.addShape('rect', {
                attrs: {
                  x: nodeOrigin.x,
                  y: nodeOrigin.y,
                  ...rectConfig,
                  cursor: 'pointer',
                  stroke: whiteString === true || isHighRiskCommandAlarms === true ? '#F2AB3F' : '#eee'
                },
                name: 'main'
              })

              const rectBBox = rect.getBBox()
              // price
              group.addShape('text', {
                attrs: {
                  ...textConfig,
                  x: rectBBox.maxX - 100,
                  y: rectBBox.maxY - 20,
                  text: functionName.length > 10 ? functionName.substr(0, 10) + '...' : functionName,
                  fontSize: 16,
                  textAlign: 'center',
                  fill: '#000',
                  opacity: 0.85,
                  cursor: 'pointer'
                },
                name: 'title'
              })

              // bottom percent
              group.addShape('rect', {
                attrs: {
                  x: rectBBox.maxX - 170,
                  y: rectBBox.maxY - 35,
                  width: 12,
                  height: 12,
                  radius: [6, 6, 6, 6],
                  fill: colors[status]
                }
              })

              // collapse rect
              if (cfg.called) {
                group.addShape('rect', {
                  attrs: {
                    x: rectConfig.width / 2 + rectConfig.width - 8,
                    y: rectConfig.height - 8,
                    width: 16,
                    height: 16,
                    stroke: 'rgba(0, 0, 0, 0.25)',
                    cursor: 'pointer',
                    fill: '#fff'
                  },
                  name: 'collapse-back',
                  modelId: cfg.id
                })

                // collpase text
                group.addShape('text', {
                  attrs: {
                    x: rectConfig.width / 2 + rectConfig.width,
                    y: rectConfig.height,
                    textAlign: 'center',
                    textBaseline: 'middle',
                    text: children && children.length > 0 ? '-' : '+',
                    fontSize: 16,
                    cursor: 'pointer',
                    fill: 'rgba(0, 0, 0, 0.25)'
                  },
                  name: 'collapse-text',
                  modelId: cfg.id
                })
              }

              this.drawLinkPoints(cfg, group)
              return rect
            },
            update(cfg, item) {
              const group = item.getContainer()
              this.updateLinkPoints(cfg, group)
            },
            setState(name, value, item) {
              if (name === 'collapse') {
                const group = item.getContainer()
                const collapseText = group.find((e) => e.get('name') === 'collapse-text')
                if (collapseText) {
                  if (!value) {
                    collapseText.attr({
                      text: '-'
                    })
                  } else {
                    collapseText.attr({
                      text: '+'
                    })
                  }
                }
              }
            },
            getAnchorPoints() {
              return [
                [0, 0.5],
                [1, 0.5]
              ]
            }
          },
          'rect'
        )

        G6.registerEdge(
          'flow-cubic',
          {
            getControlPoints(cfg) {
              let controlPoints = cfg.controlPoints // 指定controlPoints
              if (!controlPoints || !controlPoints.length) {
                const { startPoint, endPoint, sourceNode, targetNode } = cfg
                const { x: startX, y: startY, coefficientX, coefficientY } = sourceNode
                  ? sourceNode.getModel()
                  : startPoint
                const { x: endX, y: endY } = targetNode ? targetNode.getModel() : endPoint
                let curveStart = (endX - startX) * coefficientX
                let curveEnd = (endY - startY) * coefficientY
                curveStart = curveStart > 40 ? 40 : curveStart
                curveEnd = curveEnd < -30 ? curveEnd : -30
                controlPoints = [
                  { x: startPoint.x + 200 + curveStart, y: startPoint.y },
                  { x: endPoint.x + 200 + curveEnd, y: endPoint.y }
                ]
              }
              return controlPoints
            },
            getPath(points) {
              const path = []
              path.push(['M', points[0].x, points[0].y])
              path.push([
                'C',
                points[1].x,
                points[1].y,
                points[2].x,
                points[2].y,
                points[3].x,
                points[3].y
              ])
              return path
            }
          },
          'single-line'
        )
      }

      registerFn()
      //  组件props
      const props = {
        data: this.mockData,
        config: {
          padding: [20, 50],
          defaultLevel: 3,
          defaultZoom: 0.8,
          modes: { default: ['zoom-canvas', 'drag-canvas'] }
        }
      }
      const { data } = props

      const initGraph = (data) => {
        if (!data) {
          return
        }
        const { onInit, config } = props
        const tooltip = new G6.Tooltip({
          offsetX: 20,
          offsetY: 30,
          itemTypes: ['node'],
          getContent: (e) => {
            const outDiv = document.createElement('div')
            const nodeName = e.item.getModel().functionName
            let formatedNodeName = ''
            for (let i = 0; i < nodeName.length; i++) {
              formatedNodeName = `${formatedNodeName}${nodeName[i]}`
              if (i !== 0 && i % 20 === 0) formatedNodeName = `${formatedNodeName}<br/>`
            }
            outDiv.innerHTML = `${formatedNodeName}`
            return outDiv
          },
          shouldBegin: (e) => {
            if (e.target.get('name') === 'main') return true
            if (e.target.get('name') === 'title') return true
            return false
          }
        })
        this.graph = new G6.TreeGraph({
          container: 'container',

          ...defaultConfig,

          ...config,
          plugins: [tooltip]
        })
        if (typeof onInit === 'function') {
          onInit(this.graph)
        }
        this.graph.data(data)
        this.graph.render()
        this.graph.zoom(config.defaultZoom || 1)

        const handleCollapse = (e) => {
          const target = e.target
          const id = target.get('modelId')
          const item = this.graph.findById(id)
          const nodeModel = item.getModel()
          if (nodeModel.called && nodeModel.children === null) {
            if (nodeModel.status === '3' || nodeModel.status === 3) {
              this.$message.error('当前节点已标记为安全,不支持展开!')
            } else {
              queryCommandInjectionChildNext({
                called: nodeModel.called,
                calls: nodeModel.calls,
                id: nodeModel.id,
                functionName: nodeModel.functionName,
                product: nodeModel.product,
                status: nodeModel.status,
                version:nodeModel.version,
                fuid: nodeModel.fuid,
                subsystem: nodeModel.subsystem,
                tracingContext: nodeModel.tracingContext
              }).then(
                (res) => {
                  if (res.code === '0') {
                    nodeModel.children = res.data
                    nodeModel.collapsed = false
                    this.graph.layout()
                    this.graph.setItemState(item, 'collapse', nodeModel.collapsed)
                  }
                }
              )
            }
          } else {
            nodeModel.collapsed = !nodeModel.collapsed
            this.graph.layout()
            this.graph.setItemState(item, 'collapse', nodeModel.collapsed)
          }
        }
        this.graph.on('collapse-text:click', (e) => {
          handleCollapse(e)
        })
        this.graph.on('collapse-back:click', (e) => {
          handleCollapse(e)
        })
        this.graph.on('main:click', (ev) => {
          this.cunData = ev.item._cfg.model
          const data = ev.item._cfg.model
          this.handleForm(data)
        })
        this.graph.on('title:click', (ev) => {
          this.cunData = ev.item._cfg.model
          const data = ev.item._cfg.model
          this.handleForm(data)
        })
      }
      initGraph(data)
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值