具有嵌套json属性的行

时间:2013-11-03 14:56:51

标签: javascript json svg d3.js

我在访问json文件中的属性时遇到问题,无法生成折线图。 json的结构如下:

    [{
    "id" : "AustraliaNewZealand" ,
    "year" : [1990,1992,1994,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010],
    "values":[477790,485825,487296,488885,502585,511718,526594,538967,550556,563572,577171,579126,591635,599216,604267,608954,615853,623685,618961,614920]
}, 
{
    "id":"CentralEurope",
    "year":[1990,1992,1994,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010],
    "values":[1548736,1334452,1313088,1283248,1314709,1360546,1343907,1285511,1237278,1251872,1244069,1233778,1284639,1297510,1317861,1359787,1396681,1361445,1278731,1343044]
}, 
{
    "id":"EasternEurope",
    "year":[1990,1992,1994,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010],
    "values":[4418516,3530464,3287987,2925644,2775181,2672238,2540975,2495036,2513372,2515375,2540796,2544848,2598148,2637682,2622241,2709974,2714204,2740248,2565213,2680226]
}, 
{
    "id":"NorthAmerica",
    "year":[1990,1992,1994,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010],
    "values":[6750754,6821412,6948829,7059001,7166869,7386971,7460485,7509719,7573562,7790060,7675762,7710685,7769154,7896824,7918461,7841686,7966277,7751508,7277713,7493948]
}, 
{
    "id":"WesternEurope",
    "year":[1990,1992,1994,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010],
    "values":[4365949,4290345,4222425,4221029,4264725,4353056,4290057,4310736,4251628,4260565,4306230,4278128,4333237,4337031,4305560,4267515,4209481,4125479,3841580,3924831
]
}]

我想要做的是为每个id生成一个行路径,x的值是年,y是值。除了要求我试图开发的代码(下面)之外,我想问一下这是否是数据的最佳布局,我通常使用简单的csv和tsv,并且不善于管理.json。我自己组装了这个数据集,所以如果有一个更合理的方式来组织它,我会全神贯注。但回到代码中,我尝试做的是行生成器中的以下内容:

var line = d3   .svg.line()
                .interpolate("linear")
                .x(function (d, i) { for (var i = 0; i >= dataset.length; i++) {
                                        return dataset[(i)].year }})        
                .y(function (d, i) { for (var i = 0; i >= dataset.length; i++) {
                    return dataset[(i)].values; }});

然后在路径中我尝试了以下内容:

var path = svg  
                .append("path")
                .attr("class", "line")
                .attr("d", line(dataset))   
                .attr("fill", "none")
                .attr("stroke", "#E37222")
                .attr("stroke-width", 0.5 + "px");

但在控制台中我得到解析路径坐标的问题。因为我对整个.json事物都是新手,我看了一些教程并阅读了一些指南,但是我自己无法解决这个问题。关于如何解决这个问题的任何解释都将非常感谢,谢谢!

1 个答案:

答案 0 :(得分:1)

线生成器背后的想法是,您传递一个值列表,并为每个值生成一个点。因此,它希望其输入是一个元素列表,而不是像您的情况一样。如果您使用D3,则应该使用通常的.data()模式。

所以归结为你要按如下方式定义你的行。

var line = d3.svg.line().x(function(d,i) { return xscale(data[0].year[i]); })
                        .y(function(d) { return yscale(d); });

然后你可以像这样创建路径元素。

svg.selectAll("line").data(data).enter()
   .append("path").attr("d", function(d) { return line(d.values); });

这有点令人讨厌,因为你通过索引得到了一年,但是使用你当前的数据格式就是这样。

完成jsfiddle here。通过为图表上的每个数据点提供一个元素的列表,您可以使这更加漂亮和简单。也就是说,不像当前那样每行有一个元素,而是一个点(对于几行)是一个元素。格式就是这样的。

[{year: 1990, valueAustralia: 1000, valueEurope: 2000}, {year: 1991, ...}]

然后,您可以简单地为不同的行定义不同的线生成器,如下所示。

var line1 = d3.svg.line().x(function(d) { return xscale(d.year); })
                         .y(function(d) { return yscale(d.valueAustralia); }),
    line2 = d3.svg.line().x(function(d) { return xscale(d.year); })
                         .y(function(d) { return yscale(d.valueEurope); });

绘制线条的代码如下:

d3.selectAll("path.australia").data(data).enter()
  .append("path").attr("class", "australia").attr("d", line1);
// etc

当然,您可以使用嵌套元素进行完全数据驱动的设计(即列表中的每个数据点都包含不同区域的值列表),这将消除对多个线生成器的需求,并使您的代码成为更灵活。我确实建议您从使用多个生成器的简单解决方案开始。