9

I'm relatively new to D3, and I can't figure out why something isn't working. I want to draw a line-chart with d3, and this works fine, but I have problems with the axes.

With the following code it goes wrong somewhere and I don't see how to solve...

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

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

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

If d.age is an integer (like 1;2;3 etc.), it works well. But I want strings on the x-axis. Like ("netherlands", "England", "Belgium").

So if d.age is an integer it draws the graph OK, if d.age is a string it doesn't draw anything.

I have also tried instead of linear to use ordinal, but this gave an incorrect chart. (Weird looking lines...).

double-beep
  • 5,031
  • 17
  • 33
  • 41
Vincent Hogendoorn
  • 700
  • 1
  • 7
  • 23

2 Answers2

18

If you want to use categorical values on an axis, you need a categorical (ordinal) scale. Have a look at the documentation. Your code would look something like

var x = d3.scale.ordinal().rangeRoundBands([0, width]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");

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

Note that this uses map to extract the string values -- this may or may not be implemented in your particular browser, see here for more details.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • Thanx for you reaction, I knew I needed an ordinal scale, but this gave such a weird chart.. (looping lines etc). But I used range instead of rangeRoundBands. So this solved the problem, (now I have only a little problem that the points and the xaxis aren't on the same level. (there's some shift visible)). – Vincent Hogendoorn Mar 25 '13 at 08:27
  • I was wondering why use rangeRoundBands instead of rangeBands? Seems like it avoids antialiasing artifacts, but not sure if there was another reason you used it. Thanks. – yoyodunno Oct 20 '16 at 22:19
  • That's the only reason. – Lars Kotthoff Oct 20 '16 at 22:20
5

Use

var x = d3.scale.ordinal().rangePoints([0, width]);

Here is Fiddle Link http://jsfiddle.net/sk2Cf/

gunjan
  • 125
  • 3
  • 11
  • thanks for your reaction. It was already solved with the solution above, but this solution you provided also worked. I'll keep this in mind. – Vincent Hogendoorn Sep 03 '13 at 14:38
  • Thanks! Couldn't imagine a more elegant solution. – ATP Jul 10 '15 at 17:53
  • I just found this question and tried the fiddle, but it has the same problem as I currently have in my code: The x-position of the graph is not the same as the x-position of the x-scale labels. You can see it better if you remove the interpolation. The x-position of the line is where the top-left position of a bar would be if it were a bar chart. – JayTheKay Nov 03 '15 at 19:17