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