将d3.selectAll与嵌套的json一起使用

时间:2014-06-05 01:42:47

标签: json backbone.js d3.js nested

在这里,我想为每张专辑创建条形码,其中包含' a_tracks'但我无法进入节点"专辑"。

[
    {
        "blazz" : "HisName",
        "firstname" : "HisFirstname",
        "album" :
            [
                {
                    "a_name" : "titlehere",
                    "a_sells" : 90,
                    "a_years" : 2000,
                    "a_tracks" : 12
                }
                ,
                {
                    "a_name" : "othertitlehere",
                    "a_sells" : 200,
                    "a_years" : 2000,
                    "a_tracks" : 8
                }
            ]
    }
]

我试试这个,但它不起作用:

  d3.json('data.json', function(data){
    var albums = data.map(function(d) { return d.album });

    var canvas = d3.select("body").append('svg')
      .attr("width", 500)
      .attr("height",500)

    canvas.selectAll("rect")
      .data(albums)
      .enter()
        .append("rect")
        .attr('width', function(d){ return d.a_tracks*10;})
        .attr('height',50)
        .attr('y',function(d,i){ return i * 52;})
        .attr('fill','blue')

我做错了吗? (Json被授予我的骨干系列)

1 个答案:

答案 0 :(得分:0)

扩展@LarsKotthoff在评论中所说的内容......

您遇到的问题是原始数据中每个项目的"album"属性包含一个专辑数组,而不是一个代表单个专辑的对象。因此,当您将数据映射到名为albums的变量时,该变量将变为数组数组而不是对象数组。

因此,当您尝试根据d.a_tracks设置元素的宽度时,会抛出错误,因为d是一个数组,因此没有名为a_tracks的财产。实际上,它是一个包含多个对象的数组,每个具有a_tracks属性。

要解决此问题,您可以使用建议的嵌套选择:

canvas.selectAll("g")
  .data(albums)
  .enter().append("g")
    .selectAll("rect")
      .data(f‌​unction(d) { return d; })
      .enter().append("rect")

首先,数据albums绑定到传入的g(组)元素,这反映了此数据中的每个项目代表一组相册而不是单个相册的事实。然后组选择中,创建一个新选择,将每个组中的每个专辑绑定到单个rect元素。