简体   繁体   English

将json数据分组以创建分组的条形图

[英]Grouping json data to create grouped bar chart

As a precursor, I am very new to d3/js. 作为先驱,我对d3 / js非常陌生。 I am attempting to build a grouped bar chart based off an example provided by Mike Bostock. 我试图根据Mike Bostock提供的示例构建分组条形图。 His example is really good and I understand most of the source code, but I don't know how to translate it to my data. 他的示例确实很好,并且我了解大多数源代码,但是我不知道如何将其转换为我的数据。 The data provided by the mbostock example is in csv, and my data is json -- and unfortunately the formats are very different. mbostock示例提供的数据在csv中,而我的数据是json-不幸的是,格式非常不同。

The mbostock csv example is available on the page, and I've pasted my json data below. 页面上提供了mbostock csv示例,并且我在下面粘贴了json数据。

{"data":[{"id":455211,"name":"Bacon Portabella Melt on Brioche","volume":15,"trend":{"years":2013,"quarters":4,"months":10}},{"id":455097,"name":"Pretzel Bacon Cheeseburger","volume":287,"trend":{"years":2013,"quarters":4,"months":10}},{"id":455315,"name":"Spicy Chipotle Jr Cheeseburger","volume":0,"trend":{"years":2013,"quarters":4,"months":10}},{"id":455211,"name":"Bacon Portabella Melt on Brioche","volume":1474,"trend":{"years":2013,"quarters":4,"months":11}},{"id":455097,"name":"Pretzel Bacon Cheeseburger","volume":155,"trend":{"years":2013,"quarters":4,"months":11}},{"id":455315,"name":"Spicy Chipotle Jr Cheeseburger","volume":0,"trend":{"years":2013,"quarters":4,"months":11}},{"id":455211,"name":"Bacon Portabella Melt on Brioche","volume":1623,"trend":{"years":2013,"quarters":4,"months":12}},{"id":455097,"name":"Pretzel Bacon Cheeseburger","volume":47,"trend":{"years":2013,"quarters":4,"months":12}},{"id":455315,"name":"Spicy Chipotle Jr Cheeseburger","volume":13,"trend":{"years":2013,"quarters":4,"months":12}}],"countInfo":{"globalTotal":3649,"total":4359},"metadata":{"runDate":1435260902236,"resultSource":0}}

This data is the result of an API call. 此数据是API调用的结果。 My goal is to manipulate the json data in a way that I can easily bind it in d3 and call it. 我的目标是以某种方式操纵json数据,以便可以轻松地在d3中将其绑定并调用它。 For instance, I want to be able to group volumes for "Bacon Portabella Melt on Brioche" in a way that I can easily say "October (month 10) - 15, November (month 11) - 1474, December (month 12) - 1623", or in another way, "In October, each of the burgers had x volume; in November...". 举例来说,我希望能够以“十月(第10个月)-15月,11月(第11个月)-1474年,12月(第12个月)- 1623”,或用另一种方式表示,“十月份,每个汉堡的体积都是x;十一月份是……”。

To get the data bound, mbostock uses the following: 为了获取数据绑定,mbostock使用以下内容:

var ageNames = d3.keys(dataset[0]).filter(function(key) { return key !== "State"; });

dataset.forEach(function(d) {
d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
});

But I can't seem to follow this as I keep returning an empty array after running the forEach function. 但是我似乎无法遵循这一点,因为在运行forEach函数之后,我一直返回一个空数组。

I understand the drawing with SVG aspect, so I think after I get over this hurdle I'll be able to build my bar chart successfully. 我了解SVG方面的图形,因此我认为在克服这一障碍之后,我将能够成功构建条形图。 Any assistance is greatly appreciated -- a step-by-step "for dummies" (AKA me) guide would be best, but if you've just got general advice or another link to point me towards, that is awesome as well. 非常感谢您提供任何帮助-逐步的“傻瓜”指南(又称“我”)是最好的,但是如果您只是获得一般建议或其他指向我的链接,那也很棒。

D3 examples use many different types of quite specific data structures. D3示例使用许多不同类型的非常特定的数据结构。 If yours does not 1:1 match the example's one, your sample will probably fail. 如果您的示例与该示例的1:1不匹配,则您的示例可能会失败。 Compare the Bostock's sample object once the CSV is loaded (eg console.log(data)) with yours and try to provide the same structure. 将CSV加载后(例如console.log(data))与您的Bostock的示例对象进行比较,并尝试提供相同的结构。

Really there are not many examples on this. 确实没有太多的例子。 The main challenge in this, as you said, is re-engineering the dataset. 正如您所说,其中的主要挑战是重新设计数据集。

So your dataset is now grouped on burger types: 因此,您的数据集现在按汉堡类型分组:

[
   {
      "name":"Bacon Portabella Melt on Brioche",
      "value":[
         {
            "id":455211,
            "name":"Bacon Portabella Melt on Brioche",
            "volume":15,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":10
            },
            "date":"2013-10"
         },
         {
            "id":455211,
            "name":"Bacon Portabella Melt on Brioche",
            "volume":1474,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":11
            },
            "date":"2013-11"
         },
         {
            "id":455211,
            "name":"Bacon Portabella Melt on Brioche",
            "volume":1623,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":12
            },
            "date":"2013-12"
         }
      ]
   },
   {
      "name":"Pretzel Bacon Cheeseburger",
      "value":[
         {
            "id":455097,
            "name":"Pretzel Bacon Cheeseburger",
            "volume":287,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":10
            },
            "date":"2013-10"
         },
         {
            "id":455097,
            "name":"Pretzel Bacon Cheeseburger",
            "volume":155,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":11
            },
            "date":"2013-11"
         },
         {
            "id":455097,
            "name":"Pretzel Bacon Cheeseburger",
            "volume":47,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":12
            },
            "date":"2013-12"
         }
      ]
   },
   {
      "name":"Spicy Chipotle Jr Cheeseburger",
      "value":[
         {
            "id":455315,
            "name":"Spicy Chipotle Jr Cheeseburger",
            "volume":0,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":10
            },
            "date":"2013-10"
         },
         {
            "id":455315,
            "name":"Spicy Chipotle Jr Cheeseburger",
            "volume":0,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":11
            },
            "date":"2013-11"
         },
         {
            "id":455315,
            "name":"Spicy Chipotle Jr Cheeseburger",
            "volume":13,
            "trend":{
               "years":2013,
               "quarters":4,
               "months":12
            },
            "date":"2013-12"
         }
      ]
   }
]   

Now post that specify the x0 axis on burger names: 现在发布,在汉堡名称上指定x0轴:

//burger names makes the x0 axis
x0.domain(newData.map(function (d) {
    return d.name;
}));

specify the x1 axis on month and year: 在月和年上指定x1轴:

//x1 domain on month and year
x1.domain(dates).rangeRoundBands([0, x0.rangeBand()]);

Then make rectangles for the data set 然后为数据集制作矩形

Finally make the legends on year and month 终于在年份和月份创造传奇

var legend = svg.selectAll(".legend")
    .data(dates.slice().reverse())
    .enter().append("g")
    .attr("class", "legend")
    .attr("transform", function (d, i) {
    return "translate(0," + i * 20 + ")";
});

legend.append("rect")
    .attr("x", width - 18)
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", color);

Full working code is here: http://jsfiddle.net/cyril123/f3gayk2d/12/ . 完整的工作代码在这里: http : //jsfiddle.net/cyril123/f3gayk2d/12/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM