最近写项目需要画出应用程序调用链的网路拓扑图,完全自己写需要花费些时间,那么首先想到的是echarts,但echarts的自定义写法写起来非常麻烦,而且它的文档都是基于配置说明的,对于自定义开发不太方便,尝试后果断放弃,改用D3.js,自己完全可控。
我们先看看效果
我把代码分享下,供和我一样刚接触D3的同学参考,不对的地方欢迎指正!
完整代码:
html:
Titlebody{
overflow: hidden;
}
#togo{
width: 800px;
height:500px;
border:1px solid #ccc;
user-select: none;
}
#togo text{
font-size:10px;/*和js里保持一致*/
fill:#1A2C3F;
text-anchor: middle;
}
#togo .node-other{
text-anchor: start;
}
#togo .health1{
stroke:#92E1A2;
}
#togo .health2{
stroke:orange;
}
#togo .health3{
stroke:red;
}
#togo #cloud,#togo #database{
fill:#ccc;
}
#togo .link{
stroke:#E4E8ED;
}
#togo .node-title{
font-size: 14px;
}
#togo .node-code circle{
fill:#3F86F5;
}
#togo .node-code text{
fill:#fff;
}
#togo .node-bg{
fill:#fff;
}
#togo .arrow{
fill:#E4E8ED;
}
let t=new Togo('#togo',__options);
t.render();
JS:
const fontSize = 10;
const symbolSize = 40;
const padding = 10;
/*
* 调用 new Togo(svg,option).render();
* */
class Togo {
/**/
constructor(svg, option) {
this.data = option.data;
this.edges = option.edges;
this.svg = d3.select(svg);
}
//主渲染方法
render() {
this.scale = 1;
this.width = this.svg.attr('width');
this.height = this.svg.attr('height');
this.container = this.svg.append('g')
.attr('transform', 'scale(' + this.scale + ')');
this.initPosition();
this.initDefineSymbol();
this.initLink();
this.initNode();
this.initZoom();
}
//初始化节点位置
initPosition() {
let origin = [this.width / 2, this.height / 2];
let points = this.getVertices(origin, Math.min(this.width, this.height) * 0.3, this.data.length);
this.data.forEach((item, i) => {
item.x = points[i].x;
item.y = points[i].y;
})
}
//根据多边形获取定位点
getVertices(origin, r, n) {
if (typeof n !== 'number') return;
var ox = origin[0];
var oy = origin[1];
var angle = 360 / n;
var i = 0;
var points = [];
var tempAngle = 0;
while (i < n) {
tempA