Posted on 2014-09-16 13:36
TWaver 阅读(2966)
评论(0) 编辑 收藏
先看看发光链路的运行效果:
在这个Demo中主要包含三个技术点,一是如何在选取一条链路时,让整条回路发光;二是如何绘制带有箭头方向的曲线link;三是如何设置链路的样式,让整体可控。
1.如何获取整条回路的所有link,并使之发光
以前做客户支持,也处理过类似的问题,当时的解决方法是通过获取当前的Link,然后通过不断的遍历,不断获取link的fromNode和toNode,然后再获取Node的Link,从而获取回路中所有的Link和Node。这样实现的缺点是要通过大量的遍历,实现起来比较繁琐,本文的处理方法是,在创建link的时候,设置一个Client属性,在选择回路的时候,直接读取这个Client属性,并遍历一次即可。创建回路代码如下:
1 | function createCircuit(nodes, linename, flag) { |
3 | var startNode = nodes[ 0 ]; |
4 | var stopNode = nodes[nodes.length - 1 ]; |
5 | var link = new CLink(stopNode, startNode); |
6 | link.setStyle( 'link.type' , "extend.left" ); |
7 | // link.setName(linename); |
8 | link.setClient( 'linename' , linename); |
11 | for (var i = 0 ; i < nodes.length - 1 ; i++) { |
12 | var fromNode = nodes[i]; |
13 | var toNode = nodes[i + 1 ]; |
14 | var link = new CLink(fromNode, toNode); |
15 | // link.setName(linename); |
16 | link.setClient( 'linename' , linename); |
18 | link.setStyle( 'link.type' , "orthogonal.H.V" ); //orthogonal\ |
20 | link.setStyle( 'link.type' , "orthogonal.V.H" ); //orthogonal\ |
22 | link.setStyle( 'link.type' , "orthogonal.V.H" ); //orthogonal\ |
24 | // link.setStyle('link.type', "orthogonal");//orthogonal\ |
2.自定义实现带有箭头的曲线link
这个主要考察的是canvas绘制能力了,核心代码如下:
1 | cx = cx - Math.cos(angle) * radius; |
2 | cy = cy - Math.sin(angle) * radius; |
5 | ctx.moveTo(p1.x, p1.y - h1 / 2 ); |
6 | ctx.quadraticCurveTo(cx, cy, p2.x, p2.y - h2 / 2 ); |
10 | this .drawArrow(ctx, p2.x, p2.y - h2 / 5 * 3 , cx, cy+ 20 , 1 , 2 , Math.PI / 8 , 10 ); |
3.设置Link的样式
TWaver的Link支持很多样式,常用的类型可参考下图,本文主要监听mousemove事件,并在拖动Node的过程中不断计算Node之间的相对位置,从而判定Link的类型,并不断刷新。
核心代码如下:
1 | function refreshLinkType() { |
2 | box.forEach(function (element) { |
3 | if (element instanceof twaver.Link) { |
4 | var fromNode = element.getFromNode(); |
5 | var toNode = element.getToNode(); |
6 | var nextLinks = toNode.getLinks(); |
8 | nextLinks.forEach(function (element) { |
9 | if (element.getToNode() !== toNode) { |
10 | nextNode = element.getToNode(); |
13 | var fromPoint = fromNode.getCenterLocation(); |
14 | var toPoint = toNode.getCenterLocation(); |
17 | nextPoint = nextNode.getCenterLocation(); |
19 | //compute the relationship of location between fromNode and toNode |
20 | if (fromPoint.x < toPoint.x && fromPoint.y < toPoint.y) { |
21 | element.setStyle( 'link.type' , "orthogonal.V.H" ); |
22 | } else if (fromPoint.x < toPoint.x && fromPoint.y > toPoint.y) { |
23 | element.setStyle( 'link.type' , "orthogonal.V.H" ); |
24 | } else if (fromPoint.x > toPoint.x && fromPoint.y < toPoint.y) { |
25 | element.setStyle( 'link.type' , "orthogonal.V.H" ); |
26 | } else if (fromPoint.x > toPoint.x && fromPoint.y > toPoint.y) { |
27 | element.setStyle( 'link.type' , "orthogonal" ); |
30 | if (toPoint.x > fromPoint.x && toPoint.x > nextPoint.x) { |
31 | if (toPoint.y > fromPoint.y && toPoint.y < nextPoint.y) { |
32 | element.setStyle( 'link.type' , "orthogonal.H.V" ); |
34 | element.setStyle( 'link.type' , "orthogonal.V.H" ); |