【问题标题】:d3js Switching between multiple chartsd3js在多个图表之间切换
【发布时间】:2019-04-17 03:00:13
【问题描述】:

在我自己学习并且是 D3.js 的新手时,我正在尝试创建多个饼图,其中包含通过自定义按钮切换的不同类别。

我创建了一个单独的饼图,效果如下: https://bl.ocks.org/lydiawawa/7c385eaaf24cb4e6047c9b56866fac6e/252dfbf9f27123e5577f6c54ca7dffe6fd75714e

我希望通过 tooltip 和 label 实现以下效果,但我想在性别、年龄和种族之间切换,而不是橙色和苹果:

想要的效果: http://bl.ocks.org/j0hnsmith/5591116

这是我目前所拥有的: https://blockbuilder.org/lydiawawa/38243015ab2ac96b6086d3bae56572b9

最困难的部分是将两个类别的饼图转换为三个类别并添加工具提示和标签。我想在实现效果方面有所帮助。感谢您的任何意见!

编辑

我最近发现了以下三个类别的效果,但是我不知道如何将标签或图例添加到图表中,以便以后也可以用于工具提示:

http://bl.ocks.org/jfreels/6919598

我尝试以以下格式重塑 json。也许通过这种方式我们可以使用 d3.json 代替 init()?

[
 {
   "genderC": "female",
   "gender": 533,
   "raceC": "A",
   "race": 20,
   "ageC": "0 < 12 years",
   "age": 8
 },
 {
   "genderC": "male",
   "gender": 260,
   "raceC": "A E",
   "race": 19,
   "ageC": "13 years",
   "age": 1
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "A D",
   "race": 2,
   "ageC": "14 years",
   "age": 102
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "A DE",
   "race": 1,
   "ageC": "15 years",
   "age": 195
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "A C",
   "race": 5,
   "ageC": "16 years",
   "age": 200
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "A C E",
   "race": 5,
   "ageC": "17 years",
   "age": 187
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "AB D",
   "race": 1,
   "ageC": "18 years",
   "age": 100
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "ABC E",
   "race": 1,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "ABCD",
   "race": 1,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "ABCDE",
   "race": 1,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "B",
   "race": 27,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "B H",
   "race": 0,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "B E",
   "race": 6,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "B D",
   "race": 6,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "B DE",
   "race": 2,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "BC",
   "race": 2,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "BCD",
   "race": 1,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "C",
   "race": 175,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "C E",
   "race": 17,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "CD",
   "race": 3,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "D",
   "race": 14,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "DE",
   "race": 3,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "E",
   "race": 481,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 },
 {
   "genderC": "",
   "gender": null,
   "raceC": "",
   "race": null,
   "ageC": "",
   "age": null
 }
]

【问题讨论】:

  • 我正在浏览您共享的块构建器,我有点困惑您的最终数据是什么样的?在 blockbuilder 中,您的数据位于 dataset.json 中,但它只是 javascript,因为您有对象数组 var gender = [{..}],{..}]。如果您的数据已经是对象数组的形式,则不需要创建 json。将它们作为单独的变量实际上更容易。
  • @Coola 我将 json 作为脚本导入到 index.html 中,并将数组调用到 init() 中。你的意思是我不需要在 index.html 中调用它吗?我可以在 pieChart() 中定义数组吗?
  • @Coola 我想我希望做的只是使用我自己的数据集创建三个按钮切换的饼图。转换将从此示例生效:bl.ocks.org/j0hnsmith/5591116 带有标记颜色的图例或标签。也将添加工具提示效果以显示百分比。
  • 是的,您可以在main.js 中定义数组。我理解您想要什么,但是从其他来源复制代码而不了解它们的作用会使您当前的代码块变得一团糟。
  • @Coola 我将这些变量移到 main.js 中的 init() 中。代码已更新。

标签: javascript json d3.js data-visualization


【解决方案1】:

您的代码有几个问题,我不得不进行一些更改。

如果我理解正确,您的主要想法是根据用户点击的数据(即“性别”“年龄”或“种族”)重新绘制饼图。

  1. 每一个的数据都非常不同,即不同的对象键值对。我将所有count 键都设置为相同(在年龄数据集中它们是Count)。

  2. 由于数据非常不同,您显示的数据更新位置的示例可能不适用于此处,因为在这种情况下数据不会转换。相反,我采取的方法是清除 div 并重新绘制饼图。所以它做的第一件事就是清除图表区域,然后开始绘制。这大大减少了所需的代码量(您的 main.js = >300 行,而我的 138 行)

  3. 随着数据键的变化,我改进了工具提示,因此需要在工具提示中说明这一点。

  4. 我将您的数据移动到一个单独的 js 文件中,以免使 main.js 混乱。我只是确保在 index.html 文件中的 main.js 之前调用它。

  5. 我更新了 function color(d) 函数以根据数据键从对象数组中选择颜色。您可以根据需要扩展阵列。如果您想在某个范围内使用颜色,您可以使用var color = d3.scale.category20(); 并使用.attr("fill", function (d, i) { return color(i);}) 等数据的索引调用颜色,如本例所示http://bl.ocks.org/j0hnsmith/5591116

这是一个工作块https://bl.ocks.org/akulmehta/923f277f8a10d0c35b77f6e3a84929bf/

请注意,由于agerace 的许多数据点是0,因此动画会有点卡顿。另请注意,当您的弧彼此非常接近时,您的标签会重叠。因此,我建议删除标签。

【讨论】:

  • 感谢您所做的一切。您甚至为分类变量选择了颜色。今天回家后,我将查看/学习代码并进行一些修改。
  • 我回家后会接受答案,我的应用由于某种原因不允许我标记支票。
  • 我试图对您编辑的代码进行一些更改。我在 else 语句中为定义比赛类别的颜色添加了条件,但比赛图在更改后没有出现。我还尝试在删除标签后向图表添加图例,但图例也没有出现。这是我更新的旧链接:blockbuilder.org/lydiawawa/38243015ab2ac96b6086d3bae56572b9
  • 我现在会接受答案,但你能帮忙制作最后几个插件吗?我想我已经很接近了,但由于某种原因,效果没有出现。
  • 这个blockbuilder.org/akulmehta/1aa16d77c876b213d982c54a8e86e434 怎么样?调用颜色时,会将更多信息传递给函数,以使其知道它是什么类型的数据以及数据的长度。通过这样做,您可以使用它来使用序数比例来获取颜色值。希望这会有所帮助。