...我正在开展一个打算提供D3折线图的项目,但我的数据模型看起来很糟糕。
图表的轴似乎很好,所以我认为数据模型很好,但是没有线条绘制,并且函数会因错误而停止,这意味着数据不正确。< / p>
(累了,我想去机场......如果有关于我如何在这里处理数据的明显信息,请原谅我......)
以下是显着的代码段:
<svg id="chart_space" width="800" height="400"></svg>
<script>
var ymd = d3.timeParse('%Y-%m-%d');
DrawChart(); // everything in that function
function DrawChart() {
var static_data = {
"currency": "GBP",
"prices": [
{
"date": "2015-02-28",
"marketPrice": 392
},
{
"date": "2015-03-31",
"marketPrice": 394
}
]
};
var priceHistory = static_data['prices'];
var vis = d3.select("#chart_space"),
WIDTH = 800,
HEIGHT = 400,
MARGINS = {
top: 18,
right: 18,
bottom: 18,
left: 35
},
xRange = d3.time.scale().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(priceHistory, function (d) {
var dd = ymd(d.date);
return dd;
}),
d3.max(priceHistory, function (d) {
return ymd(d.date);
})
]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(priceHistory, function (d) {
return d.marketPrice;
}),
d3.max(priceHistory, function (d) {
return d.marketPrice;
})
]),
// the axes on this chart draw okay. I have to think xRange is okay
xAxis = d3.svg.axis()
.scale(xRange)
.tickSize(5)
.tickSubdivide(true),
yAxis = d3.svg.axis()
.scale(yRange)
.tickSize(5)
.orient("left")
.tickSubdivide(true);
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);
// this is where mayhem begins -- we get NaN in the log traces here
var lineFunc = d3.svg.line()
.x(function (d) {
var xd = xRange(d.date);
//console.log('X data to be plotted is: ' + xd); // emits NaN
return xRange(d.date);
})
.y(function (d) {
var yd = yRange(d.date); // (EDIT) okay, this is an error!
//console.log('Y data to be plotted is: ' + yd);
return yRange(d.marketPrice);
})
.interpolate('linear');
vis.append("svg:path")
.attr("d", lineFunc(priceHistory))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
}
</script>
控制台有一个屏幕截图:
我怀疑它与模型中的日期信息有关,但我无法理解为什么数字数据也会显示为NaN。 (编辑:因为代码中注释了错误)
我很确定我做了一些异色的事,但看不出什么,我的视力正在逐渐消失。
想法?
答案 0 :(得分:2)
首先,这不是D3 v3:
var ymd = d3.timeParse('%Y-%m-%d');
应该是:
var ymd = d3.time.format('%Y-%m-%d');
ymd.parse(string);
回到问题:您的代码问题在于您只在计算域时解析日期。数据数组保留字符串。
因此,解决方案是解析数据数组中的日期:
priceHistory.forEach(function(d) {
d.date = ymd.parse(d.date)
});
以下是您更改的代码:
var ymd = d3.time.format('%Y-%m-%d');
DrawChart(); // everything in that function
function DrawChart() {
var static_data = {
"currency": "GBP",
"prices": [{
"date": "2015-02-28",
"marketPrice": 392
},
{
"date": "2015-03-31",
"marketPrice": 394
}
]
};
var priceHistory = static_data['prices'];
priceHistory.forEach(function(d) {
d.date = ymd.parse(d.date)
});
var vis = d3.select("#chart_space"),
WIDTH = 800,
HEIGHT = 400,
MARGINS = {
top: 18,
right: 18,
bottom: 18,
left: 35
},
xRange = d3.time.scale().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(priceHistory, function(d) {
return d.date;
}),
d3.max(priceHistory, function(d) {
return d.date;
})
]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(priceHistory, function(d) {
return d.marketPrice;
}),
d3.max(priceHistory, function(d) {
return d.marketPrice;
})
]),
// the axes on this chart draw okay. I have to think xRange is okay
xAxis = d3.svg.axis()
.scale(xRange)
.tickSize(5)
.tickSubdivide(true),
yAxis = d3.svg.axis()
.scale(yRange)
.tickSize(5)
.orient("left")
.tickSubdivide(true);
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);
// this is where mayhem begins -- we get NaN in the log traces here
var lineFunc = d3.svg.line()
.x(function(d) {
var xd = xRange(d.date);
//console.log('X data to be plotted is: ' + xd); // emits NaN
return xRange(d.date);
})
.y(function(d) {
var yd = yRange(d.date); // (EDIT) okay, this is an error!
//console.log('Y data to be plotted is: ' + yd);
return yRange(d.marketPrice);
})
.interpolate('linear');
vis.append("svg:path")
.attr("d", lineFunc(priceHistory))
.attr("stroke", "blue")
.attr("stroke-width", 2)
.attr("fill", "none");
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<svg id="chart_space" width="800" height="400"></svg>