d3.layout.pack()
打包图用于表示包含与被包含的关系,也可表示各对象的权重,通常用一圆套一圆来表示前者,用圆的大小来表示后者。
打包图(Pack)的API说明
- pack.children - 取得或设置子节点的访问器。
- pack.links - 计算树节点中的父子链接。
- pack.nodes - 计算包布局并返回节点数组。
- pack.padding - 指定布局间距(以像素为单位)
- pack.radius - 指定节点半径(不是由值派生来的)
- pack.size - 指定布局尺寸。
- pack.sort - 控制兄弟节点的遍历顺序。
- pack.value - 取得或设置用于圆尺寸的值访问器。
- pack - pack.nodes的别名。
我们通过一个制作一个打包图来讲解打包布局。
1. 数据
var dataset = {
"name": "中国",
"children": [{
"name": "浙江",
"children": [{"name": "杭州"}, {"name": "宁波"}, {"name": "温州"}, {"name": "绍兴"}]
},
{
"name": "广西",
"children": [{"name": "桂林"}, {"name": "南宁"}, {"name": "柳州"}, {"name": "防城港"}]
},
{
"name": "黑龙江",
"children": [{"name": "哈尔滨"}, {"name": "齐齐哈尔"}, {"name": "牡丹江"}, {"name": "大庆"}]
},
{
"name": "*",
"children": [{"name": "乌鲁木齐"}, {"name": "克拉玛依"}, {"name": "吐鲁番"}, {"name": "哈密"}]
}
]
}
2. 数据转换
var width = 500;
var height = 500;
var pack = d3.layout.pack()
.size([width, height])
.radius(20);
var nodes = pack.nodes(dataset);
var links = pack.links(nodes);
分别将数据转换成了结点 nodes 和 连线 links。
这里只需要用到结点数据,数据被转换成了如下:
3. 绘制图形
生成SVG容器
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(0,0)");
生成打包圆形SVG
svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("fill", "rgb(31, 119, 180)")
.attr("fill-opacity", "0.4")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.attr("r", function(d) {
return d.r;
})
.on("mouseover", function(d, i) {
d3.select(this)
.attr("fill", "yellow");
})
.on("mouseout", function(d, i) {
d3.select(this)
.attr("fill", "rgb(31, 119, 180)");
});
生成节点文本
svg.selectAll("text")
.data(nodes)
.enter()
.append("text")
.attr("font-size", "10px")
.attr("fill", "white")
.attr("fill-opacity", function(d) {
if (d.depth == 2)
return "0.9";
else
return "0";
})
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("dx", -12)
.attr("dy", 1)
.text(function(d) {
return d.name;
});