An intro to D3.js

Maarten Lambrechts

PART 2

INEGI

CIMAT

15 October 2021

Course outline

Last week

Webdev 101

D3.js?

A bubble chart with D3, part 1

Today

A bubble chart with D3, part 2

Examples of D3 charts

References for learning D3

These slides

A bubble chart with D3.js, part 2

What we are making

Exercise: scale and fill circles, logarithmic scale

Scale circles with d3.scaleSqrt()

jsbin.com/coxefax/9/edit

Convert X scale to a logarithmic scale with d3.scaleLog()

jsbin.com/coxefax/10/edit

Add a color scale to fill by continent with d3.scaleOrdinal()

jsbin.com/coxefax/11/edit

Sort data

Sort data to show small bubbles on top

No D3, just "vanilla" javascript

data.sort(function(a,b){
  return b.population - a.population;
})

Exercise: sort data

Sort the data (also try to revert the sorting)

jsbin.com/coxefax/14/edit

Plot margins

Add a <g> element

Transform

Adjust scales

d3.axisBottom()

d3.axisLeft()

Exercise: margins convention, x and y axes

Refactor to implement the margins convention

jsbin.com/coxefax/14/edit

Customise axis

Custom tick values

Use ticks to make a grid

const xAxis = d3.axisBottom(xScale)
    .tickValues([500, 1000, 2000, 4000, 8000, 16000, 32000, 64000])
    .tickFormat(d3.format(".1s"))
    .tickSizeInner(-height);

Exercise: grid and text annotation

Add grid with negative inner tick size and css for colors, add tick values for the xAxis

jsbin.com/coxefax/18/edit

Text annotation for the year

jsbin.com/coxefax/19/edit

Tooltips

css for styling

div.tooltip {	
    position: absolute;			
    text-align: center;								
    height: 24px;
    padding: 5px;				
    font: 18px sans-serif;		
    background: white;	
    border: 2px solid black;		
    border-radius: 8px;			
    pointer-events: none;			
}
const tooltip = d3.select("body")
  .append("div")	
  .attr("class", "tooltip")				
  .style("opacity", 0);

Add a div for the tooltip

Hide it by setting its opacity to 0

Tooltips

Add event listeners on the bubbles with .on()

Show the tooltip and set its content on mouseover, hide the tooltip on mouseout

.on("mouseover", (event,d) => {	
  tooltip.style("opacity", 1)	
    .text(d.country)	
    .style("left", (d3.pointer(event)[0] + 10) + "px")		
    .style("top", (d3.pointer(event)[1]+50) + "px");	
   })
.on("mouseout", (d) => {
  tooltip.style("opacity", 0);
});

Exercise: tooltips

Add a div, css and event listeners for the tooltip

jsbin.com/mosudux/4/edit

Exercise: 1960 data

Add data for 1960

jsbin.com/mosudux/6/edit

Toggle

Add event listener to detect changes

d3.selectAll('input').on('change', function() {
      console.log('selection changed to ' + this.value);
    });
<form>
  <input type="radio" name="year" value="1960"> 1960<br>
  <input type="radio" name="year" value="2018" checked> 2018<br>
</form>

Html input elements

Exercise: data toggle

Add radio buttons to toggle the data

jsbin.com/mosudux/8/edit

Transitions

d3.selectAll("circle").transition()
  .duration(1500)
  .attr("cx", (d) => xScale(d.income60))
  .attr("cy", (d) => yScale(d.lifeexp60))
  .attr("r", (d) => rScale(d.population60))
}

Update attributes and use .transition() to animate

Exercise: transition

Add the transitions

jsbin.com/coxefax/27/edit

Exercise: change the year annotation

Change the content of the year annotation when the toggle is clicked

jsbin.com/coxefax/29/edit

D3 in modern web development

Modules and packages

Import and export javascript modules

import { axisLeft, axisRight } from 'd3-axis'
import { scaleLinear, scaleLog, scaleSqrt } from 'd3-scale'

npm

Node package manager

npm install d3-scale d3-axis --save

Bundling

Frontend frameworks

Take control of the DOM, decide what is rendered => d3.select(), d3.selectAll()

Manage state

Boiler plates to get started

<svg width={width} height={height}>
    <g className="bubbles-g">
        {countries.map((d) => {
            return (
                <circle
                  key={"bubble-" + d.Country}
                  cx={xScale(d.coosshare)}
                  cy={yScale(d.bmpshare)}
                  r={sizeScale(d.total)}
                  fill={colorScale(d.Region)}
                  stroke={
                    activeCountry === ""
                      ? highlightcountries.length === 0
                        ? "white"
                        : highlightcountries.includes(d.Country)
                        ? "black"
                        : "white"
                      : d.Country === activeCountry
                      ? "black"
                      : "white"
                  }
                  strokeWidth={...}
                  style={{ cursor: "pointer" }}
                  opacity={...}
                  onMouseOver={() => {//Show tooltip}}
                  onMouseLeave={() => {//Hide tooltip}}
                ></circle>
    </g>
</svg>

React & svg

Examples of D3 charts

References for learning D3

Thanks!