antv-G6使用笔记

  1. 有一个需求实现类似于企查查之类的企业图谱功能。调研了几个工具后,决定使用g6绘图来实现。
    具体使用方式查看G6官网文档
    下面附上写的一个demo代码。涵盖了节点位置,文字,颜色,节点事件等。

父组件




register-edge.js

export default G6 => {
  G6.registerEdge("kaimo-line", {
    /**
     * 绘制边,包含文本
     * @param  {Object} cfg 边的配置项
     * @param  {G.Group} group 图形分组,边中的图形对象的容器
     * @return {G.Shape} 绘制的图形,通过 node.get('keyShape') 可以获取到
     */
    draw(cfg, group) {
      const startPoint = cfg.startPoint;
      const endPoint = cfg.endPoint;
      const target = cfg.targetNode.getModel()
      const source = cfg.sourceNode.getModel()
      let shape;
      shape = group.addShape("path", {
        //线条
        attrs: {
          stroke: "#E4E7ED",
          path: [
            ["M", startPoint.x, startPoint.y],
            ["L", endPoint.x / 3 + (2 / 3) * startPoint.x, startPoint.y],
            ["L", endPoint.x / 3 + (2 / 3) * startPoint.x, endPoint.y],
            ["L", endPoint.x, endPoint.y],
          ],
          endArrow: {
            path: G6.Arrow.triangle(5, 5, 0), // 使用内置箭头路径函数,参数为箭头的 宽度、长度、偏移量(默认为 0,与 d 对应)
            d: 0,
            fill: "#E4E7ED",
            opacity: 0.5,
            lineWidth: 1,
          },
        },
        // must be assigned in G6 3.3 and later versions. it can be any value you want
        name: "path-shape",
      });
      // 关系描述
      if (target.edgesLabel) {
        group.addShape('text', {
          attrs: {
            x: endPoint.x + 10,
            y: endPoint.y,
            fontSize: 12,
            text: target.edgesLabel,
            fill: '#666'
          }
        })
      }
      return shape;
    },
  });
}

register-node.js

import G6 from '@antv/g6'
// 文本超出隐藏 (字段, 最大长度, 字体大小)
const fittingString = (str, maxWidth, fontSize) => {
  const ellipsis = "..."
  const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0]
  let currentWidth = 0
  let res = str
  const pattern = new RegExp("[\u4E00-\u9FA5]+")
  str.split("").forEach((letter, i) => {
    if (currentWidth > maxWidth - ellipsisLength) return
    if (pattern.test(letter)) {
      currentWidth += fontSize
    } else {
      currentWidth += G6.Util.getLetterWidth(letter, fontSize)
    }
    if (currentWidth > maxWidth - ellipsisLength) {
      res = `${str.substr(0, i)}${ellipsis}`
    }
  })
  return res
};
// 获取文本的长度
const getTextSize = (str, maxWidth, fontSize) => {
  let width = G6.Util.getTextSize(str, fontSize)[0]
  return width > maxWidth ? maxWidth : width
}
const getItemBakColor = (str) => {
  if (str === '股东') return '#FD924E'
  if (str === '高管') return '#7685E4'
  if (str === '客户') return '#3FCDC1'
  if (str === '对外投资') return '#F3AF17'
  if (str === '供应商') return '#FA9B2D'
  if (str === '实控人') return '#FA7370'
}

const register = G6 => {
  G6.registerNode("tree-node", {
    draw(cfg, group) {
      let rect;
      if (cfg.depth === 0) {
        rect = group.addShape("circle", {
          attrs: {
            x: 100, // x 轴移动距离
            y: 20, // y 轴移动距离
            r: 40,
            fill: "#0D85EE",
            stroke: "#0D85EE", // 边框色
          },
          name: "big-circle-shape",
        });
        group.addShape("image", {
          attrs: {
            x: 75, // x 轴移动距离
            y: -8, // y 轴移动距离
            width: 50,
            height: 50,
            img: require('@/assets/img/fangzi.png'),
          },
          name: "big-image-shape",
        });
        group.addShape("text", {
          attrs: {
            text: fittingString(cfg.label, 90, 16),
            x: 100,
            // x: getTextSize(cfg.label, 90, 16) + 35,
            y: 90,
            fontSize: 18,
            textAlign: "center",
            fontWeight: 700,
            textBaseline: "middle",
            fill: "#0D85EE",
          },
          name: "text-shape",
        });
        group.addShape("text", {
          attrs: {
            text: `[${cfg.companyCode}]`,
            x: 100,
            y: 110,
            fontSize: 18,
            textAlign: "center",
            fontWeight: 700,
            textBaseline: "middle",
            fill: "#0D85EE",
          },
          name: "text-shape",
        });
      }
      if (cfg.location === "left") {
        if (cfg.depth === 1) {
          rect = group.addShape("circle", {
            attrs: {
              x: 160, // x 轴移动距离
              y: 20, // y 轴移动距离
              r: 35,
              fill: getItemBakColor(cfg.label),
              stroke: getItemBakColor(cfg.label), // 边框色
            },
            name: "first-circle-shape",
          });
          if (cfg.label === '对外投资') {
            group.addShape("text", {
              attrs: {
                text: '对外',
                x: 160,
                y: 12,
                fontSize: 18,
                textAlign: "center",
                textBaseline: "middle",
                fill: "#fff",
              },
              name: "text-shape",
            });
            group.addShape("text", {
              attrs: {
                text: '投资',
                x: 160,
                y: 32,
                fontSize: 18,
                textAlign: "center",
                textBaseline: "middle",
                fill: "#fff",
              },
              name: "text-shape",
            });
          } else {
            group.addShape("text", {
              attrs: {
                text: cfg.label,
                x: 160,
                y: 20,
                fontSize: 18,
                textAlign: "center",
                textBaseline: "middle",
                fill: "#fff",
              },
              name: "text-shape",
            });
          }
        } else {
          if (cfg.label.indexOf('更多') > -1) {
            rect = group.addShape("rect", {
              attrs: {
                x: cfg.post ? 160 - getTextSize(cfg.label, 210, 18) - getTextSize(cfg.post, 210, 18) + 50 : 160 - getTextSize(cfg.label, 210, 18) + 50, // x 轴移动距离
                y: 0, // y 轴移动距离
                width: cfg.post ? getTextSize(cfg.label, 210, 18) + getTextSize(cfg.post, 210, 18) + 30 : getTextSize(cfg.label, 210, 18) + 30, // 宽
                height: 40, // 高
                fontSize: 18,
                radius: 4,
              },
              name: "big-rect-shape",
            });
            group.addShape("text", {
              attrs: {
                text: fittingString(cfg.label, 210, 18),
                x: 160 - getTextSize(cfg.label, 210, 18) + 80,
                y: 20,
                fontSize: 18,
                textAlign: "left",
                textBaseline: "middle",
                fill: '#0D85EE',
                cursor: 'pointer'
              },
              name: "text-shape",
            });
          } else {
            rect = group.addShape("rect", {
              attrs: {
                x: cfg.post ? 160 - getTextSize(cfg.label, 210, 18) - getTextSize(cfg.post, 210, 18) + 50 : 160 - getTextSize(cfg.label, 210, 18) + 50, // x 轴移动距离
                y: 0, // y 轴移动距离
                width: cfg.post ? getTextSize(cfg.label, 210, 18) + getTextSize(cfg.post, 210, 18) + 30 : getTextSize(cfg.label, 210, 18) + 30, // 宽
                height: 40, // 高
                fontSize: 18,
                // stroke: "#666",
                // fontWeight: 600,
                radius: 4,
              },
              name: "big-rect-shape",
            });
            // 左文本点
            group.addShape("text", {
              attrs: {
                text: fittingString(cfg.label, 210, 18),
                x: cfg.post ? 160 - getTextSize(cfg.label, 210, 18) + 50 : 160 - getTextSize(cfg.label, 210, 18) + 80,
                y: 20,
                fontSize: 18,
                textAlign: "left",
                textBaseline: "middle",
                fill: document.body.className.indexOf('custom-f4c46d')>-1?'#fff' :'#333',
              },
              name: "text-shape",
            });
            if (cfg.post) {
              group.addShape("text", {
                attrs: {
                  text: `[${cfg.post}]`,
                  x: 195 + getTextSize(cfg.post, 210, 18),
                  y: 20,
                  fontSize: 18,
                  textAlign: "left",
                  textBaseline: "middle",
                  fill: '#666',
                },
                name: "text-shape",
              });
            }
          }
        }
      } 
      if (cfg.location === "right") {
        if (cfg.depth === 1) {
          rect = group.addShape("circle", {
            attrs: {
              x: 35, // x 轴移动距离
              y: 20, // y 轴移动距离
              r: 35,
              fill: getItemBakColor(cfg.label),
              stroke: getItemBakColor(cfg.label), // 边框色
            },
            name: "first-circle-shape",
          });
          group.addShape("text", {
            attrs: {
              text: cfg.label,
              x: 35,
              y: 20,
              fontSize: 18,
              textAlign: "center",
              textBaseline: "middle",
              fill: "#fff",
            },
            name: "text-shape",
          });
        } else {
          if (cfg.label.indexOf('更多') > -1) {
            rect = group.addShape("text", {
              attrs: {
                text: fittingString(cfg.label, 210, 18),
                x: 10,
                y: 20,
                fontSize: 18,
                textAlign: "left",
                textBaseline: "middle",
                fill: '#0D85EE',
                cursor: 'pointer'
              },
              name: "text-shape",
            });
          } else {
            rect = group.addShape("text", {
              attrs: {
                text: cfg.companyType === '高管' ? cfg.label : fittingString(cfg.label, 210, 18),
                x: 10,
                y: 20,
                fontSize: 18,
                textAlign: "left",
                textBaseline: "middle",
                fill: document.body.className.indexOf('custom-f4c46d')>-1?'#fff' :'#333',
              },
              name: "text-shape",
            });
            if (cfg.post) {
              group.addShape("text", {
                attrs: {
                  text: `[${cfg.post}]`,
                  x: getTextSize(cfg.label, 210, 18) + 15,
                  y: 20,
                  fontSize: 18,
                  textAlign: "left",
                  textBaseline: "middle",
                  fill: '#666',
                },
                name: "text-shape",
              });
            }
          }
        }
      }
      return rect
    }
  })
}
export { register }

你可能感兴趣的:(日记,笔记,vue,前端)