天天看点

d3力导向图增加节点_d3.js力导向图节点如何都显示在边框内

最近用到d3.js中的force力导向图,想实现效果如下,所有城市节点都在可视范围内,如果超出有滚动条也可以。

d3力导向图增加节点_d3.js力导向图节点如何都显示在边框内

遇到的问题是,当节点一多,有的节点就会跑到外面去,这边是通过加大charge相互作用力,从原本的-300改为-3000,也是会跑到svg边框外。

d3力导向图增加节点_d3.js力导向图节点如何都显示在边框内

求教下节点怎么限制在svg边框内?

实例代码如下:

力导向图

var nodes = [ { name: "桂林" }, { name: "广州" },

{ name: "厦门" }, { name: "杭州" },

{ name: "上海" }, { name: "青岛" },

{ name: "天津" } ];

var edges = [ { 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 = 400;

var height = 400;

var svg = d3.select("body")

.append("svg")

.attr("width",width)

.attr("height",height)

.style("border","1px solid #000");

var force = d3.layout.force()

.nodes(nodes) //指定节点数组

.links(edges) //指定连线数组

.size([width,height]) //指定范围

.linkDistance(150) //指定连线长度

.charge(-3000); //相互之间的作用力

force.start(); //开始作用

console.log(nodes);

console.log(edges);

//添加连线

var svg_edges = svg.selectAll("line")

.data(edges)

.enter()

.append("line")

.style("stroke","#ccc")

.style("stroke-width",1);

var color = d3.scale.category20();

//添加节点

var svg_nodes = svg.selectAll("circle")

.data(nodes)

.enter()

.append("circle")

.attr("r",20)

.style("fill",function(d,i){

return color(i);

})

.call(force.drag); //使得节点能够拖动

//添加描述节点的文字

var svg_texts = svg.selectAll("text")

.data(nodes)

.enter()

.append("text")

.style("fill", "black")

.attr("dx", 20)

.attr("dy", 8)

.text(function(d){

return d.name;

});

force.on("tick", function(){ //对于每一个时间间隔

//更新连线坐标

svg_edges.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; });

//更新节点坐标

svg_nodes.attr("cx",function(d){ return d.x; })

.attr("cy",function(d){ return d.y; });

//更新文字坐标

svg_texts.attr("x", function(d){ return d.x; })

.attr("y", function(d){ return d.y; });

});