Reputation: 345
I just starting out with D3 and need to make a horizontal bar chart using csv file. The data is to compare the pay of men and women in different US states. Each state needs to have two touching bars (one for men's and one for women's pay). The CSV file has the header row State,Women,Men, with each row below having the name of each state and the appropriate data.
Here's what I've done so far.
var margin = { top: 20, right: 10, bottom: 100, left: 40 },
width = 700 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var svg = d3.select('body')
.append('svg')
.attr ({
"width" : width + margin.right + margin.left,
"height" : height + margin.top + margin.bottom
})
.append('g')
.attr("transform", "translate(" + margin.left + ',' + margin.right + ')');
var xScale = d3.scale.ordinal()
.rangeRoundBands([height,0], 0.2, 0.2);
var yScale = d3.scale.linear()
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("left");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("bottom");
d3.csv("state-women-men.csv", function(error, data) {
if(error) console.log("Error, data not loaded");
data.forEach(function(d) {
d.Women = +d.Women;
d.Men = +d.Men;
d.State = d.State;
console.log(d.Men);
console.log(d.Women);
});
xScale.domain(data.map(function(d) { return d.State;}) );
yScale.domain([0, d3.max(data,function (d) { return d.Women; }) ] );
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr ({
"x": function(d) { return xScale(d.State); },
"y": function(d) { return yScale(d.Women); },
"height": xScale.rangeBand(),
"width": function(d) { return (width - xScale(d.State)); }
});
svg.append("g")
.attr("class", "x axis")
//.attr("transform", "translate(0," + height +")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0," + height +")")
.call(yAxis);
});
To start out with, I'm only using the women's data, I'll figure out how to put the men's in later. The bigger problem right now is the formatting; as you can see in the picture, the bars are way to close together and too far to the bottom of the screen and the bars start at the right of screen instead of the left. Can anyone point me to the reasons in my code that cause the graph to look like this, as well as give me advice on adding the second bars, as well as color to the bars? Thanks.
Upvotes: 0
Views: 193
Reputation: 1046
Looks like the main problem is that your rect
attributes are mixed up. Try using the following, you will have much better results:
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr ({
"x": 0,
"y": function(d) { return xScale(d.State); },
"height": xScale.rangeBand(),
"width": function(d) { return (yScale(d.Women)); }
});
Reasoning:
x
value should be fixed at zero so it lines up with the axisy
value should be based off your xScale
and State
property. Kind of confusing since your scale names are flippedwidth
should simply be the x axis (yScale
) using the Women
property.Upvotes: 1