0

I'm trying to get data parsed from CSVs in D3 -- parse once and store the arrays into variable(s) for multiple functions to have access to. I'm working inside a namespace module where the parent vars should make it possible, alas, no luck. Here is a simplified example:

var namespace = namespace || {};

namespace.module = function() {
  var dataItems;                   <== want to be accessible to all functions inside module

  function getData() {
    d3.csv('data.csv', function(d) { 
      dataItems = d; 
    });
  }

  function drawChartA() {
    // want to have access to parsed CSV data here
    console.log(dataItems);         <== "error: undefined"
  }

  return {
    getData:    getData,
    drawChartA: drawChartA
  }
}();

// run code 
$(document).ready(function() {
  namespace.module.getData();
  namespace.module.drawChartA();
});

The only way I seem to have access the parsed arrays is within the scope the getData() function, but not outside. I even tried calling getData() from inside the drawChartA method, first thing, same result. Another post was suggesting to store the vars under the Window object but shouldn't there be a way to handle it all inside the namespace module? Still learning about all that.. please advise! :)

4

2 回答 2

3

一种方法是从 d3.csv 调用内部调用函数,如下所示:

d3.csv('data.csv', function(error, data) {
    drawChartA(data);
}

或者您可以将所有内容包含在您的 drawChartA 函数中,例如:

function drawChartA() {
    d3.csv('data.csv', function(error, data) {
        //Do chart A stuff
    }
}();

这是迈克博斯托克关于一个非常相似主题的帖子的链接。

于 2013-09-16T09:06:20.453 回答
2

d3.csv 的第二个参数是异步回调。它将命中服务器以加载 data.csv 文件。如果您立即调用 drawChartA,您将得到 null,因为请求尚未返回。

您将需要在 getData 函数中进行回调:

function getData(file, callback) {
  d3.csv(file, function(d) { 
    callback(d);
  });
}

然后在回调中调用绘图代码:

namespace.module.getData(function(data) {
  namespace.module.drawChartA();
});

对于多个 CSV 加载:

// files = ['data1.csv', 'data2.csv', 'data3.csv'];
function getAllData(files, callback) {
  var loadedCount = 0;
  for (var i = 0; i < files; i++) {
    getData(files[i], function(data) {
      dataItems = dataItems.concat(data);
      loadedCount++;
      if (loadedCount === files.length) {
        callback(dataItems);
      }
    }
  }
}

你可以像这样使用它:

// display loading wheel
namespace.module.getAllData(['data1.csv', 'data2.csv', 'data3.csv'],
  function(dataItems) {
    // process data
    // hide loading wheel
    namespace.module.drawChartA();
});
于 2013-09-16T17:10:56.043 回答