Built with blockbuilder.org
Last active
February 22, 2019 07:48
-
-
Save SeabassWells/b1b9642cc3465deaf29f845c406695a8 to your computer and use it in GitHub Desktop.
mappster
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
license: 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
{ | |
"default": "Choose a dataset from the dropdown and then mouse over any neighborhood to explore.", | |
"popdensityperacre": "Number of people per acre in Thousands, 2016. Source: <a href='http://default.sfplanning.org/publications_reports/SF_NGBD_SocioEconomic_Profiles/2012-2016_ACS_Profile_Neighborhoods_Final.pdf' target='_blank'>American Community Survey</a>", | |
"percapitaincome": "Average income earned per person, 2016. Source: <a href='http://default.sfplanning.org/publications_reports/SF_NGBD_SocioEconomic_Profiles/2012-2016_ACS_Profile_Neighborhoods_Final.pdf' target='_blank'>American Community Survey</a>", | |
"percentnonwhite": "Non-White percent of population, 2016. Source: <a href='http://default.sfplanning.org/publications_reports/SF_NGBD_SocioEconomic_Profiles/2012-2016_ACS_Profile_Neighborhoods_Final.pdf' target='_blank'>American Community Survey</a>", | |
"percentinpoverty": "Percent of population with earnings below the poverty line, 2016. Source: <a href='http://default.sfplanning.org/publications_reports/SF_NGBD_SocioEconomic_Profiles/2012-2016_ACS_Profile_Neighborhoods_Final.pdf' target='_blank'>American Community Survey</a>", | |
"medianhomevalue": "Median home value, 2016. Source: <a href='http://default.sfplanning.org/publications_reports/SF_NGBD_SocioEconomic_Profiles/2012-2016_ACS_Profile_Neighborhoods_Final.pdf' target='_blank'>American Community Survey</a>", | |
"unemploymentrate": "Jobless share of the labor force, 2016. Source: <a href='http://default.sfplanning.org/publications_reports/SF_NGBD_SocioEconomic_Profiles/2012-2016_ACS_Profile_Neighborhoods_Final.pdf' target='_blank'>American Community Survey</a>", | |
"percapitacriminalarrests": "Rate of Criminal Arrests per 1,000 residents, 2018. Source: <a href='https://github.com/SeabassWells/understand-sf/tree/master/crime' target='_blank'>DataSF Crime Portal</a>", | |
"percapitaencampments": "Rate of 311 Encampment Reports per 1,000 residents, 2018. Source: <a href='https://github.com/SeabassWells/understand-sf/tree/master/homelessness' target='_blank'>DataSF 311 Portal</a>", | |
"medianhoursofsummerfog": "Average hours of summertime fog and low cloud cover, 1999-2009. Source: <a href='https://github.com/SeabassWells/understand-sf/tree/master/fog' target='_blank'>Climate Commons</a>", | |
"percentinliquefaction": "Percent of land area in a Liquefaction or Landslide zone, 2018. Source: <a href='https://github.com/SeabassWells/understand-sf/tree/master/liquefaction' target='_blank'>DataSF Seismic Hazard Zones</a>" | |
} |
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> | |
<meta charset="utf-8"> | |
<head> | |
<style> | |
/* .counties { | |
fill: none; | |
} */ | |
/* .states { | |
fill: none; | |
stroke-width: 20; | |
stroke: #9400D3; | |
stroke-linejoin: round; | |
} */ | |
path { | |
stroke: #737373; | |
stroke-width: .1; | |
} | |
/* stroke: rgb(255, 255, 255); | |
stroke-width: .5px */ | |
</style> | |
<!-- | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> | |
<script src="https://d3js.org/topojson.v2.min.js"></script> --> | |
</head> | |
<body> | |
<div class="container-fluid"> | |
<div class="row" style="padding-bottom: 35px;"> | |
<div class="col-md-8 offset-md-2"> | |
<h1 class="supreme"><a href="/" style="color: white;">←</a> San Fran </h1> | |
</div> | |
</div> | |
<!-- begin content --> | |
<div class="row" style="padding-bottom: 25px;"> | |
<div class="col-md-8 offset-md-2 blurb-row"> | |
<p>The best way to understand the makeup of this country is data, not narrative. Pick which dataset is informative to you and see how it changes across states.</p> | |
<div class="dropdown"> | |
<select class="select_box" id="opts"> | |
<p></p> | |
<option value="default">Select a dataset</option> | |
<option value="popdensityperacre">Population Density</option> | |
<option value="percapitaincome">Income</option> | |
<option value="percentnonwhite">Racial Diversity</option> | |
<option value="percentinpoverty">Poverty</option> | |
<option value="medianhomevalue">Home Value</option> | |
<option value="unemploymentrate">Unemployment</option> | |
<option value="percapitacriminalarrests">Crime</option> | |
<option value="percapitaencampments">Homelessness</option> | |
<option value="medianhoursofsummerfog">Fog</option> | |
<option value="percentinliquefaction">Liquefaction</option> | |
</select> | |
</div> | |
</div> | |
</div> | |
<!-- viz row --> | |
<div class="row"> | |
<div class="col-md-8 offset-md-2 viz-row"> | |
</div> | |
</div> | |
</div> | |
<script src="w3color.js"></script> | |
<script src="https://d3js.org/topojson.v2.min.js"></script> | |
<script type="text/javascript" src="http://d3js.org/d3.v4.min.js"></script> | |
<script type="text/javascript" src="main.js"></script> | |
</body> |
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
//Alerts for browser compatibility | |
if (navigator.vendor == "Apple Computer, Inc." && !/Mobi|Android/i.test(navigator.userAgent)) { | |
alert("This visualization doesn't work very well in Safari. Try using Chrome if you can!"); | |
} | |
if (/Mobi|Android/i.test(navigator.userAgent)) { | |
alert("This visualization doesn't work very well on mobile. Try using Chrome on Desktop if you can!") | |
} | |
var w = 1000; | |
var h = 650; | |
console.log("d3 executed!") | |
function cmykToRgb(c, m, y, k) { | |
var r, g, b; | |
r = Math.round(255 - ((Math.min(1, c * (1 - k) + k)) * 255)); | |
g = Math.round(255 - ((Math.min(1, m * (1 - k) + k)) * 255)); | |
b = Math.round(255 - ((Math.min(1, y * (1 - k) + k)) * 255)); | |
return "rgb("+r+","+g+","+b+")"; | |
} | |
//Create variable for updating dataset | |
var newData; | |
var svg = d3.select("body .viz-row") | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h); | |
//Define path generator | |
var path = d3.geoPath() | |
var color = d3.scaleLinear() | |
.range([0,255]) | |
var colorcmyk = d3.scaleLinear() | |
.range([1,0]) | |
var tooltip = d3.select("body .viz-row").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0); | |
//Display data function | |
// load the dataset specified in the dropdown | |
function displayData(dataset) { | |
console.log("displayData executed on " + dataset); | |
// load the csv file with all the data | |
d3.csv("TheSFData.csv", function(data) { | |
//Set domain for color scale | |
color.domain([ | |
d3.min(data, function(d) { return parseFloat(d[dataset]); }), | |
d3.max(data, function(d) { return parseFloat(d[dataset]); }) | |
]); | |
colorcmyk.domain([ | |
d3.min(data, function(d) { return parseFloat(d[dataset]); }), | |
d3.max(data, function(d) { return parseFloat(d[dataset]); }) | |
]); | |
//Load in GeoJSON data with all the json | |
d3.json("bs.json", function(json) { | |
// json.transform.translate = [100,0] | |
var jsonClone = JSON.parse(JSON.stringify(json)); | |
json = topojson.feature(json, json.objects.SFgeojson).features | |
jsonClone = topojson.feature(jsonClone, jsonClone.objects.SFgeojson) | |
for (var i = 0; i < data.length; i++) { | |
var dataState = data[i].nhood; | |
var dataValue = parseFloat(data[i][dataset]); | |
for (var j = 0; j < json.length; j++) { | |
var jsonState = json[j].properties.nhood; | |
if (dataState == jsonState) { | |
json[j].properties.value = dataValue; | |
// console.log(json[j].properties.value) | |
break; | |
} | |
} | |
} | |
//Bind data and create one path per GeoJSON feature | |
var projection = d3.geoIdentity() | |
.reflectY(true) | |
.fitSize([w,h],jsonClone) | |
var pathFlipped = d3.geoPath() | |
.projection(projection); | |
const mapSelection = svg.selectAll("path") | |
.data(json) | |
mapSelection | |
.enter() | |
.append("path") | |
.attr("d", pathFlipped) | |
.style("fill","lightgrey") | |
// .insertBefore(this,"text") | |
// .text(function(d){ | |
// return d.properties.nhood;}) | |
// .attr("x", function(d){ | |
// return path.centroid(d)[0];}) | |
// .attr("y", function(d){ | |
// return path.centroid(d)[1];}) | |
// .attr("text-anchor","middle") | |
// .attr('font-size','6pt'); | |
// const MapLabels = mapSelection.selectAll("text") | |
// .data(json) | |
// .enter() | |
// var mapLabel = svg.selectAll("text") | |
// .data(json) | |
// .enter() | |
// .append("text") | |
// .text(function(d){ | |
// return d.properties.nhood;}) | |
// .attr("x", function(d){ | |
// return path.centroid(d)[0];}) | |
// .attr("y", function(d){ | |
// return path.centroid(d)[1];}) | |
// .attr("text-anchor","middle") | |
// .attr('font-size','6pt'); | |
// .attr("transform", "translate(" + (getBBox().x + getBBox().width/2) + " " + (getBBox().y + getBBox().height/2) + ")") | |
// // .attr("x", function(d){ | |
var mapLabel = svg.selectAll("text") | |
.data(json) | |
.enter() | |
.append("text") | |
.text(function(d){return d.properties.nhood;}) | |
.attr('transform', function(d) { return 'translate(' + path.centroid(d) + ')'; }) | |
// | |
// .attr("transform", function(d){ | |
// console.log(path) | |
// console.log(path.getBBox(d).x);}) | |
// .attr("y", function(d){ | |
// return path.centroid(d)[1];}) | |
// .attr("text-anchor","middle") | |
.attr('font-size','6pt'); | |
// var mapLabel = svg.selectAll("text") | |
// .data(json) | |
// .enter() | |
// .append("text") | |
// .text(function(d){ | |
// return d.properties.nhood;}) | |
// .getBBox() | |
// .attr("transform", "translate(" + (getBBox().x + getBBox().width/2) + " " + (getBBox().y + getBBox().height/2) + ")") | |
// // .attr("x", function(d){ | |
// // return path.centroid(d)[0];}) | |
// // .attr("y", function(d){ | |
// // return path.centroid(d)[1];}) | |
// .attr("text-anchor","middle") | |
// .attr('font-size','6pt'); | |
// var mapLabel = selectAll("text") | |
// .data(json) | |
// .enter() | |
// .append("text") | |
// .text(function(d){ | |
// return d.properties.nhood | |
// }); | |
// return d.properties.nhood;}) | |
// .attr("x", function(d){ | |
// return path.centroid(d)[0];}) | |
// .attr("y", function(d){ | |
// return path.centroid(d)[1];}) | |
// .attr("text-anchor","middle") | |
// .attr('font-size','6pt'); | |
// | |
// function addText(p) | |
// { | |
// var t = document.createElementNS("http://www.w3.org/2000/svg", "text"); | |
// var b = p.getBBox(); | |
// t.setAttribute("transform", "translate(" + (b.x + b.width/2) + " " + (b.y + b.height/2) + ")"); | |
// t.setAttribute("fill", "red"); | |
// t.setAttribute("font-size", "14"); | |
// p.parentNode.insertBefore(t, p.nextSibling); | |
// } | |
// | |
// var paths = document.querySelectorAll("path"); | |
// for (var p in paths) | |
// { | |
// addText(paths[p]) | |
// } | |
mapSelection.transition() | |
.duration(900) | |
.style("fill", function(d) { | |
//Get data value | |
var value = d.properties.value; | |
if (value) { | |
console.log("1") | |
return cmykToRgb(.98,0,.15,colorcmyk(value)); | |
} else { | |
//If default dataset | |
if (dataset == "default") { | |
console.log("2") | |
return "grey"; | |
//If any other dataset | |
} else { | |
console.log("3") | |
return "#ccc"; | |
} | |
} | |
}); | |
mapSelection.on("mouseover", function(d) { | |
//Inject data value into paragraph | |
//Remove old text | |
d3.select(".blurb-row .dropdown #value-label") | |
.remove() | |
//Display new text | |
var paragraph = d3.select(".blurb-row .dropdown") | |
.append("p") | |
.text(function() { | |
//Based on the dataset, we'll return different tooltips (formatting in terms of percentages, etc.) | |
if (["percapitaincome", "medianhomevalue"].includes(dataset)) { | |
return (d.properties.nhood + ": $" + d.properties.value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")); | |
} else if (["percentnonwhite", "percentinpoverty", "unemploymentrate", | |
"percentinliquefaction"].includes(dataset)){ | |
return (d.properties.nhood + ": " + d.properties.value + "%"); | |
} else if (["medianhoursofsummerfog"].includes(dataset)){ | |
return (d.properties.nhood + ": " + d.properties.value + " hours"); | |
} if (dataset=="default"){ | |
return (d.properties.nhood); | |
} else { | |
return (d.properties.nhood + ": " + d.properties.value); | |
} | |
}) | |
.attr("id", "value-label") | |
.classed("supreme", true) | |
.style("font-size", "1em") | |
.style("display", "inline") | |
.style("margin-left", "30px"); | |
//Highlight current state | |
d3.select(this) | |
.transition() | |
.duration(300) | |
.style("opacity", .6); | |
}) | |
.on("mouseout", function(d) { | |
//Remove old text | |
d3.select(".dropdown #value-label") | |
.remove() | |
//Return state to original opacity | |
d3.select(this) | |
.transition() | |
.duration(350) | |
.style("opacity", 1); | |
}); | |
}); | |
}); | |
}; | |
//Display text function | |
function displayInformation(dataset) { | |
//Load in dataset:description json file | |
d3.json("descriptions.json", function(json) { | |
var description = json[dataset]; | |
//Remove old text | |
d3.select("#dataset-description") | |
.remove() | |
//Display new text | |
var paragraph = d3.select("body .blurb-row") | |
.append("p") | |
.html(description) | |
.attr("id", "dataset-description") | |
.style("font-size", "1em") | |
.style("font-family", "Futura, sans-serif") | |
.style("font-style", "italic"); | |
}); | |
} | |
//Load initial data and description | |
displayData("default"); | |
displayInformation("default"); | |
// handle on click event | |
d3.select('#opts') | |
.on('change', function() { | |
newData = d3.select(this).property('value'); | |
displayInformation(newData); | |
displayData(newData); | |
}); |
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
nhood | popdensityperacre | percapitaincome | percentnonwhite | percentinpoverty | medianhomevalue | unemploymentrate | totalarrests | percapitacriminalarrests | totalencampmentreports | percapitaencampments | medianhoursofsummerfog | percentinliquefaction | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Treasure Island | 5 | 15886 | 66 | 51 | -- | 12 | 37 | 12 | 7 | 2 | 4 | 79 | |
McLaren Park | 2 | 15387 | 94 | 33 | 669643 | 26 | 34 | 40 | 19 | 22 | 7 | 4 | |
Tenderloin | 112 | 27946 | 57 | 30 | 509804 | 8 | 2589 | 92 | 3929 | 139 | 4 | 22 | |
Lakeshore | 8 | 22570 | 54 | 28 | 681159 | 16 | 418 | 29 | 24 | 2 | 8 | 14 | |
Chinatown | 103 | 24653 | 86 | 27 | 846774 | 7 | 542 | 37 | 141 | 10 | 4 | 49 | |
South of Market | 34 | 54202 | 62 | 27 | 752521 | 6 | 3613 | 188 | 12189 | 636 | 4 | 95 | |
Japantown | 47 | 68352 | 43 | 20 | 606250 | 5 | 281 | 77 | 128 | 35 | 4 | 0 | |
Bayview Hunters Point | 11 | 24817 | 86 | 19 | 566355 | 12 | 1543 | 41 | 1241 | 33 | 5 | 55 | |
Western Addition | 60 | 51264 | 57 | 17 | 636719 | 6 | 1188 | 54 | 2134 | 96 | 4 | 0 | |
North Beach | 39 | 60254 | 49 | 16 | 806903 | 7 | 1087 | 86 | 622 | 49 | 3 | 55 | |
Visitacion Valley | 47 | 20942 | 88 | 15 | 580231 | 10 | 393 | 21 | 28 | 2 | 7 | 2 | |
Nob Hill | 97 | 58623 | 45 | 14 | 685404 | 5 | 858 | 39 | 2957 | 133 | 4 | 1 | |
Mission | 49 | 53196 | 43 | 14 | 797306 | 6 | 3722 | 64 | 17388 | 297 | 5 | 33 | |
Oceanview/Merced/Ingleside | 42 | 26413 | 80 | 14 | 624528 | 10 | 354 | 13 | 84 | 3 | 8 | 1 | |
Hayes Valley | 58 | 61210 | 33 | 13 | 805046 | 5 | 875 | 48 | 644 | 35 | 4 | 13 | |
Inner Richmond | 47 | 56925 | 46 | 13 | 839002 | 6 | 466 | 21 | 314 | 14 | 6 | 0 | |
Lone Mountain/USF | 49 | 50860 | 38 | 10 | 904561 | 8 | 491 | 27 | 82 | 5 | 4 | 3 | |
Outer Richmond | 39 | 44745 | 56 | 10 | 880501 | 4 | 662 | 15 | 331 | 7 | 6 | 4 | |
Sunset/Parkside | 30 | 42430 | 65 | 10 | 829029 | 6 | 972 | 12 | 167 | 2 | 6 | 9 | |
Russian Hill | 56 | 91854 | 33 | 9 | 810158 | 3 | 718 | 40 | 146 | 8 | 4 | 12 | |
Haight Ashbury | 51 | 81392 | 20 | 9 | 908163 | 4 | 479 | 27 | 1166 | 65 | 4 | 7 | |
Excelsior | 44 | 28057 | 72 | 9 | 628628 | 8 | 530 | 14 | 82 | 2 | 6 | 2 | |
Bernal Heights | 38 | 53243 | 43 | 9 | 838307 | 7 | 549 | 21 | 557 | 21 | 6 | 11 | |
Portola | 31 | 29659 | 78 | 9 | 653611 | 7 | 349 | 21 | 157 | 10 | 7 | 7 | |
Financial District/South Beach | 24 | 114083 | 46 | 9 | 681493 | 5 | 2575 | 148 | 5215 | 299 | 4 | 61 | |
Mission Bay | 20 | 70287 | 58 | 9 | 754513 | 5 | 472 | 45 | 2141 | 203 | 4 | 93 | |
Potrero Hill | 19 | 84521 | 36 | 9 | 879765 | 6 | 720 | 52 | 2212 | 161 | 4 | 31 | |
Presidio Heights | 33 | 88517 | 31 | 8 | 913846 | 5 | 163 | 15 | 85 | 8 | 5 | 0 | |
Castro/Upper Market | 38 | 94317 | 22 | 7 | 907208 | 4 | 1030 | 49 | 4607 | 218 | 4 | 13 | |
Outer Mission | 38 | 32582 | 76 | 7 | 684176 | 8 | 450 | 19 | 129 | 5 | 6 | 4 | |
Glen Park | 19 | 72039 | 30 | 7 | 954665 | 5 | 133 | 16 | 79 | 10 | 6 | 20 | |
Pacific Heights | 47 | 102141 | 26 | 6 | 866733 | 4 | 554 | 23 | 631 | 26 | 4 | 0 | |
West of Twin Peaks | 20 | 67869 | 46 | 6 | 927384 | 4 | 622 | 16 | 60 | 2 | 7 | 7 | |
Seacliff | 18 | 117489 | 24 | 6 | 869565 | 5 | 14 | 6 | 3 | 1 | 6 | 12 | |
Marina | 38 | 98411 | 17 | 5 | 975000 | 4 | 741 | 30 | 576 | 23 | 4 | 51 | |
Twin Peaks | 18 | 64279 | 36 | 5 | 885714 | 4 | 84 | 11 | 30 | 4 | 4 | 16 | |
Noe Valley | 39 | 91014 | 22 | 4 | 934003 | 4 | 285 | 15 | 55 | 3 | 4 | 4 | |
Presidio | 3 | 86967 | 12 | 4 | -- | 1 | 8 | 2 | 9 | 2 | 5 | 19 | |
Lincoln Park | 1 | 43922 | 44 | 4 | 750000 | 10 | 10 | 31 | 9 | 28 | 5 | 38 | |
Inner Sunset | 32 | 63133 | 44 | 0.09 | 910805 | 4 | 343 | 12 | 124 | 4 | 6 | 11 | |
Golden Gate Park | 0.1 | 278 | 3089 | 203 | 2256 | 6 | 6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment