本文主要是介绍antv/g6 绘制生态图-新手入门,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
实现效果如下图:
API文档:图配置 G6.Graph(cfg) | G6
参考样例:自定义树图 | G6
坐标转换:坐标转换
一、安装 & 引用
1. 通过npm包引入
npm install --save @antv/g6
在需要使用的文件中直接引入G6即可
import G6 from "@antv/g6"
2. 通过CDN形式引入
// version <= 3.2
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-{$version}/build/g6.js"></script>// version >= 3.3
<script src="https://gw.alipayobjects.com/os/lib/antv/g6/{$version}/dist/g6.min.js"></script>
二、数据结构如下:
const mockData = {id: 'g1',name: '我是科目我是科目我是科目我是科目我是科目我是科目目目目目',dataType: 'root',amount: 123123213123.123123,children: [{id: 'g12',name: 'Deal with LONG label LONG label LONG label LONG label',amount: 123123213123.123123,children: [{id: 'g121',name: 'Name3',collapsed: true,amount: 123123213123.123123,children: [{id: 'g1211',name: 'Name4',amount: 123123213123.123123,children: [],},],},{id: 'g122',name: 'Name5',collapsed: true,amount: 2.34,children: [{id: 'g1221',name: 'Name6',amount: 0.123123,children: [{id: 'g12211',name: 'Name6-1',amount: 123123,children: [],},],},{id: 'g1222',name: 'Name7',amount: 123123213123.123123,children: [],},],},{id: 'g123',name: 'Name8',collapsed: true,amount: 12,children: [{id: 'g1231',name: 'Name8-1',amount: 123123213123.123123,children: [],},],},],},{id: 'g13',name: 'Name9',amount: 123123213123.123123,children: [{id: 'g131',name: 'Name10',amount: 12313123.123123,children: [],},{id: 'g132',name: 'Name11',amount: 123123213123.123123,children: [],},],},{id: 'g14',name: 'Name12',amount: 123123213123.123123,children: [],},],};
完整代码如下:
<template><div id="container"></div>
</template><script>
import G6 from '@antv/g6';export default {name: 'HelloWorld',props: {msg: String},created() { },mounted() {this.initAntv();},methods: {// 初始化initAntv() {// 组件propsconst props = {data: mockData,config: {padding: [20, 50],// defaultLevel: 3,defaultZoom: 0.8,modes: { default: ['zoom-canvas', 'drag-canvas'] },},};const container = document.getElementById('container');const width = container.scrollWidth;const height = container.scrollHeight || 500;// 默认配置const defaultConfig = {width,height,modes: {default: ['zoom-canvas', 'drag-canvas'],},fitView: true,animate: true,minZoom: 0.5,maxZoom: 1.5,linkCenter: false,defaultNode: { // 默认节点type: 'flow-rect',},defaultEdge: { // 默认边type: 'cubic-horizontal',style: {stroke: 'rgb(93, 162, 216)',},},layout: { // layout 布局配置type: 'mindmap', direction: 'V',dropCap: false,rankSep: 350,nodeSep: 100,getHeight: () => {return 60;},// 节点横向间距的回调函数getHGap: function getHGap() {return 150;}},};// 自定义节点const registerFn = () => {/*** 自定义节点*/G6.registerNode('flow-rect',{shapeType: 'flow-rect',draw(cfg, group) {const {name = '',collapsed,dataType,amount,} = cfg;const config = {basicColor: 'rgb(66, 151, 215)', // 左边粗线的颜色fontColor: 'rgb(74, 177, 241)', // 字体颜色borderColor: 'rgb(169, 217, 252)', // 边框颜色bgColor: 'rgb(230, 240, 250)', // 矩形背景色};const rectConfig = {width: 243,height: 64,lineWidth: 1,fontSize: 12,opacity: 1,fill: config.bgColor,stroke: config.borderColor,radius: 2,cursor: 'pointer',};const nodeOrigin = {x: -rectConfig.width / 2,y: -rectConfig.height / 2,};const textConfig = {textAlign: 'left',textBaseline: 'bottom',};if (dataType != 'root') {/* 左边的小圆点 */group.addShape('circle', {attrs: {x: nodeOrigin.x - 0,y: 0,r: 6,fill: config.basicColor,},name: 'left-dot-shape',});}// 外层矩形const rect = group.addShape('rect', {attrs: {x: nodeOrigin.x,y: nodeOrigin.y,...rectConfig,},});/* 左边的粗线 */group.addShape('rect', {attrs: {x: nodeOrigin.x,y: nodeOrigin.y,width: 3,height: rectConfig.height,fill: config.basicColor,radius: 1.5,},name: 'left-border-shape',});const rectBBox = rect.getBBox();// 科目group.addShape('text', {attrs: {...textConfig,x: 12 + nodeOrigin.x,y: 20 + nodeOrigin.y,text: name.length > 16 ? name.substr(0, 16) + '...' : name,fontSize: 12,opacity: 0.85,fill: config.fontColor,cursor: 'pointer',},name: 'name-shape',});if (amount) {// 金额-矩形const amountRect = group.addShape('rect', {attrs: {fill: '#fff',radius: 2,stroke: config.borderColor,cursor: 'pointer', // 需要调整},name: 'amount-container-shape',})// 金额const amountText = group.addShape('text', {attrs: {...textConfig,x: rectBBox.maxX - 10,y: rectBBox.maxY - 10,text: `${amount}`,fontSize: 12,textAlign: 'right',fill: '#000',},name: 'amount-text-shape',});const amountBBox = amountText.getBBox(); // 获取元素的包围盒/* amountBBox */amountRect.attr({x: rectBBox.maxX - amountBBox.width - 15,y: rectBBox.maxY - 27,width: amountBBox.width + 10,height: amountBBox.height + 10,});}// collapse rectif (cfg.children && cfg.children.length) {group.addShape('circle', {attrs: {x: rectConfig.width / 2 + 8.5,y: 0,r: 8,width: 16,height: 16,stroke: 'rgb(74, 177, 241)',cursor: 'pointer',fill: '#fff',},name: 'collapse-back',modelId: cfg.id,});// collpase textgroup.addShape('text', {attrs: {x: rectConfig.width / 2 + 8.5,y: 1,textAlign: 'center',textBaseline: 'middle',text: collapsed ? '+' : '-',fontSize: 16,cursor: 'pointer',fill: 'rgb(74, 177, 241)',},name: 'collapse-text',modelId: cfg.id,});}return rect;},update(item) {// const { level, name } = cfg;// console.log("update生命周期函数中的cfg========", cfg)const group = item.getContainer();let mask = group.find(ele => ele.get('name') === 'mask-shape');let maskLabel = group.find(ele => ele.get('name') === 'mask-label-shape');group.get('children').forEach(child => {if (child.get('name')?.includes('collapse')) return;child.show();})mask?.animate({ opacity: 0 }, {duration: 200,callback: () => mask.hide()});maskLabel?.animate({ opacity: 0 }, {duration: 200,callback: () => maskLabel.hide()});},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',);};registerFn();const { data } = props;let graph = null;const initGraph = (data) => {if (!data) {return;}const { onInit, config } = props;const tooltip = new G6.Tooltip({// offsetX and offsetY include the padding of the parent containeroffsetX: 20,offsetY: 30,// 允许出现 tooltip 的 item 类型itemTypes: ['node'],// custom the tooltip's content// 自定义 tooltip 内容getContent: (e) => {const outDiv = document.createElement('div');outDiv.style.textAlign = 'left';const nodeName = e.item.getModel().name;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') === 'name-shape' || e.target.get('name') === 'mask-label-shape') return true;const nodeName = e.item.getModel().name;if (nodeName.length > 24) {return true} else {return false;}},});graph = new G6.TreeGraph({container: 'container',...defaultConfig,...config,plugins: [tooltip],});if (typeof onInit === 'function') {onInit(graph);}graph.data(data);graph.render();const handleCollapse = (e) => {const target = e.target;const id = target.get('modelId');const item = graph.findById(id);const nodeModel = item.getModel();nodeModel.collapsed = !nodeModel.collapsed;graph.layout();graph.setItemState(item, 'collapse', nodeModel.collapsed);};graph.on('collapse-text:click', (e) => {handleCollapse(e);});graph.on('collapse-back:click', (e) => {handleCollapse(e);});};initGraph(data);if (typeof window !== 'undefined')window.onresize = () => {if (!graph || graph.get('destroyed')) return;if (!container || !container.scrollWidth || !container.scrollHeight) return;graph.changeSize(container.scrollWidth, container.scrollHeight);};}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
问题:
当我们按照以上操作绘制完图之后,发现画布中的内容并非居中展示,设置 fitView: true 并没有起作用,有可能是因为布局原因,有定位的设置可能会影响画布的中心坐标,有了解决问题的思路 ,我们就开始着手试试把。增加以下代码:
// 设置画布居中
setCenetr(graph) {const con_width = document.getElementById("container").clientWidth;const con_Height = document.getElementById("container").clientHeight;// 重新计算画布中心的坐标const centerX = con_width / 2 - 60;const centerY = con_Height / 2 - 60;// 以 x, y 为坐标中心,进行缩放graph.zoomTo(0.7, {x: centerX,y: centerY})
}
以上方法需在 graph.render() 之前执行。
友情提示:新手小白入门的话最好是先找个和自己需求相似案例看看,然后开始照猫画虎,画着画着慢慢就能就看明白了,当然 大佬略过哈 ~ 多看看官方的文档,写的很详细。
这篇关于antv/g6 绘制生态图-新手入门的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!