D3.js – d3js – TypeError: string is undefined

d3.js

I don't understand this error:

TypeError: string is undefined
function d3_time_parse(date, template, string, j) {
var c, p, i = 0, n = template.length, m = string.length;

Here my code:



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

    var parseDate = d3.time.format("%Y%m%d").parse;

    var x = d3.time.scale()
        .range([0, width]);

    var y = d3.scale.linear()
        .range([height, 0]);

    var color = d3.scale.category10();

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

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

    var line = d3.svg.line()
        .interpolate("basis")
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.index); });

    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.csv("data.csv", function(error, data) {
      color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));

      data.forEach(function(d) {
        d.date = parseDate(d.date);
      });

      var indexes = color.domain().map(function(name) {
        return {
          name: name,
          values: data.map(function(d) {
            return {date: d.date, index: +d[name]};
          })
        };
      });

      x.domain(d3.extent(data, function(d) { return d.date; }));

      y.domain([
        d3.min(indexes, function(c) { return d3.min(c.values, function(v) { return v.index; }); }),
        d3.max(indexes, function(c) { return d3.max(c.values, function(v) { return v.index; }); })
      ]);

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

      svg.append("g")
          .attr("class", "y axis")
          .call(yAxis)
        .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Variation (%)");

      var index = svg.selectAll(".index")
          .data(indexes)
        .enter().append("g")
          .attr("class", "index");

      index.append("path")
          .attr("class", "line")
          .attr("d", function(d) { return line(d.values); })
          .style("stroke", function(d) { return color(d.name); });

      index.append("text")
          .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
          .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.index) + ")"; })
          .attr("x", 3)
          .attr("dy", ".35em")
          .text(function(d) { return d.name; });
    });

and my csv file look like this:

Date,DAX,CAC40,FTSE,NASDAQ,Other
20060407,-0.000712859,-0.009013212,0.010819606,0.009846526,0.003082604
20060413,-0.007765968,-0.024263398,0.011238971,0.004128621,0.005952774
20060421,0.02261859,0.00330204,0.028734861,0.001688981,0.003459211
20060428,0.007170521,-0.007531405,0.010534438,-0.002416181,0.004012361
...

Could someone please help me?
thx
skeut

Best Answer

Date,DAX,CAC40,FTSE,NASDAQ,Other

JavaScript variable names are case sensitive, so when parsing CSV file with headers as above you need to refer to fields with:

d.Date // note the uppercase D
d.DAX // note all uppercase

Here's an example from d3 wiki https://github.com/mbostock/d3/wiki/CSV#wiki-parse

Year,Make,Model,Length

1997,Ford,E350,2.34

2000,Mercury,Cougar,2.38

When parsed with d3's CSV parser, the resulting data will be represented by the following array:

[
  {"Year": "1997", "Make": "Ford", "Model": "E350", "Length": "2.34"},
  {"Year": "2000", "Make": "Mercury", "Model": "Cougar", "Length": "2.38"}
]

Note the uppercase object keys. To access the year of the first entry, a "Year" with an uppercase Y in data[0].Year would be necessary.

Thus in your forEach function you'll need:

data.forEach(function (d) {
    d.Date = parseDate(d.Date);
});

... and later on:

return {date: d.Date, index: +d[name]};
Related Topic