目录
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>
版权归原作者 诚诚程程成 所有, 如有侵权,请联系我们删除。