Reputation: 1147
I'm trying to do a simple bar graph with y-axis having the Band scale and x-axis having a linear scale.
I'm facing the following issues -
I would appretiate any help pointing to the error or missing part. Thanks!
I have attached the code along with a JsFiddle link at the bottom.
function addBarGraph() {
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scaleLinear()
.rangeRound([0, width]);
var y = d3.scaleBand()
.rangeRound([height, 0]).padding(0.1);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var svg = d3.select('#barGraph').append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var max = d3.max(data, function(datum) {
return datum.distribution;
});
svg.append("g")
.attr("class", "xAxis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "yAxis")
.call(yAxis);
data.forEach(function(d) {
d.distribution = +d.distribution;
});
y.domain(data.map(function(d) {
return d.nv;
}));
x.domain([max, 0]);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("y", function(d) {
return y(d.nv);
})
.attr("width", function(d) {
return width - x(d.distribution);
})
.attr("height", y.bandwidth());
}
function getData() {
data = JSON.parse('[{"nv":"Channel1","distribution":60},{"nv":"channel2","distribution":30}]');
}
$(document).ready(function() {
getData();
addBarGraph();
});
.bar {
fill: steelblue;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="barGraph"></span>
Link: https://jsfiddle.net/6esyv0os/
Upvotes: 1
Views: 626
Reputation: 102198
Let's go step by step.
- Unable to get the strings displayed along with the ticks on the Yaxis
That's because you're appending the <g>
elements for the axis before setting the y
domain.
- The domain of X axis is not in sync as per the data
That's because the order in the array is inverted. It should be:
x.domain([0, max]);
- Not sure if the width of the rectangle is correct (might be getting inverted)
Yes, it's inverted. This is the correct function:
.attr("width", function (d) {
return x(d.distribution);
})
- Is it appropriate to use Band scale for the Y axis and not the Ordinal scale ?
A band scale is an ordinal scale. And yes, it's appropriate. Actually, for a bar chart (which is not an histogram), it's properly expected.
Here is your updated fiddle: https://jsfiddle.net/58fo16s9/
Even better than a fiddle, here is a SO snippet:
function addBarGraph() {
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 60
},
width = 500 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scaleLinear()
.rangeRound([0, width]);
var y = d3.scaleBand()
.rangeRound([height, 0]).padding(0.1);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y).ticks();
var svg = d3.select('body').append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var max = d3.max(data, function(datum) {
return datum.distribution;
});
data.forEach(function(d) {
d.distribution = +d.distribution;
});
y.domain(data.map(function(d) {
return d.nv;
}));
x.domain([0, max]);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("fill", "steelblue")
.attr("y", function(d) {
return y(d.nv);
})
.attr("width", function(d) {
return x(d.distribution);
})
.attr("height", y.bandwidth());
svg.append("g")
.attr("class", "xAxis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "yAxis")
.call(yAxis);
}
function getData() {
data = JSON.parse('[{"nv":"Channel1","distribution":60},{"nv":"Channel2","distribution":30}]');
}
getData();
addBarGraph();
<script src="https://d3js.org/d3.v4.min.js"></script>
Upvotes: 2