Creating a Bar Chart with D3: A Step-by-Step Guide

Learn how to create an interactive animated bar chart with D3.js, complete with smooth transitions and hover effects. Enhance your data visualizations by incorporating dynamic animations and displaying values on mouse events.



Learn how to create a dynamic bar chart using D3.js. Follow our step-by-step guide to set up SVG, scales, and axes for visualizing stock data from 2011 to 2016.

Dataset: XYZ.csv


year,value
2011,45
2012,47
2013,52
2014,70
2015,75
2016,78

Our goal is to create a vertical bar chart to visualize XYZ Foods' stock prices from 2011 to 2016.

Step 1: Setting Up SVG and Scales

First, we create the SVG element and define the scales for our bar chart:


<body>
<svg width="600" height="500"></svg>

<script>
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin;

var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);

var g = svg.append("g")
        .attr("transform", "translate(" + 100 + "," + 100 + ")");
</script>
</body>

SVG Setup: We define the SVG's width and height, and add margins.

Scales: We create an xScale using d3.scaleBand() for categorical data (years), and a yScale using d3.scaleLinear() for numerical data (stock prices).

Group Element: We add a group (g) to position our chart within the SVG.

Step 2: Loading Data and Adding Axes

Next, we load the data from the CSV file and add axes to the SVG:


<body>
<svg width="600" height="500"></svg>

<script>
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin;

var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);

var g = svg.append("g")
        .attr("transform", "translate(" + 100 + "," + 100 + ")");

d3.csv("XYZ.csv", function(error, data) {
if (error) {
    throw error;
}

xScale.domain(data.map(function(d) { return d.year; }));
yScale.domain([0, d3.max(data, function(d) { return d.value; })]);

g.append("g")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale))
    .append("text")
    .attr("y", height - 250)
    .attr("x", width - 100)
    .attr("text-anchor", "end")
    .attr("stroke", "black")
    .text("Year");

g.append("g")
    .call(d3.axisLeft(yScale).tickFormat(function(d){
        return "$" + d;
    }).ticks(10))
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", "-5.1em")
    .attr("text-anchor", "end")
    .attr("stroke", "black")
    .text("Stock Price");
});
</script>
</body>

Load Data: We load the CSV data using d3.csv().

Scales Domain: Set the domains for the x and y scales using the data.

Axes: Add x and y axes to the SVG. We format y-axis ticks as currency and add labels for both axes.

Step 3: Adding Bars

Finally, we add the bars to our chart:


<body>
<svg width="600" height="500"></svg>

<script>
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin;

svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 50)
.attr("y", 50)
.attr("font-size", "24px")
.text("XYZ Foods Stock Price");

var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);

var g = svg.append("g")
        .attr("transform", "translate(" + 100 + "," + 100 + ")");

d3.csv("XYZ.csv", function(error, data) {
if (error) {
    throw error;
}

xScale.domain(data.map(function(d) { return d.year; }));
yScale.domain([0, d3.max(data, function(d) { return d.value; })]);

g.append("g")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale))
    .append("text")
    .attr("y", height - 250)
    .attr("x", width - 100)
    .attr("text-anchor", "end")
    .attr("stroke", "black")
    .text("Year");

g.append("g")
    .call(d3.axisLeft(yScale).tickFormat(function(d){
        return "$" + d;
    }).ticks(10))
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", "-5.1em")
    .attr("text-anchor", "end")
    .attr("stroke", "black")
    .text("Stock Price");

g.selectAll(".bar")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return xScale(d.year); })
    .attr("y", function(d) { return yScale(d.value); })
    .attr("width", xScale.bandwidth())
    .attr("height", function(d) { return height - yScale(d.value); });
});
</script>
</body>

Add Bars: We use rectangles (rect) to represent each data point as a bar. The bar's position and size are based on the scales.

Complete Example with Labels

Here's the complete code for the bar chart with titles and axis labels:


<!doctype html>
<html>
<head>
<style>
.bar {
    fill: steelblue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg width="600" height="500"></svg>

<script>
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin;

svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 50)
.attr("y", 50)
.attr("font-size", "24px")
.text("XYZ Foods Stock Price");

var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);

var g = svg.append("g")
        .attr("transform", "translate(" + 100 + "," + 100 + ")");

d3.csv("XYZ.csv", function(error, data) {
if (error) {
    throw error;
}

xScale.domain(data.map(function(d) { return d.year; }));
yScale.domain([0, d3.max(data, function(d) { return d.value; })]);

g.append("g")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(xScale))
    .append("text")
    .attr("y", height - 250)
    .attr("x", width - 100)
    .attr("text-anchor", "end")
    .attr("stroke", "black")
    .text("Year");

g.append("g")
    .call(d3.axisLeft(yScale).tickFormat(function(d){
        return "$" + d;
    }).ticks(10))
    .append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", 6)
    .attr("dy", "-5.1em")
    .attr("text-anchor", "end")
    .attr("stroke", "black")
    .text("Stock Price");

g.selectAll(".bar")
    .data(data)
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return xScale(d.year); })
    .attr("y", function(d) { return yScale(d.value); })
    .attr("width", xScale.bandwidth())
    .attr("height", function(d) { return height - yScale(d.value); });
});
</script>
</body>
</html>

This code creates a bar chart that visualizes stock prices with labeled axes and a title.