0


G6绘制树形图(自定义节点、自定义边、自定义布局)

目录

1 设计节点

在 registerNode 中定义所有的节点

G6.registerNode('tree-node',{drawShape:functiondrawShape(cfg, group){
    定义图中需要的节点
    }},'single-node',);

为了使用内置的布局方式,选择参数为 ‘tree-node’ 树节点类型,数据格式可以存在children子节点,效果自动生成子树
cfg 可以拿到数据,如cfg.id、cfg.name

1.1 定义节点和文本

使用 group.addShape(‘rect’, {}) 定义节点 rect
配置参数:https://antv-g6.gitee.io/zh/docs/api/shapeProperties/#fill

// 定义节点 rect const rect = group.addShape('rect',{// 'rect'表示矩形图形attrs:{// 节点定义参数:颜色、阴影...},name:'rect-shape',// 为这个节点起名字 不过没有使用过这个名字});

使用 group.addShape(‘text’, {}) 定义文本 text

// 定义文本textconst text = group.addShape('text',{// 'text'表示文本attrs:{// 参数:颜色、文字...},name:'text-shape',});

节点和文字生成后,再定义他们的相对位置
参考官网定义复杂图样式的方式:https://antv-g6.gitee.io/zh/examples/tree/customItemTree#customTree
使用 .getBBox() 获得该文本的盒子bbox,使用文本盒子的相对位置后面的位置坐标

