使用D3.js制作简单的图表时,我遇到了这个错误。
var valueline = d3.svg.line()
.x(function(d, i) { return x(i)+2409600; })
.y(function(d) { return y(d); });
如果我对x轴使用序数标度,则在valueline中的x(i)函数返回svg内的有效值,并且正常绘制折线图。但是,如果我使用时间刻度,这些值是有效值 - 240960.如果我这样添加这个数字:
.forEach()
代码正常工作,图表再次正常绘制。为什么我会得到这个奇怪的值以及如何解决它?
答案 0 :(得分:1)
如果您使用时间刻度,则希望您传入日期。这一行:
.x(function(d, i) { return x(i); })
传入数组索引值(即0
,1
,2
...)
为此,您需要将传递给valueline
的数据更改为一个对象数组,每个对象都有一个x日期和一个y值。
这是您的整个代码段重构,具有正确的日期解析:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="3.5.17" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
</head>
<body>
<script>
var data = {
"Elektrotehnički fakultet Osijek": { "2008/09":1539, "2009/10":1678, "2010/11":1873, "2011/12":2231, "2012/13":2192, "2013/14":1841},
"Fakultet elektrotehnike i računarstva Zagreb": { "2008/09":4795, "2009/10":4538, "2010/11":4320, "2011/12":4913, "2012/13":4634, "2013/14":3290},
"Fakultet elektrotehnike strojarstva i brodogradnje Split": { "2008/09":2480, "2009/10":2685, "2010/11":2790, "2011/12":2769, "2012/13":2649, "2013/14":2633}
}
var margin = {top: 50, bottom: 70, left:70, right: 30};
var width = 700 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
var timeFormat2 = d3.time.format('%Y');
// this will end up being an array
// of objects with two properties, date and value
var properData = [];
for (key in data["Elektrotehnički fakultet Osijek"]){
var value = data["Elektrotehnički fakultet Osijek"][key],
date = timeFormat2.parse(key.split("/")[0]);
properData.push({
value: value,
date: date
})
}
var x = d3.time.scale()
.domain(d3.extent(properData, function(d){ return d.date }))
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 5000])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(function(d, i) { return Object.keys(data["Elektrotehnički fakultet Osijek"])[i].replace(/_/g, ' '); });
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
var valueline = d3.svg.line()
.x(function(d, i) { return x(d.date); })
.y(function(d) { return y(d.value); });
var linechart = svg.append("path")
.attr("class", "line")
.attr("d", valueline(properData))
.style("stroke", "blue")
.style("stroke-width", "2")
.style("fill", "none")
</script>
</body>
</html>