(oh my)
Write functions that (re)position elements on your page
var drawCircles = function(data) {
// Select svg
var mySvg = d3.select('#my-svg')
// Bind data to selection of text elements
var circles = mySvg.selectAll('circle').data(data, function(d){return d.id})
// Exit data that might be missing
circles.exit().remove()
// Enter new data elements
circles.enter().append('circle').call(positionCircles)
// Transition all circle elements
mySvg.selectAll('circle').transition().duration(500).call(positionCircles)
}
var positionCircles = function(circ){
circ.attr('cx', function(d){return Math.random()*100})
.attr('cy', function(d,i) {return (d.id)*40})
.attr('r', 15)
.style('fill', function(d){return d.color})
}
Data preparation (high level)
var draw = function() {
prepData()
setScales()
positionElements()
}
Data preparation
var rawDraw = {
{iso3: "ABW", region: "Latin America & Caribbean", ex_1960: 65.56936585, ex_1970: 69.08614634, ex_1980: 72.22014634},
{iso3: "AFG", region: "Sub-Saharan Africa", ex_1960: 31.58004878, ex_1970: 36.65943902, ex_1980: 41.23365854…}
}
settings = {
xVar:'ex_1980',
yVar:'ex_1990'
}
var prepData = function() {
data = rawData.map(function(d) {
var obj = {}
obj.region = d.region
obj.x = d[settings.xVar]
obj.y = d[settings.yVar]
return obj
})
}
var circleFunc = function(circ) {
circ
.attr('cx', function(d) {return xScale(d.x)})
.attr('cy', function(d) {return yScale(d.y)})
.attr('r', settings.radius)
}
Controls consist of HTML elements
<input> tag for buttons
<input id="button1" type="button" value="Button Text!"></input>
<input id="button1" type="button" value="Button Text!" onclick="alert('clicked')"></input>
HTML can also be used to make radios
<div id="sex">
<input type="radio" id="sex1" name="sex"><label for="sex1">Males</label>
<input type="radio" id="sex2" name="sex" checked="checked"><label for="sex2">Females</label>
<input type="radio" id="sex3" name="sex"><label for="sex3">Both</label>
</div>
HTML can also be used to make select menus
<label for="speed">Select a speed</label>
<select name="speed" id="speed">
<option>Slower</option>
<option>Slow</option>
<option selected="selected">Medium</option>
<option>Fast</option>
<option>Faster</option>
</select>
jQuery is a JavaScript library (similar to D3)
d3.select('#my-svg')
$('#my-svg')
$('#my-button').buttonset()
$('#my-button').on('click', function() {
// take actions here
})
Styling is done via jQuery's UI library
Add library > jQuery UI 1.11.1
<script src="lib/external/jquery.js"></script>
<script src="lib/jquery-ui.js"></script>
<link href="jquery-ui.css" rel="stylesheet">
Radio elements
.buttonset()
<div id="sex">
<input type="radio" id="sex1" name="sex"><label for="sex1">Males</label>
<input type="radio" id="sex2" name="sex" checked="checked"><label for="sex2">Females</label>
<input type="radio" id="sex3" name="sex"><label for="sex3">Both</label>
</div>
$('#sex').buttonset()
Select elements
.selectmenu()
<label for="speed">Select a speed</label>
<select name="speed" id="speed">
<option>Slower</option>
<option>Slow</option>
<option selected="selected">Medium</option>
<option>Fast</option>
<option>Faster</option>
</select>
$('#speed').selectmenu()
Event binding dictates the behavior of the page
$('#sex').on('change', callback)
$('#sex').on('click', callback)
$('#sex').on('hover', callback)
Change events
$('#sex').on('change', function() {
// Get value of radio
var sex = $('input[name="sex"]:checked').attr('id')
// Do something about it
settings.sex = sex
draw()
})
$('#yvar').selectmenu({
change:function() {
settings.yVar=$('#yvar').val()
draw()
},
})
Sliders elements
.slider()
<div id="slider">
</div>
$('#slider').slider()
Use the jQuery poshytip library for hovers
$('#map-svg path')
$('#map-svg path').poshytip({arguments})
<script src="lib/external/jquery.js"></script>
<script src="lib/poshytip-1.2/src/jquery.poshytip.js"></script>
<link href="lib/poshytip-1.2/src/tip-twitter/tip-twitter.css" rel="stylesheet">
$('#map-svg path').poshytip({
alignTo: 'cursor', // Align to cursor
followCursor: true, // follow cursor when it moves
showTimeout: 0, // No fade in
hideTimeout: 0, // No fade out
alignX: 'center', // X alignment
alignY: 'inner-bottom', // Y alignment
className: 'tip-ihme', // Class for styling
offsetY: 10, // Offset vertically
slide: false, // No slide animation
content: function(d){
var obj = this.__data__ // Data associated with element
var name = obj.properties.brk_name // Name from properties
var iso3 = obj.properties.adm0_a3 // iso3
mean = data[iso3] == undefined ? '' : data[iso3].mean // Value
return name + ' ' + mean // String to return
}
})
var formatter = d3.format('.2s')
var formatted = formatter (12.234) // returns 12