如何在函数之间共享解析的D3.js CSV - 范围问题?

时间:2013-09-16 07:22:26

标签: javascript d3.js scope

我试图从D3中的CSV解析数据 - 解析一次并将数组存储到变量中以供多个函数访问。我在命名空间模块中工作,其中父变量应该使它成为可能,唉,没有运气。这是一个简化的例子:

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();
});

我似乎访问已解析数组的唯一方法是在getData()函数的范围内,但不在外部。我甚至尝试从drawChartA方法中调用getData(),首先,同样的结果。另一篇文章建议将变量存储在Window对象下但是不应该有一种方法来在命名空间模块中处理它们吗?还在了解所有这些......请指教! :)

2 个答案:

答案 0 :(得分: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
    }
}();

这是一个关于非常相似主题的post by Mike Bostock的链接。

答案 1 :(得分: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();
});