Skip to content

Instantly share code, notes, and snippets.

@jashcny
Last active October 14, 2016 15:56
Show Gist options
  • Save jashcny/4b4f1043b6116642f5de to your computer and use it in GitHub Desktop.
Save jashcny/4b4f1043b6116642f5de to your computer and use it in GitHub Desktop.
Week 7: Transition Plot.
<!DOCTYPE html>
<!-- A modified example from Scott Murray's Knight d3 course. -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Scatter Transition</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Raleway:400);
@import url(https://fonts.googleapis.com/css?family=Raleway:400italic|Poiret+One|Ubuntu|Oxygen);
@import url(https://fonts.googleapis.com/css?family=Raleway:400italic|Poiret+One|Ubuntu);
body {
background-color: white;
font-family: Helvetica, Arial, sans-serif;
}
h1 {
font-family: 'Oxygen', sans-serif;
font-size: 28px;
margin-left: 120px;
color: rgb(233, 42, 58);
}
#signal {
font-size: 24px;
margin-left: 200px;
margin-top: 50px;
margin-bottom: -150px;
font-weight: bold;
}
p {
font-family: 'Oxygen', sans-serif;
font-size: 16px;
margin-top: 50px;
margin-left: 50px;
}
svg {
background-color: white;
}
img {
margin-top: 180px;
width: 350px;
height: 470px;
margin-left: 100px;
}
#source{
margin-left: 200px;
}
.dots {
fill: rgb(233, 42, 58);
opacity: 0.5;
}
.highlighted {
fill: rgba(80, 193, 252 , 0.7);
}
.axis path,
.axis line {
fill: none;
stroke: rgb(189,189,189);
stroke-width: 1.5px;
}
.axis text {
font-size: 11px;
font-family: 'Ubuntu', sans-serif;
}
.selected {
background-color:rgba(233, 42, 58,0.5);
}
.linelabel {
font-size: 10px;
stroke-width:0.1px;
}
.mytooltip {
position: absolute;
z-index: 10;
opacity: 1;
}
.mytooltip p {
width: initial;
font-family: "Open Sans", sans-serif;
line-height: 1.4;
color: black;
font-size: 13px;
background-color: rgba(255,255,255,0.8);
border: rgba(230,230,230,1) 1px solid;
padding: 5px 7px 5px 7px;
}
/* this is an adjustment to bootstrap's row for my page */
.row {
padding-top: 50px;
}
/* this is an adjustment to bootstrap for my page */
.btn-group {
padding-top: 20px;
margin-left: 30px;
padding-bottom: 40px;
}
</style>
</head>
<body>
<div class="container">
<h1>Disaggregation for children aged 2-14 who experience any violent discipline</h1>
<p id="source">Source: <a href="http://data.unicef.org/child-protection/violent-discipline.html">UNICEF</a> global databases, 2014, based on DHS, MICS and other nationally representative surveys. </p>
<div class="row">
<div class="col-md-5">
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default" id="phyPsy">Physical & Psychological</button>
<button type="button" class="btn btn-default" id="urban"> Urban & Rural</button>
<button type="button" class="btn btn-default" id="male"> Male & Female</button>
</div>
<div id="svg"></div>
</div>
<div class="col-md-5 col-md-offset-2">
<div class="map_note">
<p id="signal">Stop Violence! </p>
<img src="http://images.wisegeek.com/female-child-with-hand-over-her-mouth.jpg" alt="Stop Violence">
</div>
</div>
</div>
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script type="text/javascript">
var fullwidth = 800;
var fullheight = 610;
var margin = { top: 20, right: 10, bottom: 50, left: 80 };
var width = fullwidth - margin.left - margin.right;
var height = fullheight - margin.top - margin.bottom;
// redo this with an object for the margin settings: var margin = {top...}
var dotRadius = 6; // fix this to a nice value.
// fill in the margin values here. Also, we set domain to 0 to 100 since it's percents,
// plus some padding room!
var xScale = d3.scale.linear()
.range([ 0, width ])
.domain([-2,100]);
// top to bottom, padding just in case
var yScale = d3.scale.linear()
.range([ height, 0 ])
.domain([-2,100]);
// Custom tick count if you want it.
// Create your axes here.
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10); // fix this to a good number of ticks for your scale later.
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var svg = d3.select("#svg")
.append("svg")
.attr("width", fullwidth)
.attr("height", fullheight)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var tooltip = d3.select("body")
.append("div")
.attr("class", "mytooltip");
d3.csv("violence.csv",draw);
function draw(error, data) {
if (error) {
console.log("error reading data");
}
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle");
// Circles in SVG have cx, cy, and r attributes. x location, y location, radius.
circles.attr("cx", function(d) {
return xScale(+d.Physical);
// return the value to use for your x scale here
})
.attr("cy", function(d) {
return yScale(+d.Psychological);
})
.attr("class", function(d){
// highlighting some interesting outliers
if (d.CountryName === "Mongolia" || d.CountryName === "Kazakhstan" || d.CountryName == "Egypt") {
return "highlighted";
}
else {
return "dots";
}
});
// adding a silly intro animation to catch the eye -- using transition:
circles.sort(function(a, b) {
return d3.ascending(+a.Physical, +b.Physical);
})
.transition()
.delay(function(d, i) {
return i * 25;
})
.ease("linear") // milliseconds, so this is 1 second.
.attr("r", dotRadius);
// fix these translates so they use your margin and height width as needed
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" + (margin.left + width / 2) + " ," +
(height + margin.bottom) + ")")
.style("text-anchor", "middle")
.attr("dy", "-5")
.attr("dx","-40")
.attr("font-family","Ubuntu")
.attr("font-size","16px")
.text("Physical Punishment (%)");
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 10 - margin.left)
.attr("x", 20 - (height / 2))
.attr("dy", "1em")
.attr("font-size","16px")
.attr("font-family","Ubuntu")
.style("text-anchor", "middle")
.text("Psychological Aggression (%)");
circles
.on("mouseover", mouseover1)
.on("mousemove", mousemove1)
.on("mouseout", mouseout1);
var buttons = d3.select("body").selectAll("button");
d3.select("button#urban").on("click", function() {
circles
.transition()
.duration(500)
.ease("linear")
.attr("cx", function(d) {
return xScale(+d.Urban);
// return the value to use for your x scale here
})
.attr("cy", function(d) {
return yScale(+d.Rural);
})
var thisButton = d3.select(this);
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
svg.selectAll("text").remove();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" + (margin.left + width / 2) + " ," +
(height + margin.bottom) + ")")
.style("text-anchor", "middle")
.attr("dy", "0")
.attr("dx","-35")
.attr("font-family","Ubuntu")
.attr("font-size","16px")
.text("Urban Area (%)");
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 10 - margin.left)
.attr("x", 20 - (height / 2))
.attr("dy", "1em")
.attr("font-size","16px")
.attr("font-family","Ubuntu")
.style("text-anchor", "middle")
.text("Rural Area (%)");
circles
.on("mouseover", mouseover2)
.on("mousemove", mousemove2)
.on("mouseout", mouseout2);
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
});
d3.select("button#male").on("click", function() {
circles
.transition()
.duration(500)
.ease("linear")
.attr("cx", function(d) {
return xScale(+d.Male);
// return the value to use for your x scale here
})
.attr("cy", function(d) {
return yScale(+d.Female);
})
var thisButton = d3.select(this);
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
svg.selectAll("text").remove();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" + (margin.left + width / 2) + " ," +
(height + margin.bottom) + ")")
.style("text-anchor", "middle")
.attr("dy", "0")
.attr("dx","-35")
.attr("font-family","Ubuntu")
.attr("font-size","16px")
.text("Male (%)");
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 10 - margin.left)
.attr("x", 20 - (height / 2))
.attr("dy", "1em")
.attr("font-size","16px")
.attr("font-family","Ubuntu")
.style("text-anchor", "middle")
.text("Female (%)");
circles
.on("mouseover", mouseover3)
.on("mousemove", mousemove3)
.on("mouseout", mouseout3);
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
});
d3.select("button#phyPsy").on("click", function() {
circles
.transition()
.duration(500)
.ease("linear")
.attr("cx", function(d) {
return xScale(+d.Physical);
// return the value to use for your x scale here
})
.attr("cy", function(d) {
return yScale(+d.Psychological);
})
.attr("id", "change2");
var thisButton = d3.select(this);
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
svg.selectAll("text").remove();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" + (margin.left + width / 2) + " ," +
(height + margin.bottom) + ")")
.style("text-anchor", "middle")
.attr("dy", "-5")
.attr("dx","-40")
.attr("font-family","Ubuntu")
.attr("font-size","16px")
.text("Physical Punishment (%)");
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 10 - margin.left)
.attr("x", 20 - (height / 2))
.attr("dy", "1em")
.attr("font-size","16px")
.attr("font-family","Ubuntu")
.style("text-anchor", "middle")
.text("Psychological Aggression (%)");
circles
.on("mouseover", mouseover4)
.on("mousemove", mousemove4)
.on("mouseout", mouseout4);
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
});
};
function mouseover1(d) {
d3.select(this)
.transition()
.attr("r", 15);
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Country: " +d.CountryName +
"<br>" +"Physical punishment: "+ d.Physical + "%" +
"<br>" + "Psychological aggression: "+ d.Psychological + "%");
}
function mouseout1(d) {
d3.select(this)
.transition()
.attr("r", 5);
tooltip.style("display", "none");
}
function mousemove1(d) {
//console.log("events", window.event, d3.event);
tooltip
.style("top", (d3.event.pageY - 10) + "px" )
.style("left", (d3.event.pageX + 10) + "px");
}
d3.select("button#phyPsy").classed("selected", true);
function mouseover2(d) {
d3.select(this)
.transition()
.attr("r", 15);
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Country: " + d.CountryName +
"<br>" + d.Urban + "% of Urban children has experienced violent discipline."+
"<br>" + d.Rural + "% of Rural children has experienced violent discipline.</p>");
}
function mouseout2(d) {
d3.select(this)
.transition()
.attr("r", 5);
tooltip.style("display", "none");
}
function mousemove2(d) {
//console.log("events", window.event, d3.event);
tooltip
.style("top", (d3.event.pageY - 10) + "px" )
.style("left", (d3.event.pageX + 10) + "px");
}
function mouseover3(d) {
d3.select(this)
.transition()
.attr("r", 15);
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Country: " + d.CountryName +
"<br>" + d.Male + "% of male has experienced violent discipline."+
"<br>" + d.Female + "% of female children has experienced violent discipline.</p>");
}
function mouseout3(d) {
d3.select(this)
.transition()
.attr("r", 5);
tooltip.style("display", "none");
}
function mousemove3(d) {
//console.log("events", window.event, d3.event);
tooltip
.style("top", (d3.event.pageY - 10) + "px" )
.style("left", (d3.event.pageX + 10) + "px");
}
function mouseover4(d) {
d3.select(this)
.transition()
.attr("r", 15);
tooltip
.style("display", null) // this removes the display none setting from it
.html("<p>Country: " +d.CountryName +
"<br>" +"Physical punishment: "+ d.Physical + "%" +
"<br>" + "Psychological aggression: "+ d.Psychological + "%");
}
function mouseout4(d) {
d3.select(this)
.transition()
.attr("r", 5);
tooltip.style("display", "none");
}
function mousemove4(d) {
//console.log("events", window.event, d3.event);
tooltip
.style("top", (d3.event.pageY - 10) + "px" )
.style("left", (d3.event.pageX + 10) + "px");
}
</script>
</body>
</html>
CountryName Physical Psychological Male Female Urban Rural
Afghanistan 69 62 75 74 78 74
Albania 61 71 81 73 70 82
Algeria 75 84 89 87 89 87
Armenia 43 66 72 67 70 70
Azerbaijan 51 74 80 74 76 78
Barbados 56 62 78 72 77 72
Belarus 34 59 67 62 66 62
Belize 57 54 71 70 70 71
Bosnia and Herzegovina 40 42 60 50 54 56
Burkina Faso 58 79 84 82 86 82
Cameroon 78 87 93 93 92 94
Central African Republic 81 84 92 92 92 92
Chad 77 71 85 84 83 85
Congo 69 80 87 86 85 90
Costa Rica 30 31 52 39 47 45
C_te d'Ivoire 73 88 91 91 92 90
Democratic Republic of the Congo 80 82 92 91 94 91
Djibouti 67 57 73 71 73 61
Dominican Republic 45 50 69 65 67 69
Egypt 82 83 92 90 90 92
Gambia 74 81 90 91 89 91
Georgia 50 59 70 63 68 66
Ghana 73 89 94 94 94 94
Guinea-Bissau 74 68 82 81 84 80
Guyana 63 66 79 74 74 77
Haiti 79 64 85 84 85 85
Iraq 63 75 81 77 78 80
Jamaica 68 72 87 82 83 87
Jordan 67 88 91 89 91 88
Kazakhstan 29 43 54 45 49 50
Kyrgyzstan 37 43 58 49 51 55
Lao People's Democratic Republic 44 71 77 74 74 76
Liberia 76 84 90 90 92 89
Mauritania 78 82 87 87 84 89
Mongolia 25 38 48 43 47 44
Montenegro 45 56 64 61 62 64
Morocco 67 89 92 90 90 92
Niger 66 77 82 81 83 82
Nigeria 79 81 91 90 91 91
Republic of Moldova 48 69 77 74 74 77
Saint Lucia 44 60 71 64 77 65
Serbia 37 60 70 64 67 68
Sierra Leone 65 74 81 82 83 81
State of Palestine 76 90 94 92 93 93
Suriname 60 82 87 85 85 88
Swaziland 66 82 90 88 90 89
Syrian Arab Republic 78 84 90 88 88 89
Tajikistan 60 73 80 75 77 78
The former Yugoslav Republic of Macedonia 52 56 71 67 67 72
Togo 77 86 94 93 90 95
Tunisia 74 90 94 92 93 94
Ukraine 30 57 68 55 59 65
Vanuatu 72 77 83 84 83 84
Viet Nam 55 55 76 71 69 76
Yemen 86 92 95 95 95 94
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment