Image
Code

Circles with D3

Curran Kelleher

Last edited Mar 15, 2024
Created on Jan 09, 2024

Creating circles with D3.

Creating Circles with D3

In this tutorial, we will learn how to create circles using D3.js, a powerful JavaScript library for manipulating documents based on data. We will cover various concepts including the D3 General update pattern, method chaining, and more, all in the context of hot reloading for instant visual feedback.

Setting Up the Environment

First, we need to set up our environment with an index.js file where we will write our D3 code. We will also have a package.json file specifying D3 as a dependency.

{
  "dependencies": {
    "d3": "7.8.5"
  },
  "vizhub": {
    "libraries": {
      "d3": {
        "global": "d3",
        "path": "/dist/d3.min.js"
      }
    }
  }
}

This is the format of package.json, which includes some VizHub-specific configuration to tell VizHub how to pull in the library from a CDN (Content Distribution Network) and which browser global to look for. Besides the vizhub field, this package.json format is compatible with NPM, so you can export the code and run it locally. To lean more on running the code locally, see vite-export-template.

import { select } from 'd3';

Once package.json is there, we can import things from D3!

Selecting DOM Elements with D3

We start by importing the select function from D3, which allows us to select DOM elements. We will use this to create an SVG element within our container.

export const main = (container) => {
  const svg = select(container)
    .selectAll('svg')
    .data([null])
    .join('svg');
};

This pattern allows the code to run multiple times without creating multiple SVG elements.

Setting the Dimensions of the SVG Element

To set the dimensions of our SVG element, we use the attr method. We will set the width and height based on the container's dimensions.

const width = container.clientWidth;
const height = container.clientHeight;

svg
  .attr('width', width)
  .attr('height', height)
  .style('background', '#F0FFF4');

We can use container.clientWidth and container.clientHeight to measure the container DOM element at page load time. This works because of an assumption that the parent DOM element has a defined width and height.

Defining the Data for Our Circles

Next, we define the data that will drive our circles. Each object in our data array represents a circle with its coordinates (x, y), radius (r), and fill color.

const data = [
  { x: 155, y: 386, r: 20, fill: '#0000FF' },
  { x: 340, y: 238, r: 52, fill: '#FF0AAE' },
  // Add more circle data here...
];

This is a "data-driven approach", where we decouple the data from the rendering logic responsible for transforming it on the screen. This is a stepping stone towards loading in data from CSV or JSON files.

Drawing Circles with D3

We use D3's data join pattern to bind our data to the circles we will create. For each data object, we set the circle's attributes (center coordinates, radius, and fill color).

svg
  .selectAll('circle')
  .data(data)
  .join('circle')
  .attr('cx', (d) => d.x)
  .attr('cy', (d) => d.y)
  .attr('r', (d) => d.r)
  .attr('fill', (d) => d.fill)
  .attr('opacity', 0.708); // Optional: Set opacity for overlap effect

This is a typical example of D3's "method chaining" API, wherein the selection is returned from the .attr method, which defines values for an attribute of the DOM elements.

Conclusion

Now you have a basic understanding of how to create and manipulate circles with D3.js. You can experiment with different data and styles to create your own visualizations. Happy coding!

Feel free to modify or add more sections to the article as needed.

Challenge

  • Fork this example
  • Modify it
  • Maybe make it Halloween themed
  • Maybe make it Christmas themed
  • Be creative and have fun!
MIT Licensed