布局:layout
作用: 将不适合用于绘图的数据转换成了适合用于绘图的数据。所以说,布局的作用可以解释为:数据转换。
今天选力导向图(Force)和饼状图(Pie)作为例子。
力导向图:
在二维或三维空间里配置节点,节点之间用线连接,称为连线。各连线的长度几乎相等,且尽可能不相交。节点和连线都被施加了力的作用,力是根据节点和连线的相对位置计算的。根据力的作用,来计算节点和连线的运动轨迹,并不断降低他们的能量,最终达到一种能量很低的安定状态。力导向图能表示节点之间多对多的关系。
现在我们拿到了这样的一些初始数据:
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 } ];
这两个数组分别是表示节点和连线。
要作图,我们首先需要在页面中定义一块svg画布。
// 定义一下svg的宽和高。
var height = 1000;
var width = 1000;
var svg = d3.select("body").append("svg").attr("width",width).attr("height",height); // 添加一块svg画布
接下来需要一个力导向图的布局:
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width,height])
.linkDistance(150)
.charge([400]);
force.start()// 开始作用
上面的代码中 nodes:指定节点数组 links :指定连线数组 size : 指定作用范围 linkDistance:指定连线长度 charge: 相互之间的作用力
转换后,节点对象里多了一些变量。其意义如下:
index - 节点的索引号
px, py - 节点上一个时刻的坐标
x, y - 节点的当前坐标
weight - 节点的权重
接下来,绘制的图形元素有:
- line 线段,连线
- cilcle 圆,表示节点
- text 文字,描述节点
//添加连线
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; });
});
下面是饼状图的代码:
一个饼状图
>