Creating circles with D3! To use code like this in various frameworks or vanilla HTML, see d3-rosetta
Full Playlist: Constructing Visualizations
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.
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!
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.
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.
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.
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.
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.