圆形分区图
最后更新于:2022-04-01 20:04:35
分区图布局的 size 函数很有意思,即可用于制作矩形分区图,也可用于制作圆形分区图。本文就来谈讨一下圆形分区图的制作。
[![311](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-17_57b41784932fc.png)](http://www.ourd3js.com/wordpress/wp-content/uploads/2014/11/311.png)
本文与【[进阶 - 第 3.0 章](http://www.ourd3js.com/wordpress/?p=643)】基本相同,只有布局函数的 size 函数和绘制图形的部分稍有区别。
## 1. 数据
本文仍然使用【[入门 - 第 9.4 章](http://www.ourd3js.com/wordpress/?p=254)】的数据,内容为中国境内几个城市的所属关系。
## 2. 布局(数据转换)
~~~
var partition = d3.layout.partition()
.sort(null)
.size([2 * Math.PI, radius * radius])
.value(function(d) { return 1; });
~~~
第 3 行:size 函数,第一个值为 2 * PI ,第二个值为圆半径的平方。如果您只需要得到效果,可不比深究为什么这么做,只需记得这么用即可。
注意第3行与【[进阶 - 第 3.0 章](http://www.ourd3js.com/wordpress/?p=643)】的不同。
## 3. 绘制
先定义一个绘制弧形的函数,这个函数在【[入门 - 第 9.1 章](http://www.ourd3js.com/wordpress/?p=190)】中也用过。
~~~
var arc = d3.svg.arc()
.startAngle(function(d) { return d.x; })
.endAngle(function(d) { return d.x + d.dx; })
.innerRadius(function(d) { return Math.sqrt(d.y); })
.outerRadius(function(d) { return Math.sqrt(d.y + d.dy); });
~~~
请好好体会上面的代码是什么意思。如果以圆形的形式来转换数据,那么 d.x 和 d.y 分别代表圆弧的绕圆心方向的起始位置和由圆心向外方向的其实位置。d.dx 和 d.dy 分别代表各自的宽度。
接下来分别绘制圆弧和文字。
~~~
var arcs = svg.selectAll("g")
.data(nodes)
.enter().append("g");
arcs.append("path")
.attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
.attr("d", arc)
.style("stroke", "#fff")
.style("fill", function(d) { return color((d.children ? d : d.parent).name); })
.on("mouseover",function(d){
d3.select(this)
.style("fill","yellow");
})
.on("mouseout",function(d){
d3.select(this)
.transition()
.duration(200)
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
});
});
arcs.append("text")
.style("font-size", "12px")
.style("font-family", "simsun")
.attr("text-anchor","middle")
.attr("transform",function(d,i){
//第一个元素(最中间的),只平移不旋转
if( i == 0 )
return "translate(" + arc.centroid(d) + ")";
//其他的元素,既平移也旋转
var r = 0;
if( (d.x+d.dx/2)/Math.PI*180 < 180 ) // 0 - 180 度以内的
r = 180 * ((d.x + d.dx / 2 - Math.PI / 2) / Math.PI);
else // 180 - 360 度以内的
r = 180 * ((d.x + d.dx / 2 + Math.PI / 2) / Math.PI);
//既平移也旋转
return "translate(" + arc.centroid(d) + ")" +
"rotate(" + r + ")";
})
.text(function(d) { return d.name; });
~~~
绘制方法问题不大,唯一要注意的是文字的旋转角度问题,请好好看看上面的注释问题。
## 4. 结果
完整代码,请点击下面的链接,再右键点击查看源代码:
[http://www.ourd3js.com/demo/J-3.1/circle_partition.html](http://www.ourd3js.com/demo/J-3.1/circle_partition.html)
### 文档信息
- 版权声明:署名(BY)-非商业性(NC)-禁止演绎(ND)
- 发表日期:2014 年 11 月 30 日
- 更多内容:[OUR D3.JS - 数据可视化专题站](http://www.ourd3js.com/) 和 [CSDN个人博客](http://blog.csdn.net/lzhlzz)
- 备注:本文发表于 [OUR D3.JS](http://www.ourd3js.com/) ,转载请注明出处,谢谢
';