如何使用NGX-Graph创建带自定义节点形状、颜色及带标签边的DAG图
没问题!ngx-graph本身就提供了非常灵活的自定义能力,我帮你拆解成三个核心需求来一步步实现,附上完整的代码示例:
1. 自定义节点形状
ngx-graph允许通过自定义模板来完全控制节点的外观,你可以用SVG元素绘制任何你想要的形状(圆角矩形、圆形、复杂路径都可以)。具体做法是用<ng-template>定义节点模板,再通过nodeTemplate属性绑定到ngx-graph组件上。
示例代码:
<!-- 主组件模板 --> <ngx-graph [view]="[700, 500]" [nodes]="graphNodes" [links]="graphLinks" [nodeTemplate]="customNodeTemplate" layout="dagre" > </ngx-graph> <!-- 自定义节点模板 --> <ng-template #customNodeTemplate let-node> <svg:g> <!-- 这里用圆角矩形作为自定义形状,你可以换成circle/path等 --> <svg:rect [attr.width]="node.size?.width || 120" [attr.height]="node.size?.height || 60" [attr.x]="-(node.size?.width || 120)/2" [attr.y]="-(node.size?.height || 60)/2" rx="10" ry="10" [attr.fill]="node.style?.bgColor" stroke="#333" stroke-width="2" /> <!-- 节点文本 --> <svg:text text-anchor="middle" dominant-baseline="central" [attr.fill]="node.style?.textColor || '#fff'" font-size="14" > {{ node.label }} </svg:text> </svg:g> </ng-template>
在组件类中,你可以给节点添加自定义属性(比如尺寸、样式):
graphNodes = [ { id: 'node1', label: '用户中心', size: { width: 140, height: 70 }, style: { bgColor: '#2ecc71' } }, { id: 'node2', label: '权限系统', size: { width: 140, height: 70 }, style: { bgColor: '#3498db', textColor: '#000' } } ];
2. 自定义节点/边颜色
颜色自定义可以和形状模板结合实现:
- 节点颜色:直接在模板中绑定节点数据里的颜色属性(如上例的
node.style.bgColor) - 边颜色:同样通过自定义边模板来实现,同时还能顺便添加边标签
3. 给边添加标签
和自定义节点一样,我们可以通过linkTemplate属性绑定自定义边模板,在模板中添加SVG文本元素来显示边的标签,ngx-graph会自动计算好标签的位置(link.labelPosition)。
完整的边模板示例:
<!-- 自定义边模板 --> <ng-template #customLinkTemplate let-link> <svg:g> <!-- 边的路径 --> <svg:path [attr.d]="link.path" stroke-width="2" [attr.stroke]="link.style?.color || '#95a5a6'" fill="none" /> <!-- 边的标签 --> <svg:text [attr.x]="link.labelPosition.x" [attr.y]="link.labelPosition.y - 5" <!-- 上移5像素避免和边重叠 --> text-anchor="middle" font-size="12" fill="#333" > {{ link.label }} </svg:text> </svg:g> </ng-template>
然后在组件类的链接数据中添加标签和颜色:
graphLinks = [ { id: 'link1', source: 'node1', target: 'node2', label: '依赖调用', style: { color: '#e74c3c' } } ];
完整整合示例
把上面的代码整合起来,你就能得到一个完全自定义的图:
<!-- app.component.html --> <div style="width: 100%; height: 500px;"> <ngx-graph [view]="[700, 500]" [nodes]="graphNodes" [links]="graphLinks" [nodeTemplate]="customNodeTemplate" [linkTemplate]="customLinkTemplate" layout="dagre" > </ngx-graph> </div> <ng-template #customNodeTemplate let-node> <svg:g> <svg:rect [attr.width]="node.size?.width || 120" [attr.height]="node.size?.height || 60" [attr.x]="-(node.size?.width || 120)/2" [attr.y]="-(node.size?.height || 60)/2" rx="10" ry="10" [attr.fill]="node.style?.bgColor" stroke="#ecf0f1" stroke-width="2" /> <svg:text text-anchor="middle" dominant-baseline="central" [attr.fill]="node.style?.textColor || '#fff'" font-size="14" font-weight="500" > {{ node.label }} </svg:text> </svg:g> </ng-template> <ng-template #customLinkTemplate let-link> <svg:g> <svg:path [attr.d]="link.path" stroke-width="3" [attr.stroke]="link.style?.color || '#bdc3c7'" fill="none" /> <svg:text [attr.x]="link.labelPosition.x" [attr.y]="link.labelPosition.y - 5" text-anchor="middle" font-size="13" fill="#2c3e50" font-weight="500" > {{ link.label }} </svg:text> </svg:g> </ng-template>
// app.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { graphNodes = [ { id: 'node-a', label: '用户管理', size: { width: 130, height: 65 }, style: { bgColor: '#27ae60' } }, { id: 'node-b', label: '权限配置', size: { width: 130, height: 65 }, style: { bgColor: '#f39c12' } }, { id: 'node-c', label: '菜单管理', size: { width: 130, height: 65 }, style: { bgColor: '#3498db' } } ]; graphLinks = [ { id: 'link-ab', source: 'node-a', target: 'node-b', label: '包含', style: { color: '#e67e22' } }, { id: 'link-ac', source: 'node-a', target: 'node-c', label: '关联', style: { color: '#2980b9' } } ]; }
注意事项
- 确保你已经在Angular项目中正确安装并导入了
NgxGraphModule - 可以根据需求替换SVG元素,比如用
<circle>做圆形节点,或者用<path>绘制更复杂的自定义形状 - 边的标签位置可以通过调整
y属性来优化显示效果,避免和边重叠
内容的提问来源于stack exchange,提问作者RV.
相关产品推荐
相关产品推荐

