Scrollytelling

Using scrolling to tell stories

Michael Freeman

Outline

Data binding

Reusable functions

Conceptual approach

Scrolling events

Putting it all together

{data binding}

Exiting, transitioning

Binding

var circles = svg.selectAll('circle').data([1,2,3])

Exiting

circles.exit().remove()

Transitioning

svg.selectAll('circle')
    .transition()
    .duration(500)
    .call(positionFunction)

Generalizing, simplifying

Reusable draw function

var draw = function(data) {
    // Bind self.settings.data
    var circles = svg.selectAll('circle').data(data)
	
    // Enter new elements
    circles.enter().append('circle').call(circleFunc)
	
    // Exit elements that may have left
    circles.exit().remove()
	
    // Transition all circles to new dself.settings.data
    svg.selectAll('circle').transition().duration(1500).call(circleFunc)  
}

Positioning function

var circleFunc = function(circle) {
    circle.attr('r', 15)
          .attr('fill', 'blue')
          .attr('x', function(d) { return xScale(d.x)})
}

Conceptual approach

Write reusable draw function

Write different data/settings for each section

Listen for updates

Changing options

Switch/case is if/else but better

switch(value) {
    case 1:
        data = [{x:1, y:2}, {x:4, y:4}, {x:3, y:1}] 
        break;
    case 2:
        data = [{x:3, y:2}, {x:4, y:4}]
        break;
}

Set-up (HTML)

Create your sections

<div id='graphic'>
    <div id='sections'>
          <section class="step">
	        <div class="title">My title</div>
	         <text>Some text.</text>
	  </section>
    </div>
    <div id="vis"></div>
</div>

Set-up (CSS)

The important parts

#sections {
  position: relative;
  display: inline-block;
  width: 350px;
}

#vis {
  display: inline-block;
  position: fixed;
  top: 60px;
  height: 600px;
  width: 750px;
  border:1px solid gray;
}

Bring in our chart

Easy: build inside the vis div

var svg = d3.select('#vis')
  .append('svg')
  .attr('height', 200)
  .attr('width', 200)

....

draw(data)

Scrolling (finally)

Read in scrolling function (HTML)

<script src="...js/scroller.js"></script>

Create new scrolling element

// setup scroll functionality
var scroll = scroller()
    .container(d3.select('#graphic'));

// pass in .step selection as the steps
scroll(d3.selectAll('.step'));

// Pass in desired update function
scroll.update(update)

Consider settings

An object holding current preferences

var settings = {
    showColor:true, 
    showX:true, 
    showY:true,
}

Remember your circle function?

var circleFunc = function(circle) {
    circle.attr('cx', function(d) {
        return settings.showX == true ? xScale(d.x) : 100
    }
}

{A more robust example}

{an applied example}

Questions?

scrollytelling

By Michael Freeman

scrollytelling

Using scrolling to tell stories

  • 1,283