一、圆环绘制
圆环绘制必须要先有一个弧生成器,必须提供的参数有起始角度和中止角度,例如:
var dataset = { startAngle: 0 , endAngle: Math.PI * 0.75 };
//创建一个弧生成器
在此基础上再利用d3的svg中的arc进行生成弧,这边要设定内半径和外半径大小。
var arcPath = d3.svg.arc()
.innerRadius(50)
.outerRadius(100);
然后,我们要添加路径,必须提供参数,包括使用的弧生成器,还可以进行平移、填充颜色、边框颜色设定,举例如下:
svg.append("path")
.attr("d",arcPath(dataset))
.attr("transform","translate(250,250)")
.attr("stroke","black")
.attr("stroke-width","3px")
.attr("fill","yellow");
上述的代码就可以生成这么一个圆弧:
懂了圆弧,就可以轻松制作饼图或是环图,两个都是在圆弧的基础上构建的。
二、饼图&环图
这两块放在一起讨论,因为饼图和环图的区别就在于内半径的设定是否为0.
给出如下的代码,读者可以自行尝试:
var dataset = [{ startAngle: 0 , endAngle: Math.PI * 0.6 },
{ startAngle: Math.PI * 0.6 , endAngle: Math.PI },
{ startAngle: Math.PI , endAngle: Math.PI * 1.7 },
{ startAngle: Math.PI * 1.7 , endAngle: Math.PI * 2 }];
//创建一个弧生成器
var arcPath = d3.svg.arc()
.innerRadius(0)
.outerRadius(100);
var color = d3.scale.category10(); //V3中的Color为函数Function
//添加路径
svg.selectAll("path")
.data(dataset)
.enter()
.append("path")
.attr("d",function(d){ return arcPath(d); })
.attr("transform","translate(250,250)")
.attr("stroke","black")
.attr("stroke-width","2px")
.attr("fill",function(d,i){ return color(i); });
这边需要注意的是,可以给出一个dataset手动打出每一段圆弧的起始角度和中止角度,最后直接采用svg.selectAll("path")选中所有路径进行操作。
在这段代码中采用了一个category10,这个需要注意,在笔者的实践中,这个代码可能仅在v3版本中可以使用。
同直方图一样,可以在这里加上文字。
代码如下:
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("transform",function(d){
return "translate(250,250)" +
"translate(" + arcPath.centroid(d) + ")";
})
.attr("text-anchor","middle")
.attr("fill","white")
.attr("font-size","18px")
.text(function(d){ return Math.floor((d.endAngle - d.startAngle)*180/Math.PI) + "°"; });
这段代码中,值得注意点如下:
- 使用transform平移操作将文字移动至中心位置,arcPath.centroid(d)参数是计算弧中心的,可以参考D3的文档:https://github.com/d3/d3/
- 采用这个板块进行圆弧的拼接时,采用的是弧度的计算方式,所以说显示角度时,需要转化为人们所习惯的角度模式,所以将endAngle-startAngle的值进行了*180/Math.PI的操作。
这段饼图的代码运行结果如下:
三、准备数据的情况
这点与第二大点类似,在这里不再赘述。
主要讨论的点是:已经准备好的数据,如何利用弧生成器成为备用数据。
可以想象,我们需要的饼图是原数据+角度数据+坐标点数据,
也就是D3.pie+D3.ARC+SVG.PATH。需要准备以上三组数据。
分以下几步:
- 创建数据对象dataset
- var pie=d3.pie;var piedata=pie(dataset) (角度数据)
- var arc=d3.arc(弧生成器)
- var arcs=svg.selectAll("path").data(piedata).enter().append("path")绑定路径
以下代码是笔者在上《数据可视化》这门课时,学到饼图时写的代码片段,仅供参考。
var dataset = [["Super Smash Bros",22.76],["Red Dead Redemption 2(PS4)",14.56],["Call of Duty: Black Ops IIII(PS4)",10.55],["Mario Kart 8 Deluxe",9.04],["Spider-Man (PS4)",8.80],["Super Mario Party",8.70],["FIFA",7.69],["Pokemon: Let's Go, Pikachu!",6.96],["Red Dead Redemption 2(Xone)",5.79],["Call of Duty: Black Ops IIII(Xone)",5.17]];
var svg = d3.select("#title")
.append("svg")
.attr("width", width)
.attr("height", height);
var pie = d3.pie()
.value(function(d){return d[1];});
var piedata = pie(dataset);
var outerRadius = 300; //外半径
var innerRadius = 0; //内半径,为0则中间没有空白
var arc = d3.arc() //弧生成器
.innerRadius(innerRadius) //设置内半径
.outerRadius(outerRadius); //设置外半径
var color = d3.scaleOrdinal(d3.schemeCategory10);
var arcs = svg.selectAll("g")
.data(piedata)
.enter()
.append("g")
.attr("transform","translate("+ (width/2) +","+ (height/2) +")");
arcs.append("path")//每个g元素都追加一个path元素用绑定到这个g的数据d生成路径信息
.attr("fill",function(d,i){
return color(i);
})
.attr("d",function(d){
return arc(d);//将角度转为弧度(d3使用弧度绘制)
});