在angular中使用AntV G6绘制树状图
注意:引入的g6库的版本必须和typescript版本相匹配,否则在项目中会报错,在这个案例中由于项目版本中ts的版本为4.0.2所以我安装的g6版本为3.8.5。下面这个案例是创建一个垂直的树形图,且当叶子节点文本超过10时,文本会显示为省略号。且节点选中和未选中状态显示的填充色和文本颜色不一样。(2)创建自定义节点(包含超出范围用省略号显示、以及选中效果)3.在ts中获取这个dom节点,然后创
·
目录
一、AntV G6
是阿里巴巴蚂蚁金服旗下 AntV 数据可视化团队开发的一款专注于关系数据的图可视化引擎,旨在帮助开发者高效构建专业的图可视化、图分析或图编辑器应用。
二、使用步骤
下面这个案例是创建一个垂直的树形图,且当叶子节点文本超过10时,文本会显示为省略号。且节点选中和未选中状态显示的填充色和文本颜色不一样。
1.引入库
注意:引入的g6库的版本必须和typescript版本相匹配,否则在项目中会报错,在这个案例中由于项目版本中ts的版本为4.0.2所以我安装的g6版本为3.8.5。
npm i @antv/g6@3.8.5
2.在项目中使用g6
1.在ts文件中引入
import G6 from '@antv/g6';
2.在html中创建一个有宽高的容器
<div #orgElement class="echarts-width"></div>
3.在ts中获取这个dom节点,然后创建g6图例
**注意:在创建graph图表前最好调需要创建的自定义节点、边,但事件需要在graph.render方法渲染后才调
onInitGraph() {
/**设置自定义边*/
this.onRegisterEdge();
/**设置自定义节点 */
this.onSetNewNode();
const container = this.orgElement.nativeElement;
this.graph = new G6.TreeGraph({
container: container,
width: container.offsetWidth,
height: container.offsetHeight,
plugins: [this.onSetTooltip()], //显示tooltip
fitView: true, //自适应
linkCenter: true, //连接线从节点中心出发
modes: { default: ['drag-canvas', 'zoom-canvas'] },// 支持画布拖拽,缩放
defaultNode: {
type: 'self-text-node', // 使用自定义节点
size: [100, 40], // 宽度固定,高度动态
clipCfg: { show: false } // 禁用裁剪
},
/**节点选中样式 */
nodeStateStyles: {
selected: {
// 选中状态样式
fill: '#3eaeff', // 蓝色背景
stroke: 'transparent', // 无边框
'text-shape': {
fill: '#fff' // 白色字体
}
}
},
defaultEdge: {
type: 'vertical-line',
style: {
stroke: '#1890ff'
}
},
layout: {
type: 'dendrogram',
direction: 'TB', // 从上到下布局(根节点在顶部)
nodeSep: 200, // 节点间距
rankSep: 100 // 层级间距,
}
});
this.graph.data(this.graphDataIfy.data);
this.graph.render();
// 默认选中根节点
const node = this.graph.findById(this.leftOrgIfy.activedNode.key);
this.graph.setItemState(node, 'selected', true); //true表示启用选中状态
this.onClickNode();
}
4.创建图表使用的自定义方法、点击方法等
(1)设置自定义边
创建根节点与叶子结点的连接边,垂直显示
/**自定义边,根节点和叶子结点的连接线 */
onRegisterEdge() {
G6.registerEdge('vertical-line', {
draw(cfg, group) {
/**由于设置了linkCenter所以都是从节点中心开始[0.5,0.5] */
const { startPoint, endPoint } = cfg;
/**M 移动到指定坐标,L 直线到指定坐标,从中心垂直向下后水平移动再垂直向下 */
const path = [
['M', startPoint.x, startPoint.y], //移动到起点
['L', startPoint.x, (startPoint.y + endPoint.y) / 2], // 垂直向下
['L', endPoint.x, (startPoint.y + endPoint.y) / 2], // 水平移动
['L', endPoint.x, endPoint.y] // 垂直向下
];
return group.addShape('path', {
attrs: { path, stroke: '#1890ff' }
});
}
});
}
(2)创建自定义节点(包含超出范围用省略号显示、以及选中效果)
/**设置新的节点 */
onSetNewNode() {
// // 在graph初始化前添加自定义节点类型
G6.registerNode('self-text-node', {
/**
* @param cfg 节点配置项
* @param group 节点容器
*/
draw(cfg: any, group) {
const { width, height } = this.calcSize(cfg);
const rect = this.drawRect(group, width, height);
this.drawText(cfg, group);
return rect;
},
calcSize(cfg) {
const mockCtx = document.createElement('canvas').getContext('2d');
mockCtx.font = '12px sans-serif';
// 截断文本(10个中文字符+省略号)
const displayText =
cfg.label.length > 10 && cfg.depth !== 0
? cfg.label.substr(0, 10) + '...'
: cfg.label;
const metrics = mockCtx.measureText(displayText); //获取文本的宽度
return {
width: Math.max(100, metrics.width + 20),
height: Math.max(40, 24)
};
},
drawRect(group, w, h) {
return group.addShape('rect', {
attrs: {
x: -w / 2,
y: -h / 2,
width: w,
height: h,
fill: '#f0f1f5',
radius: 4
},
name: 'node-rect'
});
},
drawText(cfg, group) {
// 保持与calcSize相同的截断逻辑
const displayText =
cfg.label.length > 10 && cfg.depth !== 0
? cfg.label.substr(0, 10) + '...'
: cfg.label;
group.addShape('text', {
attrs: {
text: displayText,
x: 0,
y: 0,
fontSize: 12,
fill: '#3eaeff',
textAlign: 'center',
textBaseline: 'middle'
},
name: 'node-text'
});
},
/**设置选中时的填充和文字颜色
* @param name 状态名称 selected、hover
* @param value 状态值 true为选中,false为未选中
* @param item 节点实例对象
*/
setState(name, value, item) {
const group = item.get('group');
['node-rect', 'node-text'].forEach(key => {
const shape = group.find(e => e.get('name') === key);
if (shape)
shape.attr(
key.includes('text') ? 'fill' : 'fill',
value
? key.includes('text')
? '#fff'
: '#3eaeff'
: key.includes('text')
? '#3eaeff'
: '#f0f1f5'
);
});
}
});
}
(3)点击节点事件实现选中效果和调取接口
/**点击事件 */
onClickNode() {
this.graph.on('node:click', e => {
const clickedNode = e.item;
// 清除所有节点选中状态
this.graph.getNodes().forEach(node => {
if (node !== clickedNode) {
this.graph.setItemState(node, 'selected', false);
}
});
this.graph.setItemState(clickedNode, 'selected', true);
this.graphDataIfy.selectedNode = clickedNode;
/**层级置于最顶层 */
clickedNode.toFront();
//...调接口
});
}
(4)设置超出文本10长度显示tootip文字提示
/**设置tootip */
onSetTooltip() {
const tooltip = new G6.Tooltip({
offsetX: 500, // 偏移量
itemTypes: ['node'], // 仅节点生效
container: this.orgElement.nativeElement,
getContent: e => {
return e.item.getModel().label; // 显示完整文本
},
shouldBegin: e => {
const text = e.item.getModel().label;
return text.length; // 仅超长文本触发
}
});
return tooltip;
}
三、最终效果图

更多推荐
所有评论(0)