D3.js - 形状 API
D3.js - 形状 API (d3-shape)
Section titled “D3.js - 形状 API (d3-shape)”D3.js 提供了一个强大的模块 d3-shape,用于生成各种图形形状(如圆弧 [用于饼图/环形图]、线 [用于折线图] 和区域 [用于面积图])的 SVG 路径数据。这些形状生成器(shape generator)接收数据,并返回 SVG <path> 元素的 d 属性所需的字符串值。
设置 D3.js
Section titled “设置 D3.js”要使用 D3.js 形状 API,需要在 HTML 文件中引入 D3.js 库。最简单的方法是使用 CDN(内容分发网络)上的完整 D3 包,其中包含 d3-shape 及其依赖 d3-path。
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <title>D3.js Shapes API Example</title> <script src="https://d3js.org/d3.v7.min.js"></script> </head> <body> <svg id="visualization" width="400" height="300"></svg> <script> // Your D3.js code using d3-shape will go here </script> </body></html>D3.js 提供了几种形状生成器。让我们探索一些主要的。
圆弧 API (d3.arc)
Section titled “圆弧 API (d3.arc)”圆弧生成器(d3.arc())用于生成圆形或环形扇区的路径数据,常用于饼图和环形图。
d3.arc(): 创建一个使用默认设置的新圆弧生成器。arc(dataObject): 为圆弧生成路径字符串。dataObject通常需要innerRadius、outerRadius、startAngle和endAngle等属性。例如:{ innerRadius: 0, outerRadius: 100, startAngle: 0, endAngle: Math.PI / 2 }会定义一个四分之一圆。arc.innerRadius([radius]): 设置或获取内半径。radius可以是一个常数,也可以是一个接收数据并返回值的函数。默认访问器(accessor)为:function innerRadius(d) { return d.innerRadius; }。arc.outerRadius([radius]): 设置或获取外半径。默认访问器为:function outerRadius(d) { return d.outerRadius; }。arc.startAngle([angle]): 设置或获取起始角度(以弧度为单位)。默认访问器为:function startAngle(d) { return d.startAngle; }。arc.endAngle([angle]): 设置或获取结束角度(以弧度为单位)。默认访问器为:function endAngle(d) { return d.endAngle; }。arc.padAngle([angle]): 设置或获取圆弧之间的填充角度(pad angle,用于分隔饼图扇区)。默认访问器为:function padAngle(d) { return d && d.padAngle; }。arc.cornerRadius([radius]): 设置或获取圆角半径(corner radius),用于使圆弧的角变圆润。对于样式效果很有帮助。arc.centroid(dataObject): 计算圆弧中心线的中心点 [x, y]。对于放置标签很有用。
示例用法:
const arcGenerator = d3.arc() .innerRadius(50) .outerRadius(100) .startAngle(0) .endAngle(Math.PI / 2); // 一个四分之一的环形扇区
const pathData = arcGenerator(); // 生成具有固定值的单个圆弧的路径字符串
// 或者,如果绑定了数据:// const pathData = arcGenerator(dataObjectForArc);
d3.select("#visualization").append("path") .attr("d", pathData) .attr("transform", "translate(150, 150)") // 定位圆弧 .attr("fill", "steelblue");饼图 API (d3.pie)
Section titled “饼图 API (d3.pie)”饼图生成器(d3.pie())本身不绘制任何内容。它接收一个数据数组,并计算饼图每个扇区所需的起始角度(start angle)和结束角度(end angle)。d3.pie() 的输出通常会传递给 d3.arc(),用于生成每个扇区的实际路径数据。
d3.pie(): 构造一个使用默认设置的新饼图生成器。pie(dataArray): 计算给定dataArray的角度。它返回一个对象数组,其中每个对象代表一个扇区,并包含:data: 该扇区的原始输入数据项。value: 扇区的数值(用于角度计算)。index: 数据项的原始索引。startAngle: 计算出的扇区起始角度。endAngle: 计算出的扇区结束角度。padAngle: 填充角度(如果在饼图生成器上设置)。pie.value([accessor]): 设置或获取从每个数据元素中提取数值的访问器函数。默认值:function value(d) { return d; }。pie.sort([comparator]): 设置或获取用于按原始数据对象对扇区进行排序的比较器(comparator)函数。设置为null可保留输入顺序。pie.sortValues([comparator]): 设置或获取用于按计算出的数值对扇区进行排序的比较器函数。设置为null可保留输入顺序。默认为降序。pie.startAngle([angle]): 设置或获取饼图的整体起始角度(例如,0表示 12 点钟方向)。pie.endAngle([angle]): 设置或获取饼图的整体结束角度(例如,2 * Math.PI表示一个整圆)。pie.padAngle([angle]): 设置或获取用于分隔扇区的角度。
与 d3.arc 配合使用的示例用法:
const dataset = [10, 20, 30, 40];const pieGenerator = d3.pie();const arcData = pieGenerator(dataset);
// arcData 现在是一个包含 startAngle, endAngle 等属性的对象数组// 例如,[{data: 10, value: 10, index: 0, startAngle: ..., endAngle: ..., padAngle:...}, ...]
const arcGeneratorForPie = d3.arc().innerRadius(0).outerRadius(100);
d3.select("#visualization") .selectAll(".pieSlice") .data(arcData) .enter() .append("path") .attr("class", "pieSlice") .attr("d", arcGeneratorForPie) .attr("fill", (d, i) => d3.schemeCategory10[i]) .attr("transform", "translate(150, 150)");线 API (d3.line)
Section titled “线 API (d3.line)”线生成器(d3.line())用于生成折线的路径数据,这对于折线图至关重要。
d3.line(): 创建一个新的线生成器。line(dataArray): 根据数据点数组生成线的路径字符串。dataArray中的每个点通常包含 x 和 y 分量。line.x([accessor]): 设置或获取每个点 x 坐标的访问器。默认值:function x(d) { return d[0]; }(假设点是[x, y]数组)。line.y([accessor]): 设置或获取每个点 y 坐标的访问器。默认值:function y(d) { return d[1]; }。line.defined([accessor]): 设置或获取一个访问器,用于控制一个点是否被定义。如果一个点是 undefined,线将在此处断开。默认值:function defined() { return true; }。line.curve([curveType]): 设置或获取用于绘制点之间线的插值策略(interpolation strategy)(例如,d3.curveLinear、d3.curveBasis、d3.curveStep)。line.context([canvasContext]): 如果直接绘制到 Canvas 2D API,则设置渲染上下文(rendering context)(对于 SVG 较少使用)。
示例用法:
const lineData = [ [0, 80], [100, 100], [200, 30], [300, 50], [400, 40] ];const lineGenerator = d3.line(); // 使用默认的 x 和 y 访问器
// 或者,如果数据是一个对象数组:// const lineData = [ {xVal:0, yVal:80}, {xVal:100, yVal:100}, ... ];// const lineGenerator = d3.line()// .x(d => d.xVal)// .y(d => d.yVal);
const pathString = lineGenerator(lineData);
d3.select("#visualization").append("path") .attr("d", pathString) .attr("fill", "none") .attr("stroke", "green");径向线 API (d3.lineRadial)
Section titled “径向线 API (d3.lineRadial)”d3.lineRadial() 与 d3.line() 类似,但它生成的是极坐标(角度和半径)而不是笛卡尔坐标(x 和 y)下的线。对于雷达图或螺旋图很有用。
d3.lineRadial(): 创建一个新的径向线生成器。lineRadial.angle([accessor]): 设置或获取角度(以弧度为单位)的访问器。lineRadial.radius([accessor]): 设置或获取半径(与原点的距离)的访问器。
这些形状生成器是 D3.js 中创建常见图表类型的基本工具,它们简化了复杂 SVG 路径数据的构建。