当数据链接到变量时,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);
}
我正在尝试使用从外部 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);
}