Reputation: 25
My goal is to display a bar chart on the page using sample data. I would like there to be an x and y axis.
I have followed a tutorial on how to create a D3.JS bar chart, which worked fine until I added x and y axis. I would have expected the bar chart to fit inside the axis however the actual result has the barchart outside of the axis.I'm not getting any error messages in the console.
I have tried repositioning the code so that the bar chart is created both before and after the axis with no joy.
var data = [80, 100, 56, 120, 180, 30, 40, 120, 160];
var svgWidth = 500,
svgHeight = 300,
barPadding = 5;
var barWidth = (svgWidth / data.length);
var svg = d3.select('svg')
.attr("width", svgWidth)
.attr("height", svgHeight);
var barChart = svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("y", function(d) {
return svgHeight - d
})
.attr("height", function(d) {
return d;
})
.attr("width", barWidth - barPadding)
.attr("transform", function(d, i) {
var translate = [barWidth * i, 0];
return "translate(" + translate + ")";
});
var xScale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([0, svgWidth]);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([svgHeight, 0]);
var x_axis = d3.axisBottom().scale(xScale);
var y_axis = d3.axisLeft().scale(yScale);
svg.append("g")
.attr("transform", "translate(50, 10)")
.call(y_axis);
var xAxisTranslate = svgHeight - 20;
svg.append("g")
.attr("transform", "translate(50, " + xAxisTranslate + ")")
.call(x_axis);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="bar-chart"></svg>
Upvotes: 1
Views: 39
Reputation: 4241
I tried to change your code as little as possible.
Check out this example for a really clean approach: https://bl.ocks.org/caravinden/d04238c4c9770020ff6867ee92c7dac1
var data = [80, 100, 56, 120, 180, 30, 40, 120, 160];
var svgWidth = 500,
svgHeight = 300,
barPadding = 10;
const margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};
var svg = d3.select('svg')
.attr("width", svgWidth)
.attr("height", svgHeight);
const width = +svg.attr("width") - margin.left - margin.right;
const height = +svg.attr("height") - margin.top - margin.bottom;
var barWidth = (width / data.length);
var barChartGroup = svg.append('g')
.attr("transform", `translate(${margin.left}, ${margin.top})`)
var xScale = d3.scaleBand()
.domain(data.map((d,i) => i))
.rangeRound([0, width])
.padding(barPadding);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([height, 0]);
var x_axis = d3.axisBottom(xScale);
var y_axis = d3.axisLeft(yScale);
barChartGroup.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("y", function(d) {
return yScale(d);
})
.attr("x", function(d,i) {
return xScale(i) - (barWidth-barPadding)/2;
})
.attr("height", function(d) {
return height - yScale(d);
})
.attr("width", barWidth - barPadding) //xScale.bandwidth()
svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
.call(y_axis);
svg.append("g")
.attr("transform", `translate(${margin.left}, ${height + margin.top})`)
.call(x_axis);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="bar-chart"></svg>
Output:
Example with array of objects:
var data = [
{val: 80, name:"A"},
{val: 100, name:"B"},
{val: 56, name:"C"},
{val: 120, name:"D"},
{val: 180, name:"E"},
{val: 30, name:"F"},
{val: 40, name:"G"},
{val: 120, name:"H"},
{val: 160, name:"I"}
];
var svgWidth = 500,
svgHeight = 300,
barPadding = 10;
const margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
};
var svg = d3.select('svg')
.attr("width", svgWidth)
.attr("height", svgHeight);
const width = +svg.attr("width") - margin.left - margin.right;
const height = +svg.attr("height") - margin.top - margin.bottom;
var barWidth = (width / data.length);
var barChartGroup = svg.append('g')
.attr("transform", `translate(${margin.left}, ${margin.top})`)
var xScale = d3.scaleBand()
.domain(data.map((d,i) => d.name))
.rangeRound([0, width])
.padding(barPadding);
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.val)])
.range([height, 0]);
var x_axis = d3.axisBottom(xScale);
var y_axis = d3.axisLeft(yScale);
barChartGroup.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("y", function(d) {
return yScale(d.val);
})
.attr("x", function(d,i) {
return xScale(d.name) - (barWidth - barPadding)/2; //barWidth - barPadding
})
.attr("height", function(d) {
return height - yScale(d.val);
})
.attr("width", barWidth - barPadding); //xScale.bandwidth()
svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
.call(y_axis);
svg.append("g")
.attr("transform", `translate(${margin.left}, ${height + margin.top})`)
.call(x_axis);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="bar-chart"></svg>
Output:
Upvotes: 1