const bbox = text.getBBox();// 获得文本的盒子// 设置rect 节点的位置
        rect.attr({x:-bbox.width /2-5,// x坐标y:-bbox.height,// y坐标width: bbox.width +12,// 宽height: bbox.height +8,// 高});// 设置text文本的位置
        text.attr({x:-bbox.width /2,y:-bbox.height /2+3,})

效果如下
在这里插入图片描述

1.2 增加节点

如果想为节点再增加一个小节点,并且位置随着大节点移动,如图
在这里插入图片描述
新增节点和文本 rect2 text2

rect2 = group.addShape('rect',{attrs:{// 参数},name:'rect-shape2',});const text2 = group.addShape('text',{attrs:{// 参数},name:'text-shape2',});

为rect2 text2设置坐标,以bbox作为参考位置

// 设置坐标轴和宽高
              rect2.attr({x:-bbox.width /2-24,y:-bbox.height /2-1,width:14,height:10,});
              text2.attr({x:-bbox.width /2-23,y:-bbox.height /2+4,})

1.3 自定义节点样式

            roup.addShape('dom',{attrs:{x:-bbox.width /2-24+14,// 即:rect的坐标 + rect的宽 y:-bbox.height /2-1,width:10,height:10,html:`
                  <div style="border: 5px solid red;">
                      自定义dom
                  </div>
                    `,},draggable:true,});

使用自定义dom,在 new G6.TreeGraph中 需要设置

renderer:'svg',// 奇怪的是设置之后原来节点的布局有些影响

2 树图配置

2.1 允许使用自定义dom节点

renderer:'svg',

2.2 内置行为

https://antv-g6.gitee.io/zh/docs/manual/middle/states/defaultBehavior#%E5%86%85%E7%BD%AE-behavior

modes:{default:[{type:'collapse-expand',onChange:functiononChange(item, collapsed){const data = item.get('model');
                graph.updateItem(item,{
                  collapsed,});
                data.collapsed = collapsed;returntrue;},},'drag-canvas',// 允许拖动'zoom-canvas',// ....],},

自定义边

defaultEdge:{type:'cubic-horizontal',style:{stroke:'red'//红色},},

layout布局

https://antv-g6.gitee.io/zh/docs/manual/middle/layout/tree-graph-layout

layout:{type:'indented',direction:'LR',// 节点从左向右分布dropCap:false,indent:190,getHeight:()=>{return13;},getVGap:functiongetVGap(){return10;},},

demo

<template><div class="main-content-box"><div id="container"></div></div></template><script>importG6from'@antv/g6';exportdefault{name:'multTagsSec',data(){return{gDatas:{"id":"1","name":"storehouse A","children":[{"id":"2","name":"B","percentage":"60%","children":[{"id":"3","name":"storehouse C","percentage":"80%","children":[{"name":"storehouse C","percentage":"80%","children":[{"name":"D","percentage":"20%"},{"name":"storehouselllllll C","percentage":"20%"}]},{"name":"storehouse D","percentage":"20%"}]},{"name":"storehouse D","percentage":"20%"}]},{"name":"storehouse C","percentage":"100%"},{"name":"storehouse B","percentage":"20%"},{"name":"storehouse C","percentage":"20%"},{"name":"storehouse C","percentage":"20%","children":[{"name":"D","percentage":"20%"},{"name":"storehouse A","percentage":"20%"}]}]}}},mounted(){this.getInit();},methods:{getInit(){// var mycfg = null;G6.registerNode('tree-node',{drawShape:functiondrawShape(cfg, group){// console.log(cfg)// --------------------标签内容节点----------------------var hasChildren = cfg.children && cfg.children.length >0;// 是否有孩子节点var strokeColor =  hasChildren ==true?'red':null// 有孩子 为红色// 节点设置 const rect = group.addShape('rect',{attrs:{fill:'#fff',stroke: strokeColor,// 边框颜色lineWidth:1,// 边框粗细radius:2,shadowBlur:15,shadowColor:'#666',// shadowOffsetX: 2,// shadowOffsetY: 2},name:'rect-shape',});// 文本设置const text = group.addShape('text',{attrs:{text: cfg.name,// 赋值name属性fontFamily:'normal',fontSize:11,fontWeight:800,x:0,y:0,textAlign:'left',textBaseline:'middle',fill:'#666'},name:'text-shape',});const bbox = text.getBBox();// 获得文本的盒子 之后的两个节点的xy轴坐标参考bbox//const minbbox = rect.getBBox();// 设置 rect方框和text文本 的 x y坐标轴
            rect.attr({x:-bbox.width /2-5,y:-bbox.height,// width: bbox.width + (hasChildren ? 20 : 12),width: bbox.width +12,height: bbox.height +8,});
            text.attr({x:-bbox.width /2,y:-bbox.height /2+3,})// -----------百分比节点----------var hasPercentage = cfg.percentage;var rect2 =0;if(hasPercentage){// 节点设置 2
                rect2 = group.addShape('rect',{attrs:{fill:'#4682B4',stroke:'',// 边框颜色lineWidth:0,// 边框粗细shadowBlur:0,shadowColor:'',},name:'rect-shape2',});// 文本设置 2const text2 = group.addShape('text',{attrs:{text: cfg.percentage,// 赋值name属性fontFamily:'normal',fontSize:5,fontWeight:500,textAlign:'left',textBaseline:'middle',fill:'white'},name:'text-shape2',});// 设置坐标轴和宽高
              rect2.attr({x:-bbox.width /2-24,y:-bbox.height /2-1,width:14,height:10,});
              text2.attr({x:-bbox.width /2-23,y:-bbox.height /2+4,})// -------连接两个节点的小节点----------// const rect3 = group.addShape('rect', {//     attrs: {//         fill: '#00BFFF',//         stroke: '',  // 边框颜色//         lineWidth: 0,       // 边框粗细//         shadowBlur: 0,//         shadowColor: '',//     },//     name: 'rect-shape3',// });// rect3.attr({//     x: -bbox.width / 2 - 24 + 14,   // 即:rect的坐标 + rect的宽 //     y: -bbox.height / 4 + 1,//     width: 4,//     height: 4// });// -------连接两个节点的小节点 三角形----------// 需要设置svg才能使用
              group.addShape('dom',{attrs:{x:-bbox.width /2-24+14,// 即:rect的坐标 + rect的宽 y:-bbox.height /2-1,width:10,height:10,html:`
                  <div style="border-left: 5px solid red; 
                              border-right: 5px solid transparent;
                              border-top: 5px solid transparent;
                              border-bottom: 5px solid transparent;">
                  </div>
                    `,},draggable:true,});}// 小圆圈if(hasChildren){const redcircle = group.addShape('marker',{attrs:{symbol: cfg.collapsed ?G6.Marker.expand :G6.Marker.collapse,// symbol: cfg.collapsed ? COLLAPSE_ICON : EXPAND_ICON,stroke:'red',fill:'red',lineWidth:1.8,},name:'collapse-icon',});
              redcircle.attr({x: bbox.width /2+7,y:-3,r:4,})}return rect;},update:(cfg, item)=>{const group = item.getContainer();const icon = group.find((e)=> e.get('name')==='collapse-icon');
            icon.attr('symbol', cfg.collapsed ?G6.Marker.expand :G6.Marker.collapse);},},'single-node',);const container = document.getElementById('container');const width = container.scrollWidth;const height = container.scrollHeight ||500;const graph =newG6.TreeGraph({renderer:'svg',// 创建自定义DMO时定义 会报一个错 但好像不影响 container:'container',
        width,
        height,modes:{default:[{type:'collapse-expand',onChange:functiononChange(item, collapsed){const data = item.get('model');
                graph.updateItem(item,{
                  collapsed,});
                data.collapsed = collapsed;returntrue;},},// 'drag-canvas',    // 不可拖动'zoom-canvas',],},defaultNode:{type:'tree-node',anchorPoints:[[0,0.5],[1,0.5],],},// 设置边的参数defaultEdge:{type:'cubic-horizontal',style:{stroke:'red'},},layout:{type:'indented',direction:'LR',dropCap:false,indent:190,getHeight:()=>{return13;},getVGap:functiongetVGap(){return10;},},});
  
  
      
  
      graph.data(this.gDatas);
      graph.render();
      graph.fitView();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><style scoped></style>

在这里插入图片描述

标签: javascript 前端 html5

本文转载自: https://blog.csdn.net/weixin_52268321/article/details/129324972
版权归原作者 诚诚程程成 所有, 如有侵权,请联系我们删除。

“G6绘制树形图(自定义节点、自定义边、自定义布局)”的评论:

还没有评论