Tutorials, Data Visualization, freeCodeCamp 7 min read
1 view
This article explores my journey from hearing about data to learning traditional data visualization tools and how I applied them using D3.js. Also this article is written in somewhat of a technical style. I publish this article on my blog first and then to any other platform such as dev.to or LinkedIn.
In 2017, at the MARTA hackathon, I first heard that data had become more valuable than oil. At the time, I had no clue what to do with this knowledge, but it stuck with me. Fast forward to the last 18 months, and I’ve come to understand that numbers and data tell compelling stories—I just needed to learn the right tools to unlock them.
I learned to use Microsoft Excel at an intermediate level over the years, often being the “tech person” in various spaces. Excel has long been a powerhouse for displaying data in all shapes, types, and forms—from simple tables to complex pivots and charts. Excel makes data accessible for millions, but it is proprietary software. While there are alternatives, we may run into limitations when we need to continuously use these tools for data storytelling.
Here’s my thought process in championing data visualization tools as a software developer in the web development space. P.S: I gained greater insight after completing the freeCodeCamp data visualization course and earning the certificate.
While Excel excels at static and semi-dynamic visualizations, it can be limiting when:
This is where D3.js comes into play.

D3.js (Data-Driven Documents) is a powerful JavaScript library that enables developers to create dynamic, interactive data visualizations directly in web browsers. Unlike Excel, D3.js manipulates the Document Object Model (DOM) based on data, giving developers total control over how everything is displayed.
Other programming languages and frameworks like Matplotlib, JavaFX, and Seaborn serve similar purposes in their respective ecosystems.
D3.js shines in several key areas:
Understanding these core concepts is essential for working effectively with D3.js:
Typical applications include web-based business dashboards, advanced scientific visualizations, and interactive infographics.
d3.select, d3.selectAll)Purpose: Select DOM elements to read or modify them.
d3.select() picks the first element matching a selector, while d3.selectAll() grabs every matching element.
d3.select("p"); // Select first <p> element
d3.selectAll(".bar"); // Select all elements with class 'bar'
.data(), Data Join)Purpose: Attach arrays of data to groups of DOM elements. This is the core of D3’s “data-driven” philosophy.
The .data() method binds each datum to an element, while the .join(), .enter(), and .exit() workflow manages the creation and removal of elements when the number of elements and data points don’t match.
d3.selectAll("p")
.data([1, 2, 3])
.text(d => d);
// Attach each number to a <p> and update its text
.append(), .remove())Purpose: Dynamically build visualizations in the DOM—especially SVG elements for graphics.
.append() creates a new child element, .remove() deletes selected elements.
d3.select("svg").append("rect");
d3.select("rect.bar").remove();
.attr(), .style())Purpose: Change SVG or DOM element properties (position, size, color, visibility, etc.).
.attr() is for HTML/SVG attributes, .style() for CSS properties.
d3.select("rect")
.attr("width", 100)
.style("fill", "red");
.transition())Purpose: Animate changes for a smoother and more dynamic user experience.
Use .transition() to change values (position, color) over time—useful for emphasizing changes or animating data updates.
d3.select("rect")
.transition()
.duration(1000)
.style("fill", "blue");
Purpose: Map data values to pixel or color space using d3.scaleLinear, d3.scaleBand, d3.scaleTime, and more.
Axes visually represent scales, aiding interpretation through d3.axisBottom(scale), d3.axisLeft(scale), etc.
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, 400]);
const axis = d3.axisBottom(scale);
svg.append("g").call(axis);
.on())Purpose: Allow charts and graphics to respond to user input, like clicks or mouse movements.
The .on() method attaches event listeners to interactive elements, useful for tooltips, filtering, highlighting, zoom, and more.
d3.selectAll("rect.bar")
.on("mouseover", function(event, d) {
// Display tooltip or change style
});
SVG is used almost exclusively for scalable, flexible graphics in D3. SVG supports basic shapes, groupings, and interactivity.
Canvas is less common for D3 but is used for very large or complex real-time datasets that require performance over interactivity.
A standard practice to structure graphics so axes, labels, and legends don’t overlap the chart area. Define margin, then calculate the width and height of the main chart.
const margin = {top: 20, right: 30, bottom: 50, left: 60};
const width = 500 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
Domain specifies the input dataset’s minimum and maximum values; Range specifies where those numbers should be mapped (pixels, colors).
const scale = d3.scaleLinear()
.domain([minDataValue, maxDataValue])
.range([0, chartWidth]);
Primary visual element for bar and column charts; each rect is mapped to one data item.
svg.selectAll("rect")
.data(data)
.join("rect")
.attr("x", d => xScale(d.name))
.attr("y", d => yScale(d.value))
.attr("width", xScale.bandwidth())
.attr("height", d => chartHeight - yScale(d.value));
Used for scatter plots and bubble charts to represent data distribution and relationships.
svg.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", d => xScale(d.x))
.attr("cy", d => yScale(d.y))
.attr("r", d => rScale(d.size));
Used in line charts, area charts, and for complex shapes by connecting points or tracing geospatial data.
const lineGenerator = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y));
svg.append("path")
.attr("d", lineGenerator(data));

D3.js is built on JavaScript. To unlock its full potential, you need to understand:
A solid JavaScript foundation makes learning and troubleshooting D3.js significantly easier. Understanding these fundamentals will accelerate your D3.js journey.

Some of my favorite D3.js applications include:

Based on my experience, here’s what works:

These resources cover everything from the basics to advanced techniques for creating data-driven visualizations.

To accelerate your D3.js mastery:

Ready to move beyond static charts? Dive into D3.js with a hands-on project. Pick a dataset that interests you, start with something simple, and let your creativity bring the numbers to life. Let data tell its story with interactivity and impact—you might be surprised by the opportunities it creates.
The transition from Excel to D3.js isn’t just about learning a new tool; it’s about embracing a new way of thinking about data visualization that’s interactive, web-native, and infinitely customizable.