score:1

Accepted answer

In a scale, the domain has to be an array. So, this:

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

Should be:

x.domain(data.map(function(d) { return d.date; }));

You can see the difference in these demos. First, your code:

var data = [{date: "Q1 2014", close: 58},
           {date: "Q2 2014", close: 48},
           {date: "Q3 2014", close: 67},
           {date: "Q4 2014", close: 33},
           {date: "Q1 2014", close: 27},
           {date: "Q2 2014", close: 87},
           {date: "Q3 2014", close: 23},
           {date: "Q4 2014", close: 56}];

var scale = d3.scaleOrdinal().domain(data, function(d){
  return d.date;
});
                                     
console.log(scale.domain());
<script src="https://d3js.org/d3.v4.min.js"></script>

Now, using map:

var data = [{date: "Q1 2014", close: 58},
           {date: "Q2 2014", close: 48},
           {date: "Q3 2014", close: 67},
           {date: "Q4 2014", close: 33},
           {date: "Q1 2014", close: 27},
           {date: "Q2 2014", close: 87},
           {date: "Q3 2014", close: 23},
           {date: "Q4 2014", close: 56}];

var scale = d3.scaleOrdinal().domain(data.map(function(d){
  return d.date;
}));
                                     
console.log(scale.domain());
<script src="https://d3js.org/d3.v4.min.js"></script>

EDIT: Since you are making a line chart, you should use a time scale or another scale, but not an ordinal one. The reason is that an ordinal scale expects the same number of values in the range as the number of values in the domain. That being said, you can use a scalePoint:

var x = d3.scalePoint().range([0, width])
    .domain(data.map(function(d) { return d.date; }));

Related Query