未捕获的TypeError:n.getMonth不是d3条形图中的函数

时间:2017-12-11 16:27:17

标签: javascript json date d3.js

我怀疑是日期对象,来自通过d3读取的json文件。

我的代码基于此示例:https://bl.ocks.org/mbostock/1134768

我修改了这个来读取json文件,而不是tsv。该函数应该在json中读取,然后运行一个名为type()的函数,该函数应该从json读取日期字符串并将它们解析为日期对象。

我在jsfiddle

创建了一个示例

我的功能如下:

var dataURL = 'https://api.myjson.com/bins/x9e87';
var timeOfDay = ["Before 03:00","Before 08:00","Before 10:00", "Before 15:00", "Before 17:00","Before 23:59"];
var parseDate = d3.time.format("%d/%m/%Y").parse;

var margin = {top: 20, right: 50, bottom: 30, left: 20},
    width = 500 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal().rangeRoundBands([0, width]);
var y = d3.scale.linear().rangeRound([height, 0]);
var z = d3.scale.category20();

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickFormat(d3.time.format("%b"));

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("right");

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.json(dataURL, function(error, ingestionAmount) {
  if (error) throw error;

  var layers = d3.layout.stack()(timeOfDay.map(function(c) {
    return ingestionAmount.map(function(d) {
      return {x: d.date, y: d[c]};
    });
  }));

  x.domain(layers[0].map(function(d) { return d.x; }));
  y.domain([0, d3.max(layers[layers.length - 1], function(d) { return d.y0 + d.y; })]).nice();

  var layer = svg.selectAll(".layer")
      .data(layers)
      .enter().append("g")
      .attr("class", "layer")
      .style("fill", function(d, i) { return z(i); });

  layer.selectAll("rect")
      .data(function(d) { return d; })
      .enter().append("rect")
      .attr("x", function(d) { return x(d.x); })
      .attr("y", function(d) { return y(d.y + d.y0); })
      .attr("height", function(d) { return y(d.y0) - y(d.y + d.y0); })
      .attr("width", x.rangeBand() - 1);

  svg.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

  svg.append("g")
      .attr("class", "axis axis--y")
      .attr("transform", "translate(" + width + ",0)")
      .call(yAxis);

      type();
});

function type(d) {
  d.date = parseDate(d.date);
  timeOfDay.forEach(function(c) { d[c] = +d[c]; });
  return d;
}

我的json很简单(这里有完整的文件https://api.myjson.com/bins/x9e87

[  
   {  
      "date":"11/11/2017",
      "Before 03:00":31,
      "Before 08:00":5,
      "Before 10:00":44,
      "Before 15:00":18,
      "Before 17:00":98,
      "Before 23:59":12
   },
   {  
      "date":"12/11/2017",
      "Before 03:00":30,
      "Before 08:00":3,
      "Before 10:00":67,
      "Before 15:00":4,
      "Before 17:00":24,
      "Before 23:59":33
   },
{ ///
]

我想也许d3是关于日期格式的,所以我添加了小时,分钟和秒,但这没有任何区别。我还发现this Q/A建议更改d3比例功能。再次这不起作用。我正在以d3应该期望"%d/%m/%Y"的方式解析日期,所以我无法解决问题所在。

1 个答案:

答案 0 :(得分:2)

以下是演示:JS FIDDLE

调用“type”函数的方式不正确。如果您在https://bl.ocks.org/mbostock/1134768调试图表,您将看到数组“crimea”中的每个元素都在type函数中进行了解析和格式化。

既然d3.json没有accessor参数,您可以在type中传递d3.csv(function(<filename>, type, callback){})函数,我们必须手动执行此操作。

相关代码:

解析数组的每个元素:

ingestionAmount.forEach(function(d) {
  type(d);
});

希望这会有所帮助。 :)