数据可视化D3js 之饼状图与交互

今天是关于一个d3画饼状图的一个简单剖析和讲解。(本次用例是基于Vue和D3 v4)
在画图之前,首先,我们来了解一下D3画图的一个重要概念,就是布局。布局是什么,其实就是数据转换。假设有数据[5,10,15,20,25,30] 。要将这个数据画成饼状图,直接使用数组中的数据是不行的,需要将数据转换成扇形的起始角度和终止角度。构成整个圆形,这个过程如果自己画,显然太过于复杂,所以d3js把这些数据转化的成功通过布局直接完成。目前已经提供来很多的布局,如Pie(饼状图),Chord(弦图),Histogram(直方图)等。


第一阶段,画一个饼图

先来一段准备好到Html 和css




开始准备初始数据

 initPie() {
        //初始化数据,这是一份2014年各大手机厂商在中国的出货量
        let dataset = [
          ["小米", 60.8],
          ["三星", 58.4],
          ["联想", 47.3],
          ["苹果", 46.6],
          ["华为", 41.3],
          ["酷派", 40.1],
          ["其他", 111.5],
        ];
        //创建饼状图布局和它的数据规则访问器
        let pie = d3.pie().value((d)=>d[1]);
        let pieData = pie(dataset);
        //绘制图形的
        let width = 500,
          height = 500;
        let outerRadius = width / 3,
          innerRadius = 0;
        let svg = d3.select("#pie-svg-wrap").append("svg")
          .attr("width", width)
          .attr("height", height)
          .attr('fill', 'white');
  }

在准备好基础数据之后,接下里画圆弧进行图形绘制

     //创建弧生成器,弧生成器中的需要内外半径的参数
        let arc = d3.arc().innerRadius(innerRadius)
          .outerRadius(outerRadius);
        let color = d3.schemeCategory10;
  
        //添加对应数目的弧数,即元素
        let arcs = svg.selectAll("g")
          .data(pieData) //绑定转换后的数据piedata
          .enter()
          .append("g")
          .attr("transform", `translate(${width/2},${height/2})`);
        
        //添加弧的路径元素
        arcs.append("path")
        .attr("fill", (d,i)=>{
          return color[i];//设置每个弧的颜色
        })
        .attr("d", d=>{
          return arc(d);  //使用弧生成器获取路径信息
        })

接着给每个弧添加相应的文字
这里有必要给大家讲解下 arc.centroid这个方法(以下是官方文档)

# arc.centroid(arguments…)
计算由给定 arguments 生成的 generated的中间点 [x, y]. arguments 是任意的,它们会被传递给 arc 生成器的访问器。为了与生成的弧保持一致,访问器必须是确定的。例如,相同的参数返回相同的值。中间点被定义为 (startAngle + endAngle) / 2 和 (innerRadius + outerRadius) / 2。例如:

Circular Sector Centroids
Annular Sector Centroids

注意,中间点 并不是几何中心,因为几何中心点可能位于弧之外; 这个方法可以用来方便的对 labels 进行定位。

        //添加弧内的文字元素
        arcs.append('text')
        .attr("transform", d=>{
          let x = arc.centroid(d)[0] * 1.4; //文字的x坐标
          let y = arc.centroid(d)[1] * 1.4; //文字的y坐标
          return `translate(${x},${y})`
        })
        .attr("text-anchor", "middle")
        .text(d=>{
          let percent = (Number(d.value) /d3.sum(dataset, d=>d[1]))*100;
          return percent.toFixed(1) + "%"
        })

如下图。


屏幕快照 2018-11-30 下午6.04.16.png

接下来,我们有可能会需要用到添加一些额外的信息

       //添加连接弧外的文字的直线元素和文字
        arcs.append("line")
        .attr("stroke", "black")
        .attr("x1", d=> arc.centroid(d)[0] * 2)
        .attr("y1", d=> arc.centroid(d)[1] * 2)
        .attr("x2", d=> arc.centroid(d)[0] * 2.2)
        .attr("y2", d=> arc.centroid(d)[1] * 2.2);

        arcs.append("text")
        .attr("transform", d=>{
          let x = arc.centroid(d)[0] * 2.5; //文字的x坐标
          let y = arc.centroid(d)[1] * 2.5; //文字的y坐标
          return `translate(${x},${y})`
        })
        .attr("fill", "black")
        .attr("text-anchor", "middle")
        .text(d=>d.data[0])
屏幕快照 2018-11-30 下午6.20.24.png

到这里,第一阶段就结束了。

第二阶段

你可能感兴趣的:(数据可视化D3js 之饼状图与交互)