---
title: 'D3.js getting started: a first tutorial'
url: https://blog.octoperf.com/d3js-getting-started-a-first-tutorial/
date: '2018-04-12'
authors:
- gpereira
categories:
- Development
tags:
- D3.js
- Open Source
- Data
- Tutorial
description: Learn how to use D3.js to manipulate DOM elements to match evolving data. An animated guide to the enter/update/exit concept.
---

# D3.js getting started: a first tutorial

<link rel="stylesheet" href="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/style.css">
<script src="https://d3js.org/d3.v5.min.js"></script>

**D3.js (Data-Driver Documents)** is an Open-Source JavaScript library for manipulating DOM elements based on data. D3 makes use of the standards SVG, HTML5, and CSS.

It **is good at creating charts, maps, or any other visual representations of data.** D3.js allows great control over the final visual result, at the cost of a steep learning curve.

Some concepts must be understood before using this powerful library. That is the exact purpose of this blog post: **help you to get started with D3 code samples and animated graphics**.


## Installation

Installing D3.js is as simple as including the following script in your HTML page:

```html
<script src="https://d3js.org/d3.v5.min.js"></script>
```

It gives you access to the [`d3`](https://github.com/d3/d3/blob/master/API.md) object globally in your JavaScript code.

Also the source code, various releases (this article uses the version 5.0) and documentations are available on [github.com/d3](https://github.com/d3/d3).

## How to use D3.js selectors

The first and most common concept is Selectors. Similar to the ones of JQuery and AngularJs, it's based on the [W3C selectors API](https://www.w3.org/TR/selectors-api/).

**D3 has two selection methods: `select` to select one DOM element and `selectAll` to select many.**

> D3's functional style allows to chain selects. For example, you can call the following code to select all children _div_ of the element whose id is `container`.
>
> `d3.select("#container").selectAll("div")`

The most simple selectors are:

* `d3.select("tag")` where _tag_ is the DOM element tag name like _body_ or _div_,
* `d3.select("#id")` where _id_ is the id of the element,
* `d3.select(".class")` where _class_ is a CSS class of the element.

But you can do more advanced selections.


### Select simple example

The following sample code _selects_ the `#select-div` element bellow and sets its background color to blue. Click on the _Try it_ button to check it out.

<div id="select-div">
&lt;div id="select-div">
<br/>
&lt;/div>
</div>


<div id="select">
    <div class="apply" style="float:right;">Try it!</div>
</div>


```javascript
d3.select("#select-div").style("background-color", "#039BE5");
```

> D3's functional style also allows to chain updates. For example, you can edit multiple style attributes by using the syntax `d3.select("body").style("key1", "value1").style("key2", "value2")`.


### Select all dynamic properties example


This code sample changes the background color of all DIV elements with the css class `select-all-div`. Instead of a static value, it calls a function to compute a dynamic one:

<div class="select-all-div">
&lt;div class="select-all-div">
Div #1
&lt;/div>
</div>
<div class="select-all-div">
&lt;div class="select-all-div">
Div #2
&lt;/div>
</div>
<div class="select-all-div">
&lt;div class="select-all-div">
Div #3
&lt;/div>
</div>


<div id="select-all">
    <div class="apply" style="float:right;">Try it!</div>
</div>


```javascript
d3.selectAll(".select-all-div")
    .style("background-color", function (d, i) {
        return "hsl(" + Math.random() * 360 + "," + 10 * (i + 1) + "%,50%)";
    });
```

<script src="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/select.js"></script>


The parameters for this function are:

* `d` the data. You can feed data to your selection. Take a look at [the data binding chapter](#how-to-use-data-binding) to know more.
* `i` the index, starting from zero.

The complete code for these samples is available [here](https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/select.js).

## The Enter / Update / Exit concept

### How to use Data binding

**D3.js allows you to bind data to your selections using the `data` function and dynamic values.**

For the following example we want to update `.item` DIVs contained in a parent `.selection` DIV:

```html
<div class="selection">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
</div>
```

We want to set the color of each item using pre-defined values: our data. The syntax is pretty simple:

```javascript
d3.select(".selection")
    .selectAll(".item")
    .data(["#039BE5", "#00897B", "#00ACC1"])
    .style("background-color", function (d) {
        return d;
    });
```

D3 loops over the data values and feeds it to the `style()` update method. The parameter _d_ is the current data value.
Try it by yourself:


<div id="update">
    <div class="data">
        <label class="border-label">Data</label>
        <div class="item" style="background-color: #039BE5">1</div>
        <div class="item" style="background-color: #00897B">2</div>
        <div class="item" style="background-color: #00ACC1">3</div>
    </div>
    <div class="apply">Apply to selection</div>
    <div></div>
    <div class="selection">
        <label class="border-label">Selection</label>
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</div>

<script src="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/update.js"></script>


The complete code for these samples is available [here](https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/update.js).

The selection `d3.select(".selection").selectAll(".item")` contains exactly 3 DIV elements, and our data 3 values. **What happens if we have more data than selected elements?**


### Adding DOM elements to match extra data


Let's find out what happens if we have more data than selected items using a live example (Click on "Apply to selection").

<div id="enter-fail">
    <div class="data">
        <label class="border-label">Data</label>
        <div class="item" style="background-color: #039BE5">1</div>
        <div class="item" style="background-color: #00897B">2</div>
        <div class="item" style="background-color: #00ACC1">3</div>
        <div class="item" style="background-color: #F9A825">4</div>
    </div>
    <div class="apply">Apply to selection</div>
    <div></div>
    <div class="selection">
        <label class="border-label">Selection</label>
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</div>

<script src="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/enter-fail.js"></script>

The answer is that **our extra data is simply ignored**.
To create a new DOM element we must use the `enter()` method that handles data entering the selection.

First let's save our selection and data into a _div_ variable:

```javascript
var div = d3.select(".selection")
    .selectAll(".item")
    .data(data);
```

Then let's **use the `enter()` method followed by `append()` to create a new DIV for each extra data**. Then set its class to _item_ using the `classed()` method and update its `text()`.
Finally we can update every created item background color with `style()`;

```javascript
 div.enter()
    .append("div")
    .classed("item", true)
    .text(function (d, i) {
        return i + 1;
    })
    .transition()
    .duration(500)
    .style("background-color", function (d) {
        return d;
    });
```

Don't forget to also update the existing DIVs background color.

```javascript
div.transition()
    .duration(500)
    .style("background-color", function (d) {
        return d;
    });
```

Try it using the live sample (a new colored div is created this time):

<div id="enter">
    <div class="data">
        <label class="border-label">Data</label>
        <div class="item" style="background-color: #039BE5">1</div>
        <div class="item" style="background-color: #00897B">2</div>
        <div class="item" style="background-color: #00ACC1">3</div>
        <div class="item" style="background-color: #F9A825">4</div>
    </div>
    <div class="apply">Apply to selection</div>
    <div></div>
    <div class="selection">
        <label class="border-label">Selection</label>
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</div>

<script src="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/enter.js"></script>

The complete code for this sample is available [here](https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/enter.js).

> You can also use the `enter()` method without using a temporary variable:
>
>
```javascript
d3.select("#enter")
  .select(".selection")
  .selectAll(".item")
  .data(data)
  .style("background-color", function (d) {
      return d;
  })
  .enter()
  .append("div")
  .classed("item", true)
  .text(function (d, i) {
      return i;
  })
  .style("background-color", function (d) {
      return d;
  });
```
>
> But this approach makes your code a bit more complex and harder to read.
>


What happens if on the contrary, there is less data than selected item?

### Removing DOM elements to match missing data

**Let's find out what happens if we have less data than selected items** using a live example:

<div id="exit-fail">
    <div class="data">
        <label class="border-label">Data</label>
        <div class="item" style="background-color: #039BE5">1</div>
        <div class="item" style="background-color: #00897B">2</div>
    </div>
    <div class="apply">Apply to selection</div>
    <div></div>
    <div class="selection">
        <label class="border-label">Selection</label>
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</div>

<script src="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/exit-fail.js"></script>

This time **the extra selection is ignored**.
To remove extra DOM element we must use the `exit()` method that handles data exiting the selection.

First let's save our selection and data into a _div_ variable:

```javascript
var div = d3.select(".selection")
    .selectAll(".item")
    .data(data);
```

Then let's **use the `exit()` method followed by `remove()` to delete extra DIVs**.

```javascript
div.exit().remove();
```

Once again don't forget to update the existing DIVs background color.

```javascript
div.transition()
    .duration(500)
    .style("background-color", function (d) {
        return d;
    });
```

Try it using the live sample (the last div is removed this time):

<div id="exit">
    <div class="data">
        <label class="border-label">Data</label>
        <div class="item" style="background-color: #039BE5">1</div>
        <div class="item" style="background-color: #00897B">2</div>
    </div>
    <div class="apply">Apply to selection</div>
    <div></div>
    <div class="selection">
        <label class="border-label">Selection</label>
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</div>

<script src="https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/exit.js"></script>

The complete code for this sample is available [here](https://blog.octoperf.com/img/blog/d3-js-getting-started-tutorial/exit.js).

## Conclusion

I hope you found this tutorial interesting and useful. If you need more information about D3.js I can suggest you a few books:

<script type="text/javascript">
amzn_assoc_placement = "adunit0";
amzn_assoc_search_bar = "true";
amzn_assoc_tracking_id = "octoperf-20";
amzn_assoc_search_bar_position = "bottom";
amzn_assoc_ad_mode = "search";
amzn_assoc_ad_type = "smart";
amzn_assoc_marketplace = "amazon";
amzn_assoc_region = "US";
amzn_assoc_title = "";
amzn_assoc_default_search_phrase = "d3.js";
amzn_assoc_default_category = "All";
amzn_assoc_linkid = "f09691502d85b5b73419cad7e5d2dca4";
</script>
<script src="//z-na.amazon-adsystem.com/widgets/onejs?MarketPlace=US"></script>
