javascript - 在 D3.js 中使用时间刻度时,x(i) 返回错误值

标签 javascript d3.js

使用 D3.js 制作简单图表时,我遇到了此错误。

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 timeFormat2 = d3.time.format('%Y');
function returnArray(){
        var a = [];
        var keys = Object.keys(data["Elektrotehnički fakultet Osijek"]);
        for(var i = 0; i < Object.keys(data["Elektrotehnički fakultet Osijek"]).length; i++){
            a.push(timeFormat2(new Date(keys[i].substring(0, keys[i].indexOf('/')))))
        }
        console.log(a);
        return a;
    }

var x = d3.time.scale()
    .domain(returnArray())
    .range([0, width/5, 2*width/5, 3*width/5, 4*width/5, 5*width/5]);

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(i); })
    .y(function(d) { return y(d); });
var linechart = svg.append("path")
    .attr("class", "line")
    .attr("d", valueline(Object.values(data["Elektrotehnički fakultet Osijek"])))
    .style("stroke", "blue")
    .style("stroke-width", "2")
    .style("fill", "none")

如果我对 x 轴使用序数比例,valueline 中的 x(i) 函数将返回 svg 内的有效值,并且折线图会正常绘制。但如果我使用时间刻度,这些值是有效值 - 240960。如果我像这样添加这个数字:

var valueline = d3.svg.line()
    .x(function(d, i) { return x(i)+2409600; })
    .y(function(d) { return y(d); });

代码有效,图表再次正常绘制。为什么我会得到这个奇怪的值以及如何修复它?

最佳答案

如果您使用时间刻度,它希望您传入日期。这一行:

.x(function(d, i) { return x(i); })

正在传入数组索引值(即012 ...)

为此,您需要将传递给 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>

关于javascript - 在 D3.js 中使用时间刻度时,x(i) 返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42879515/

相关文章:

javascript - D3 条形图条形文本标签不正确可见

javascript - 主干操作方法重复 subview

javascript - 拆分 div 文本,不使用制表符空格

javascript - range.toString() 的奇怪行为

javascript - 使用 jquery 和数组填充 html 列表

javascript - 如何在 d3.js 中有选择地缩放 x 和/或 y - 动态?

javascript - 定位一个复选框并使用 Jquery 删除它

d3.js - D3 map : zoom to group of paths

javascript - 将 d3.nest rollup 应用于嵌套饼图(以改变饼图的大小)

javascript - jQuery:隐藏带有点击事件的菜单