My data looks like this…
var data = [{name:'a', value : 97},
{name:'b', value : 24},
{name:'c', value : 10}];
I have an ordinal scale created like this…
var y = d3.scale.ordinal().rangeBands([0, 30 * data.length]);
and I am using it to create a basic graph like this…
chart.selectAll("rect")
.data(data)
.enter().append("svg:rect")
.attr("y", function(d,i){ return y(d.name);})
.attr("width", function(d,i){ return x(d.value);})
.attr("height", y.rangeBand());
According to the d3 docs (here) you dont HAVE to specify a domain for an ordinal scale, and it will get populated as you try to use it. In my situation however y(d.name) always returns 0 and y.rangeBand() raises an exception, even though when I look the domain array has been populated inside the scale object.
So, I have worked around this by pre-defining my domain…
.domain(data.map(function (d){ return d.name;}))
but I would like to be able to dynamically add to this domain and right now if I do, it doesn’t expand beyond the original values set on creation. Is this even possible?
I’m very new to d3, so I may be missing something important here.
With rangeBands and rangePoints, you must define a domain in order to access the range. The domain tells the ordinal scale how many bands or points you want to display. However, you can change the domain later (by calling
scale.domain(newDomain)) and the range will update. You just can’t do that implicitly by passing a previously-unseen value to the scale. It’s generally a good idea to define domains with ordinal scales anyway, so that you always get deterministic behavior.