Intro to D3.js – Chris Uehlinger – Themes



Intro to D3.js – Chris Uehlinger – Themes

0 1


IntroToD3

A 1 hour talk about D3

On Github chrisuehlinger / IntroToD3

Intro to D3.js

Chris Uehlinger

7/18/2015

Themes

Reveal.js comes with a few themes built in: Default - Sky - Beige - Simple - Serif - Night Moon - Solarized

* Theme demos are loaded after the presentation which leads to flicker. In production you should load your theme in the <head> using a <link>.

What is D3?

  • An awesome Data Visualization tool
  • Built by Mike Bostock and the New York Times Graphics Department
  • jQuery with Data selectors
  • A tool for calculating layouts, which can be used to render:
    • HTML elements (<div>'s, <span>'s, <ul>'s, <li>'s)
    • SVG elements (<g>'s, <circle>'s, <rect>'s, <text>'s)
    • Canvas (using the browser's Canvas API)

How can I learn D3?

A Quick Overview

  • SVG
  • Selectors
  • Data Joins
  • Scales
  • Layouts

An SVG Primer

  • SVG stands for Scalable Vector Graphics
  • A text-based image format
  • Can be output by image editors (Adobe Illustrator, Inkskape, Sketch)
  • Can be edited by text editors (Notepad, Sublime Text, Visual Studio)

An SVG Example

SVG is basically HTML with shapes:

D3 Selectors

Similar to jQuery Selectors:

var jQuerySelection = $(".foo #bar div:first-child");

// is equivalent to:
var d3Selection = d3.selectAll(".foo #bar div:first-child");

Many similar abilities:

$(".foo").append("ul");
d3.selectAll(".foo").append("ul");

SVG is free out-of-the-box!

$("svg.myPicture").append("circle");
d3.selectAll("svg.myPicture").append("circle");

Method Chaining

Get used to seeing things like this:

d3.selectAll("svg.my-picture")
  .append("g")
    .attr("class", "circle-group")
  .append("circle")
    .attr("cx", 100)
    .attr("y", 200)
    .attr("r", 50);

To create things like this:

<svg class="my-picture">
  <g class="circle-group">
    <circle cx="100" cy="200" r="50"></circle>
  </g>
</svg>

Got it?

Roll your own chained method:

function foo(){
  return {
    bar:function(n){ 
      return n+1;
    }
  };
};

And then use it like this:

var baz = foo().bar(3);

// -> 4
console.log(baz);

Keeping track of chained methods

Capture chains in variables:

var group = d3.selectAll("svg.foo")
              .append("g")
                .attr("class", "bar");

To build nested stuff:

<svg class="foo">
  <g class="bar"></g>
</svg>
group.append("circle")
    .attr("cx", 100)
    .attr("y", 200)
    .attr("r", 50);
<svg class="foo">
  <g class="bar">
    <circle cx="100" cy="200" r="50">
    </circle>
  </g>
</svg>
group.append("text")
    .text("Hello World");
<svg class="foo">
  <g class="bar">
    <circle cx="100" cy="200" r="50">
    </circle>
    <text>Hello World</text>
  </g>
</svg>

Data Joins

  • Quite possibly the most confusing part of D3
  • Mike Bostock's Thinking With Joins article DataEnterUpdateElementsExit

Data Selectors

Here's some data:

var data = [
  {
    xPos:120,
    yPos:200
  },
  {
    xPos:220,
    yPos:100
  },
  {
    xPos:150,
    yPos:80
  }
];

And here's our markup:

<svg></svg>

Not confusing at all

Let's make a circle for each data point:

svg.selectAll("circle")
    .data(data)
  .enter().append("circle")
    .attr("cx", function(d) { return d.xPos; })
    .attr("cy", function(d) { return d.yPos; })
    .attr("r", 25);

Whoa there...

The Enter Selector

Data

var data = [
  {
    xPos:120,
    yPos:200
  },
  {
    xPos:220,
    yPos:100
  },
  {
    xPos:150,
    yPos:80
  }
];

D3 Code

svg.selectAll("circle")
    .data(data)
  .enter().append("circle")
    .attr("cx", function(d) { return d.xPos; })
    .attr("cy", function(d) { return d.yPos; })
    .attr("r", 25);

Markup

<svg>

</svg>

Enter, Update and Exit

var data = [
  {
    xPos:120,
    yPos:200
  },
  {
    xPos:220,
    yPos:100
  },
  {
    xPos:150,
    yPos:80
  }
];
var circle = svg.selectAll("circle")
    .data(data);
// Enter
circle.enter()
  .append("circle")
    .attr("cx", function(d) { return d.xPos; })
    .attr("cy", function(d) { return d.yPos; })
    .attr("r", 25);
// Update
circle
    .attr("cx", function(d) { return d.xPos; })
    .attr("cy", function(d) { return d.yPos; })
    .attr("r", 25);
// Exit
circle.exit()
    .remove();
<svg>
    <circle cx="120" cy="200" r="25"></circle>
    <circle cx="220" cy="100" r="25"></circle>
    <circle cx="150" cy="80" r="25"></circle>
</svg>

Scales

Scales are functions that map from an input domain to an output range. That's it.

var myScale = d3.scale.linear()
                .domain([0, 100]) // Takes in a number from 1 to 100
                .range([0, 1]);   // Outputs a number between 0 and 1
                
myScale(50)  // -> 0.5
myScale(22)  // -> 0.22
myScale(101) // -> 1.01

Color Scales

D3 handles colors really well out of the box.

var color = d3.scale.linear()
              .domain([0, 100])         // Takes in a number from 1 to 100
              .range(["#000", "#fff"]); // Outputs a color from black to white
                
color(0)    // -> "#000" (black)
color(100)  // -> "#fff" (white)
color(50)   // -> "#808080" (medium gray)

Here's a CodePen that demonstrates color scales.

Other Scales

  • Qualitative Scales for fluid ranges
  • Ordinal Scales for discrete numbers
  • Time Scales for dealing with the complex nature of time

Layouts