我遇到这个奇怪的问题,用D3解析数据对象数组中的简单折线图。
当我将数据对象数组硬编码到我的代码中时,图形将呈现正常。但是,当我解析一个JSON文件,创建一个数据对象,并将其推送到一个数组时,它将不会呈现...
两个数组(硬编码与解析)具有完全相同的数据,但只有硬编码才会呈现图形。
硬编码数据......(creates graph)
var lineData = [
{date: new Date("03/04/15"), rain: "2.2"},
{date: new Date("03/05/15"), rain: "2.3"},
{date: new Date("03/06/15"), rain: "0.0"},
{date: new Date("03/07/15"), rain: "2.0"},
{date: new Date("03/08/15"), rain: "5.0"},
{date: new Date("03/09/15"), rain: "2.3"},
{date: new Date("03/10/15"), rain: "15.0"},
{date: new Date("03/11/15"), rain: "0.0"},
{date: new Date("03/12/15"), rain: "7.0"},
{date: new Date("03/13/15"), rain: "0.0"},
{date: new Date("03/14/15"), rain: "1.0"},
{date: new Date("03/15/15"), rain: "0.0"},
{date: new Date("03/16/15"), rain: "2.3"},
{date: new Date("03/17/15"), rain: "8.0"},
{date: new Date("03/18/15"), rain: "1.4"},
{date: new Date("03/19/15"), rain: "0.0"},
{date: new Date("03/20/15"), rain: "1.0"}
];
var vis = d3.select("#visualisation"),
WIDTH = 600,
HEIGHT = 250,
MARGINS = {
top: 20,
right: 20,
bottom: 20,
left: 50
},
xRange = d3.time.scale().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(lineData, function (d) {
return d.date;
}),
d3.max(lineData, function (d) {
return d.date;
})
]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(lineData, function (d) {
return d.rain;
}),
d3.max(lineData, function (d) {
return d.rain * 1.2;
})
]),
xAxis = d3.svg.axis()
.scale(xRange)
.tickSize(5),
yAxis = d3.svg.axis()
.scale(yRange)
.tickSize(5)
.orient("left");
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineFunc = d3.svg.line()
.x(function (d) {
return xRange(d.date);
})
.y(function (d) {
return yRange(d.rain);
})
.interpolate('linear');
vis.append("svg:path")
.attr("d", lineFunc(lineData))
.attr("stroke", "blue")
.attr("stroke-width", .5)
.attr("fill", "none");
解析JSON(live example)...
// global variables
var dailyRainTotal = 0,
lineData = [],
day = {};
// get the data
d3.json("https://api.myjson.com/bins/53grr", function(error, data) {
// log the returned object on console unless error
if (error) return console.error(error);
console.log(data);
var days = data.data.weather;
// step through each day
days.forEach(function(d) {
// step through each hour
d.hourly.forEach(function(h) {
dailyRainTotal = dailyRainTotal + parseFloat(h.precipMM);
});
// add data to day
day = {date: new Date(d.date), rain: dailyRainTotal.toFixed(2)};
// push day to results array
lineData.push(day);
// reset the total
dailyRainTotal = 0;
});
});
var vis = d3.select("#visualisation"),
WIDTH = 600,
HEIGHT = 250,
MARGINS = {
top: 20,
right: 20,
bottom: 20,
left: 50
},
xRange = d3.time.scale().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(lineData, function (d) {
return d.date;
}),
d3.max(lineData, function (d) {
return d.date;
})
]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(lineData, function (d) {
return d.rain;
}),
d3.max(lineData, function (d) {
return d.rain * 1.2;
})
]),
xAxis = d3.svg.axis()
.scale(xRange)
.tickSize(5),
yAxis = d3.svg.axis()
.scale(yRange)
.tickSize(5)
.orient("left");
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineFunc = d3.svg.line()
.x(function (d) {
return xRange(d.date);
})
.y(function (d) {
return yRange(d.rain);
})
.interpolate('linear');
vis.append("svg:path")
.attr("d", lineFunc(lineData))
.attr("stroke", "blue")
.attr("stroke-width", .5)
.attr("fill", "none");
当我检查控制台时,lineData数组具有与硬编码数据相同的格式和值,但x / y轴和线将不会显示。请帮忙!
答案 0 :(得分:2)
d3 json
函数是异步的。因此,创建行的代码将在json数据实际到达之前执行。您需要将行创建代码移动到json
函数:
d3.json("https://api.myjson.com/bins/53grr", function(error, data) {
// log the returned object on console unless error
if (error) return console.error(error);
console.log(data);
var days = data.data.weather;
// step through each day
days.forEach(function(d) {
// step through each hour
d.hourly.forEach(function(h) {
dailyRainTotal = dailyRainTotal + parseFloat(h.precipMM);
});
// add data to day
day = {date: new Date(d.date), rain: dailyRainTotal.toFixed(2)};
// push day to results array
lineData.push(day);
// reset the total
dailyRainTotal = 0;
});
var vis = d3.select("#visualisation"),
WIDTH = 600,
HEIGHT = 250,
MARGINS = {
top: 20,
right: 20,
bottom: 20,
left: 50
},
xRange = d3.time.scale().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(lineData, function (d) {
return d.date;
}),
d3.max(lineData, function (d) {
return d.date;
})
]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(lineData, function (d) {
return d.rain;
}),
d3.max(lineData, function (d) {
return d.rain * 1.2;
})
]),
xAxis = d3.svg.axis()
.scale(xRange)
.tickSize(5),
yAxis = d3.svg.axis()
.scale(yRange)
.tickSize(5)
.orient("left");
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineFunc = d3.svg.line()
.x(function (d) {
return xRange(d.date);
})
.y(function (d) {
return yRange(d.rain);
})
.interpolate('linear');
vis.append("svg:path")
.attr("d", lineFunc(lineData))
.attr("stroke", "blue")
.attr("stroke-width", .5)
.attr("fill", "none");
});