返回

D3 入门与实践(四):描绘数据分布饼状图

前端

D3.js 简介

D3.js 是一个流行的 JavaScript 库,用于创建交互式数据可视化。它提供了丰富的函数和类,可以轻松地将数据转换为可视化的图形。D3.js 最初由 Mike Bostock 开发,他也是著名的数据可视化书籍《可视化数据的艺术》(The Art of Data Visualization)的作者。D3.js 广泛应用于各种领域,如新闻媒体、金融、医疗保健和科学研究等。

饼状图基础

饼状图是一种常用的数据可视化图表,它可以显示不同类别的数据在总数据中所占的比例。饼状图由一个圆形组成,圆形被分成若干个扇形,每个扇形的面积与该类别的数据值成正比。饼状图通常用于比较不同类别的数据大小,并突出显示最大和最小的类别。

创建基本饼状图

为了创建一个基本饼状图,我们需要使用 D3.js 的 pie() 函数来计算每个类别的弧度。pie() 函数接受一个数据数组作为输入,并返回一个弧度生成器。弧度生成器可以用来创建弧度对象,弧度对象包含了弧度的起始角度、结束角度、内半径和外半径。

const data = [
  { category: "A", value: 20 },
  { category: "B", value: 30 },
  { category: "C", value: 40 },
  { category: "D", value: 10 }
];

const pie = d3.pie()(data);

接下来,我们需要使用 D3.js 的 arc() 函数来创建弧度路径。arc() 函数接受一个弧度对象作为输入,并返回一个路径生成器。路径生成器可以用来创建路径对象,路径对象包含了弧度的路径数据。

const arc = d3.arc()
  .innerRadius(0)
  .outerRadius(200);

最后,我们需要使用 D3.js 的 select() 和 enter() 函数来将弧度路径添加到 SVG 元素中。select() 函数选择 SVG 元素,enter() 函数用于将数据绑定到 SVG 元素。

const svg = d3.select("svg");

const g = svg.append("g")
  .attr("transform", "translate(200, 200)");

const path = g.selectAll("path")
  .data(pie)
  .enter()
  .append("path")
  .attr("d", arc)
  .attr("fill", "steelblue");

添加标签

为了让饼状图更易于理解,我们可以添加标签来显示每个类别的名称和值。可以使用 D3.js 的 arcLabel() 函数来创建弧度标签。arcLabel() 函数接受一个弧度对象和一个标签文本作为输入,并返回一个路径生成器。路径生成器可以用来创建路径对象,路径对象包含了弧度标签的路径数据。

const arcLabel = d3.arcLabel()
  .innerRadius(0)
  .outerRadius(220)
  .label("middle");

const label = g.selectAll("text")
  .data(pie)
  .enter()
  .append("text")
  .attr("transform", function(d) { return "translate(" + arcLabel.centroid(d) + ")"; })
  .attr("text-anchor", "middle")
  .text(function(d) { return d.data.category + ": " + d.data.value; });

添加工具提示

为了让饼状图更具交互性,我们可以添加工具提示来显示更多信息。可以使用 D3.js 的 tooltip() 函数来创建工具提示。tooltip() 函数接受一个选择器和一个内容生成器作为输入,并返回一个工具提示对象。工具提示对象可以用来显示或隐藏工具提示。

const tooltip = d3.tooltip()
  .attr("class", "tooltip")
  .style("opacity", 0)
  .html(function(d) { return d.data.category + ": " + d.data.value; });

svg.call(tooltip);

path.on("mouseover", function(d) {
  tooltip.style("opacity", 1);
  tooltip.html(d.data.category + ": " + d.data.value);
  tooltip.style("left", (d3.event.pageX + 10) + "px");
  tooltip.style("top", (d3.event.pageY + 10) + "px");
});

path.on("mouseout", function() {
  tooltip.style("opacity", 0);
});

添加动画

为了让饼状图更具动态感,我们可以添加动画来显示饼状图的绘制过程。可以使用 D3.js 的 transition() 函数来创建动画。transition() 函数接受一个选择器和一个动画配置对象作为输入,并返回一个过渡对象。过渡对象可以用来设置动画的持续时间、延迟时间和缓动函数。

path.transition()
  .duration(1000)
  .attrTween("d", function(d) {
    const interpolate = d3.interpolate({ startAngle: 0, endAngle: 0 }, d);
    return function(t) {
      return arc(interpolate(t));
    };
  });

结语

在本文中,我们使用 D3.js 创建了一个饼状图,并添加了标签、工具提示和动画。通过本文,您应该已经对 D3.js 的基本使用有了初步的了解。在下一节中,我们将继续学习如何使用 D3.js 创建其他类型的数据可视化图表。