Back to articles

Building Interactive Data Visualizations with React and D3.js

AuthorMajd Muhtaseb09/03/202512 minutes
Building Interactive Data Visualizations with React and D3.js

Introduction

React and D3.js are powerful tools for building interactive data visualizations. React provides a declarative approach for managing the user interface, while D3.js offers unparalleled flexibility for manipulating the DOM based on data. Combining them allows for creating highly performant and maintainable visualizations.

Setting Up Your Project

First, create a new React project using Create React App:

npx create-react-app react-d3-visualization
cd react-d3-visualization
npm install d3

Creating a Basic Bar Chart

Let's start with a simple bar chart. Create a new component called BarChart.js:

// BarChart.js
import React, { useRef, useEffect } from 'react';
import * as d3 from 'd3';

const BarChart = ({ data, width = 600, height = 400 }) => {
  const svgRef = useRef();

  useEffect(() => {
    const svg = d3.select(svgRef.current)
      .attr("width", width)
      .attr("height", height);

    const xScale = d3.scaleBand()
      .domain(data.map((d) => d.label))
      .range([0, width])
      .padding(0.1);

    const yScale = d3.scaleLinear()
      .domain([0, d3.max(data, (d) => d.value)])
      .range([height, 0]);

    svg.selectAll(".bar")
      .data(data)
      .enter().append("rect")
      .attr("class", "bar")
      .attr("x", (d) => xScale(d.label))
      .attr("y", (d) => yScale(d.value))
      .attr("width", xScale.bandwidth())
      .attr("height", (d) => height - yScale(d.value))
      .attr("fill", "steelblue");
  }, [data, height, width]);

  return <svg ref={svgRef}></svg>;
};

export default BarChart;

Using the Bar Chart in App.js

Now, import and use the BarChart component in your App.js:

// App.js
import React from 'react';
import BarChart from './BarChart';

const data = [
  { label: "A", value: 10 },
  { label: "B", value: 15 },
  { label: "C", value: 13 },
  { label: "D", value: 20 },
  { label: "E", value: 8 }
];

function App() {
  return (
    <div className="App">
      <h1>Simple Bar Chart</h1>
      <BarChart data={data} />
    </div>
  );
}

export default App;

Adding Interactivity

To make the chart interactive, let's add a tooltip that displays the value of each bar on hover. Modify BarChart.js:

// BarChart.js
import React, { useRef, useEffect } from 'react';
import * as d3 from 'd3';

const BarChart = ({ data, width = 600, height = 400 }) => {
  const svgRef = useRef();

  useEffect(() => {
    const svg = d3.select(svgRef.current)
      .attr("width", width)
      .attr("height", height);

    const xScale = d3.scaleBand()
      .domain(data.map((d) => d.label))
      .range([0, width])
      .padding(0.1);

    const yScale = d3.scaleLinear()
      .domain([0, d3.max(data, (d) => d.value)])
      .range([height, 0]);

    const tooltip = d3.select("body").append("div")
        .attr("class", "tooltip")
        .style("opacity", 0)
        .style("position", "absolute")
        .style("background-color", "white")
        .style("border", "solid")
        .style("border-width", "1px")
        .style("border-radius", "5px")
        .style("padding", "5px");

    svg.selectAll(".bar")
      .data(data)
      .enter().append("rect")
      .attr("class", "bar")
      .attr("x", (d) => xScale(d.label))
      .attr("y", (d) => yScale(d.value))
      .attr("width", xScale.bandwidth())
      .attr("height", (d) => height - yScale(d.value))
      .attr("fill", "steelblue")
      .on("mouseover", (event, d) => {
        tooltip.transition()
          .duration(200)
          .style("opacity", .9);
        tooltip.html("Value: " + d.value)
          .style("left", (event.pageX) + "px")
          .style("top", (event.pageY - 28) + "px");
      })
      .on("mouseout", (event, d) => {
        tooltip.transition()
          .duration(500)
          .style("opacity", 0);
      });

  }, [data, height, width]);

  return <svg ref={svgRef}></svg>;
};

export default BarChart;

Add the following CSS to your App.css file:

/* App.css */
.tooltip {
  font-family: sans-serif;
  font-size: 12px;
}

Conclusion

This example provides a basic introduction to creating data visualizations with React and D3.js. You can expand upon this by adding more complex charts, interactions, and data sources. The combination of React's component-based architecture and D3.js's data manipulation capabilities unlocks powerful possibilities for building dynamic and informative visualizations.