D3.js - 绘制图表
D3.js 用于创建静态 SVG 图表。它有助于绘制以下图表 −
- 条形图
- 圆形图
- 饼图
- 环形图
- 折线图
- 气泡图等
本章介绍如何在 D3 中绘制图表。让我们详细了解每一个图表。
条形图
条形图是最常用的图形类型之一,用于显示和比较不同离散类别或组的数量、频率或其他度量(例如平均值)。此图的构造方式是,不同条形的高度或长度与它们所代表的类别的大小成比例。
x 轴(横轴)表示不同的类别,没有刻度。y 轴(纵轴)有刻度,表示测量单位。条形可以垂直或水平绘制,具体取决于类别的数量以及类别的长度或复杂性。
绘制条形图
让我们使用 D3 在 SVG 中创建条形图。对于此示例,我们可以使用 rect 元素 表示条形,并使用 text 元素 显示与条形相对应的数据值。
要使用 D3 在 SVG 中创建条形图,让我们按照以下步骤操作。
步骤 1 − 在 rect 元素中添加样式 −让我们将以下样式添加到 rect 元素。
svg rect { fill: gray; }
步骤 2 − 在文本元素中添加样式 − 添加以下 CSS 类以将样式应用于文本值。将此样式添加到 SVG 文本元素。它定义如下 −
svg text { fill: yellow; font: 12px sans-serif; text-anchor: end; }
此处,Fill 用于应用颜色。Text-anchor 用于将文本定位到条形图的右端。
步骤 3 − 定义变量 − 让我们在脚本中添加变量。下面将对此进行解释。
<script> var data = [10, 5, 12, 15]; var width = 300, scaleFactor = 20, barHeight = 30; </script>
这里,
Width − SVG 的宽度。
Scalefactor − 缩放到屏幕上可见的像素值。
Barheight − 这是水平条的静态高度。
步骤 4 − 附加 SVG 元素 − 让我们使用以下代码在 D3 中附加 SVG 元素。
var graph = d3.select("body") .append("svg") .attr("width", width) .attr("height", barHeight * data.length);
在这里,我们首先选择文档主体,创建一个新的 SVG 元素,然后将其附加。我们将在这个 SVG 元素内构建条形图。然后,设置 SVG 的宽度和高度。高度计算为条形高度 * 数据值的数量。
我们将条形高度设为 30,数据数组长度为 4。然后 SVG 高度计算为条形高度 * 数据长度,即 120 像素。
步骤 5 − 应用转换 − 让我们使用以下代码在条形图中应用转换。
var bar = graph.selectAll("g") .data(data) .enter() .append("g") .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
这里,里面的每个条形图都对应一个元素。因此,我们创建组元素。我们的每个组元素都需要一个接一个地放置,以构建水平条形图。让我们采用转换公式索引 * 条形图高度。
步骤 6 − 将 rect 元素附加到条形图 − 在上一步中,我们附加了组元素。现在使用以下代码将 rect 元素添加到条形图。
bar.append("rect") .attr("width", function(d) { return d * scaleFactor; }) .attr("height", barHeight - 1);
这里的宽度是(数据值 * 比例因子),高度是(条形图高度 - 边距)。
步骤 7 − 显示数据 − 这是最后一步。让我们使用以下代码显示每个条形上的数据。
bar.append("text") .attr("x", function(d) { return (d*scaleFactor); }) .attr("y", barHeight / 2) .attr("dy", ".35em") .text(function(d) { return d; });
此处,宽度定义为(数据值 * 比例因子)。文本元素不支持填充或边距。因此,我们需要为其指定一个"dy"偏移量。这用于垂直对齐文本。
步骤 8 − 工作示例 − 完整的代码清单显示在以下代码块中。创建网页 barcharts.html 并添加以下更改。
barcharts.html
<html> <head> <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script> <style> svg rect { fill: gray; } svg text { fill: yellow; font: 12px sans-serif; text-anchor: end; } </style> </head> <body> <script> var data = [10, 5, 12, 15]; var width = 300 scaleFactor = 20, barHeight = 30; var graph = d3.select("body") .append("svg") .attr("width", width) .attr("height", barHeight * data.length); var bar = graph.selectAll("g") .data(data) .enter() .append("g") .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; }); bar.append("rect").attr("width", function(d) { return d * scaleFactor; }) .attr("height", barHeight - 1); bar.append("text") .attr("x", function(d) { return (d*scaleFactor); }) .attr("y", barHeight / 2) .attr("dy", ".35em") .text(function(d) { return d; }); </script> </body> </html>
现在请求您的浏览器,您将看到以下响应。
圆形图
圆形图是一种圆形统计图形,它被分成多个部分来说明数字比例。
绘制圆形图
让我们使用 D3 在 SVG 中创建一个圆形图。为此,我们必须遵循以下步骤 −
步骤 1 − 定义变量 − 让我们在脚本中添加变量。它显示在下面的代码块中。
<script> var width = 400; var height = 400; var data = [10, 20, 30]; var colors = ['green', 'purple', 'yellow']; </script>
此处,
width − SVG 的宽度。
height − SVG 的高度。
data − 数据元素数组。
colors − 将颜色应用于圆形元素。
步骤 2 − 附加 SVG 元素 −让我们使用以下代码在 D3 中附加 SVG 元素。
var svg = d3.select("body") .append("svg") .attr("width", width) .attr("height", height);
步骤 3 − 应用转换 − 让我们使用以下代码在 SVG 中应用转换。
var g = svg.selectAll("g") .data(data) .enter() .append("g") .attr("transform", function(d, i) { return "translate(0,0)"; })
这里,
var g = svg.selectAll("g") − 创建组元素来保存圆圈。
.data(data) − 将我们的数据数组绑定到组元素。
.enter() − 为我们的组元素创建占位符。
.append("g") − 将组元素附加到我们的页面。
.attr("transform", function(d, i) { return "translate(0,0)"; })
这里,translate 用于相对于原点定位元素。
步骤 4 − 附加圆圈元素 −现在,使用以下代码将圆圈元素附加到组中。
g.append("circle")
现在,使用以下代码将属性添加到组中。
.attr("cx", function(d, i) { return i*75 + 50; })
这里,我们使用每个圆圈中心的 x 坐标。我们将圆圈的索引乘以 75,并在圆圈之间添加 50 的填充。
接下来,我们设置每个圆圈中心的 y 坐标。这用于统一所有圆圈,定义如下。
.attr("cy", function(d, i) { return 75; })
接下来,设置每个圆的半径。它定义如下,
.attr("r", function(d) { return d*1.5; })
在这里,半径与数据值以及常数"1.5"相乘以增加圆的大小。最后,使用以下代码为每个圆圈填充颜色。
.attr("fill", function(d, i){ return colors[i]; })
步骤 5 − 显示数据 − 这是最后一步。让我们使用以下代码显示每个圆圈上的数据。
g.append("text") .attr("x", function(d, i) { return i * 75 + 25; }) .attr("y", 80) .attr("stroke", "teal") .attr("font-size", "10px") .attr("font-family", "sans-serif") .text(function(d) { return d; });
步骤 6 − 工作示例 − 完整的代码清单显示在以下代码块中。创建一个网页 circlecharts.html 并在其中添加以下更改。
circlecharts.html
<html> <head> <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script> </head> <body> <script> var width = 400; var height = 400; var data = [10, 20, 30]; var colors = ['green', 'purple', 'yellow']; var svg = d3 .select("body") .append("svg") .attr("width", width) .attr("height", height); var g = svg.selectAll("g") .data(data) .enter() .append("g") .attr("transform", function(d, i) { return "translate(0,0)"; }) g.append("circle").attr("cx", function(d, i) { return i*75 + 50; }) .attr("cy", function(d, i) { return 75; }) .attr("r", function(d) { return d*1.5; }) .attr("fill", function(d, i){ return colors[i]; }) g.append("text").attr("x", function(d, i) { return i * 75 + 25; }) .attr("y", 80) .attr("stroke", "teal") .attr("font-size", "10px") .attr("font-family", "sans-serif").text(function(d) { return d; }); </script> </body> </html>
现在,请求您的浏览器,以下是响应。
饼图
饼图是一种圆形统计图。它被分成几部分以显示数字比例。让我们了解如何在 D3 中创建饼图。
绘制饼图
在开始绘制饼图之前,我们需要了解以下两种方法 −
- d3.arc() 方法和
- d3.pie() 方法。
让我们详细了解这两种方法。
d3.arc() 方法 − d3.arc() 方法生成一个圆弧。您需要为圆弧设置内半径和外半径。如果内半径为 0,结果将为饼图,否则结果将为圆环图,这将在下一节中讨论。
d3.pie() 方法 − d3.pie() 方法用于生成饼图。它从数据集中获取数据并计算饼图每个楔形的起始角度和结束角度。
让我们按照以下步骤绘制饼图。
步骤 1 − 应用样式 − 让我们将以下样式应用于弧形元素。
.arc text { font: 12px arial; text-anchor: middle; } .arc path { stroke: #fff; } .title { fill: green; font-weight: italic; }
此处,填充用于应用颜色。文本锚点用于将文本定位到弧线的中心。
步骤 2 − 定义变量 − 定义脚本中的变量,如下所示。
<script> var svg = d3.select("svg"), width = svg.attr("width"), height = svg.attr("height"), radius = Math.min(width, height) / 2; </script>
此处,
width − SVG 的宽度。
height − SVG 的高度。
radius − 可以使用 Math.min(width, height) / 2 函数计算;
步骤 3 − 应用转换 − 使用以下代码在 SVG 中应用以下转换。
var g = svg.append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
现在使用下面给出的 d3.scaleOrdinal 函数添加颜色。
var color = d3.scaleOrdinal(['gray', 'green', 'brown', 'orange']);
步骤 4 − 生成饼图 − 现在,使用下面给出的函数生成饼图。
var pie = d3.pie() .value(function(d) { return d.percent; });
在这里,您可以绘制百分比值。需要一个匿名函数来返回 d.percent 并将其设置为饼图值。
步骤 5 − 定义饼图楔形的弧线 − 生成饼图后,现在使用下面给出的函数为每个饼图楔形定义弧线。
var arc = d3.arc() .outerRadius(radius) .innerRadius(0);
在这里,此弧线将设置为路径元素。计算出的半径设置为外半径,而内半径设置为 0。
步骤 6 − 在楔形中添加标签 − 通过提供半径在饼形楔形中添加标签。其定义如下。
var label = d3 .arc() .outerRadius(radius) .innerRadius(radius - 80);
步骤 7 − 读取数据 − 这是一个重要的步骤。我们可以使用下面给出的函数读取数据。
d3.csv("populations.csv", function(error, data) { if (error) { throw error; } });
此处,populations.csv 包含数据文件。d3.csv 函数从数据集读取数据。如果数据不存在,则会引发错误。我们可以将此文件包含在您的 D3 路径中。
步骤 8 − 加载数据 − 下一步是使用以下代码加载数据。
var arc = g.selectAll(".arc") .data(pie(data)) .enter() .append("g") .attr("class", "arc");
此处,我们可以将数据分配给数据集中每个数据值的组元素。
步骤 9 − 附加路径 −现在,添加路径并为组分配一个类"arc",如下所示。
arcs.append("path") .attr("d", arc) .attr("fill", function(d) { return color(d.data.states); });
此处,fill 用于应用数据颜色。它取自 d3.scaleOrdinal 函数。
步骤 10 − 添加文本 − 使用以下代码在标签中显示文本。
arc.append("text") .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; }) .text(function(d) { return d.data.states; });
此处,SVG 文本元素用于在标签中显示文本。我们之前使用 d3.arc() 创建的标签弧返回一个质心点,这是标签的位置。最后,我们使用 d.data.browser 提供数据。
步骤 11 − 附加组元素 −附加组元素属性并添加类标题以对文本进行着色并使其变为斜体,这在步骤 1 中指定并在下面定义。
svg.append("g") .attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")") .append("text") .text("Top population states in india") .attr("class", "title")
步骤 12 − 工作示例 − 要绘制饼图,我们可以获取印度人口的数据集。此数据集显示虚拟网站中的人口,定义如下。
population.csv
states,percent UP,80.00 Maharastra,70.00 Bihar,65.0 MP,60.00 Gujarat,50.0 WB,49.0 TN,35.0
让我们为上述数据集创建一个饼图可视化。创建一个网页"piechart.html"并在其中添加以下代码。
<!DOCTYPE html> <html> <head> <style> .arc text { font: 12px arial; text-anchor: middle; } .arc path { stroke: #fff; } .title { fill: green; font-weight: italic; } </style> <script type = "text/javascript" src = "https://d3js.org/d3.v4.min.js"></script> </head> <body> <svg width = "400" height = "400"></svg> <script> var svg = d3.select("svg"), width = svg.attr("width"), height = svg.attr("height"), radius = Math.min(width, height) / 2; var g = svg.append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var color = d3.scaleOrdinal([ 'gray', 'green', 'brown', 'orange', 'yellow', 'red', 'purple' ]); var pie = d3.pie().value(function(d) { return d.percent; }); var path = d3.arc() .outerRadius(radius - 10).innerRadius(0); var label = d3.arc() .outerRadius(radius).innerRadius(radius - 80); d3.csv("populations.csv", function(error, data) { if (error) { throw error; } var arc = g.selectAll(".arc") .data(pie(data)) .enter() .append("g") .attr("class", "arc"); arc.append("path") .attr("d", path) .attr("fill", function(d) { return color(d.data.states); }); console.log(arc) arc.append("text").attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; }) .text(function(d) { return d.data.states; }); }); svg.append("g") .attr("transform", "translate(" + (width / 2 - 120) + "," + 20 + ")") .append("text").text("Top population states in india") .attr("class", "title") </script> </body> </html>