introduction
弦图大致分为两个部分,表示各个变量的部分和表示各个变量之间的关系部分,即外部弦和内部弦,分别绑定的数据是chord.group
和chord
。
绘制外部弦的部分就和绘制一个饼状图是一样的,调用的仍然是弧生成器,只不过布局器由原来的d3.pie().value()
变为现在的d3.chord()
,关于添加弦图之上表示各个块的名字就是在弦图之上添加text,用之前的表示各个变量名的数组添加name属性,然后再添加一定的平移翻转变换。
绘制内部弦就是直接绑定chord
数据,包含有source
和target
属性,分别表示该弦的源子分组对象和目标子分组对象,就可以直接作出内部弦,调用的不是弧生成器,而是d3.ribbon()
,接受的参数有source
对象和target
对象。
demo
//部分关键代码
function groupTicks(d,step){
var k = (d.endAngle - d.startAngle)/d.value;
return d3.range(0,d.value,step).map(value=>{
return {value:value,angle:value*k+d.startAngle};
});
}
var outerRadius = Math.min(width,height)*0.5-30;
var innerRadius = outerRadius - 20;
var s = d3.formatSpecifier("f");
s.precision = d3.precisionFixed(0.1);
var f = d3.format(s);
var chord = d3.chord()
.padAngle(0.05)
.sortSubgroups(d3.descending);
var arc = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var ribbon = d3.ribbon()
.radius(innerRadius);
var color = d3.scaleOrdinal()
.domain(d3.range(12))
.range(d3.schemePaired);
var chords = chord(pccs);
var group = svg.append("g")
.selectAll("g")
.data(chords.groups)
.enter()
.append("g");
group.append("path")
.attr("fill",d=>color(d.index))
.attr("stroke",d=>d3.rgb(color(d.index)).darker())
.attr("d",arc);
group.append("text")
.each(function(d,i){
d.angle = (d.startAngle + d.endAngle)/2;
d.name = textelement[i];
})
.attr("dy",".35em")
.attr("transform",function(d){
return "rotate("+(d.angle*180/Math.PI)+")"+
"translate(-10,"+ -1*(outerRadius-15)+")"+
(((d.angle>Math.PI*3/4)&&(d.angle<Math.PI*5/4))?"rotate(180)":"");
})
.text(d=>d.name);
var groupTick = group.append("g")
.selectAll("g")
.data(d=>groupTicks(d,0.5))
.enter()
.append("g")
.attr("transform",d=>`rotate(${d.angle*180/Math.PI-90})translate(${outerRadius},0)`);
groupTick.append("line")
.attr("stroke","#000")
.attr("x2",6);
groupTick.filter(d=>f(d.value)%0.5===0)
.append("text")
.attr("x",8)
.attr("dy",".35em")
.attr("transform",d=>d.angle>Math.PI?"rotate(180)translate(-16)":null)
.attr("text-anchor",d=>d.angle>Math.PI?"end":null)
.text(d=>f(d.value));
var currentcolor;
svg.append("g")
.attr("fill-opacity",0.67)
.selectAll("path")
.data(chords)
.enter()
.append("path")
.attr("d",ribbon)
.attr("fill",d=>color(d.target.index))
.attr("stroke",d=>d3.rgb(color(d.target.index)).darker())