d3

Super easy DOM and data manipulation that combos with SVG and CSS to make easy, scriptable graphics

Easy DOM manipulation, data binding, transitions, and animations

Install from https://d3js.org/

Great examples of whats possible at https://github.com/d3/d3/wiki/Gallery

DOM

select([Selector String])

selectAll([Selector String])

selectAll("h2 span")=> span within h2

Must use d3 commands with return

Modifiers of Selector

  • .text("hot")

  • .html('<strong class="temp">hot</strong>'

  • .append('span') => add to end of element

  • .insert('span', ':first-child') => append with granularity

  • .remove()

  • .style('background', 'red')

  • .classed('label', true) =>turn label on

  • .attr(?) //defined in html

  • .property(?) //property of DOM node

Example

d3.selectAll("tr:nth-child(1) .temp").text("hot")
d3.selectAll("tr:nth-child(1) .temp").append('span').html("F")

Binding Data

Assign data to selector, with callback access and index

1).data(...)

  • generously assigns first data to first selection

  • extra data and extra html will be ignored

  • array or dict

2) use callback ft function(d, i) { return d }

D3.selectAll(".day-high")
    .data([45,78,77,66]) //will assign when possible
    .html(function(d, i) {
        if (i == 0) {
            return d;
        } 
        return '<strong>' + d + '</strong>'
    })

Inside D3 Fts

function(d, i) {
        d //data
    i //index
    d3.event.pageX // event accesss
    d3.select(this) //get this element 
}

Data

Importing

ajax based method for csv, tsv, json, etc

Wont work locally, need server

d3.json('[path]', function(d) {
    let data = [];
    for (let i = 0; i < d.list.length; i++) {
        data.push(d.list[i]);
    }
    //Create graphic
});

Creating HTML from Data

Select things that dont exist ,enter them ,and create your selection

.enter() create sub-selection

.exit() sub-selection

HTML

<tbody> </tbody>

JS

mydata = [{'date': '4/1/19'}, {'date': '4/1/19'}]
d3.select('tbody')
.selectAll('tr')//but there are none
.data(mydata)
.enter().append('tr')//appending after entering creating them
.html(function (d) { return d.date })

Scales

Linear

Can scale values to size of graphics

.scaleLinear, .domain, .range

var yScale = d3.scaleLinear()
    .domain([0, d3.max(bardata)])
    .range([0,height]); //height of graphic

...
    .attr('height', function (d) { return yScale(d)})
//OR
    .attr('height', yScale);

yScale is a ft that maps values from domain to range(normalizes height)

Colors scales

linear extrapolation between two colors

can do multiple color stops by putting multiple values in domain&range

var colors = d3.scaleLinear()
    .domain([0, d3.max(bardata)])
    .range(['#FFB832', '#C61C6F'])

...
    .attr('fill', function(d) { return colors(d) }) //Hey j, Can I just put colors here?

Ordinal Scales

Ordinal needs order

.scaleBand, .domain, .range, .padding OR .paddingInner and .paddingOuter

var xScale = d3.scaleBand()
    .domain(bardata)
    .padding(.2) //add spacing at end and beginning
    .range([0, width])

Guides

  • .axisTop, .axisRight, .axisBottom, .axisLeft

  • tick methods, and group elements

  • this is pretty complex because of padding and margins, see example

  • ticks can be much more complex and date scales are possible

let yAxisValues = d3.scaleLinear()
    .domain([0, d3.max(temps)])
    .range([height, 0]);

let yAxisTicks = d3.axisLeft(yAxisValues)
    .tick(10) //how many elements

let yGuide = d3.select('svg').append('g').call(yAxisTicks);

Events

.on('mouseover', function(d) {
    d3.select(this)
        .style('opacity', .5)
})

.on('mouseout', function(d) {
    d3.select(this)
        .style('opacity', 1)
})

Transitions

Create startup animations and movement or hover effects

Check out CSS transitions for more information

  • .transition()

  • .duration()

  • .ease()

  • .delay()

.on('mouseover', function(d) {
    d3.select(this)
        .transition()
        .delay(400)
        .duration(1000)
        .style('opacity', .5)
})

Other Ideas

Tooltip, by changing absolute position of element on hover and adding transition of opacity

Last updated