D3.js 中的异步回调

Asynchronous callback in D3.js

我正在使用 D3 进行可视化,我仍在学习过程中(包括 JS),我想从 maxExportYearsmaxImportYears 中删除重复的代码。

function calcMaximum(json) {

   let maxExportYears = json.map(function (obj) {
      let maxByYear = [];
      obj.entries.map( function(entry) {
          maxByYear.push(parseFloat(entry.exported));
      });
      return d3.max(maxByYear, function(d) { return d; });
   });

  /// calculate the maximum Export across all years
  let maxExport = d3.max(maxExportYears, function(d) {return d;} );

  /// calculate the maximum Import on each year
  let maxImportYears = json.map(function (obj) {
      let maxByYear = [];
      obj.entries.map( function(entry) {
          maxByYear.push(parseFloat(entry.imported));
      });
      return d3.max(maxByYear, function(d) { return d; });
  });

  /// calculate the maximum Import across all years
  let maxImport = d3.max(maxImportYears, function(d) {return d;} );


  /// calculate the maximum between maxExport and maxImport
  let maximum = d3.max([maxExport, maxImport], function(d) {return d;});
  return maximum;
}

 d3.json('/file_name.json', function(error, json) {
    if (error) throw error;
    let data = json;

    let maximum =  calcMaximum(data);
    let scaleRadius = d3.scaleSqrt().domain([0, maximum]).range([0,150]); 
}

我创建了以下函数来替换重复的代码:

function calculateMaxByYear(json, activity) {
  json.map(function (obj) {
    let maxByYear = [];
      obj.entries.map( function(entry) {
        maxByYear.push(parseFloat(entry[activity]));
      })
      let maximus = d3.max(maxByYear, function(d) { return d; });
    return maximus;
  })
};

在同步方式下可能会被称为calculateMaxByYear(json, 'imported');calculateMaxByYear(json, 'exported');,但我不知道如何在异步方式下使用它。

非常欢迎任何关于如何解决这个问题的想法!

非常感谢!

要么你觉得问题比实际情况复杂,要么我误解了问题。

首先,您需要将函数固定为 return .map 操作的结果:

function calculateMaxByYear(json, activity) {
    return json.map(...);
//  ^^^^^^
}

然后您只需将现有代码替换为调用此函数即可:

function calcMaximum(json) {

  let maxExportYears = calculateMaxByYear(json, 'exported');
  // call function     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  let maxExport = d3.max(maxExportYears, function(d) {return d;} );
  let maxImportYears = calculateMaxByYear(json, 'imported');
  // call function     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  let maxImport = d3.max(maxImportYears, function(d) {return d;} );
  let maximum = d3.max([maxExport, maxImport], function(d) {return d;});

  return maximum;
}

不过整体可以简化为

function calcMaximum(json) {
  return d3.max(
    calculateMaxByYear(json, 'exported')
      .concat(calculateMaxByYear(json, 'imported'))
  );
}

不需要所有这些中间值,也不需要将回调传递给 d3.max。识别函数基本上是默认回调。


正如我在评论中所说,d3.json 是异步的这一事实对 calculateMaxByYear 的调用方式没有影响。