antv G6关系图收缩

<template>
  <div>
    <div id="drawGraph"></div>
  </div>
</template>

<script>
import G6 from '@antv/g6'
let graphG = null
export default {
  mounted() {
    this.initData()
  },
  methods: {
    initData() {
      let combos = [
        { id: '100-600', label: '100-600', type: 'root' },
        { id: '100-200', label: '100-200' },
        { id: '200-300', label: '200-300' },
        { id: '300-400', label: '300-400' },
        { id: '400-500', label: '400-500' },
        { id: '500-600', label: '500-600' }
      ]
      let edges = [
        { source: '100-200', target: '100-600' },
        { source: '200-300', target: '100-600' },
        { source: '300-400', target: '100-600' },
        { source: '400-500', target: '100-600' },
        { source: '500-600', target: '100-600' }
      ]
      let data = { combos, edges }
      this.makeRelationData(data)
    },
    // 分组 点 连线处理
    makeRelationData(data) {
      if (graphG) {
        graphG.destroy()
      }
      let drawGraph = document.getElementById('drawGraph')
      this.graphWidth = drawGraph.scrollWidth
      this.graphHeight = drawGraph.scrollHeight || 1200
      let origin = [this.graphWidth / 2, 100]
      let row = 150,
        clo = 180
      let combos = data.combos
      let row_clo = Math.floor(Math.sqrt(combos.length))
      for (let i = 0; i < combos.length; i++) {
        let rowindex = Math.floor(i / row_clo) + 1
        let cloindex = (i % row_clo) + 1
        // 分组默认样式设置
        if (combos[i].type === 'root') {
          combos[i].x = this.graphWidth / 3
          combos[i].y = this.graphHeight / 3
          combos[i].style = {
            fill: '#B19693',
            opacity: 0.4,
            cursor: 'pointer'
          }
        } else {
          // 分组定位
          combos[i].x = origin[0] + clo * cloindex
          combos[i].y = origin[1] + row * rowindex
          if (i % 2 === 1) {
            combos[i].y += 40
          }
          combos[i].style = {
            fill: '#FAD069',
            opacity: 0.5,
            cursor: 'pointer'
          }
        }
      }
      this.drawQfast(data)
    },
    drawQfast(data) {
      graphG = new G6.Graph({
        container: 'drawGraph',
        width: this.graphWidth,
        height: this.graphHeight,
        groupByTypes: false,
        modes: {
          default: [
            { type: 'zoom-canvas', enableOptimize: true, optimizeZoom: 0.2 },
            { type: 'drag-canvas', enableOptimize: true },
            {
              type: 'drag-node',
              enableOptimize: true,
              onlyChangeComboSize: true
            },
            {
              type: 'drag-combo',
              enableOptimize: true,
              onlyChangeComboSize: true
            },
            { type: 'brush-select', enableOptimize: true }
          ]
        },
        defaultEdge: {
          type: 'cubic-horizontal',
          lineWidth: 1,
          style: {
            endArrow: true,
            stroke: '#FAD069'
          }
        },
        edgeStateStyles: {
          hover: {
            lineWidth: 2
          }
        },
        defaultNode: {
          type: 'circle',
          size: 15,
          labelCfg: {
            position: 'bottom',
            style: {
              fontSize: 15
            }
          }
        },
        defaultCombo: {
          type: 'circle',
          opacity: 0,
          lineWidth: 1,
          collapsed: true,
          labelCfg: {
            position: 'top',
            refY: 5,
            style: {
              fontSize: 16
            }
          }
        }
      })
      graphG.data(data)
      graphG.render() // 渲染图
      graphG.zoom(0.8) // 如果觉得节点大,可以缩放整个图
      graphG.on('edge:mouseenter', e => {
        graphG.setItemState(e.item, 'hover', true)
      })

      graphG.on('edge:mouseleave', e => {
        graphG.setItemState(e.item, 'hover', false)
      })

      graphG.on('combo:dblclick', e => {
        e.item._cfg.model.type =
          e.item._cfg.model.type === 'rect' ? 'circle' : 'rect' // 分组形状,方圆切换
        e.item._cfg.model.labelCfg.refY =
          e.item._cfg.model.type === 'rect' ? -20 : 5 // 切换形状,改变label定位

        const comboId = e.item._cfg.model.id
        graphG.collapseExpandCombo(comboId)

        // 分组收缩时,删除分组内的连线和节点
        if (e.item._cfg.model.collapsed) {
          // 收缩
          let newedges = e.item.getEdges()
          let newNodes = e.item.getNodes()
          for (let j = 0; j < newedges.length; j++) {
            graphG.removeItem(newedges[j])
          }
          for (let i = 0; i < newNodes.length; i++) {
            graphG.removeItem(newNodes[i])
          }
          data.edges.forEach(edge => {
            graphG.addItem('edge', edge)
          })
        } else {
          // 展开
          // 分组展开时, 添加节点和连线,并给分组内的节点 添加位置信息
          let origin = [e.item._cfg.model.x, e.item._cfg.model.y] // 获取当前分组combs的坐标
          let row = 110,
            clo = 150
          // 生成(10-20)随机数个 随机数 模拟展开分组内的节点
          let randomCount = Math.floor(Math.random() * 10) + 10
          let row_clo = Math.floor(Math.sqrt(randomCount))
          let nodes = []
          for (let i = 0; i < randomCount; i++) {
            let min = comboId.split('-')[0] - 0
            let max = comboId.split('-')[1] - 0
            let randomNum = Math.floor(Math.random() * (max - min)) + min
            if (nodes.indexOf(randomNum) > -1) {
              i--
              continue
            }
            nodes.push(randomNum)
            let rowindex = Math.floor(i / row_clo)
            let cloindex = i % row_clo
            let y = origin[1] + row * rowindex
            let node = {
              label: randomNum,
              id: randomNum.toString(),
              comboId: comboId,
              style: {
                fillOpacity: 0.5,
                cursor: 'pointer',
                fill: randomNum % 5 == 0 ? '#81C7D4' : '#986DB2'
              },
              x: origin[0] + clo * cloindex,
              y: i % 2 == 0 ? y + 40 : y
            }
            graphG.addItem('node', node) // 将节点添加至分组
          }
          nodes.sort((a, b) => a - b) // 将分组内的数字排序,从小到大依次连接,模拟真实数据
          for (let i = 0; i < nodes.length - 1; i++) {
            let edge = {
              source: nodes[i].toString(),
              target: nodes[i + 1].toString(),
              lineWidth: 1,
              style: {
                lineDash: [2, 2],
                lineWidth: 0.5,
                stroke: '#00AA90'
              }
            }
            graphG.addItem('edge', edge) // 添加连线   将分组内的数字排序,从小到大依次连接
          }
        }
      })
    }
  }
}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于antV G6引入本地片的问题,您可以使用G6提供的image节点来插入本地片。例如: ``` import G6 from '@antv/g6'; const data = { /* 节点数据 */ nodes: [ { id: 'node', x: 100, y: 100, label: '片节点', labelCfg: { position: 'bottom' }, /* 自定义节点 */ type: 'image-node', /* 自定义节点属性 */ subtype: 'normal', /* 自定义节点样式 */ style: { width: 80, height: 80, img: 'https://gw.alipayobjects.com/mdn/rms/afts/img/A*KfYTQIobizcAAAAAAAAAAABjAQAAAQ/original', cursor: 'move', stroke: '#eee', shadowOffsetX: 0, shadowOffsetY: 0, shadowColor: 'rgba(0, 0, 0, .2)', shadowBlur: 10 } } ], /* 边数据 */ edges: [] }; G6.registerNode('image-node', { /* 绘制节点 */ draw(cfg, group) { const { style: { img, ...style } } = cfg; const keyShape = group.addShape('image', { attrs: { x: 0, y: 0, width: 80, height: 80, img } }); /* 添加锚点 */ keyShape.addAnchor([ [0.5, 0], [1, 0.5], [0.5, 1], [0, 0.5] ]); return keyShape; } }); const graph = new G6.Graph({ container: 'mountNode', width: 800, height: 600, /* 支持片节点 */ supportCSSTransform: true, /* 拓扑配置 */ layout: { type: 'dagre', rankdir: 'LR', align: 'DL', nodesep: 40, ranksep: 40 }, defaultNode: { type: 'image-node', subtype: 'normal' }, modes: { default: [ { type: 'drag-canvas', enableOptimize: true, optimizeZoom: 3 }, { type: 'zoom-canvas', enableOptimize: true, optimizeZoom: 3 }, 'click-select', { type: 'tooltip', formatText: function formatText(model) { return "<div class=\"tooltip-title\">".concat(model.label, "</div>"); }, offset: 10, shouldUpdate: function shouldUpdate(e) { return e.item.getType() !== 'edge'; } }, { type: 'brush-select' } ] }, /* 数据 */ data }); graph.render(); ``` 在节点的style中,可以通过img属性引入本地片,例如img: require('./images/icon.png')。 希望我的回答对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值