多行图:用途、代码与说明
学习如何创建多行图,以在同一图表中表示不同的数据。
目的
能够创建多线图是一项非常实用的功能。在课程早期,我们曾通过一个扩展简单图表的例子来实现这一点。在那个例子中,我们使用了一个CSV文件,其中每条线的数据值分别存储在不同的列中。
1date,close,open 21-May-12,68.13,34.12 330-Apr-12,63.98,45.56 4...
这是一种常见的数据存储方式。但如果你从数据库中获取数据,可能无法享受这种按列排列的便利。数据可能以更线性的方式呈现,即每条线的值都存储在单独的一行中,同时该行也包含标识该线的名称。例如,上述数据也可以如下形式展示:
1price,date,value 2close,1-May-12,68.13 3close,30-Apr-12,63.98 4...
在这种情况下,我们需要“转置”数据,以生成与原始格式相同的多列表示形式。这并不总是容易实现,但可以使用 d3.group 函数来完成,我们将对此进行研究。
此外,我们希望自动为各条线分配不同颜色,并添加一个图例,显示每条线的名称及其对应的颜色。
最后,由于我们将构建一个能处理任意数量线条(在合理范围内)的图表脚本,因此还需要具备隐藏/显示单条线的功能,以便在图表过于杂乱时帮助清晰表达。
本书中已经分别讲解了所有这些功能,我们现在要将它们整合起来,形成一个优雅的多线图,效果大致如下:
代码
以下是初始示例的代码,它是原始简单图表的一个稍作修改的版本。
No configuration found for ID: d8e896cbdad14ac647fe662d9a68be336e20958965497277ed4f74d7aebbae77
说明
数据分组
上述示例代码与简单图表有两个主要区别。
首先,脚本加载的是文件 stocks.csv。这意味着使用的变量名有所不同:price 表示股票价格,symbol 表示股票名称,而 date 仍表示日期。我们必须调整 parseDate 函数以解析修改后的日期格式。
其次,我们添加了代码块,用于处理加载的 stocks.csv 数据,并应用 d3.group 函数,然后绘制每一条线。
第67至70行: 这段代码对数据进行分组。
-
我们使用
Array.from将数据映射转换为数组,同时将 [键, 值] 格式转换为便于代码访问的形式。 -
我们将新数组命名为
dataNest,并通过调用group函数创建数组。 -
指定我们要分组的数据源为
data,并设置分组的“键”为symbol。“键”意味着:“我们将根据这个字段进行分组。” 换句话说,最终生成的数组将为每个唯一的symbol(即每只股票)创建一个条目,每个条目本身是一个包含日期和数值的数组。
第72至79行: 接着,我们利用分组后的数据遍历每只股票并绘制线条。
- 对
dataNest应用forEach函数,意味着它会遍历我们刚刚用d3.group定义的每一个键(即每只股票),并使用每只股票的值来附加一条对应的线条。
最终结果如下所示:
你可能会觉得这看起来相当混乱。显然,虽然我们成功让每只股票绘制出对应的线条,但如果无法区分它们,这张图就毫无意义。