D3js - 将数据绑定到多个甜甜圈图表

时间:2014-02-21 17:49:35

标签: javascript json d3.js

长期潜伏者,第一次发帖。

我创建了一个fiddle来说明我在下面讨论的内容。

我可以使用从数据库返回的数据创建单个圆环图。这很好,但我真的需要能够创建4个圆环图,显示每个网站的填充百分比。正如你在小提琴中看到的那样,当我创建前景弧时,如下所示:

    // Foreground arc
    svg.selectAll("svg")
    svg.append("path")
      .datum({endAngle: prctFilled * twoPi})
      .attr("d", arc)
      .style("fill", "orange");

我只从我的json数据集中获取最后一个值,它将显示在所有4个圆环图中。

我的第一个想法是创建一个prctFilled数组,然后遍历前景弧中的值。像这样:

data.forEach(function (d) {
    prctFilled.push(1 - ((d.capacity - d.filled) / d.capacity));

});

当我检查控制台时,我可以看到值在那里[0.09999999999999998,0.25,0.5,0.75],但我不知道如何在前景弧的代码中迭代它们。说实话,我甚至都不知道这是不是我应该做的。我已经和他摔跤了好几天了,我记不起我尝过的所有东西,但是我可以给你一个我看过的几个例子的清单(不幸的是我的声誉不到10,所以我不能发布更多比2个链接)

来自Mike Bostock:3个小圈子教程,Donut Multiples,Pie Multiples

http://jsfiddle.net/RKHnt/3/ - 这似乎与我想做的非常相似

我还看了以下问题:

(使用https://stackoverflow.com/questions/然后插入号码):

15264575

21733536

16894068 - 有一次我收到了NaN错误,但我无法为这篇文章重复这些错误。

此时我很困惑,可能答案就在我面前,我只是看不到它。很沮丧。任何帮助是极大的赞赏。我真的很挣扎。我之前从未发布过,所以如果需要更多信息,我会很乐意提供。谢谢!

2 个答案:

答案 0 :(得分:2)

解决了我的问题!

这是工作小提琴:http://jsfiddle.net/qYGPC/12/

我做了什么

基本上,它归结为我的前景路径。在我的代码顶部,我没有在arc生成器中指定.endAngle参数。

var arc = d3.svg.arc()
    .innerRadius(22.5)
    .outerRadius(30)
    .startAngle(0);

那是因为我打算在我的背景和前景路径中做这件事。所以,由于背景是一个完整的圆圈,它的.endAngle是2 * Pi。

// Background arc
svg.selectAll("svg")
svg.append("path")
    .datum({endAngle: twoPi})
    .style("fill", "#e6e6e6")
    .attr("d", arc);

我知道我必须在前景路径中做同样的事情,但我无法弄清楚我需要指定的位置.endAngle。为了增加我的困惑,我想我需要遍历我的代码并计算我的“填充百分比”,然后在我的前景路径中使用该结果。我确实需要这样做但是我的代码在错误的位置。我最初把它放在代码的顶部,如下所示:

data.forEach(function (d) {
  prctFilled = (1 - ((d.capacity - d.filled) / d.capacity));
});

嗯,这就是为什么我的JSON中的最后一个值被应用到所有4个图表的原因!我需要杀掉那段代码。我还需要杀死

.datum({endAngle: twoPi * prctFilled})

在我的前景路径中,相反,包含一个迭代我的数据集的函数,并在我的前景路径中返回“填充百分比”作为属性(并记住将其乘以2Pi) 。像这样:

// Foreground arc
svg.selectAll("svg")
svg.append("path")
    .attr("d", arc.endAngle(function (d) {return (twoPi * (1 - ((d.capacity - d.filled) / d.capacity)));}))
    .style("fill", "orange");

一旦我这样做,我得到了我正在寻找的答案。

这是代码(无数据集):

var width = 120,
    height = 62.5,
    twoPi = 2 * Math.PI;

var arc = d3.svg.arc()
    .innerRadius(22.5)
    .outerRadius(30)
    .startAngle(0);


var svg = d3.select("body").selectAll("svg")
    .data(data)
    .enter().append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

// Background arc
svg.selectAll("svg")
svg.append("path")
    .datum({endAngle: twoPi})
    .style("fill", "#e6e6e6")
    .attr("d", arc);

// Foreground arc
svg.selectAll("svg")
svg.append("path")
    .attr("d", arc.endAngle(function (d) {return (twoPi * (1 - ((d.capacity - d.filled) / d.capacity)));}))
    .style("fill", "orange");

// Add the site names to the center of the chart
svg.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .text(function (d) {return d.site;});

再一次,这是工作小提琴:http://jsfiddle.net/qYGPC/12/

注意:如果有人想知道,我需要为每个网站获得“填充百分比”结果。如果我没有从1中减去((d.capacity - d.filled)/ d.capacity)我会得到“剩余百分比”而不是“填充百分比”。这对大多数人来说可能是显而易见的,但我想我会把它扔出去。

感谢您的回复。我希望这可以帮助那些正在努力的人。

答案 1 :(得分:0)

如果你想要4个图表,你应该使用4个数据集,将你拥有的json分成dataHmidataPoplar等。然后找出如何构建一个圆环图,这应该有帮助{{3} }