This scatterplot is a representation of the change in number of crimes in SanFrancisco over the years. It seems that if we check the correlation in number of crimes between two different crime categories, and then swipe throught the years we can observe weather the SFPD is doing a good job or not by checking how closer the points in the scatterplot come to the beginning of the axes(0,0). The size of the points relate to the total number of crimes in 2003 and 2015 respectively.
Last active
March 26, 2017 17:55
-
-
Save oikonang/c645e2aa3a4fe313269afc1c39c8a05d to your computer and use it in GitHub Desktop.
Scatterplot with a toggle button using D3.v4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
licence: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Scatterplot with a toggle button</title> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"> | |
<!-- <link rel="stylesheet" type="text/css" href="styles/barplot.css"> --> | |
<style rel="stylesheet" type="text/css"> | |
#scatterplot { | |
padding: 10px; | |
} | |
#scatterplot div#area1{ | |
display: block; | |
} | |
#scatterplot .axis path, | |
#scatterplot .axis line { | |
fill: none; | |
stroke: black; | |
shape-rendering: crispEdges; | |
} | |
#scatterplot text { | |
font-size: 12px; | |
fill: #212121; | |
font-weight: bold; | |
} | |
.axisLabel { | |
fill: #000 !important; | |
} | |
#scatterplot circle { | |
stroke: #991f00; | |
stroke-width: 2px; | |
fill: #E64A19; | |
} | |
#scatterplot .axis text { | |
fill: #000; | |
font-size: 11px; | |
} | |
#scatterplot .title { | |
font-size: 20px; | |
} | |
#scatterplot svg { | |
padding-left: 100px; | |
padding-bottom: 30px; | |
padding-top: 20px; | |
} | |
#scatterplot button { | |
background-color:#f2f2f2; | |
text-align:center; | |
border-radius: 5px; | |
font-size: 20px; | |
font-weight: bold; | |
} | |
#scatterplot button:hover { | |
background-color: #b3b3b3; | |
} | |
</style> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | |
</head> | |
<body> | |
<div id="scatterplot"> | |
<p> | |
Click to toggle between <b>2003</b> to <b>2015</b> data: <button>Change Year</button> | |
</p> | |
<div id="scatterSvg"> | |
</div> | |
</div> | |
<script type="text/javascript" src="js/d3-tip.js"></script> | |
<script type="text/javascript"> | |
//JS Object used to switch between 2003 and 2015 data using a simple button | |
function yearSwitcherConstructor(year) { | |
this.currentYear = year; | |
this.prostitutionAttr = "count_pros_"+year; | |
this.vehicleAttr = "count_veh_"+year; | |
this.totalAttr = "count_tot_"+year; | |
} | |
//Load default 2003 data | |
currentYear = 2003; | |
var yearSwitcher = new yearSwitcherConstructor(currentYear); | |
console.log(yearSwitcher); | |
function loadScatterplot() { | |
//Load total data from csv | |
d3.csv("total.csv", function(data) { | |
dataset = data; | |
//Width and height | |
var w = 1000; | |
var h = 450; | |
var padding = 30; | |
//Create scaled x | |
var xScale = d3.scaleLinear() | |
.domain([0, d3.max(dataset, function(d) { return +d[yearSwitcher.prostitutionAttr];})]) // from 0 to maximum value of input(x) | |
.range([padding, w - padding * 2]); //from padding to the number of pixels declared in width - pad in order to avoid the edges | |
//Create scaled y | |
var yScale = d3.scaleLinear() | |
.domain([0, d3.max(dataset, function(d) { return +d[yearSwitcher.vehicleAttr]; })]) // from 0 to maximum value of input(y) | |
.range([h - padding, padding]); //from height - padding to the number of pixels declared in pad in order to avoid the edges and turn y upside down | |
//Create scaled r(radius) of the scatter points | |
var rScale = d3.scaleLinear() | |
.domain([0, d3.max(dataset, function(d) { return +d[yearSwitcher.totalAttr]; })]) // from 0 to maximum value of input(y) | |
.range([2, 30]); // Size of points | |
//Define X axis | |
var xAxis = d3.axisBottom() | |
.scale(xScale) | |
.ticks(5); | |
//Define Y axis | |
var yAxis = d3.axisLeft() | |
.scale(yScale) | |
.ticks(5); | |
//Create SVG element | |
var svg = d3.select("#scatterSvg") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
//Define clipping path | |
svg.append("clipPath") //Make a new clipPath | |
.attr("id", "chart-area") //Assign an ID | |
.append("rect") //Within the clipPath, create a new rect | |
.attr("x", padding) | |
.attr("y", padding) | |
.attr("width", w - padding * 3) | |
.attr("height", h - padding *2); | |
//Create circles | |
svg.append("g") | |
.attr("id", "circles") | |
.attr("clip-path", "url(#chart-area)") | |
.selectAll("circle") | |
.data(dataset) | |
.enter() | |
.append("circle") | |
.attr("cx", function(d) { | |
return xScale(+d[yearSwitcher.prostitutionAttr]); | |
}) | |
.attr("cy", function(d) { | |
return yScale(+d[yearSwitcher.vehicleAttr]); | |
}) | |
.attr("r", function(d) { | |
return rScale(+d[yearSwitcher.totalAttr]); | |
}); | |
//Create labels | |
svg.selectAll("text") | |
.data(dataset) | |
.enter() | |
.append("text") | |
.text(function(d) { | |
return d.PdDistrict; | |
}) | |
.attr("x", function(d) { | |
return xScale(+d[yearSwitcher.prostitutionAttr]); | |
}) | |
.attr("y", function(d) { | |
return yScale(+d[yearSwitcher.vehicleAttr]); | |
}); | |
//Create X axis | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + (h - padding) + ")") | |
.call(xAxis); | |
// Text label for the X axis | |
svg.append("text") | |
.attr("transform","translate(" + w/2 + ", " + (h+10) + ")") | |
.style("text-anchor", "middle") | |
.text("PROSTITUTION") | |
.classed("axisLabel",true); | |
//Create Y axis | |
svg.append("g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + padding + ",0)") | |
.call(yAxis); | |
// Text label for the Y axis | |
svg.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 0 - padding) | |
.attr("x",0 - (h / 2)) | |
.attr("dy", "1em") | |
.style("text-anchor", "middle") | |
.text("VEHICLE THEFT") | |
.classed("axisLabel",true); | |
// Text for the title of the plot | |
svg.append("text") | |
.attr("transform","translate(" + w/2 + ",0)") | |
.style("text-anchor","middle") | |
.text("Correlation of San Francisco crimes in "+currentYear) | |
.classed("title",true); | |
//////////////////////////////////////On click update with new data//////////////////////////////////// | |
d3.select("#scatterplot button").on("click", function(){ | |
if (currentYear==2003) | |
currentYear = 2015; | |
else | |
currentYear = 2003; | |
yearSwitcher = new yearSwitcherConstructor(currentYear); | |
//Update all circles | |
svg.selectAll("circle") | |
.data(dataset) | |
.transition() | |
.duration(1000) | |
.attr("cx", function(d) { | |
return xScale(+d[yearSwitcher.prostitutionAttr]); | |
}) | |
.attr("cy", function(d) { | |
return yScale(+d[yearSwitcher.vehicleAttr]); | |
}) | |
.attr("r", function(d) { | |
return rScale(+d[yearSwitcher.totalAttr]); | |
}); | |
//Update label's position | |
svg.selectAll("text") | |
.data(dataset) | |
.transition() | |
.duration(1000) | |
.attr("x", function(d) { | |
return xScale(+d[yearSwitcher.prostitutionAttr]); | |
}) | |
.attr("y", function(d) { | |
return yScale(+d[yearSwitcher.vehicleAttr]); | |
}); | |
//Update title | |
svg.selectAll(".title") | |
.text("Correlation of San Francisco crimes in "+currentYear); | |
}); | |
}); | |
} | |
loadScatterplot(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PdDistrict | count_veh_2003 | count_pros_2003 | count_tot_2003 | count_veh_2015 | count_pros_2015 | count_tot_2015 | |
---|---|---|---|---|---|---|---|
BAYVIEW | 2121 | 11 | 15739 | 985 | 7 | 14711 | |
CENTRAL | 1193 | 70 | 13622 | 552 | 44 | 18565 | |
INGLESIDE | 2319 | 5 | 14008 | 1368 | 5 | 13414 | |
MISSION | 2063 | 713 | 21163 | 1198 | 66 | 18542 | |
NORTHERN | 1879 | 581 | 18975 | 945 | 42 | 20092 | |
PARK | 1207 | 2 | 8219 | 640 | 1 | 9341 | |
RICHMOND | 1081 | 15 | 7692 | 561 | 9 | 9082 | |
SOUTHERN | 1426 | 18 | 25692 | 795 | 96 | 30095 | |
TARAVAL | 1665 | 10 | 11329 | 789 | 81 | 11966 | |
TENDERLOIN | 371 | 527 | 12737 | 113 | 23 | 10735 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment