Expanding on the concepts of dynamic scaling in D3, in this lesson Ben discusses the use of rangeBands
to horizontally scale your D3 charts.
If you need to have duplicate values in your dataset, you should set your xScale domain to a range from 0 to your dataset length, and use rangeRoundBands instead of rangeBands. When doing that, anywhere you used xScale and passed 'd', you'll need to pass the index instead.
http://stackoverflow.com/questions/17841437/wrong-usage-of-d3-scale-with-same-values-in-data
g.selectAll('rect')
.data(scope.data)
.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', function(d, i) {
return xScale(i);
}).attr('y', function(d) {
return height - yScale(d);
}).attr('width', xScale.rangeBand())
.attr('height', function(d) {
return yScale(d);
}).attr('fill', 'red');
That is a good point. The code shown in the video is just meant to introduce the concept of rangeBands. In a real world scenario it is very unlikely you'd have duplicate values in your dataset (and you almost certainly wouldn't be using plain numbers), so you're unlikely to run into that issue.
What is the best way to achieve the same outcome using the newer version with d3.scaleBand()
(rather than d3.scaleOrdinal()
and .rangeBand()
) ?
this should work just fine:
var xScale = d3.scaleBand() .domain(dataset) .range([0, w]);