首先我们考虑到所有需要实现得图形

1.圆
2.圆文字
3.圆是否显示图片
4.圆得颜色添加渐变
5.线
6线文字
6.线文字遮挡住线
7线变弧
8环形菜单
9.箭头
10.缩放
要绘制以上图形,我们先定好 画布-SVG append(“svg”);
定义连线 this.linkGroup =this.svg.append(“g”).attr(“class”, “line”);
定义连线文字 this.linkTextGroup =this.svg.append(“g”).attr(“class”, “lineText”);
定义节点 this.nodeGroup =this.svg.append(“g”).attr(“class”, “node”);
定义节点文字 this.nodeTextGroup =this.svg.append(“g”).attr(“class”, “nodeText”);
定义节点唯一标识 this.nodeSymbolGroup =this.svg.append(“g”).attr(“class”, “nodeSymbol”);
定义环形菜单 this.nodeButtonGroup =this.svg.append(“g”).attr(“class”, “nodeButton”);

根据数据来驱动图形 -拿到所需数据进行绘制
绘制细节看代码
把数据绑定到元素上
letlink= this.linkGroup.selectAll(“.line >path”).data(links,function(d){})
这样数据绑定到元素上。因为每次渲染都是根据根据数据来渲染,那我们需要把之前渲染得给删除。然后再进行渲染。
link.exit().remove();
保持是干净得元素下进行渲染。
进行渲染得基础看代码。
渲染完之后,我们需要监听我们渲染得元素,进行某些特定得调整。这里就需要用到 tick函数,进行监控
再里面进行特定得调整,比如,X,Y位置,翻转,移动,缩放,等。根据需求来定
我们要定义线,使用path即可,但是我们可能有多条线连接一个节点。那这里需要把线弧起来。
绘制弧线,需要用到

贝塞尔曲线

贝塞尔曲线就是这样的一条曲线,它是依据四个位置任意的点坐标绘制出的一条光滑曲线;可以绘制任何曲线,自然包括直线。包括了很多种类型:线性贝塞尔曲线二次方贝塞尔曲线三次方贝塞尔曲线四次方贝塞尔曲线五次方贝塞尔曲线
M = moveto 移动到某点。
L = lineto 画一条直线到某点。
H = horizontal lineto 画一条水平线到某点。
V = vertical lineto 画一条垂直线到某点。
Q = quadratic Bézier curveto 二次贝塞尔曲线
T = smooth quadratic Bézier curveto 平滑二次贝塞尔曲线
C = curveto 三次贝塞尔曲线
S = smooth curveto 平滑三次贝塞尔曲线
A = elliptical Arc 弧形
Z = closepath 从结束点到开始点画一条直线,形成一个闭合的区域。
三次贝塞尔曲线
我们从稍微复杂一点的三次贝塞尔曲线C入手,三次贝塞尔曲线需要定义一个点和两个控制点,所以用C命令创建三次贝塞尔曲线,需要设置三组坐标参数:
C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)
这里的最后一个坐标(x,y)表示的是曲线的终点,另外两个坐标是控制点,(x1,y1)是起点的控制点,(x2,y2)是终点的控制点。如果你熟悉代数或者微积分的话,会更容易理解控制点,控制点描述的是曲线起始点的斜率,曲线上各个点的斜率,是从起点斜率到终点斜率的渐变过程。(文字描述不好,维基百科上有图示,更直观。)
image.png

弧形

弧形命令A是另一个创建SVG曲线的命令。基本上,弧形可以视为圆形或椭圆形的一部分。假设,已知椭圆形的长轴半径和短轴半径,并且已知两个点(在椭圆上),根据半径和两点,可以画出两个椭圆,在每个椭圆上根据两点都可以画出两种弧形。所以,仅仅根据半径和两点,可以画出四种弧形。为了保证创建的弧形唯一,A命令需要用到比较多的参数:
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
image.png

具体绘制弯曲曲线。详情看代码皆有注释。
这块应该是比较复杂得。

绘制好了线,我们再绘制箭头,将箭头放置线条尾部,使用maker-end属性指定箭头。
然后进行绑定事件等~
再需要绘制线上文字,需要用到TextPath 元素。文字始终再线上。这样实现了文字
但是并没有文字背景没办法遮挡住线条。那这里添加过滤器,滤镜 filter feFlood feComposite
进行遮挡。也可以添加rect矩形进行遮挡。
相应属性找到SVG文档进行阅读理解