D3.js(v4) 力导向图布局 一定要用tick() 方法么才能得到正确地数据坐标点么?
Demo
http://codepen.io/jingxiao/pe...
var nodes = [ { name: "BeiJing" }, { name: "XiaMen" },
{ name: "XiAn" }, { name: "HangZhou" },
{ name: "ShangHai" }, { name: "QingDao" },
{ name: "NanJing" } ];
var links = [ { source : 0 , target: 1 } , { source : 0 , target: 2 } ,
{ source : 0 , target: 3 } , { source : 1 , target: 4 } ,
{ source : 1 , target: 5 } , { source : 1 , target: 6 } ];
var width = 800;
var height = 600;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
// 通过布局来转换数据,然后进行绘制
var simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).distance(100))
.force("charge",d3.forceManyBody())
.force("center",d3.forceCenter(width/2, height/2));
var color = d3.scaleOrdinal(d3.schemeCategory20);
// 绘制
var svg_links = svg.selectAll("line")
.data(links)
.enter()
.append("line")
.style("stroke","#ccc")
.style("stroke-width",3);
var svg_nodes = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r",10)
.style("fill",function(d,i){
return color(i);
})
.attr("cx",function(d){return d.x;})
.attr("cy",function(d){return d.y;});
var svg_text = svg.selectAll("text")
.data(nodes)
.enter()
.append("text")
.style("fill","#000")
.attr("dx",20)
.attr("dy",10)
.text(function(d){return d.name;});
console.log("转换后的nodes links数据:");
console.log(nodes);
console.log(links);
function draw(){
svg_nodes
.attr("cx",function(d){console.log(d);return d.x;})
.attr("cy",function(d){return d.y;});
svg_text
.attr("x", function(d){ return d.x; })
.attr("y", function(d){ return d.y; });
svg_links
.attr("x1",function(d){return d.source.x; })
.attr("y1",function(d){ return d.source.y; })
.attr("x2",function(d){ return d.target.x; })
.attr("y2",function(d){ return d.target.y; });
}
simulation.on("tick",draw);
//draw();
通过力导向图来转换节点nodes和线路links为可绘制的数据,然后去绘制连线图。有个疑问是tick()方法。
上述代码中为什么我不能在得到nodes links数据后,直接调用draw() 绘制呢,这个时候的数据有问题,用tick正常,为什么?
类似问题
Why do we need force.on('tick'.. in d3
在console地方 感觉已经得到正确的节点线路坐标数据,
然后就可以直接绘制调用draw() 方法把对应的坐标数据绑定到元素上这样应该就ok了,但事实上在demo中注释tick方法调用,直接draw() 得到的结果是这样
都跑到左上角去了,事实上此时的坐标点位置并不是刚刚console.log()输出的那些数据。
我在draw()
方法中输出了数据
比如Beijingz这个点的 坐标位置(0,0),下面节点显示的位置也和之前不对。但我把输出的object展开看数据又是对的。
有点懵逼,这是怎么回事呢?
tick()方法的作用,我的理解是没到一个时刻都要调用里面的方法更新节点坐标位置。
但我只想初始化数据得到可绘制的数据,然后初始化显示,后面的节点拖拽更新自己写方法来做,只是想用力导向图来转换第一次的数据。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
自问自答
有一点要清楚就是 力导向图布局的形成是一个异步的过程而且需要一定时间几秒钟
所以当draw() 去执行的时候,力导向图布局并没有完成,所以取到各节点的坐标是很小的偏移量,如上图三。所以绘制的图形都在左上角去了。
验证这一点,加个setTimeout就行了
你会发现几秒后布局不好了,数据就正常了绘制出来的图形就OK了,但为什么console.log()打印出来的数据展开会变是什么原因呢,调试工具的问题,好奇怪。