I'm new to d3 and using it for creating a simple chart using array of numbers where the value '16' appears twice in it.
It generate the chart with one 'missing' 'rect' element for the 2nd '16' value, when I check the html I see that both '16' rect has same 'y' value of 72.
Please tell me what I'm doing wrong, thanks
code:
var data = [4, 8, 15, 16, 23, 16];
var chart = d3.select("body").append("svg")
.attr("class", "chart")
.attr("width", 420)
.attr("height", 20 * data.length);
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, 420])
var y = d3.scale.ordinal()
.domain(data)
.rangeBands([0, 120]);
chart.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("y", y)
.attr("width", x)
.attr("height", y.rangeBand());
The way you are setting the
y
attribute of the rectangles will utilize the same value for all duplicate elements. You can use some offsetting like so:Also you might have to adjust the height of your overall chart to see all the bands.
The problem with your code is that you are trying to use the values from your
data
array to create range bands on an ordinal scale. Since the same input value will always be mapped to the same output value that means that both inputs16
get mapped to the same range band72
.If you want each input value to be mapped to its own "bar" then you need to use array indices instead of array values.
First you prepare the indices
Then you use them to define the
y
scale domainFinally, instead of using array values as inputs use array indices when mapping to
y
As an added bonus this code will automatically rescale the chart if the amount of data changes or if you decide to change the chart width or height.
Here's a jsFiddle demo: http://jsfiddle.net/q8SBN/1/
Complete code: