当数据链接到变量时,d3js 不进行绘图

No plotting by d3js when data is linked to a variable

我正在尝试使用从外部 JSON 文件获得的数据绘制最简单的图(任何类型)。我使用 plotly.js,它是 d3js 的扩展。

这是感兴趣的部分:

var dates = [], scores = [];
var user_json = 'https://hacker-news.firebaseio.com/v0/user/anton_tarasenko.json';
var item_json = 'https://hacker-news.firebaseio.com/v0/item/';

$.getJSON(user_json, function (user) {
    $.each(user.submitted, function(i, item_id) {
        $.getJSON(item_json + item_id + '.json', function(item) {
            if (item.type == 'story') {
                scores.push(Number(item.score));
                dates.push(Number(item.time));
            }
        });
    });
});

var data = [{
    x: dates,
    y: scores,
    mode: 'lines+markers',
    type: 'scatter'
}];
Plotly.newPlot('myDiv', data);

这 returns 一个空的情节。但是,当我将 x: dates 替换为 x: [1461189218, 1460844086, ... , 1427738937] 并将 y: scores 替换为 y: [1, 154, ..., 1]console.log(dates)log(scores) 的输出)时,它工作正常。

那么为什么库会忽略对数组的引用?我想我滥用了变量,但不确定如何。

有什么想法吗?

我认为这是一个异步问题。尝试将您的代码放在回调中:

var dates = [], scores = [];
var user_json = 'https://hacker-news.firebaseio.com/v0/user/anton_tarasenko.json';
var item_json = 'https://hacker-news.firebaseio.com/v0/item/';
var ii = 0;
$.getJSON(user_json, function (user) {
  $.each(user.submitted, function(i, item_id) {
    $.getJSON(item_json + item_id + '.json', function(item) {

         ii++;
        if (item.type == 'story') {
            scores.push(Number(item.score));
            dates.push(Number(item.time));
            //check for last iteration
            if(ii === user.submitted.length){
            var data = [{
                x: dates,
                y: scores,
                mode: 'lines+markers',
                type: 'scatter'
                 }];
                Plotly.newPlot('myDiv', data);
            }
        }


     });
  });
});

这不是一个非常优雅的解决方案,但应该可行。

您的问题与异步编程的性质有关。由于 $.getJSON() 是异步的,您的所有后续代码实际上都是在填充分数或日期数组之前执行的。

为了让您的代码按预期工作,您可以采用的方法包括将所有剩余代码移动到回调中(并为每个项目调用 plot)或使用 promises(并使用所有数据调用一次 plot)。使用 jQuery 您可以相对轻松地使用 promise。

var user_json = 'https://hacker-news.firebaseio.com/v0/user/anton_tarasenko.json';
var item_json = 'https://hacker-news.firebaseio.com/v0/item/';

// Main

getUser()
  .then(getScoresAndDates)
  .then(plot);

// Declarations
function all(arrayOfPromises) {
  return jQuery.when.apply(jQuery, arrayOfPromises).then(function() {
    return Array.prototype.slice.call(arguments, 0);
  });
}

function getUser() {
  return $.getJSON(user_json);
};

function getScoresAndDates(user) {

  var scoresAndDates = [];

  $.each(user.submitted, function(i, item_id) {
    scoresAndDates.push($.getJSON(item_json + item_id + '.json'));
  });

  return all(scoresAndDates);
}

function plot(result) {
  scoresAndDates = result
  .map(function(v){
    return v[0];
  })
  .filter(function(v) {
    return v.type == 'story';
  })

  var scores = scoresAndDates.map(function(v) {
    return v.score
  });
  var dates = scoresAndDates.map(function(v) {
    return v.time
  });

  var data = [{
    x: dates,
    y: scores,
    mode: 'lines+markers',
    type: 'scatter'
  }];

  Plotly.newPlot('myDiv', data);
}