2014-07-10 221 views
0

D3.js中嵌套加载JSON文件的正确方法是什么?这是我试图使用的代码。我遇到的问题是,d.dataset.toString()返回错误无法读取未定义的属性'toString'。D3.js中嵌套的JSON加载

main.json

[ 
    { 
     "name" : "A-Module", 
     "file" : "a.json" 
    }, 
    { 
     "name" : "B-Module", 
     "file" : "b.json" 
    } 
] 

a.json

[ 
    { 
     "owner" : "A-Module", 
     "dataset" : [1,2,3,4,5,6] 
    } 
] 

b.json

[ 
    { 

     "owner" : "B-Module", 
     "dataset" : [7,8,9,10] 
    } 
] 

var width = 500, 
     height = 500, 
     svg; 

    svg = d3.select("body").append("svg").attr("width", width).attr("height",height); 

    d3.json("main.json", function(metrics){ 

     for (var i=0; i<metrics.length; i++){ 
      var path = metrics[i].file; 
      d3.json(path,function(data){ 
       for(var j=0; j<metrics.length;j++){ 
        var owner = data.owner; 
        var metricName = metrics[j].name; 

        if (owner === metricName){ 
         metrics[j].dataset = data.dataset; 
        } 
       } 

      }); 
     } 

     svg.selectAll("g") 
     .data(metrics) 
     .enter() 
     .append("g") 
     .append("text") 
     .text(function(d,i){ 
      return d.dataset.toString(); 
     }); 
    }); 

---更新的非工作考试对于Queue.js,我现在遇到的问题是“owner”未定义。

var width = 500, 
     height = 500, 
     svg; 

    svg = d3.select("body").append("svg").attr("width", width).attr("height",height); 

    d3.json("main.json", function(metrics){ 
     var tasks = [], 
      q = queue(1), 
      path; 
     for (var i=0; i<metrics.length; i++){ 
      path = metrics[i].file; 
      tasks[i] = function(callback) { 
       d3.json(path,function(data){ 
        for(var j=0; j<metrics.length;j++){ 
         var owner = data.owner; 
         var metricName = metrics[j].name; 
         console.log("1",owner,"2", metricName) 
         if (owner === metricName){ 
          metrics[j].dataset = data.dataset; 
          callback(null,data); 
          console.log("THIS SHOULD NEVER PRINT"); 
          break; 
         } 
        } 

       }); 
      }; 
     } 
     tasks.forEach(function(t) { q.defer(t); }); 
     q.awaitAll(function(error, results) { 
      svg.selectAll("g") 
      .data(metrics) 
      .enter() 
      .append("g") 
      .append("text") 
      .text(function(d,i){ 
       return d.dataset.toString(); 
      }); 
     }); 
    }); 
+0

'd3.json'是异步的。 [这个问题](http://stackoverflow.com/questions/16455194/how-to-store-a-json-object-loaded-from-a-file)可能会有所帮助。 –

+0

如果我有一个包含10个不同公司的主JSON文件,它会存储关于这10个公司中每一个公司的名称,地址等信息,我该如何做到这一点?我想创建一个ag元素并用名称和地址填充该g元素。然后,对于每个公司,还存在一个data_companyA.json文件,其中包含我想用来绘制应放入相应公司的g元素中的线图的数据。你可以制定一些伪代码,说明我可以如何做到这一点,因为我完全失去了好几天,它很烂:( – user3748315

+0

那么你需要嵌套的JSON回调或者使用类似[queue](https:// github。 com/mbostock/queue) –

回答

0

所以我终于搞定了。查看下面的代码以查看一个工作示例,并阅读this了解更多详情。

 var width = 500, 
      height = 500, 
      svg; 

     svg = d3.select("body").append("svg").attr("width", width).attr("height",height); 

     d3.json("main.json", function(metrics){ 
      var tasks = [], 
       q = queue(), 
       paths = []; 
      for (var i=0; i<metrics.length; i++){ 
       paths[i] = metrics[i].file; 
      } 
      paths.forEach(function(fileName){ 

       q.defer(function(callback) { 
        d3.json(fileName,function(data){ callback(null, data) }); 
       }); 
      }); 

      q.awaitAll(restOfCode) 

      function restOfCode(err, results){ 
       //Add files into one big file and all the rest of my data bindings 
       for(var j=0; j<results.length;j++){ 
        for(var k=0; k<metrics.length;k++){ 
         var owner = results[j][0].owner ; 
         var metricName = metrics[k].name; 
         if (owner === metricName){ 
          metrics[k].dataset = results[j][0].dataset; 
         } 
        } 
       } 
       svg.selectAll("g") 
       .data(metrics) 
       .enter() 
       .append("g") 
       .append("text") 
       .text(function(d,i){ 
        return d.dataset.toString(); 
       }); 
      } 
     })