由于工作,需要使用一个arbor的js库做点东西,琢磨了一天,终于大致满足了需求。
需求一共有四个吧:
一、不同的点可以显示相同的文字
二、在边上显示文字
三、点击node时弹出一个表单
四、边上要带箭头
这个库的官方网址是:http://arborjs.org/。可以看到官网上的demo做的还是很不错的,把它的代码download下来,可以看到点和边的定义都在site.js中, 这个库是基于jQuery的,所以我写了一个按钮的jQuery的函数,用来测试。
首先看了arbor提供的api可以知道动态添加点和边的函数,通过这个加上ajax就可以动态交互了,我们最终的结果是这样的,不过这里只满足上面的需求就好了。
$("Button").click(function(){
//alert("nihao");
var nn=sys.addNode("FSB",{label:'nihao',color:CLR.branch, shape:"dot", alpha:1,expanded:true});
var nm=sys.addNode("FSB",{label:'sad',color:CLR.branch, shape:"dot", alpha:1});
var ee=sys.addEdge(nm,nn,{label:"nihao"});
//var nodes=sys.getEdges(nm,nn);
//nodes[0].data.label="nihaoasfsa";
alert(""+nodes[0].data.label);
});
添加了这样的代码之后,发现只能添加一个点而且名字是“FSB”,通过浏览器的控制台很容易得到node的数据结果,这里就不说了,,看一下Renderer函数中重写了redraw函数,
在里面的sys.eachNode函数使用的是node.name
gfx.text(node.name, pt.x, pt.y+9, {color:"white", align:"center", font:"Arial", size:12})
所以显示的肯定是“FSB”,改为
gfx.text(node.data.label, pt.x, pt.y+9, {color:"white", align:"center", font:"Arial", size:12})
这下其实可以满足第一个需求了,只要name不同设置相同的label就可以显示相同的文字的node了,不过为了看看源码在深入一点,这里为什么只有一个点呢,看一下arbor的源码,由于直接down下来的js是压缩过的,不太好看所以下来源码看看,addNode在src\physics\system.js中,在开头有这段代码,通过看其他的源码可以知道state维护着node,而且通过的是id维护的,但是下面的代码,
var priorNode = state.names[name]
if (priorNode){
priorNode.data = data
return priorNode
}
意思很明确,如果找到name相同的就更新data后,返回该节点,所以就只能显示一个了,将这段代码注释掉果然可以显示两个name相同的了,不过第一种方法已经可以满足我们能见到的所有的需求了,所以尽量不修改源码。
有了解决第一个需求的过程第二个就简单了,先给Edge添加label属性在redraw函数里面修改sys.eachEdge方法,在后面添加
ctx.fillStyle = "black";
ctx.font = 'italic 13px sans-serif';
ctx.fillText (edge.data.label, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
OK了,第二个需求解决。
第三个需求就是一个简单的js问题了,redraw里面的_initMouseHandling函数
逻辑就是点击node时如果移动距离小于一个值就弹出,里面需要调一些阈值
stiffness:900, repulsion:2000, gravity:true, dt:0.015,precision:0.8还有nearest.distance的值来优化用户的体验,具体可以查看代码。
第四个需求比较麻烦了,需要数学计算,因为要找到node外框和边的交点,然后再画箭头,不过源码里的demo,有一个是带箭头的边的,就是那个halfviz,参考一下代码省了不少的力气。
同样这需要修改Renderer中的redraw函数,这里主要有三个步骤:
1、通过点计算边框
2、画line和箭头
3、画点
三个顺序不能改变,第一步肯定在前的这个不用说,第三步如果在第二步的前面,显示出来的线直接延伸到了点心,影响美观,当然这要看算法,我直接用的demo的算法,通过Edge的directed:true配置,当然也可以修改算法定义方向。具体参看源码
最终的测试效果如图:
源码地址:http://download.csdn.net/detail/apple_boys/7555241