几天的稍稍有点难度,估计还得反复多敲几遍才能有更深刻的领悟
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>弦图制作入门</title>
<style type="text/css">
.chord path {
fill-opacity:0.67;
stroke:#000;
stroke-width:0.5px;
}
</style>
<script type="text/javascript" src="../d3/d3.min.js"></script>
</head>
<body>
<script type="text/javascript">
//原数据
var city_name = ["北京", "上海", "深圳", "广州", "香港"];
//population矩阵
//eg:第一行第一列表示北京本地人1000
//第一行第二列表示北京有3045人来自上海
//以此类推
var population = [
[1000, 3045, 4567, 1289, 3987],
[1892, 3754, 3729, 1093, 3749],
[3743, 3829, 7484, 3847, 2384],
[1838, 3748, 4844, 4099, 1022],
[2874, 2943, 1923, 2843, 3821]
];
//转换数据格式
//为画弦图所需要的数据
var chord_layout = d3.layout.chord()
.padding(0.03)
.sortSubgroups(d3.descending)
.matrix(population);
//padding:节点之间的间隔
//sortSubgroups:排序,
//每个城市的人口来源按照降序排序
//体现在图形中就是顺时针子集数量减少
//引入需要的矩阵population
var groups = chord_layout.groups();
var chords = chord_layout.chords();
//groups:布局之后产生的节点
//chords:布局之后产生的连线
console.log(groups);
console.log(chords);
//截至到这儿,控制台输出的数据不太对
//节点没有name元素
//没有就对了
//还没有添加节点的name
var width = 600,
height = 600;
var innerRadius = width / 2 * 0.7;
var outerRadius = innerRadius * 1.1;
//不同于饼状图
//这里只需要画外面的那个圆环
var color = d3.scale.category20();
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");//?这个g
//这里面的g是将整个svg看成是一个分组
//将整个svg的坐标原点平移到了svg的中心
var outer_arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
//弧生成器
var g_outer = svg.append("g");
//g:指定外层圆环整个为一个组
//每一个path和text都采用相同的计算
g_outer.selectAll("path")
.data(groups)
.enter()
.append("path")
.style("fill", function (d) {return color(d.index);})
.style("stroke", function (d) {return color(d.index);})
.attr("d", outer_arc);
//这里的path为将要生成的每一段弧
//所以这儿的data采用的是布局之后产生的节点数据:groups
g_outer.selectAll("text")
.data(groups)
.enter()
.append("text")
.each(function (d, i) {
d.angle = (d.startAngle + d.endAngle) / 2;
d.name = city_name[i];
})
.attr("dy",".35em")
.attr("transform", function (d) {
return "rotate(" + (d.angle * 180 / Math.PI) + ")" +
"translate(0," + -1.0 * (outerRadius + 10) + ")" +
((d.angle > Math.PI * 3 / 4 && d.angle < Math.PI * 5 / 4) ? "rotate(180)" : "");
})
.text(function (d) {return d.name;});
//.35em:相对于当前对象内文本的字体尺寸
//先rotate再translate
//((d.angle > Math.PI * 3 / 4 && d.angle < Math.PI * 5 / 4) ? "rotate(180)" : "")
//上一句为了让字全都是依着弧的方向正着的
//此处才添加了城市名称:d.name
var inner_chord = d3.svg.chord()
.radius(innerRadius);
svg.append("g")
.attr("class","chord")
.selectAll("path")
.data(chords)
.enter()
.append("path")
.attr("d",inner_chord)
.style("fill", function (d) {return color(d.source.index);})
.style("opacity", 1)
.on("mouseover", function (d, i) {
d3.select(this)
.style("fill", "yellow");
})
.on("mouseout", function (d,i) {
d3.select(this)
.transition()
.duration(1000)
.style("fill", color(d.source.index));
})
</script>
</body>
</html>