├── .gitignore ├── .DS_Store ├── css ├── map1.png ├── .DS_Store ├── ccusa.jpg ├── ccusa.png ├── stock-photo-sandbags-outside-front-door-of-flooded-house-344300294.jpg ├── overlay.css ├── rese.css ├── sidenav.css ├── style.css ├── mapbox-geocoder.css ├── map.css └── normalize.css ├── static ├── dk.png ├── dkdc.png ├── map1.png ├── .DS_Store ├── attom.jpeg ├── dkdc1.png ├── github.png ├── mapbox.png ├── ccusa_logo.png ├── ccusa_logo_white.png └── ccusa_logo.svg ├── icons ├── datakind.svg ├── thumbnail.PNG ├── tornado.svg ├── tornado - black.svg ├── flag.svg ├── hurricane.svg ├── hurricane - black.svg ├── earthquake.svg ├── earthquake - black.svg ├── hail.svg ├── hail - black.svg ├── info.svg ├── wildfire.svg ├── wildfire - black.svg ├── flood.svg └── flood - black.svg ├── .idea ├── vcs.xml ├── misc.xml ├── modules.xml ├── Disaster_Vulnerability_Map.iml └── workspace.xml ├── assets ├── sources.js └── layers.js ├── js ├── legend.js ├── bars.js ├── newdonut.js └── mapbox.js ├── scripts ├── ShapefileCreation.sh ├── Phase2.R └── DataClean.R ├── LICENSE ├── README.md ├── sample-data.tsv ├── about.html ├── index.html └── data.html /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/.DS_Store -------------------------------------------------------------------------------- /css/map1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/css/map1.png -------------------------------------------------------------------------------- /css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/css/.DS_Store -------------------------------------------------------------------------------- /css/ccusa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/css/ccusa.jpg -------------------------------------------------------------------------------- /css/ccusa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/css/ccusa.png -------------------------------------------------------------------------------- /static/dk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/dk.png -------------------------------------------------------------------------------- /static/dkdc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/dkdc.png -------------------------------------------------------------------------------- /static/map1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/map1.png -------------------------------------------------------------------------------- /static/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/.DS_Store -------------------------------------------------------------------------------- /static/attom.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/attom.jpeg -------------------------------------------------------------------------------- /static/dkdc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/dkdc1.png -------------------------------------------------------------------------------- /static/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/github.png -------------------------------------------------------------------------------- /static/mapbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/mapbox.png -------------------------------------------------------------------------------- /icons/datakind.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/icons/datakind.svg -------------------------------------------------------------------------------- /icons/thumbnail.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/icons/thumbnail.PNG -------------------------------------------------------------------------------- /static/ccusa_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/ccusa_logo.png -------------------------------------------------------------------------------- /static/ccusa_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/static/ccusa_logo_white.png -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /css/stock-photo-sandbags-outside-front-door-of-flooded-house-344300294.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccusa/Disaster_Vulnerability_Map/HEAD/css/stock-photo-sandbags-outside-front-door-of-flooded-house-344300294.jpg -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/sources.js: -------------------------------------------------------------------------------- 1 | const mapSources = [ 2 | [ 3 | "highlight", 4 | { 5 | "type": "geojson", 6 | "data": { 7 | "type": "FeatureCollection", 8 | "features": [] 9 | } 10 | } 11 | ], 12 | [ 13 | "maps", 14 | { 15 | "type": "vector", 16 | "url": "mapbox://datakinddc.dov5hqec,datakinddc.7x3n5g42" 17 | } 18 | ] 19 | ]; 20 | -------------------------------------------------------------------------------- /.idea/Disaster_Vulnerability_Map.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /css/overlay.css: -------------------------------------------------------------------------------- 1 | /*.map-overlay { 2 | position: absolute; 3 | bottom: 0px; 4 | right: 0px; 5 | background:rgba(0,0,0,.85); 6 | overflow: auto; 7 | color: white; 8 | }*/ 9 | 10 | .h-line { 11 | width: 100%; 12 | border-bottom: 1px solid black; 13 | } 14 | 15 | #overlay-title { 16 | margin: 0 0 5px 0; 17 | } 18 | 19 | .inline { 20 | display: inline-block; 21 | } 22 | 23 | #overlay-data { 24 | right: 10px; 25 | width: 190px; 26 | height: 390px; 27 | } 28 | -------------------------------------------------------------------------------- /icons/tornado.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /icons/tornado - black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /icons/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /js/legend.js: -------------------------------------------------------------------------------- 1 | function updateLegend(id,name) { 2 | mapLayers.forEach(function(layer) { 3 | if (layer[0].id === id) { 4 | $('.legend-block').remove() 5 | 6 | let stops = layer[0].paint['fill-color'].stops 7 | let stopsLength = stops.length - 1 8 | 9 | stops.forEach(function(stop, idx) { 10 | let number = stop[0]; 11 | let color = stop[1]; 12 | 13 | console.log(id); 14 | console.log(name); 15 | 16 | if (id=='tract') { 17 | d3.select('.legend-title').text('Total Flags') 18 | }else{ 19 | d3.select('.legend-title').text(name);} 20 | 21 | if (idx == stopsLength && id=='tract') { 22 | number = stop[0] + '+' 23 | } 24 | 25 | let div = "
" + number + 27 | "
" 28 | 29 | $('#legend').append(div) 30 | 31 | }) 32 | } 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /icons/hurricane.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /icons/hurricane - black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /css/rese.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | html, body, div, span, applet, object, iframe, 6 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 7 | a, abbr, acronym, address, big, cite, code, 8 | del, dfn, em, img, ins, kbd, q, s, samp, 9 | small, strike, strong, sub, sup, tt, var, 10 | b, u, i, center, 11 | dl, dt, dd, ol, ul, li, 12 | fieldset, form, label, legend, 13 | table, caption, tbody, tfoot, thead, tr, th, td, 14 | article, aside, canvas, details, embed, 15 | figure, figcaption, footer, header, hgroup, 16 | menu, nav, output, ruby, section, summary, 17 | time, mark, audio, video { 18 | margin: 0; 19 | padding: 0; 20 | border: 0; 21 | font-size: 100%; 22 | font: inherit; 23 | vertical-align: baseline; 24 | } 25 | /* HTML5 display-role reset for older browsers */ 26 | article, aside, details, figcaption, figure, 27 | footer, header, hgroup, menu, nav, section { 28 | display: block; 29 | } 30 | body { 31 | line-height: 1; 32 | } 33 | ol, ul { 34 | list-style: none; 35 | } 36 | blockquote, q { 37 | quotes: none; 38 | } 39 | blockquote:before, blockquote:after, 40 | q:before, q:after { 41 | content: ''; 42 | content: none; 43 | } 44 | table { 45 | border-collapse: collapse; 46 | border-spacing: 0; 47 | } 48 | -------------------------------------------------------------------------------- /css/sidenav.css: -------------------------------------------------------------------------------- 1 | label[for="nav-trigger"] { 2 | display: flex; 3 | position: fixed; 4 | background-color: #FF921A; 5 | text-align: center; 6 | vertical-align: sub; 7 | top: 100px; 8 | right:0px; 9 | z-index: 2; 10 | width: 180px; 11 | height: 50px; 12 | cursor: pointer; 13 | background-size: contain; 14 | 15 | transition-property: background-color, color; 16 | transition-duration: .2s; 17 | transition-timing-function: ease-in-out; 18 | } 19 | 20 | label[for="nav-trigger"]:hover { 21 | background-color: white; 22 | 23 | transition-property: background-color, color; 24 | transition-duration: .2s; 25 | transition-timing-function: ease-in-out; 26 | } 27 | 28 | label[for="nav-trigger"]:hover > strong { 29 | color: #FF921A; 30 | transition: all 0.5s ease; 31 | } 32 | 33 | 34 | label[for="nav-trigger"] > strong{ 35 | width: 175px; 36 | height: 12px; 37 | margin: auto; 38 | font-size: 1em; 39 | color: white; 40 | vertical-align: sub; 41 | font-family: 'Roboto', sans-serif; 42 | } 43 | 44 | .nav-trigger { 45 | position: absolute; 46 | clip: rect(0, 0, 0, 0); 47 | top: 50px; 48 | } 49 | 50 | 51 | .nav-trigger:checked + label { 52 | right: 240px; 53 | } 54 | 55 | .nav-trigger:checked ~ #map { 56 | right: 240px; 57 | width: calc(100% - 240px); 58 | } 59 | 60 | .nav-trigger:checked ~ #menu { 61 | right: 0px; 62 | } 63 | 64 | .nav-trigger + label, #map { 65 | transition: left 0.4s; 66 | } 67 | 68 | 69 | 70 | 71 | @media print { 72 | 73 | strong { 74 | color: transparent !important; 75 | } 76 | 77 | } -------------------------------------------------------------------------------- /scripts/ShapefileCreation.sh: -------------------------------------------------------------------------------- 1 | # This script converts the shapefiles from shapefiles 2 | # to GeoJSON and then to tile vectors 3 | 4 | ## Installation should only be run if the programs are not installed 5 | # Install tippecanoe using homebrew from the command line 6 | brew install tippecanoe 7 | 8 | # Install GDAL 9 | brew install gdal --enable-unsupported --with-libkml --with-mysql 10 | 11 | # Install node.js 12 | brew install node 13 | 14 | # Install MBTiles 15 | npm install -g mbview 16 | 17 | ## File conversion 18 | # SVI data is available at both county and tract level. 19 | # In the map, we show county level data until the viewer zooms in 20 | # to 8, when we display tract level data. 21 | 22 | ## Convert shapefile to GeoJSON 23 | # ensure you set your directory properly using cd 24 | # Ex. cd DisasterVulnerability 25 | # County level data 26 | ogr2ogr -f GeoJSON svi2014_county.geojson counties.shp -progress 27 | 28 | # Tract level data 29 | ogr2ogr -f GeoJSON svi2014_tract.geojson tracts.shp -progress 30 | 31 | ## Convert GeoJSON into vector tiles 32 | # County level data 33 | tippecanoe -o svi2014_county.mbtiles svi2014_county.geojson -Z 3 -z 7 --no-tiny-polygon-reduction --detect-shared-borders --simplification=10 --layer=SVI_County 34 | 35 | # Tract level data 36 | tippecanoe -o svi2014_tract.mbtiles svi2014_tract.geojson -Z 8 -z 12 --no-tiny-polygon-reduction --detect-shared-borders --simplification=10 --layer=SVI_Tract 37 | 38 | ## View data using MBTiles 39 | # Set API key 40 | export MAPBOX_ACCESS_TOKEN='pk.eyJ1IjoibHVrYXNtYXJ0aW5lbGxpIiwiYSI6ImNqMHBuYXEwcDAwdGoycXJ4Z2xwb2d2NjYifQ.KYk6rQNWpAZ4fBm6utbb2w' 41 | 42 | # Launch view in browser 43 | mbview svi2014_tract.mbtiles 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, Max Richman, Phillip Shebel, Richard Carder, Lukas Martinelli, Alex Wasson, Jake Snyder 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /icons/earthquake.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 13 | 17 | 25 | 26 | -------------------------------------------------------------------------------- /icons/earthquake - black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 13 | 17 | 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *** 2 | # Catholic Charities USA Disaster Vulnerability Map 3 | *** 4 | [View current map](https://ccusa.github.io/Disaster_Vulnerability_Map/) 5 | 6 | ![dvm](https://user-images.githubusercontent.com/23619819/29878962-cc7321e8-8d71-11e7-842a-7ec46d0368f4.gif) 7 | *** 8 | ## Purpose 9 | *** 10 | CCUSA wanted to create a map to **better target mitigation, preparedness, relief, and recovery projects** in order to best serve communities that are both at greatest risk for disasters and most overlooked or outright excluded from federal assistance during disasters. Specifically, they wanted to see the presence of acutely vulnerable populations such as uninsured (homeowners or renters), homeless, or subsidized renters at the local level. 11 | 12 | This map can be used to strategically allocate resources to prepare for disasters, as well as identifying where vulnerable populations live within an area affected by a disaster. 13 | *** 14 | ## How to contribute 15 | *** 16 | Interested in helping? Issues or pull requests are welcome! Join the [DataKind DC meetup group](https://www.meetup.com/DataKind-DC/) to find out about work sessions and new projects. 17 | *** 18 | ## Data 19 | *** 20 | This map uses data from the CDC’s [Social Vulnerability Index](https://svi.cdc.gov) and a proprietary dataset which maps disaster risk that we were given permission to use. 21 | 22 | From the CDC’s website, social vulnerability refers to the resilience of communities when confronted by external stresses on human health, stresses such as natural or human-caused disasters, or disease outbreaks. Reducing social vulnerability can decrease both human suffering and economic loss. ATSDR's Social Vulnerability Index uses U.S. census variables at tract level to help local officials identify communities that may need support in preparing for hazards, or recovering from disaster. 23 | 24 | The proprietary dataset shows risk of six types of natural disasters: floods, earthquakes, hurricanes, tornados, wildfires, and hail. It uses data from FEMA, USGS, and NOAA. 25 | *** 26 | ## Convert data into Vector Tiles 27 | *** 28 | The data was converted from a shape file into vector tiles, due to the size of the data. Please see the ShapefileCreation file to view how the file was converted. 29 | *** 30 | ## Hackpad for data access 31 | *** 32 | The tiles are hosted on a MapBox server. Please visit [this hackpad](https://hackpad.com/DKDC-Catholic-Charities-USA-wZxoDDUvGzO) for more information. 33 | -------------------------------------------------------------------------------- /icons/hail.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 25 | 26 | 27 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /icons/hail - black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 25 | 26 | 27 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /icons/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 20 | 27 | 30 | 31 | -------------------------------------------------------------------------------- /icons/wildfire.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 29 | 30 | -------------------------------------------------------------------------------- /icons/wildfire - black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 29 | 30 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | /*these are classes, put in class declaration*/ 2 | 3 | 4 | .navbar, 5 | .navbar-collapse, 6 | .navbar-brand, 7 | .nav, 8 | #aboutlink, 9 | #print-link, 10 | .navbar-header { 11 | background: #332A85; 12 | color: #ffffff; 13 | text-align: right; 14 | } 15 | 16 | .navbar-default .navbar-nav>li>a { 17 | color: #fff !important; 18 | } 19 | 20 | #menu a.active, #menu a:hover ,.nav>li>a:focus, .nav>li>a:hover{ 21 | transition-property: background-color, color; 22 | transition-duration: .2s; 23 | transition-timing-function: ease-out; 24 | background-color: #332A85; 25 | color: #fff; 26 | } 27 | 28 | #print-link { 29 | pointer-events: none; 30 | cursor: default; 31 | } 32 | 33 | 34 | .ccusa_container{ 35 | padding-top: 12em; 36 | padding-left: 12em; 37 | padding-right: 12em; 38 | margin-bottom: 10px; 39 | color: black; 40 | font-size: 15px; 41 | font-family: 'Roboto'; 42 | text-align: justify; 43 | background-color: white; 44 | } 45 | 46 | .jumbotron { 47 | background-color: black; 48 | border: 2px solid black; 49 | text-align: center; 50 | height: 450px; 51 | color: white; 52 | font-family: 'Roboto', sans-serif; 53 | padding-top: 10em; 54 | padding-left: 4em; 55 | padding-right: 4em; 56 | margin-bottom: 10px; 57 | } 58 | 59 | /*-- # = ids -*/ 60 | 61 | html, body { 62 | height: 0%; 63 | margin: 0; 64 | padding: 0; 65 | font-family: 'Roboto', sans-serif; 66 | font-size: 0.9em; 67 | background-color: white; 68 | color: black; 69 | } 70 | 71 | 72 | h2, h3 { 73 | font-size: 1.2em; 74 | font-weight: 400; 75 | font-family: 'Roboto', sans-serif; 76 | } 77 | 78 | h4 { 79 | font-family: 'Roboto', sans-serif; 80 | font-size: 1.5em; 81 | margin-top: 1.5em; 82 | margin-bottom: 0.5em; 83 | } 84 | 85 | 86 | p { 87 | margin: 10px; 88 | text-align: left; 89 | } 90 | 91 | 92 | a.header1 { 93 | font-family: 'Roboto', sans-serif; 94 | font-size: 0.9em; 95 | color: #fff; 96 | } 97 | 98 | a.body1{ 99 | color: purple; 100 | } 101 | 102 | 103 | 104 | hr { 105 | display: block; 106 | margin-top: 1.5em; 107 | margin-bottom: 1.5em; 108 | margin-left: auto; 109 | margin-right: auto; 110 | border-style: solid; 111 | border-width: 2px; 112 | } 113 | .closeinfo { 114 | padding-top: 8em; 115 | padding-left: 8em; 116 | padding-right: 8em; 117 | margin-bottom: 10px; 118 | font-family: 'Roboto', sans-serif; 119 | font-size: 0.9em; 120 | background-color: black; 121 | color: #fff; 122 | text-align: center; 123 | height: 300px; 124 | } 125 | table { 126 | border-collapse: collapse; 127 | width: 100%; 128 | } 129 | 130 | th, td, th { 131 | padding: 8px; 132 | text-align: left; 133 | border: 1px solid black; 134 | } 135 | 136 | th { 137 | text-align: left; 138 | } 139 | -------------------------------------------------------------------------------- /scripts/Phase2.R: -------------------------------------------------------------------------------- 1 | --- 2 | title: "CCUSA Phase 2" 3 | author: "Rich Carder" 4 | date: "July 6, 2020" 5 | --- 6 | 7 | 8 | library(dplyr) 9 | library(reshape) 10 | library(stringr) 11 | library(tidyr) 12 | library(lubridate) 13 | library(RJSONIO) 14 | library(maps) 15 | library(rlang) 16 | library(mapdata) 17 | library(geosphere) 18 | library(ggmap) 19 | library(ggplot2) 20 | library(tidyverse) 21 | library(tidyselect) 22 | library(tidycensus) 23 | library(sf) 24 | library(haven) 25 | library(jsonlite) 26 | library(geojsonio) 27 | library(lwgeom) 28 | 29 | 30 | options(scipen=999) 31 | 32 | ##Load Shapefiles and Eviction Data 33 | setwd("C:/Users/rcarder/documents/dev/CCUSA Data") 34 | 35 | #Shapefiles 36 | counties <- st_read("SVI2018_US_COUNTY")%>% 37 | dplyr::select(-c(7,9:73))%>% 38 | dplyr::select(-c(33:51,53:59))%>% 39 | dplyr::select(!starts_with("SPL"))%>% 40 | mutate(FIPS=as.character(FIPS))%>% 41 | mutate(across(8:27,round,3))%>% 42 | mutate(across(8:27,~ .x *100))%>% 43 | mutate(across(8:27,~ ifelse(.x >=90,1,0),.names = "mysum{col}")) %>% 44 | mutate(FNew=rowSums(across(starts_with("mysumEPL"))))%>% 45 | dplyr::select(-c(1,2,3,4,30:49)) 46 | 47 | tracts <- st_read("SVI2018_US")%>% 48 | dplyr::select(-c(8,10:74))%>% 49 | dplyr::select(-c(34:52,54:60))%>% 50 | dplyr::select(!starts_with("SPL"))%>% 51 | mutate(FIPS=as.character(FIPS))%>% 52 | mutate(across(9:28,round,3))%>% 53 | mutate(across(9:28,~ .x *100))%>% 54 | mutate(across(9:28,~ ifelse(.x >=90,1,0),.names = "mysum{col}")) %>% 55 | mutate(FNew=rowSums(across(starts_with("mysumEPL"))))%>% 56 | dplyr::select(-c(1,2,3,4,5,31:50)) 57 | 58 | #Eviction, Diocese, and Hazard Data 59 | countyEviction<-read.csv("counties.csv")%>% 60 | filter(year==2016)%>% 61 | mutate(GEOID=str_pad(GEOID, width=5, side="left", pad="0"))%>% 62 | dplyr::select(1,8,12,23)%>% 63 | mutate(RenterOccupied=ntile(pct.renter.occupied,1000)/10, 64 | RentBurden=ntile(rent.burden,1000)/10, 65 | EvictionRate=ntile(eviction.rate,1000)/10)%>% 66 | dplyr::select(1,5,6,7) 67 | 68 | countyHazard<-read.csv("hazard.csv")%>% 69 | dplyr::select(2,6:12)%>% 70 | dplyr::rename("TotalHazard"=2, 71 | "Earthquake"=3, 72 | "Tornado"=4, 73 | "Hail"=5, 74 | "Hurricane"=6, 75 | "Flood"=7, 76 | "Wildfire"=8)%>% 77 | mutate(FIPS=str_pad(FIPS, width=5, side="left", pad="0")) 78 | 79 | countyDiocese<-read.csv("diocese.csv")%>% 80 | dplyr::select(7,12)%>% 81 | mutate(FIPS=str_pad(FIPS, width=5, side="left", pad="0")) 82 | 83 | tractEviction<-read.csv("tracts.csv")%>% 84 | filter(year==2016)%>% 85 | mutate(GEOID=str_pad(GEOID, width=11, side="left", pad="0"))%>% 86 | dplyr::select(1,8,12,23)%>% 87 | mutate(RenterOccupied=ntile(pct.renter.occupied,1000)/10, 88 | RentBurden=ntile(rent.burden,1000)/10, 89 | EvictionRate=ntile(eviction.rate,1000)/10)%>% 90 | dplyr::select(1,5,6,7) 91 | 92 | 93 | 94 | 95 | #Join Eviction and Hazard Data to SVI County 96 | countiesdata<-st_drop_geometry(counties) 97 | counties 98 | countiesdata[countiesdata==-99900]<-0 99 | countiesdata[countiesdata==-999]<-0 100 | CountiesMaster<-counties%>% 101 | dplyr::select(1)%>% 102 | left_join(countiesdata, by="FIPS")%>% 103 | left_join(countyHazard, by="FIPS")%>% 104 | left_join(countyEviction,by=c("FIPS"="GEOID"))%>% 105 | left_join(countyDiocese, by="FIPS") 106 | CountiesMaster[is.na(CountiesMaster)]<-0 107 | 108 | #Join Eviction Data to SVI Tract 109 | tractdata<-st_drop_geometry(tracts) 110 | tractdata[tractdata==-99900]<-0 111 | tractdata[tractdata==-999]<-0 112 | tractsMaster<-tracts%>% 113 | dplyr::select(1)%>% 114 | mutate(FIP2=str_sub(FIPS,1,5))%>% 115 | left_join(tractdata, by="FIPS")%>% 116 | left_join(tractEviction,by=c("FIPS"="GEOID"))%>% 117 | left_join(countyDiocese, by=c("FIP2"="FIPS")) 118 | tractsMaster[is.na(tractsMaster)]<-0 119 | 120 | #Convert Coordinate System to Mapbox native CRS 121 | CountiesMaster<-st_transform(CountiesMaster, crs=3857,proj4string="+proj=longlat +datum=WGS84 +no_defs") 122 | tractsMaster<-st_transform(tractsMaster, crs=3857,proj4string="+proj=longlat +datum=WGS84 +no_defs") 123 | 124 | #Write Shapefiles 125 | shp_out <- st_write(CountiesMaster, "Counties.shp") 126 | shp_out_tract <- st_write(tractsMaster, "Tracts.shp") 127 | 128 | 129 | -------------------------------------------------------------------------------- /sample-data.tsv: -------------------------------------------------------------------------------- 1 | FID AFFGEOID TRACTCE ST STATE ST_ABBR STCNTY COUNTY FIPS LOCATION AREA_SQMI E_TOTPOP M_TOTPOP E_HU M_HU E_HH M_HH E_POV M_POV E_UNEMP M_UNEMP E_PCI M_PCI E_NOHSDP M_NOHSDP E_AGE65 M_AGE65 E_AGE17 M_AGE17 E_DISABL M_DISABL E_SNGPNT M_SNGPNT E_MINRTY M_MINRTY E_LIMENG M_LIMENG E_MUNIT M_MUNIT E_MOBILE M_MOBILE E_CROWD M_CROWD E_NOVEH M_NOVEH E_GROUPQ M_GROUPQ EP_POV MP_POV EP_UNEMP MP_UNEMP EP_PCI MP_PCI EP_NOHSDP MP_NOHSDP EP_AGE65 MP_AGE65 EP_AGE17 MP_AGE17 EP_DISABL MP_DISABL EP_SNGPNT MP_SNGPNT EP_MINRTY MP_MINRTY EP_LIMENG MP_LIMENG EP_MUNIT MP_MUNIT EP_MOBILE MP_MOBILE EP_CROWD MP_CROWD EP_NOVEH MP_NOVEH EP_GROUPQ MP_GROUPQ EPL_POV EPL_UNEMP EPL_PCI EPL_NOHSDP SPL_THEME1 RPL_THEME1 EPL_AGE65 EPL_AGE17 EPL_DISABL EPL_SNGPNT SPL_THEME2 RPL_THEME2 EPL_MINRTY EPL_LIMENG SPL_THEME3 RPL_THEME3 EPL_MUNIT EPL_MOBILE EPL_CROWD EPL_NOVEH EPL_GROUPQ SPL_THEME4 RPL_THEME4 SPL_THEMES RPL_THEMES F_POV F_UNEMP F_PCI F_NOHSDP F_THEME1 F_AGE65 F_AGE17 F_DISABL F_SNGPNT F_THEME2 F_MINRTY F_LIMENG F_THEME3 F_MUNIT F_MOBILE F_CROWD F_NOVEH F_GROUPQ F_THEME4 F_TOTAL E_UNINSUR M_UNINSUR EP_UNINSUR MP_UNINSUR E_DAYPOP 2 | -1 1400000US36065023400 23400 36 New York NY 36065 Oneida 36065023400 Census Tract 234, Oneida County, New York 2.4316036 4432 445 2456 84 2094 163 756 351 157 92 21900 2404 327 106 1115 170 894 216 855 176 280 117.4 407 630 43 68.1 223 95.7 0 11 0 15.6 245 102 442 206 18.4 8.6 8.1 4.6 21900 2404 10.6 3.4 25.2 4.3 20.2 4.4 19.9 3.7 13.4 5.5 9.2 14.2 1 1.6 9.1 3.9 0 1.2 0 0.7 11.7 4.8 10 4.5 0.656 0.4667 0.6379 0.4716 2.2322 0.5811 0.9432 0.3109 0.885 0.764 2.9032 0.9442 0.215 0.4519 0.6669 0.3143 0.6381 0 0 0.7569 0.9462 2.3412 0.4844 8.1435 0.6302 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 2 154 125 3.6 2.9 10017 3 | -1 1400000US36065023501 23501 36 New York NY 36065 Oneida 36065023501 Census Tract 235.01, Oneida County, New York 1.17476514 2406 137 1020 53 980 61 78 46 30 27 37997 3529 77 38 556 55 466 60 297 92 34 22.8 45 194.5 0 44 0 15.6 15 23 4 12.5 50 45 0 11 3.3 1.9 2.4 2.1 37997 3529 4.1 1.9 23.1 2.1 19.4 2.2 12.3 3.7 3.5 2.3 1.9 8.1 0 1.9 0 1.5 1.5 2.2 0.4 1.3 5.1 4.5 0 0.5 0.0833 0.0385 0.1751 0.1518 0.4488 0.0453 0.9162 0.2641 0.5122 0.1381 1.8307 0.3671 0.0285 0 0.0285 0.0184 0 0.5721 0.2321 0.47 0 1.2742 0.1242 3.5822 0.0399 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 151 100 6.3 4.2 912 4 | -1 1400000US36065023502 23502 36 New York NY 36065 Oneida 36065023502 Census Tract 235.02, Oneida County, New York 8.89152095 4498 298 1818 96 1771 115 257 188 101 48 37688 3578 155 66 825 111 1021 129 374 91 51 34.2 59 416.5 19 45.8 0 15.6 0 11 0 15.6 52 36 0 11 5.7 4.1 4.4 2.1 37688 3578 4.9 2.1 18.3 2 22.7 2.4 8.3 2.1 2.9 1.9 1.3 9.3 0.4 1.1 0 0.9 0 1.6 0 0.9 2.9 2 0 0.2 0.1872 0.1435 0.1798 0.1908 0.7013 0.1074 0.7759 0.4857 0.2188 0.1048 1.5852 0.2283 0.0186 0.3124 0.331 0.1365 0 0 0 0.279 0 0.279 0.0147 2.8965 0.0122 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 131 85 2.9 1.8 3057 5 | -1 1400000US36065023702 23702 36 New York NY 36065 Oneida 36065023702 Census Tract 237.02, Oneida County, New York 34.61642809 3799 39 1554 156 1455 129 231 103 194 106 31120 5342 88 65 587 142 772 203 580 165 46 50 163 121.4 0 44 0 15.6 235 110 27 43.4 79 58 0 11 6.1 2.7 10 5.2 31120 5342 3.3 2.3 15.5 3.7 20.3 5.3 15.3 4.3 3.2 3.4 4.3 3.2 0 1.2 0 1 15.1 6.9 1.9 3 5.4 3.9 0 0.3 0.2052 0.6135 0.3073 0.1134 1.2395 0.2702 0.621 0.3207 0.6995 0.1206 1.7619 0.325 0.093 0 0.093 0.0444 0 0.8464 0.5173 0.4907 0 1.8544 0.2867 4.9487 0.1607 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 385 136 10.2 3.6 1407 6 | -1 1400000US36065023901 23901 36 New York NY 36065 Oneida 36065023901 Census Tract 239.01, Oneida County, New York 2.32785799 2298 103 897 74 877 69 93 68 58 33 29452 2675 40 21 401 42 494 65 167 64 79 37.6 91 153.6 7 44 0 15.6 0 11 0 15.6 8 10 13 13 4.1 3 4.7 2.7 29452 2675 2.5 1.4 17.4 1.7 21.5 2.7 7.3 2.8 9 4.2 4 6.7 0.3 2 0 1.7 0 3.3 0 1.8 0.9 1.2 0.6 0.6 0.117 0.1668 0.3538 0.0784 0.7161 0.1118 0.7313 0.3995 0.1545 0.5458 1.8311 0.3674 0.0839 0.266 0.3498 0.1458 0 0 0 0.0826 0.6128 0.6953 0.0397 3.5924 0.0404 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 165 97 7.2 4.3 1646 7 | -1 1400000US36065023902 23902 36 New York NY 36065 Oneida 36065023902 Census Tract 239.02, Oneida County, New York 30.61365383 1997 88 774 40 735 46 212 111 116 59 30232 3156 127 74 265 52 400 36 179 97 17 14.9 32 126.6 34 57.1 18 30.1 142 45 0 15.6 57 41 0 11 10.6 5.4 10.1 4.6 30232 3156 9.4 5.4 13.3 2.6 20 1.6 9 4.7 2.3 2 1.6 6.3 1.8 3 2.3 3.9 18.3 5.7 0 2.1 7.8 5.6 0 0.6 0.3992 0.6208 0.3314 0.4181 1.7695 0.4379 0.4789 0.302 0.2679 0.0772 1.1261 0.0748 0.0237 0.5597 0.5834 0.2674 0.4147 0.8773 0 0.6257 0 1.9176 0.3099 5.3967 0.2176 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 155 77 7.8 3.8 873 8 | -1 1400000US36065024000 24000 36 New York NY 36065 Oneida 36065024000 Census Tract 240, Oneida County, New York 43.3764427 4480 31 1972 135 1735 113 347 134 79 57 30145 2960 210 76 753 114 1048 133 525 123 96 47.9 94 57.1 26 46.6 8 17 220 68 12 19.4 79 56 36 18 7.8 3 3.4 2.4 30145 2960 6.8 2.5 16.8 2.5 23.4 3 11.7 2.7 5.5 2.7 2.1 1.3 0.6 1.1 0.4 0.9 11.2 3.4 0.7 1.1 4.6 3.1 0.8 0.4 0.2809 0.0791 0.334 0.2877 0.9817 0.1897 0.6997 0.5369 0.469 0.2861 1.9917 0.4738 0.0343 0.362 0.3963 0.1688 0.2502 0.7998 0.3031 0.4312 0.6596 2.4439 0.5306 5.8136 0.2751 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 169 85 3.8 1.9 4696 9 | -1 1400000US36065024101 24101 36 New York NY 36065 Oneida 36065024101 Census Tract 241.01, Oneida County, New York 76.91523888 1481 127 2015 51 681 68 218 85 82 37 27850 3003 101 35 391 95 167 41 312 84 21 15.8 29 180.3 0 44 0 15.6 182 55 0 15.6 18 14 0 11 14.9 5.8 11.8 5.2 27850 3003 8.4 3 26.4 5.8 11.3 2.6 21.1 5.2 3.1 2.3 2 12.2 0 3 0 0.8 9 2.7 0 2.3 2.6 2 0 0.7 0.5554 0.7213 0.4038 0.3693 2.0498 0.5263 0.9531 0.0575 0.9123 0.1159 2.0388 0.5075 0.0307 0 0.0307 0.0196 0 0.7677 0 0.2494 0 1.0171 0.0798 5.1363 0.1837 0 0 0 0 0 1 0 1 0 2 0 0 0 0 0 0 0 0 0 2 93 38 6.3 2.5 921 -------------------------------------------------------------------------------- /js/bars.js: -------------------------------------------------------------------------------- 1 | var barwidth = 130; 2 | var barheight = 12; 3 | var color_range =['#ffffd9','#edf8b1','#c7e9b4','#7fcdbb','#41b6c4','#1d91c0','#225ea8','#253494','#081d58']; 4 | var width = d3.scaleLinear().domain([0, 100]).range([0, barwidth]); 5 | var data_bins = [11, 22, 33, 44, 55, 66, 77, 88, 105]; 6 | var colorScale = d3.scaleLinear().domain(data_bins).range(color_range); 7 | 8 | var container = d3.select('#overlay-ses'); 9 | 10 | // 11 | 12 | var layout = [ 13 | { 14 | title: 'Socioeconomic Status', 15 | items: [ 16 | { title: 'Below poverty', code: 'EPL_POV' }, 17 | { title: 'Unemployed', code: 'EPL_UNEMP' }, 18 | { title: 'Income', code: 'EPL_PCI' }, 19 | { title: 'No High School Diploma', code: 'EPL_NOHSDP' } 20 | ] 21 | }, 22 | { 23 | title: 'Household Composition', 24 | items: [ 25 | { title: 'Aged 65 or Over', code: 'EPL_AGE6' }, 26 | { title: 'Aged 17 or Younger', code: 'EPL_AGE1' }, 27 | { title: 'Disability Aged 5+', code: 'EPL_DIS' }, 28 | { title: 'Single-Parent Households', code: 'EPL_SNGPNT' } 29 | ] 30 | }, 31 | { 32 | title: 'Minority Status/Language', 33 | items: [ 34 | { title: 'Minority', code: 'EPL_MINRTY' }, 35 | { title: 'Speaks English "Less than Well"', code: 'EPL_LIMENG' } 36 | ] 37 | }, 38 | { 39 | title: 'Housing and Transportation', 40 | items: [ 41 | { title: 'Multi-Unit Structures', code: 'EPL_MUNIT' }, 42 | { title: 'Mobile Homes', code: 'EPL_MOBILE' }, 43 | { title: 'Crowding', code: 'EPL_CROWD' }, 44 | { title: 'No Vehicle', code: 'EPL_NOVEH' }, 45 | { title: 'Group Quarters', code: 'EPL_GRO' } 46 | ] 47 | } 48 | ]; 49 | 50 | //function updateSidebarTitle(title) { 51 | // $('#overlay-title').text(title)} 52 | 53 | function updateSidebar(options) { 54 | console.log(options); 55 | layout.forEach(function(category) { 56 | category.items.forEach(function(item) { 57 | item.value = options[item.code] || options[item.code.substring(0, 7)]; 58 | }); 59 | }); 60 | 61 | d3.select('#location').text(options.LOCATIO); 62 | d3.select('#F_Total-bignumber').text(options.FNew); 63 | d3.select('#population').text(function(d) { 64 | return 'Population ' + d3.format(',')(options.E_TOTPO); 65 | }); 66 | d3.select('#diocese').text(function(d) { 67 | return 'Catholic Diocese: ' + options.Diocese; 68 | }); 69 | 70 | var categories = container 71 | .selectAll('div.category') 72 | .data(layout, function(d) { 73 | return d.title; 74 | }); 75 | 76 | var categoryEnter = categories 77 | .enter() 78 | .append('div') 79 | .attr('class', 'category'); 80 | 81 | categoryEnter.append('div').append('h6').text(function(category) { 82 | return category.title; 83 | }); 84 | 85 | var items = categories.merge(categoryEnter).selectAll('div.item').data( 86 | function(data) { 87 | return data.items; 88 | }, 89 | function(data) { 90 | return data.title; 91 | } 92 | ); 93 | 94 | var itemEnter = items.enter().append('div').attr('class', 'item cf'); 95 | 96 | itemEnter.append('div').attr('class', 'item-title fl w-40').text(function(category) { 97 | return category.title; 98 | }); 99 | 100 | 101 | 102 | 103 | var img = items.selectAll('div.flag-col').data(function(data) { 104 | return data.value > 90 ? [data] : []; 105 | }); 106 | 107 | img.exit().remove(); 108 | 109 | img 110 | .enter() 111 | .append('div') 112 | .attr('class', 'flag-col fl w-10 center') 113 | .append('img') 114 | .attr('src', 'icons/flag.svg') 115 | .attr('width', 12) 116 | .style('vertical-align', 'top') 117 | .style('padding-left', '3px') 118 | .attr('height', 12); 119 | 120 | 121 | 122 | itemEnter.append('div').attr('class', 'item-number fl w-10'); 123 | items = items.merge(itemEnter); 124 | 125 | var svg = items.selectAll('g').data(function(data) { 126 | return [data]; 127 | }); 128 | 129 | svg.selectAll(".point").remove(); 130 | 131 | 132 | var svgEnter = svg 133 | .enter() 134 | .append('div') 135 | .attr('class', 'fl w-40') 136 | .append('svg') 137 | .attr("preserveAspectRatio", "xMinYMin meet") 138 | .attr("viewBox", "0 0 130 8") 139 | // .attr('width', barwidth + 2) 140 | .style('vertical-align', 'top') 141 | // .attr('height', barheight + 2) 142 | .append('g') 143 | .attr('transform', 'translate(2, 2)'); 144 | 145 | svgEnter 146 | .append('rect') 147 | .attr('class', 'bar-background') 148 | .attr('rx', 0) 149 | .attr('ry', 0) 150 | .attr('height', 10) 151 | .attr('width', width(100)) 152 | .style('stroke', 'none') 153 | .style('fill', '#ccc'); 154 | 155 | svgEnter 156 | .append('rect') 157 | .attr('class', 'bar') 158 | .attr('rx', 0) 159 | .attr('ry', 0) 160 | .attr('height', 10) 161 | .attr('width', 0) 162 | .style('fill', '#fff'); 163 | 164 | 165 | 166 | svgEnter 167 | .append('svg') 168 | .attr('class', 'flag') 169 | .attr('y', 12) 170 | .style('fill', '#ffffff'); 171 | 172 | svg = svg.merge(svgEnter); 173 | items = items.merge(itemEnter); 174 | 175 | svg 176 | .select('rect.bar') 177 | .transition() 178 | .duration(300) 179 | .attr('width', function(d) { 180 | return d.value !== undefined ? 181 | width(d.value) : width(1); 182 | }) 183 | .style('fill', function(d) { 184 | return d.value !== undefined ? 185 | colorScale(d.value) : '#ccc'; 186 | }); 187 | 188 | items 189 | .select('div.item-number') 190 | .text(function(d) { 191 | return d.value === undefined ? 192 | 'N/A' : d3.format('.1f')(d.value); 193 | }); 194 | } 195 | 196 | updateSidebar({}); 197 | -------------------------------------------------------------------------------- /css/mapbox-geocoder.css: -------------------------------------------------------------------------------- 1 | .mapboxgl-ctrl-geocoder, 2 | .mapboxgl-ctrl-geocoder *, 3 | .mapboxgl-ctrl-geocoder *:after, 4 | .mapboxgl-ctrl-geocoder *:before { 5 | -webkit-box-sizing:border-box; 6 | -moz-box-sizing:border-box; 7 | box-sizing:border-box; 8 | } 9 | .mapboxgl-ctrl-geocoder { 10 | font:15px/20px font-family: 'Roboto', sans-serif; 11 | position:relative; 12 | margin-right: 10px; 13 | margin-left: 10px; 14 | background-color:white; 15 | width:30%; 16 | min-width:180px; 17 | max-width:360px; 18 | z-index:1; 19 | border-radius:12px; 20 | } 21 | 22 | .mapboxgl-ctrl-geocoder input[type='text'] { 23 | font-size:12px; 24 | font-family: 'Roboto', sans-serif; 25 | width:100%; 26 | border:0; 27 | background-color:transparent; 28 | height:25px; 29 | margin:0; 30 | color:rgba(0,0,0,1); 31 | padding:10px 10px 10px 40px; 32 | text-overflow:ellipsis; 33 | white-space:nowrap; 34 | overflow:hidden; 35 | } 36 | .mapboxgl-ctrl-geocoder input:focus { 37 | color:rgba(0,0,0,.75); 38 | font-family: 'Roboto', sans-serif; 39 | outline:0; 40 | box-shadow:none; 41 | outline:thin dotted\8; 42 | } 43 | 44 | .mapboxgl-ctrl-geocoder .geocoder-icon-search { 45 | position:absolute; 46 | top:3px; 47 | left:10px; 48 | } 49 | .mapboxgl-ctrl-geocoder button { 50 | padding:0; 51 | margin:0; 52 | background-color:#fff; 53 | border:none; 54 | cursor:pointer; 55 | } 56 | .mapboxgl-ctrl-geocoder .geocoder-pin-right * { 57 | background-color:#fff; 58 | z-index:2; 59 | position:absolute; 60 | right:10px; 61 | top:10px; 62 | display:none; 63 | } 64 | 65 | .mapboxgl-ctrl-geocoder, 66 | .mapboxgl-ctrl-geocoder ul { 67 | box-shadow: 0 0 0 2px rgba(0,0,0,0.1); 68 | } 69 | 70 | /* Suggestions */ 71 | .mapboxgl-ctrl-geocoder ul { 72 | background-color:#fff; 73 | border-radius: 0 0 3px 3px; 74 | left:0; 75 | list-style:none; 76 | margin:0; 77 | padding:0; 78 | position:absolute; 79 | width:100%; 80 | top:100%; 81 | z-index:1000; 82 | overflow:hidden; 83 | font-size:12px; 84 | } 85 | .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl-geocoder ul, 86 | .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl-geocoder ul { 87 | top:auto; 88 | bottom:100%; 89 | } 90 | .mapboxgl-ctrl-geocoder ul > li > a { 91 | clear:both; 92 | font-family: 'Roboto', sans-serif; 93 | cursor:default; 94 | display:block; 95 | padding:5px 10px; 96 | white-space:nowrap; 97 | overflow:hidden; 98 | text-overflow:ellipsis; 99 | white-space:nowrap; 100 | border-bottom:1px solid rgba(0,0,0,0.1); 101 | color:#404040; 102 | } 103 | .mapboxgl-ctrl-geocoder ul > li:last-child > a { border-bottom:none; } 104 | .mapboxgl-ctrl-geocoder ul > li > a:hover { 105 | font-family: 'Roboto', sans-serif; 106 | color:#fff; 107 | background-color:#332A85; 108 | text-decoration:none; 109 | cursor:pointer; 110 | } 111 | .mapboxgl-ctrl-geocoder ul > li.active > a { 112 | color:#fff; 113 | font-family: 'Roboto', sans-serif; 114 | background-color:#332A85; 115 | text-decoration:none; 116 | cursor:pointer; 117 | } 118 | 119 | @-webkit-keyframes rotate { from { -webkit-transform: rotate(0deg); } to { -webkit-transform: rotate(360deg); } } 120 | @-moz-keyframes rotate { from { -moz-transform: rotate(0deg); } to { -moz-transform: rotate(360deg); } } 121 | @-ms-keyframes rotate { from { -ms-transform: rotate(0deg); } to { -ms-transform: rotate(360deg); } } 122 | @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } 123 | 124 | /* icons */ 125 | .geocoder-icon { 126 | display:inline-block; 127 | width:20px; 128 | height:20px; 129 | vertical-align:middle; 130 | speak:none; 131 | background-repeat:no-repeat; 132 | } 133 | .geocoder-icon-search { 134 | background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgdmVyc2lvbj0iMS4xIj4NCiAgPHBhdGggZD0iTTguNSA0QzYgNCA0IDYgNCA4LjUgNCAxMSA2IDEzIDguNSAxMyA5LjQgMTMgMTAuMiAxMi44IDEwLjggMTIuM0wxMC45IDEyLjMgMTQuMyAxNS43QzE0LjUgMTUuOSAxNC43IDE2IDE1IDE2IDE1LjYgMTYgMTYgMTUuNiAxNiAxNSAxNiAxNC43IDE1LjkgMTQuNSAxNS43IDE0LjNMMTIuMyAxMC45IDEyLjMgMTAuOEMxMi44IDEwLjIgMTMgOS40IDEzIDguNSAxMyA2IDExIDQgOC41IDR6TTguNSA1LjVDMTAuMiA1LjUgMTEuNSA2LjggMTEuNSA4LjUgMTEuNSAxMC4yIDEwLjIgMTEuNSA4LjUgMTEuNSA2LjggMTEuNSA1LjUgMTAuMiA1LjUgOC41IDUuNSA2LjggNi44IDUuNSA4LjUgNS41eiIgZmlsbD0iIzAwMCIvPg0KPC9zdmc+); 135 | } 136 | .geocoder-icon-close { 137 | background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgdmVyc2lvbj0iMS4xIiBoZWlnaHQ9IjIwIiB3aWR0aD0iMjAiPg0KICA8cGF0aCBkPSJtNSA1IDAgMS41IDMuNSAzLjUtMy41IDMuNSAwIDEuNSAxLjUgMCAzLjUtMy41IDMuNSAzLjUgMS41IDAgMC0xLjUtMy41LTMuNSAzLjUtMy41IDAtMS41LTEuNSAwLTMuNSAzLjUtMy41LTMuNS0xLjUgMHoiIGZpbGw9IiMwMDAiLz4NCjwvc3ZnPg==); 138 | } 139 | .geocoder-icon-loading { 140 | background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIiB2aWV3Qm94PSIwIDAgMjAgMjAiPjxwYXRoIGQ9Im0xMCAyIDAgMy4zYzIuNiAwIDQuNyAyLjEgNC43IDQuN2wzLjMgMGMwLTQuNC0zLjYtOC04LTh6IiBmaWxsPSIjMDAwIi8+PHBhdGggZD0iTTEwIDJDNi44IDIgMy43IDQuMSAyLjYgNy4xIDEuNCAxMCAyLjEgMTMuNiA0LjUgMTUuOGMyLjQgMi40IDYuNCAyLjkgOS40IDEuMiAyLjUtMS40IDQuMi00LjIgNC4yLTctMS4xIDAtMi4yIDAtMy4zIDAgMC4xIDIuMi0xLjcgNC4zLTMuOCA0LjZDOC43IDE1IDYuNCAxMy44IDUuNyAxMS43IDQuOCA5LjcgNS42IDcuMSA3LjYgNiA4LjMgNS42IDkuMSA1LjMgMTAgNS4zYzAtMS4xIDAtMi4yIDAtMy4zeiIgc3R5bGU9ImZpbGw6IzAwMDtvcGFjaXR5OjAuMiIvPjwvc3ZnPg==); 141 | -webkit-animation: rotate 400ms linear infinite; 142 | -moz-animation: rotate 400ms linear infinite; 143 | -ms-animation: rotate 400ms linear infinite; 144 | animation: rotate 400ms linear infinite; 145 | } -------------------------------------------------------------------------------- /js/newdonut.js: -------------------------------------------------------------------------------- 1 | var Donut=function(el,variable,iconurl){ 2 | var donut=this; 3 | 4 | var ele = features.offsetWidth; 5 | /* Below is the width of ele */ 6 | 7 | console.log(ele); 8 | 9 | donut.variable=variable; 10 | 11 | donut.tau = 2 * Math.PI; // http://tauday.com/tau-manifesto 12 | 13 | // An arc function with all values bound except the endAngle. So, to compute an 14 | // SVG path string for a given angle, we pass an object with an endAngle 15 | // property to the `arc` function, and it will return the corresponding string. 16 | 17 | var donutwidth = (ele/7.5); 18 | console.log(donutwidth); 19 | var donutheight = donutwidth; 20 | var donut_color_range = 21 | ['#ffffcc','#ffeda0','#fed976','#feb24c','#fd8d3c','#fc4e2a','#e31a1c','#bd0026','#800026']; 22 | 23 | var donut_data_bins = [3,6,9,12,15,18,21,24,60]; 24 | donut.donutcolorScale = d3.scaleLinear().domain(donut_data_bins).range(donut_color_range); 25 | 26 | 27 | 28 | // nothing here yet 29 | 30 | 31 | 32 | donut.arc = d3.arc() 33 | .innerRadius((donutwidth/2)*.5) 34 | .outerRadius(donutwidth/2*.9) 35 | .startAngle(0); 36 | 37 | // Get the SVG container, and apply a transform such that the origin is the 38 | // center of the canvas. This way, we don’t need to position arcs individually. 39 | var svg = d3.select("#donut-1").append("svg") 40 | .attr('id','donut') 41 | .attr('width',donutwidth) 42 | .attr('height',donutheight) 43 | 44 | g = svg.append("g").attr("transform", "translate(" + donutwidth / 2 + "," + donutheight / 2 + ")"); 45 | 46 | // Add the background arc, from 0 to 100% (tau). 47 | var background = g.append("path") 48 | .datum({endAngle: donut.tau}) 49 | .style('stroke', 'none') 50 | .style('fill', '#ccc') 51 | .attr("d", donut.arc); 52 | 53 | donut.foreground = g.append("path") 54 | .datum({endAngle: 0 * donut.tau}) 55 | .style("fill", "orange") 56 | .style('border-radius',4) 57 | .attr("d", donut.arc); 58 | 59 | 60 | 61 | // Add the foreground arc in orange, currently showing 12.7%. 62 | 63 | 64 | //var text = g.append("text") 65 | // .attr("x", 0) 66 | //.attr("y", 0) 67 | //.style('fill','#fff') 68 | //.text(""); 69 | 70 | 71 | var img=g.append('image') 72 | .attr("xlink:href", iconurl) 73 | .style('fill','#fff') 74 | .attr("x", -9) 75 | .attr("y", -9) 76 | .attr("width", 17) 77 | .attr("height", 17); 78 | 79 | }; 80 | 81 | // Every so often, start a transition to a new random angle. The attrTween 82 | // definition is encapsulated in a separate function (a closure) below. 83 | Donut.prototype.updateHazard=function(options) { 84 | var donut=this; 85 | console.log(options); 86 | donut.foreground.transition() 87 | .duration(300) 88 | .style('fill',function(d) { 89 | return donut.donutcolorScale(options[donut.variable]);}) 90 | .attrTween("d", donut.arcTween(options[donut.variable]/60 * donut.tau)); 91 | 92 | } 93 | 94 | 95 | 96 | // Returns a tween for a transition’s "d" attribute, transitioning any selected 97 | // arcs from their current angle to the specified new angle. 98 | Donut.prototype.arcTween=function(newAngle) { 99 | var donut=this; 100 | // The function passed to attrTween is invoked for each selected element when 101 | // the transition starts, and for each element returns the interpolator to use 102 | // over the course of transition. This function is thus responsible for 103 | // determining the starting angle of the transition (which is pulled from the 104 | // element’s bound datum, d.endAngle), and the ending angle (simply the 105 | // newAngle argument to the enclosing function). 106 | return function(d) { 107 | 108 | // To interpolate between the two angles, we use the default d3.interpolate. 109 | // (Internally, this maps to d3.interpolateNumber, since both of the 110 | // arguments to d3.interpolate are numbers.) The returned function takes a 111 | // single argument t and returns a number between the starting angle and the 112 | // ending angle. When t = 0, it returns d.endAngle; when t = 1, it returns 113 | // newAngle; and for 0 < t < 1 it returns an angle in-between. 114 | var interpolate = d3.interpolate(d.endAngle, newAngle); 115 | 116 | // The return value of the attrTween is also a function: the function that 117 | // we want to run for each tick of the transition. Because we used 118 | // attrTween("d"), the return value of this last function will be set to the 119 | // "d" attribute at every tick. (It’s also possible to use transition.tween 120 | // to run arbitrary code for every tick, say if you want to set multiple 121 | // attributes from a single function.) The argument t ranges from 0, at the 122 | // start of the transition, to 1, at the end. 123 | return function(t) { 124 | 125 | // Calculate the current arc angle based on the transition time, t. Since 126 | // the t for the transition and the t for the interpolate both range from 127 | // 0 to 1, we can pass t directly to the interpolator. 128 | // 129 | // Note that the interpolated angle is written into the element’s bound 130 | // data object! This is important: it means that if the transition were 131 | // interrupted, the data bound to the element would still be consistent 132 | // with its appearance. Whenever we start a new arc transition, the 133 | // correct starting angle can be inferred from the data. 134 | d.endAngle = interpolate(t); 135 | 136 | // Lastly, compute the arc path given the updated data! In effect, this 137 | // transition uses data-space interpolation: the data is interpolated 138 | // (that is, the end angle) rather than the path string itself. 139 | // Interpolating the angles in polar coordinates, rather than the raw path 140 | // string, produces valid intermediate arcs during the transition. 141 | return donut.arc(d); 142 | }; 143 | }; 144 | } 145 | 146 | var donuts = [ 147 | new Donut('#donut-1', 'Hurricn','icons/hurricane - black.svg'), 148 | new Donut('#donut-2', 'Flood','icons/flood - black.svg'), 149 | new Donut('#donut-3', 'Earthqk','icons/earthquake - black.svg'), 150 | new Donut('#donut-4', 'Wildfir','icons/wildfire - black.svg'), 151 | new Donut('#donut-5', 'Tornado','icons/tornado - black.svg'), 152 | new Donut('#donut-6', 'Hail','icons/hail - black.svg'), 153 | ]; 154 | 155 | function updateDonuts(options) { 156 | donuts.forEach(function(donut) { 157 | donut.updateHazard(options); 158 | }) 159 | } 160 | -------------------------------------------------------------------------------- /scripts/DataClean.R: -------------------------------------------------------------------------------- 1 | # Install as necessary: 2 | #install.packages('magrittr') 3 | #install.packages('rgdal') 4 | #install.packages('stringr') 5 | #install.packages('raster') 6 | #install.packages('dplyr') 7 | 8 | library(magrittr) 9 | library(rgdal) 10 | library(stringr) 11 | library(raster) 12 | library(sf) 13 | library(dplyr) 14 | 15 | # CDC data. Available at https://svi.cdc.gov/SVIDataToolsDownload.html 16 | # replace /Users/jakesnyder/DisasterVulnerability/ with the path to the data on your machine 17 | 18 | #Jake's Paths 19 | cdc_county_path <- "/Users/jakesnyder/DisasterVulnerability/County" 20 | cdc_tract_path <- "/Users/jakesnyder/DisasterVulnerability/Tract" 21 | hazard_path <- "/Users/jakesnyder/DisasterVulnerability/ATTOM hazard.csv" 22 | ccusa_path <- "/Users/jakesnyder/DisasterVulnerability/CountiesDioceses_052017.csv" 23 | main_path <- "/Users/jakesnyder/DisasterVulnerability" 24 | pr_county_path <- "/Users/jakesnyder/DisasterVulnerability/PRCounty" 25 | pr_tract_path <- "/Users/jakesnyder/DisasterVulnerability/PRTract" 26 | 27 | #Rich's Paths 28 | #cdc_path<-"/Users/Richard/Documents/dev/DisasterVulnerability/merge_no_nulls" 29 | #hazard_path<-"/Users/Richard/Documents/dev/DisasterVulnerability/ATTOM.csv" 30 | #ccusa_path<-"/Users/Richard/Documents/dev/DisasterVulnerability/Poly_Counties.csv" 31 | 32 | cdc_data <- readOGR(dsn = cdc_county_path, layer = "counties", stringsAsFactors = F) 33 | pr_county_data <- readOGR(dsn = pr_county_path, layer = "PUERTORICO_CNTY", stringsAsFactors = F) 34 | 35 | # Disaster likelyhood by fips. Available if you have accest to proprietary data 36 | hazard_data <- read.csv(hazard_path,stringsAsFactors = F, colClasses = c("FIPS" = "character")) 37 | 38 | #remove extra columns 39 | hazard_data<-hazard_data[,1:12] 40 | 41 | # remove NA's from hazard data 42 | hazard_data <- na.omit(hazard_data) 43 | 44 | # Load CCUSA agency and remove extra columns 45 | ccusa <- read.csv(ccusa_path,stringsAsFactors = F) 46 | ccusa <- ccusa %>% select(FIPS,Diocese) %>% 47 | mutate(FIPS = str_pad(FIPS,5,pad="0")) 48 | 49 | 50 | # join hazard data to shapefile 51 | merge_data <- merge(cdc_data, hazard_data, by.x="FIPS", by.y="FIPS", all.x=T) 52 | merge_data <- merge(merge_data, ccusa, by = "FIPS", all.x=T) 53 | 54 | # getting data as data frame 55 | county <- merge_data@data 56 | pr_counties <- pr_county_data@data 57 | 58 | # removing columns we don't need to keep the shapefile smaller 59 | county <- county %>% select(FIPS, 60 | LOCATIO, 61 | E_TOTPO, 62 | F_TOTAL, 63 | starts_with('EP'), 64 | -EP_UNIN, 65 | starts_with('RP'), 66 | contains('Risk'), 67 | Diocese) %>% 68 | # rename columns to match tract file 69 | rename(LOCATION = LOCATIO, 70 | E_TOTPOP = E_TOTPO, 71 | EP_UNEMP = EP_UNEM, 72 | EP_NOHSDP = EP_NOHS, 73 | EP_AGE65 = EP_AGE6, 74 | EP_AGE17 = EP_AGE1, 75 | EP_DISABL = EP_DISA, 76 | EP_SNGPNT = EP_SNGP, 77 | EP_MINRTY = EP_MINR, 78 | EP_LIMENG = EP_LIME, 79 | EP_MUNIT = EP_MUNI, 80 | EP_MOBILE = EP_MOBI, 81 | EP_CROWD = EP_CROW, 82 | EP_NOVEH = EP_NOVE, 83 | EP_GROUPQ = EP_GROU, 84 | EPL_UNEMP = EPL_UNE, 85 | EPL_NOHSDP = EPL_NOH, 86 | EPL_AGE65 = EPL_AGE6, 87 | EPL_AGE17 = EPL_AGE1, 88 | EPL_DISABL = EPL_DIS, 89 | EPL_SNGPNT = EPL_SNG, 90 | EPL_MINRTY = EPL_MIN, 91 | EPL_LIMENG = EPL_LIM, 92 | EPL_MUNIT = EPL_MUN, 93 | EPL_MOBILE = EPL_MOB, 94 | EPL_CROWD = EPL_CRO, 95 | EPL_NOVEH = EPL_NOV, 96 | EPL_GROUPQ = EPL_GRO) %>% 97 | # set null values created by join to 0 98 | mutate(Total.Natural.Hazard.Risk.Index = ifelse(is.na(Total.Natural.Hazard.Risk.Index),0,Total.Natural.Hazard.Risk.Index)) %>% 99 | mutate(Earthquake.Risk.Index = ifelse(is.na(Earthquake.Risk.Index),0,Earthquake.Risk.Index)) %>% 100 | mutate(Tornado.Risk.Index = ifelse(is.na(Tornado.Risk.Index),0,Tornado.Risk.Index)) %>% 101 | mutate(Hail.Risk.Index = ifelse(is.na(Hail.Risk.Index),0,Hail.Risk.Index)) %>% 102 | mutate(Hurricane.Storm.Surge.Risk.Index = ifelse(is.na(Hurricane.Storm.Surge.Risk.Index),0,Hurricane.Storm.Surge.Risk.Index)) %>% 103 | mutate(Flood.Risk.Index = ifelse(is.na(Flood.Risk.Index),0,Flood.Risk.Index)) %>% 104 | mutate(Wildfire.Risk.Index = ifelse(is.na(Wildfire.Risk.Index),0,Wildfire.Risk.Index)) %>% 105 | # rename hazard field names to be <11 characters 106 | rename(Total.Risk = Total.Natural.Hazard.Risk.Index, 107 | Earthquake = Earthquake.Risk.Index, 108 | Tornado = Tornado.Risk.Index, 109 | Hail = Hail.Risk.Index, 110 | Hurricane = Hurricane.Storm.Surge.Risk.Index, 111 | Flood = Flood.Risk.Index, 112 | Wildfire = Wildfire.Risk.Index) 113 | 114 | # modify PR counties to match other counties 115 | county_cols <- colnames(county) 116 | pr_counties <- pr_counties %>% 117 | mutate(Total.Risk = 0, 118 | Earthquake = 0, 119 | Tornado = 0, 120 | Hail = 0, 121 | Hurricane = 0, 122 | Flood = 0, 123 | Wildfire = 0, 124 | Diocese = '') %>% 125 | select_(.dots=county_cols) 126 | 127 | # setting it back to a large SpatialPolygonsDataframe 128 | merge_data@data <- county 129 | pr_county_data@data <- pr_counties 130 | 131 | # merge PR into larger dataset 132 | merge_data <- raster::union(merge_data,pr_county_data) 133 | 134 | # write to shapefile 135 | writeOGR(merge_data, dsn=main_path, layer="counties", driver="ESRI Shapefile", overwrite_layer = T) 136 | 137 | ## tract file reduction 138 | svi <- readOGR(cdc_tract_path, stringsAsFactors = F) 139 | tract <- svi@data 140 | 141 | pr_tract_data <- readOGR(dsn = pr_tract_path, layer = "PUERTORICO", stringsAsFactors = F) 142 | pr_tracts <- pr_tract_data@data 143 | 144 | # removing columns we don't need to keep the shapefile smaller 145 | tract <- tract %>% select(FIPS, 146 | LOCATION, 147 | E_TOTPOP, 148 | F_TOTAL, 149 | starts_with('EP'), 150 | -EP_UNINSUR, 151 | starts_with('RP')) 152 | 153 | # modify PR tract data to match tract 154 | tract_names <- colnames(tract) 155 | 156 | pr_tracts <- pr_tracts %>% 157 | select_(.dots=tract_names) 158 | 159 | # change null values to zero 160 | tract[tract==-999] <- 0 161 | pr_tracts[pr_tracts==-999] <- 0 162 | 163 | # setting it back to a large SpatialPolygonsDataframe 164 | svi@data <- tract 165 | pr_tract_data@data <- pr_tracts 166 | 167 | # merge PR into larger dataset 168 | svi <- raster::union(svi,pr_tract_data) 169 | 170 | # write to shapefile 171 | writeOGR(svi, dsn=main_path, layer="tracts", driver="ESRI Shapefile", overwrite_layer = T) 172 | -------------------------------------------------------------------------------- /icons/flood.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 31 | 48 | 49 | 57 | 65 | 73 | 74 | -------------------------------------------------------------------------------- /icons/flood - black.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 31 | 48 | 49 | 57 | 65 | 73 | 74 | -------------------------------------------------------------------------------- /js/mapbox.js: -------------------------------------------------------------------------------- 1 | mapboxgl.accessToken = 'pk.eyJ1IjoiZGF0YWtpbmRkYyIsImEiOiJjaWppcmZtMHcwMnZ2dHlsdDlzenN0MnRqIn0.FsB8WZ_HKhb3mPa1MPXxdw'; 2 | 3 | const toggleableLayerIds = [ 4 | 'Social Vulnerability - Overall', 5 | 'Socioeconomic Status', 6 | 'Household Composition & Disability', 7 | 'Housing & Transportation', 8 | 'Total Natural Hazard Risk', 9 | 'Earthquake Risk', 10 | 'Tornado Risk', 11 | 'Hail Risk', 12 | 'Hurricane Risk', 13 | 'Flood Risk', 14 | 'Wildfire Risk' 15 | ]; 16 | const toggleableLayersSocial = [ 17 | { ids: ['tract', 'county'], name: ['Social Vulnerability - Overall']}, 18 | { ids: ['tract-socio','county-socio'], name: ['Socioeconomic Vulnerability']}, 19 | { ids: ['tract-household','county-household'], name: ['Household Composition and Disability Vulnerability']}, 20 | { ids: ['tract-minority','county-minority'], name: ['Minority Status and Language Vulnerability']}, 21 | { ids: ['tract-household','county-housing'], name: ['Housing and Transportation Vulnerability']}, 22 | ]; 23 | 24 | const toggleableLayersHazard = [ 25 | { ids: ['county-hazard'], name: ['Overall Hazard Risk']}, 26 | { ids: ['county-hurricane'], name: ['Hurricane Risk'], icon: ['icons/hurricane.svg']}, 27 | { ids: ['county-flood'], name: ['Flood Risk'], icon: ['icons/flood.svg']}, 28 | { ids: ['county-earthquake'], name: ['Earthquake Risk'], icon: ['icons/earthquake.svg']}, 29 | { ids: ['county-wildfire'], name: ['Wildfire Risk'], icon: ['icons/wildfire.svg']}, 30 | { ids: ['county-tornado'], name: ['Tornado Risk'], icon: ['icons/tornado.svg']}, 31 | { ids: ['county-hail'], name: ['Hail Risk'], icon: ['icons/hail.svg']}, 32 | ]; 33 | 34 | function addCustomLayers(map) { 35 | 36 | mapSources.forEach(function(source) { 37 | let id = source[0]; 38 | let obj = source[1]; 39 | map.addSource(id, obj) 40 | }); 41 | 42 | mapLayers.forEach(function(layer) { 43 | let obj = layer[0]; 44 | let label = layer[1]; 45 | map.addLayer(obj, label); 46 | }); 47 | 48 | } 49 | 50 | 51 | function hideAllLayers() { 52 | toggleableLayersSocial.forEach(function(layer, i) { 53 | var link = menusocial.children[i]; 54 | link.className = ''; 55 | layer.ids.forEach(function(layerId) { 56 | map.setLayoutProperty(layerId, 'visibility', 'none'); 57 | }); 58 | }); 59 | toggleableLayersHazard.forEach(function(layer, i) { 60 | var link = menuhazard.children[i]; 61 | link.className = ''; 62 | layer.ids.forEach(function(layerId) { 63 | map.setLayoutProperty(layerId, 'visibility', 'none'); 64 | }); 65 | }); 66 | } 67 | 68 | function setOnLinkClickHandler(link, layer) { 69 | link.onclick = function (e) { 70 | e.preventDefault(); 71 | e.stopPropagation(); 72 | hideAllLayers(); 73 | this.className = 'active'; 74 | layer.ids.forEach(function(layerId) { 75 | map.setLayoutProperty(layerId, 'visibility', 'visible'); 76 | }); 77 | 78 | updateLegend(layer.ids[0],layer.name[0]) 79 | 80 | }; 81 | } 82 | 83 | function takeSnapshot() { 84 | newTab = window.open(printLink, 'Image'); 85 | newTab.focus(); 86 | } 87 | 88 | function loadPrintLink(map) { 89 | 90 | let el = $("#print-link"); 91 | el.text('Print Current View'); 92 | el.css("pointer-events", "all"); 93 | el.css("cursor", "pointer"); 94 | 95 | el.click(function() { 96 | printLink = map.getCanvas().toDataURL("image/png"); 97 | takeSnapshot() 98 | }); 99 | } 100 | 101 | 102 | var geocoder = new MapboxGeocoder({ 103 | accessToken: mapboxgl.accessToken, 104 | zoom: 14, 105 | types: 'region,postcode,district,place', 106 | country: 'US' 107 | }); 108 | 109 | 110 | var map = new mapboxgl.Map({ 111 | container: 'map', // container id 112 | style: 'mapbox://styles/datakinddc/cin4w64ct0005abkuk6wxrak1', 113 | zoom: 2, 114 | hash:true, 115 | center: [-110.93, 38.49], 116 | minZoom: 3.5, 117 | // We only need to preserve drawing buffer if we implement printing 118 | // otherwise it is a performance drawback 119 | preserveDrawingBuffer: true, 120 | attributionControl: false 121 | }); 122 | 123 | function addLayerNav(map) { 124 | 125 | var menusocial = document.getElementById('menusocial'); 126 | var menuhazard = document.getElementById('menuhazard'); 127 | 128 | toggleableLayersSocial.forEach(function(layer) { 129 | var link = document.createElement('a'); 130 | link.href = '#'; 131 | link.textContent = layer.name; 132 | 133 | setOnLinkClickHandler(link, layer); 134 | 135 | menusocial.appendChild(link); 136 | }); 137 | 138 | toggleableLayersHazard.forEach(function(layer) { 139 | var link = document.createElement('a'); 140 | link.href = '#'; 141 | link.textContent = layer.name; 142 | 143 | setOnLinkClickHandler(link, layer); 144 | 145 | menuhazard.appendChild(link); 146 | }); 147 | } 148 | 149 | //map.addControl(geocoder, 'top-left'); 150 | 151 | d3.select('#search') 152 | .node() 153 | .appendChild(geocoder.onAdd(map)); 154 | 155 | 156 | map.on('load', function() { 157 | addCustomLayers(map); 158 | addLayerNav(map); 159 | loadPrintLink(map); 160 | 161 | 162 | var lastFIPS=0; 163 | var click='FALSE'; 164 | 165 | map.on('click', function (e){ 166 | if(click==='TRUE'){ 167 | click='FALSE' 168 | }else{click='TRUE'}; 169 | console.log(click); 170 | } ); 171 | 172 | 173 | map.on('mousemove', function (e) { 174 | if(click==='FALSE'){ 175 | var county = map.queryRenderedFeatures(e.point, { 176 | layers: ['county','county-socio','county-housing','county-household','county-minority', 177 | 'county-hazard','county-hurricane','county-flood', 'county-earthquake','county-wildfire', 178 | 'county-tornado','county-hail'] 179 | }); 180 | var tract = map.queryRenderedFeatures(e.point, { 181 | layers: ['tract','tract-socio','tract-household','tract-housing','tract-minority'] 182 | }); 183 | 184 | if (tract.length>0){ 185 | tract.map(function(e2){ 186 | e2.properties.Earthquake = 0; 187 | e2.properties.Hail = 0; 188 | e2.properties.Flood = 0; 189 | e2.properties.Hurricane = 0; 190 | e2.properties.Tornado = 0; 191 | e2.properties.Diocese = 0; 192 | return e2; 193 | }); 194 | if (county.length > 0){ 195 | tract.map(function(e2){ 196 | e2.properties.Earthquake = county[0].properties.Earthquake; 197 | e2.properties.Hail = county[0].properties.Hail; 198 | e2.properties.Flood = county[0].properties.Flood; 199 | e2.properties.Hurricane = county[0].properties.Hurricane; 200 | e2.properties.Tornado = county[0].properties.Tornado; 201 | e2.properties.Diocese = county[0].properties.Diocese; 202 | return e2; 203 | }); 204 | } 205 | } 206 | 207 | if (county.length > 0 && map.getZoom() < 8.0) { 208 | map.getSource('highlight').setData({ 209 | "type": "FeatureCollection", 210 | "features": county 211 | }); 212 | if (county[0].properties.FIPS !== lastFIPS) { 213 | updateSidebar(county[0].properties); 214 | updateDonuts(county[0].properties); 215 | lastFIPS = county[0].properties.FIPS; 216 | } 217 | 218 | } 219 | else if (tract.length>0 && map.getZoom() >= 8.0) { 220 | map.getSource('highlight').setData({ 221 | "type": "FeatureCollection", 222 | "features": tract 223 | }); 224 | if (tract[0].properties.FIPS !== lastFIPS) { 225 | updateSidebar(tract[0].properties); 226 | updateDonuts(tract[0].properties); 227 | lastFIPS = tract[0].properties.FIPS; 228 | } 229 | } else { 230 | map.getCanvas().style.cursor = 'default'; 231 | } 232 | }; 233 | }); 234 | }); 235 | 236 | -------------------------------------------------------------------------------- /css/map.css: -------------------------------------------------------------------------------- 1 | .mapbox-portal{ 2 | height: 100%; 3 | min-height: 300px; 4 | width: 50%; 5 | } 6 | .navbar-default .navbar-nav>li>a { 7 | color: #ffffff !important; 8 | border-color:none; 9 | font-family: 'Roboto', sans-serif; 10 | 11 | font-size: 0.9em; 12 | } 13 | 14 | .navbar-default .navbar-collapse, .navbar-default .navbar-form{ 15 | border-color:none; 16 | } 17 | 18 | a.header1 { 19 | font-family: 'Roboto', sans-serif; 20 | font-size: 1.2em !important; 21 | font-weight: 600 !important; 22 | color: #fff; 23 | } 24 | 25 | 26 | html, body { 27 | height: 0%; 28 | margin: 0; 29 | padding: 0; 30 | font-family: 'Roboto', sans-serif; 31 | font-size: 0.8em; 32 | color: #000; 33 | } 34 | 35 | h2, h3 { 36 | font-weight: 600; 37 | font-family: 'Nunito', sans-serif; 38 | } 39 | 40 | h4,h5,h6 { 41 | font-family: 'Nunito', sans-serif; 42 | } 43 | p { 44 | margin: 10px; 45 | text-align: left; 46 | } 47 | 48 | .title, .title:hover, .title:focus { 49 | color: #fff; 50 | font-family: 'Nunito', sans-serif; 51 | } 52 | 53 | #DKDC { 54 | position:absolute; 55 | right:5px; 56 | bottom:20px; 57 | } 58 | 59 | a { 60 | color: #000; 61 | } 62 | 63 | a.mapboxgl-ctrl-logo{ 64 | display: none !important; 65 | } 66 | 67 | /** 68 | * Create a position for the map 69 | * on the page */ 70 | #map { 71 | position:absolute; 72 | top: 50px; 73 | left: 0px; 74 | bottom:0; 75 | width:100%; 76 | } 77 | /** 78 | * Set rules for how the map overlays 79 | * (info box and legend) will be displayed 80 | * on the page. */ 81 | 82 | .map-overlay { 83 | position: absolute; 84 | bottom: 0px; 85 | left: 0px; 86 | background:rgba(255,255,255,1); 87 | overflow: auto; 88 | } 89 | 90 | .navbar,.navbar-default,.nav,#aboutlink,#print-link{ 91 | background: #332A85; 92 | color: #ffffff; 93 | text-align: right; 94 | border-color: none; 95 | } 96 | 97 | .navbar-toggle { 98 | position: relative; 99 | float: right; 100 | padding: 9px 10px; 101 | margin-top: 8px; 102 | margin-right: 15px; 103 | margin-bottom: 8px; 104 | background-color: transparent; 105 | background-image: none; 106 | border: 1px solid transparent; 107 | border-radius: 6px; 108 | border-color: transparent; 109 | 110 | } 111 | 112 | .navbar-default .navbar-toggle .icon-bar { 113 | background-color: #fff; 114 | border-color:none; 115 | } 116 | .navbar-default .navbar-toggle:focus, .navbar-default .navbar-toggle:hover { 117 | background-color: transparent; 118 | border-color:none; 119 | } 120 | 121 | 122 | 123 | #print-link { 124 | pointer-events: none; 125 | cursor: default; 126 | } 127 | 128 | #search{ 129 | padding-top: 12px; 130 | padding-bottom: 10px; 131 | } 132 | 133 | #features { 134 | top: 50px; 135 | border-right: 1px solid #ccc; 136 | margin-top: 0px; 137 | width: 33%; 138 | min-width: 300px; 139 | } 140 | 141 | #menu { 142 | background: #fff; 143 | position: absolute; 144 | z-index: -2; 145 | top: 50px; 146 | height: calc(100% - 50px); 147 | width: 240px; 148 | } 149 | 150 | #menu a { 151 | display: block; 152 | margin: 0; 153 | padding: 10px; 154 | text-decoration: none; 155 | background-color: #fff; 156 | transition-property: background-color, color; 157 | transition-duration: .2s; 158 | transition-timing-function: ease-out; 159 | } 160 | 161 | #menu a:last-child { 162 | border: none; 163 | } 164 | 165 | #menu a.active, #menu a:hover ,.nav>li>a:focus, .nav>li>a:hover{ 166 | transition-property: background-color, color; 167 | transition-duration: .2s; 168 | transition-timing-function: ease-out; 169 | background-color: #FF921A; 170 | color: #fff; 171 | } 172 | 173 | .navbar-default .navbar-collapse, .navbar-default .navbar-form { 174 | border-color:none !important; 175 | } 176 | 177 | #menu a.active:hover { 178 | background: #FF921A; 179 | } 180 | 181 | .menutitles{ 182 | margin-left: 10px; 183 | } 184 | 185 | #footer { 186 | position: absolute; 187 | bottom: 0; 188 | right: 0; 189 | padding-right: 10px; 190 | padding-top: 2px; 191 | padding-bottom: 2px; 192 | } 193 | 194 | #F_Total-bignumber { 195 | text-align: center; 196 | vertical-align: baseline; 197 | font-size: 18px; 198 | width:30px; 199 | font-weight: 500; 200 | } 201 | 202 | .btn-primary { 203 | background: #332A85; 204 | color: #ffffff; 205 | border-color: #332A85; 206 | } 207 | 208 | #legend { 209 | position: absolute; 210 | bottom: 0px; 211 | left: 33%; 212 | padding: 20px; 213 | width: 100px; 214 | color: #000; 215 | } 216 | 217 | @media all and (max-width: 900px) { 218 | #legend{ 219 | margin-right: 0px; 220 | right: 300px; 221 | } 222 | } 223 | 224 | .center { 225 | margin-right: auto; 226 | margin-left: auto; 227 | } 228 | 229 | .legend-key { 230 | display: inline-block; 231 | border-radius: 20%; 232 | width: 10px; 233 | height: 10px; 234 | margin-right: 5px; 235 | } 236 | 237 | .legend-number { 238 | margin-right: 5px; 239 | } 240 | 241 | .legend-title { 242 | padding-bottom: 1em; 243 | } 244 | 245 | /* Popup container */ 246 | .popup { 247 | position: relative; 248 | display: inline-block; 249 | cursor: pointer; 250 | } 251 | 252 | /* The actual popup (appears on top) */ 253 | .popup .popuptext { 254 | visibility: hidden; 255 | font-family: 'Roboto', sans-serif; 256 | font-size: 0.6em; 257 | width: 220px; 258 | color: #000; 259 | background-color: rgba(255,255,255,1); 260 | text-align: left; 261 | border-radius: 6px; 262 | padding: 8px; 263 | position: absolute; 264 | z-index: 1; 265 | bottom: 125%; 266 | left: 50%; 267 | margin-left: -110px; 268 | } 269 | 270 | /* Popup arrow */ 271 | .popup .popuptext::after { 272 | content: ""; 273 | font-family: 'Roboto', sans-serif; 274 | color: #000; 275 | font-size: 0.8em; 276 | position: absolute; 277 | top: 100%; 278 | left: 50%; 279 | margin-left: -5px; 280 | border-width: 5px; 281 | border-style: solid; 282 | border-color: rgba(255,255,255,.8) transparent transparent transparent; 283 | } 284 | 285 | /* Toggle this class when clicking on the popup container (hide and show the popup) */ 286 | .popup .show { 287 | visibility: visible; 288 | -webkit-animation: fadeIn 1s; 289 | animation: fadeIn 1s 290 | } 291 | .popup2 { 292 | position: relative; 293 | display: inline-block; 294 | cursor: pointer; 295 | } 296 | 297 | /* The actual popup (appears on top) */ 298 | .popup2 .popuptext2 { 299 | visibility: hidden; 300 | font-family: 'Roboto', sans-serif; 301 | font-size: 0.6em; 302 | width: 220px; 303 | color: #000; 304 | background-color: rgba(255,255,255,1); 305 | text-align: left; 306 | border-radius: 6px; 307 | padding: 8px; 308 | position: absolute; 309 | z-index: 1; 310 | top: 125%; 311 | left: 50%; 312 | margin-left: -110px; 313 | } 314 | 315 | /* Popup arrow */ 316 | .popup2 .popuptext2::after { 317 | content: ""; 318 | font-family: 'Roboto', sans-serif; 319 | color: #000; 320 | font-size: 0.8em; 321 | position: absolute; 322 | bottom: 100%; 323 | left: 50%; 324 | margin-left: -5px; 325 | border-width: 5px; 326 | border-style: solid; 327 | border-color: rgba(255,255,255,.8) transparent transparent transparent; 328 | } 329 | 330 | /* Toggle this class when clicking on the popup container (hide and show the popup) */ 331 | .popup2 .show { 332 | visibility: visible; 333 | -webkit-animation: fadeIn 1s; 334 | animation: fadeIn 1s 335 | } 336 | 337 | 338 | 339 | /* Add animation (fade in the popup) */ 340 | @-webkit-keyframes fadeIn { 341 | from {opacity: 0;} 342 | to {opacity: 1;} 343 | } 344 | 345 | @keyframes fadeIn { 346 | from {opacity: 0;} 347 | to {opacity:1 ;} 348 | } 349 | 350 | @media print { 351 | .map-overlay { 352 | position: absolute; 353 | bottom: 0px; 354 | left: 0px; 355 | background:rgba(255,255,255,1) !important; 356 | overflow: auto; 357 | -webkit-print-color-adjust: exact; 358 | } 359 | 360 | 361 | 362 | 363 | } 364 | 365 | 366 | 367 | 368 | 369 | 370 | @media print { 371 | 372 | html, body, h1, h2, h3, h4, h5, .item-title, #location, #population, #diocese, .fl, #F_Total-bignumber { 373 | color: #fff !important; 374 | } 375 | 376 | .mapbox-portal{ 377 | height: 100% !important; 378 | min-height: 300px; 379 | width: 50%; 380 | } 381 | 382 | } 383 | 384 | 385 | -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CCUSA Disaster Operations Map - About 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
36 | 37 |
38 | 66 |
67 |
68 | 69 | 70 |
71 |

CCUSA provides disaster relief assistance and wanted to create a map to better target mitigation, preparedness, relief, and recovery projects in order 72 | to best serve communities that are both at greatest risk for disasters and most overlooked or outright excluded 73 | from federal assistance during disasters. Specifically, they wanted to see the presence of acutely vulnerable 74 | populations such as uninsured (homeowners or renters), homeless, or subsidized renters at the local level. 75 | Information about a particular area's social vulnerability, housing and transportation vulnerability, and demographics are visualized. 76 | The Disaster Operations Map can be used to strategically allocate resources to prepare for disasters, 77 | as well as identifying where vulnerable populations live within an area affected by a disaster. 78 |

79 |
80 | 81 |
82 |
83 |
84 |

85 |

The code for the map is open source and available on our GitHub account. We are also very grateful to ATTOM Data Solutions, who kindly provided us with data for this project. Lastly, thank you MapBox DC for connecting us to your experts who helped us get started. 86 |



87 |
88 |
89 |
90 | 91 |
92 |
93 | 94 |
95 |

96 |
97 |

GitHub

98 |
99 | Our work is open source to benefit as many as possible. 100 |

101 |
102 |
103 |

104 |
105 |

Mapbox

106 |
107 | The Mapbox platform 108 |
109 |
110 |

111 |
112 |

ATTOM

113 | 114 |
115 | ATTOM is a data provider and generously provided disaster data to this project. 116 |
117 |
118 |
119 |

120 | 121 |
122 | 123 |
124 |
125 |
126 |

127 | 128 |

We would like to acknowledge and thank our amazing team and partners. Richard Carder and Jake Snyder were the DataKind Data Ambassadors. Lukas Martinelli, Tom MacWright, Lew Ting, Mohammed Kemal, and many others contributed significantly, as well as volunteers who participated in our Data Jam and Data Dives. 129 | DKDC Chapter Leaders Max Richman and Judy Yang assisted with project supervision. 130 | Thank you Zach Cahalan (CCUSA partner liaison) for providing guidance to the team, we hope the Disaster Operations Map makes a true and positive impact in your work! 131 |

132 |

133 |
134 |
135 |
136 | 137 |
138 |
139 |
140 |

141 |
142 |
143 |
144 | Catholic Charities USA is a national organization that offers support to member agencies, 145 | provides disaster relief and promotes poverty-reduction through research and legislative reform.

146 |
147 | 148 |
149 |

150 |
151 |
152 |
153 | DataKind brings high-impact organizations together with leading data scientists to use data science in the service of humanity. 154 | Our work helps organizations develop evidence-based decision making, increase efficiency, and enhance their data literacy. 155 |

156 |
157 |
158 |
159 |

160 |
161 |

162 | 163 |
164 | If you have any questions or feedback, please contact DataKind, or Catholic Charities USA. 165 |
166 | 167 | 168 | -------------------------------------------------------------------------------- /css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ 2 | 3 | /* Document 4 | ========================================================================== */ 5 | 6 | /** 7 | * 1. Correct the line height in all browsers. 8 | * 2. Prevent adjustments of font size after orientation changes in 9 | * IE on Windows Phone and in iOS. 10 | */ 11 | 12 | html { 13 | line-height: 1.15; /* 1 */ 14 | -ms-text-size-adjust: 100%; /* 2 */ 15 | -webkit-text-size-adjust: 100%; /* 2 */ 16 | } 17 | 18 | /* Sections 19 | ========================================================================== */ 20 | 21 | /** 22 | * Remove the margin in all browsers (opinionated). 23 | */ 24 | 25 | body { 26 | margin: 0; 27 | } 28 | 29 | /** 30 | * Add the correct display in IE 9-. 31 | */ 32 | 33 | article, 34 | aside, 35 | footer, 36 | header, 37 | nav, 38 | section { 39 | display: block; 40 | } 41 | 42 | /** 43 | * Correct the font size and margin on `h1` elements within `section` and 44 | * `article` contexts in Chrome, Firefox, and Safari. 45 | */ 46 | 47 | h1 { 48 | font-size: 2em; 49 | margin: 0.67em 0; 50 | } 51 | 52 | /* Grouping content 53 | ========================================================================== */ 54 | 55 | /** 56 | * Add the correct display in IE 9-. 57 | * 1. Add the correct display in IE. 58 | */ 59 | 60 | figcaption, 61 | figure, 62 | main { /* 1 */ 63 | display: block; 64 | } 65 | 66 | /** 67 | * Add the correct margin in IE 8. 68 | */ 69 | 70 | figure { 71 | margin: 1em 40px; 72 | } 73 | 74 | /** 75 | * 1. Add the correct box sizing in Firefox. 76 | * 2. Show the overflow in Edge and IE. 77 | */ 78 | 79 | hr { 80 | box-sizing: content-box; /* 1 */ 81 | height: 0; /* 1 */ 82 | overflow: visible; /* 2 */ 83 | } 84 | 85 | /** 86 | * 1. Correct the inheritance and scaling of font size in all browsers. 87 | * 2. Correct the odd `em` font sizing in all browsers. 88 | */ 89 | 90 | pre { 91 | font-family: monospace, monospace; /* 1 */ 92 | font-size: 1em; /* 2 */ 93 | } 94 | 95 | /* Text-level semantics 96 | ========================================================================== */ 97 | 98 | /** 99 | * 1. Remove the gray background on active links in IE 10. 100 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. 101 | */ 102 | 103 | a { 104 | background-color: transparent; /* 1 */ 105 | -webkit-text-decoration-skip: objects; /* 2 */ 106 | } 107 | 108 | /** 109 | * 1. Remove the bottom border in Chrome 57- and Firefox 39-. 110 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. 111 | */ 112 | 113 | abbr[title] { 114 | border-bottom: none; /* 1 */ 115 | text-decoration: underline; /* 2 */ 116 | text-decoration: underline dotted; /* 2 */ 117 | } 118 | 119 | /** 120 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6. 121 | */ 122 | 123 | b, 124 | strong { 125 | font-weight: inherit; 126 | } 127 | 128 | /** 129 | * Add the correct font weight in Chrome, Edge, and Safari. 130 | */ 131 | 132 | b, 133 | strong { 134 | font-weight: bolder; 135 | } 136 | 137 | /** 138 | * 1. Correct the inheritance and scaling of font size in all browsers. 139 | * 2. Correct the odd `em` font sizing in all browsers. 140 | */ 141 | 142 | code, 143 | kbd, 144 | samp { 145 | font-family: monospace, monospace; /* 1 */ 146 | font-size: 1em; /* 2 */ 147 | } 148 | 149 | /** 150 | * Add the correct font style in Android 4.3-. 151 | */ 152 | 153 | dfn { 154 | font-style: italic; 155 | } 156 | 157 | /** 158 | * Add the correct background and color in IE 9-. 159 | */ 160 | 161 | mark { 162 | background-color: #ff0; 163 | color: #000; 164 | } 165 | 166 | /** 167 | * Add the correct font size in all browsers. 168 | */ 169 | 170 | small { 171 | font-size: 80%; 172 | } 173 | 174 | /** 175 | * Prevent `sub` and `sup` elements from affecting the line height in 176 | * all browsers. 177 | */ 178 | 179 | sub, 180 | sup { 181 | font-size: 75%; 182 | line-height: 0; 183 | position: relative; 184 | vertical-align: baseline; 185 | } 186 | 187 | sub { 188 | bottom: -0.25em; 189 | } 190 | 191 | sup { 192 | top: -0.5em; 193 | } 194 | 195 | /* Embedded content 196 | ========================================================================== */ 197 | 198 | /** 199 | * Add the correct display in IE 9-. 200 | */ 201 | 202 | audio, 203 | video { 204 | display: inline-block; 205 | } 206 | 207 | /** 208 | * Add the correct display in iOS 4-7. 209 | */ 210 | 211 | audio:not([controls]) { 212 | display: none; 213 | height: 0; 214 | } 215 | 216 | /** 217 | * Remove the border on images inside links in IE 10-. 218 | */ 219 | 220 | img { 221 | border-style: none; 222 | } 223 | 224 | /** 225 | * Hide the overflow in IE. 226 | */ 227 | 228 | svg:not(:root) { 229 | overflow: hidden; 230 | } 231 | 232 | /* Forms 233 | ========================================================================== */ 234 | 235 | /** 236 | * 1. Change the font styles in all browsers (opinionated). 237 | * 2. Remove the margin in Firefox and Safari. 238 | */ 239 | 240 | button, 241 | input, 242 | optgroup, 243 | select, 244 | textarea { 245 | font-family: sans-serif; /* 1 */ 246 | font-size: 100%; /* 1 */ 247 | line-height: 1.15; /* 1 */ 248 | margin: 0; /* 2 */ 249 | } 250 | 251 | /** 252 | * Show the overflow in IE. 253 | * 1. Show the overflow in Edge. 254 | */ 255 | 256 | button, 257 | input { /* 1 */ 258 | overflow: visible; 259 | } 260 | 261 | /** 262 | * Remove the inheritance of text transform in Edge, Firefox, and IE. 263 | * 1. Remove the inheritance of text transform in Firefox. 264 | */ 265 | 266 | button, 267 | select { /* 1 */ 268 | text-transform: none; 269 | } 270 | 271 | /** 272 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` 273 | * controls in Android 4. 274 | * 2. Correct the inability to style clickable types in iOS and Safari. 275 | */ 276 | 277 | button, 278 | html [type="button"], /* 1 */ 279 | [type="reset"], 280 | [type="submit"] { 281 | -webkit-appearance: button; /* 2 */ 282 | } 283 | 284 | /** 285 | * Remove the inner border and padding in Firefox. 286 | */ 287 | 288 | button::-moz-focus-inner, 289 | [type="button"]::-moz-focus-inner, 290 | [type="reset"]::-moz-focus-inner, 291 | [type="submit"]::-moz-focus-inner { 292 | border-style: none; 293 | padding: 0; 294 | } 295 | 296 | /** 297 | * Restore the focus styles unset by the previous rule. 298 | */ 299 | 300 | button:-moz-focusring, 301 | [type="button"]:-moz-focusring, 302 | [type="reset"]:-moz-focusring, 303 | [type="submit"]:-moz-focusring { 304 | outline: 1px dotted ButtonText; 305 | } 306 | 307 | /** 308 | * Correct the padding in Firefox. 309 | */ 310 | 311 | fieldset { 312 | padding: 0.35em 0.75em 0.625em; 313 | } 314 | 315 | /** 316 | * 1. Correct the text wrapping in Edge and IE. 317 | * 2. Correct the color inheritance from `fieldset` elements in IE. 318 | * 3. Remove the padding so developers are not caught out when they zero out 319 | * `fieldset` elements in all browsers. 320 | */ 321 | 322 | legend { 323 | box-sizing: border-box; /* 1 */ 324 | color: inherit; /* 2 */ 325 | display: table; /* 1 */ 326 | max-width: 100%; /* 1 */ 327 | padding: 0; /* 3 */ 328 | white-space: normal; /* 1 */ 329 | } 330 | 331 | /** 332 | * 1. Add the correct display in IE 9-. 333 | * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. 334 | */ 335 | 336 | progress { 337 | display: inline-block; /* 1 */ 338 | vertical-align: baseline; /* 2 */ 339 | } 340 | 341 | /** 342 | * Remove the default vertical scrollbar in IE. 343 | */ 344 | 345 | textarea { 346 | overflow: auto; 347 | } 348 | 349 | /** 350 | * 1. Add the correct box sizing in IE 10-. 351 | * 2. Remove the padding in IE 10-. 352 | */ 353 | 354 | [type="checkbox"], 355 | [type="radio"] { 356 | box-sizing: border-box; /* 1 */ 357 | padding: 0; /* 2 */ 358 | } 359 | 360 | /** 361 | * Correct the cursor style of increment and decrement buttons in Chrome. 362 | */ 363 | 364 | [type="number"]::-webkit-inner-spin-button, 365 | [type="number"]::-webkit-outer-spin-button { 366 | height: auto; 367 | } 368 | 369 | /** 370 | * 1. Correct the odd appearance in Chrome and Safari. 371 | * 2. Correct the outline style in Safari. 372 | */ 373 | 374 | [type="search"] { 375 | -webkit-appearance: textfield; /* 1 */ 376 | outline-offset: -2px; /* 2 */ 377 | } 378 | 379 | /** 380 | * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. 381 | */ 382 | 383 | [type="search"]::-webkit-search-cancel-button, 384 | [type="search"]::-webkit-search-decoration { 385 | -webkit-appearance: none; 386 | } 387 | 388 | /** 389 | * 1. Correct the inability to style clickable types in iOS and Safari. 390 | * 2. Change font properties to `inherit` in Safari. 391 | */ 392 | 393 | ::-webkit-file-upload-button { 394 | -webkit-appearance: button; /* 1 */ 395 | font: inherit; /* 2 */ 396 | } 397 | 398 | /* Interactive 399 | ========================================================================== */ 400 | 401 | /* 402 | * Add the correct display in IE 9-. 403 | * 1. Add the correct display in Edge, IE, and Firefox. 404 | */ 405 | 406 | details, /* 1 */ 407 | menu { 408 | display: block; 409 | } 410 | 411 | /* 412 | * Add the correct display in all browsers. 413 | */ 414 | 415 | summary { 416 | display: list-item; 417 | } 418 | 419 | /* Scripting 420 | ========================================================================== */ 421 | 422 | /** 423 | * Add the correct display in IE 9-. 424 | */ 425 | 426 | canvas { 427 | display: inline-block; 428 | } 429 | 430 | /** 431 | * Add the correct display in IE. 432 | */ 433 | 434 | template { 435 | display: none; 436 | } 437 | 438 | /* Hidden 439 | ========================================================================== */ 440 | 441 | /** 442 | * Add the correct display in IE 10-. 443 | */ 444 | 445 | [hidden] { 446 | display: none; 447 | } 448 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | CCUSA Disaster Operations Map 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 47 | 48 | 49 | 50 | 51 |
52 | 83 |
84 | 85 | 86 | 87 |
88 | 96 |
97 |
98 |
99 |

Social Vulnerability
100 | Index scores range from 0 to 1, which depicts the percentiles of a particular county or tract relative to the rest of the USA. The higher the percentile ranking, the more vulnerable an area is in that category. A red flag indicates that an area is highly vulnerable, or in the top 90th percentile of a particular vulnerability. 101 | 102 |
103 |

104 |
105 |
106 |
107 |
108 | Total Flags 109 |
110 |
111 |
112 |
113 |
114 |
County/Tract
115 |
Population:
116 |
117 |
118 |
119 |
120 |
Catholic Diocese:
121 |
122 |
123 | 124 |
125 |
126 |
127 |
128 |
129 |

Hazard Risk 130 | 140 |

141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | 150 |
151 |
Legend
152 |
1
153 |
2
154 |
3
155 |
4
156 |
5
157 |
6
158 |
7+
159 |
160 | 167 |
168 | 169 |
170 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CCUSA Disaster Operations Map - Data 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 |
40 | 68 |
69 | 70 | 71 |
72 |

73 | Two data sources are used in the Disaster Operations Map. 74 | First, the Social Vulnerability Index (SVI) is a public data base curated by the Center for Disease Control (CDC). 75 | Second, te Natural Hazard Housing Risk Index is a proprietary data set released by ATTOM Data Solutions. 76 |

77 | Social Vulnerability Index (CDC 2018) 78 |
Natural Hazard Housing Risk Index (ATTOM 2016) 79 | 80 |

81 |
82 | 83 |
84 | 85 |
86 |
87 | 88 |
89 |

Methodology

90 | We pull the data we need from these files and bring them into a .mbtiles file to use with Mapbox and D3.js. Full methodology on this data manipulation is available on the GitHub 91 | page. 92 |
93 |

Social Vulnerability Index

94 |
  • Level of disaggregation: U.S. Census Tract
  • 95 |
  • Year: 2018
  • 96 |
  • Source: CDC
  • 97 |
  • Additional Information
  • 98 |

    99 | 100 | The Overall Social Vulnerability Index (SVI) is a composite score of four broad vulnerability indicators: Socioeconomic Status, Household Composition, Minority Status/Language, and Housing and Transportation. 101 | Each sub-category is calculated from specific indicators described in the table below. 102 | 103 |

    104 | Index scores range from 0 to 1; which depicts the percentiles of a particular county or tract relative to the rest of the USA. 105 | The higher the percentile ranking, the more vulnerable an area is in that category. A red flag indicates that an area is highly vulnerable, or in the top 90th percentile of a particular vulnerability. 106 | 107 |

    108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
    IndicatorVulnerability CategoryDescription
    Below PovertySocioeconomic StatusPersons below poverty estimate
    UnemployedSocioeconomic StatusCivilian (age 16+)
    IncomeSocioeconomic StatusPer capita income
    No High School DiplomaSocioeconomic StatusPersons (age 25+) with no high school diploma
    Aged 65 or olderHousehold CompositionPersons aged 65 or older
    Aged 17 or youngerHousehold CompositionPersons aged 17 or younger
    Civilian with a disabilityHousehold CompositionCivilian noninstitutionalized
    Single-Parent HouseholdsHousehold CompositionSingle parent household with children under 18
    MinorityMinority Status/LanguageMinority (all persons except white, non-Hispanic)
    Speak English “Less than Well”Minority Status/LanguagePersons (age 5+) who speak English "less than well"
    Multi-Unit StructuresHousing and TransportationHousing in structures with 10 or more units
    Mobile HomesHousing and TransportationMobile homes
    CrowdingHousing and TransportationAt household level (occupied housing units), more people than rooms
    No VehicleHousing and TransportationHouseholds with no vehicle available estimate
    Population
    Location Text description of tract, county, and state
    206 | 207 | 208 | 209 |
    210 | 211 |

    Natural Hazard Housing Risk Index

    212 |
  • Level of disaggregation: more than 3,000 USA counties
  • 213 |
  • Year: 2016
  • 214 |
  • Source: ATTOM Data Solutions
  • 215 |
  • Additional Information
  • 216 | 217 |

    218 | 219 | The Hazard Risk is an additive composite of six measures: Hurricane, Flood, Earthquake, Wildfire, Tornado, and Hail. 220 | Each hazard risk component is measured on a scale from 0-60, with a potential Overall Hazard Risk of 360. 221 | 222 |

    223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 |
    IndicatorDescription
    Overall Hazard RiskDescrip
    Hurricane RiskData is from FEMA and the National Hurricane Center (NHC), and risk level is based on two factors with equal weight: number and intensity of hurricane strikes historically; and percentage of homes located in flood zones identified as having a risk of “storm-induced waves”
    Flood RiskData is based on flood zones created by the Federal Emergency Management Agency (FEMA), and the level of risk was based on the percentage of homes in each county located in high-risk flood zones
    Earthquake RiskData is from the United States Geological Survey (USGS), and the level of risk was based on the probability of a magnitude 5.0 earthquake in each county
    Wildfire RiskData is from the United States Department of Agriculture Forest Service and Fire Modeling Institute, and risk level is based on the percentage of homes in each county located in “Very High” or “High” Wildfire Hazard Potential (WHP) areas.
    Tornado RiskData is from the National Oceanic and Atmospheric Administration (NOAA), and level of risk was based on the Destruction Potential Index (DPI) for each county. DPI is calculated using number of tornadoes, path of tornadoes in square miles, and intensity of tornadoes on the Fujita scale.
    Hail RiskData is from NOAA and the risk level is based on the average number of hail storms per year in each county with hail that exceeds 1-inch in size over the past 15 years.
    259 | 260 |

    261 |
    262 |
    263 |
    264 |
    265 | 266 |
    267 | If you have any questions or feedback, please contact DataKind, or Catholic Charities USA. 268 |
    269 | 270 | 271 | -------------------------------------------------------------------------------- /assets/layers.js: -------------------------------------------------------------------------------- 1 | const mapLayers = [ 2 | [ 3 | { 4 | "id": "highlight", 5 | "type": "line", 6 | "source": "highlight", 7 | "layout": {}, 8 | "paint": { 9 | "line-color": "#332A85", 10 | "line-width": 2 11 | } 12 | }, 13 | '' 14 | ], 15 | [ 16 | { 17 | "id": "county", 18 | "type": "fill", 19 | "source": "maps", 20 | "source-layer":"CountiesNew-55jzpj", 21 | "maxzoom": 20, 22 | paint: { 23 | 'fill-color': { 24 | property: 'FNew', 25 | type: 'interval', 26 | stops: [ 27 | 28 | [1, '#ffffd9'], 29 | [2, '#edf8b1'], 30 | [3, '#c7e9b4'], 31 | [4, '#7fcdbb'], 32 | [5, '#41b6c4'], 33 | [6, '#1d91c0'], 34 | [7, '#225ea8'], 35 | [9, '#0c2c84'] 36 | ] 37 | }, 38 | 'fill-opacity': { 39 | stops:[[0, 0.5], [8, 0.5], [10, 0]] 40 | } 41 | } 42 | }, 43 | "airport-label" 44 | ], 45 | [ 46 | { 47 | "id": "tract", 48 | "type": "fill", 49 | "source": "maps", 50 | "source-layer":"TractsNew-3gvy4k", 51 | "minzoom": 8, 52 | paint: { 53 | 'fill-color': { 54 | property: 'FNew', 55 | type: 'interval', 56 | stops: [ 57 | [1, '#ffffd9'], 58 | [2, '#edf8b1'], 59 | [3, '#c7e9b4'], 60 | [4, '#7fcdbb'], 61 | [5, '#41b6c4'], 62 | [6, '#1d91c0'], 63 | [7, '#225ea8'], 64 | [9, '#253494'], 65 | [10, '#081d58'] 66 | ] 67 | }, 68 | 'fill-opacity': { 69 | stops:[[0, 0], [8, 0], [10, 0.5]] 70 | } 71 | } 72 | }, 73 | "county","waterway","waterway-label","airport-label" 74 | ], 75 | [ 76 | { 77 | "id": "county-socio", 78 | "type": "fill", 79 | "source": "maps", 80 | "source-layer":"CountiesNew-55jzpj", 81 | "maxzoom": 20, 82 | layout: { 83 | visibility:'none' 84 | }, 85 | paint: { 86 | 'fill-color': { 87 | property: 'RPL_THEME1', 88 | type: 'exponential', 89 | stops: [ 90 | [.1, '#ffffd9'], 91 | [.2, '#edf8b1'], 92 | [.3, '#c7e9b4'], 93 | [.4, '#7fcdbb'], 94 | [.5, '#41b6c4'], 95 | [.6, '#1d91c0'], 96 | [.7, '#225ea8'], 97 | [.9, '#253494'], 98 | [1, '#081d58']] 99 | }, 100 | 'fill-opacity': { 101 | stops:[[0,0.5],[8,0.5],[10,0]] 102 | } 103 | } 104 | }, 105 | "airport-label" 106 | ], 107 | [ 108 | { 109 | "id": "tract-socio", 110 | "type": "fill", 111 | "source": "maps", 112 | "source-layer":"TractsNew-3gvy4k", 113 | "minzoom": 0, 114 | layout: { 115 | visibility:'none' 116 | }, 117 | paint: { 118 | 'fill-color': { 119 | property: 'RPL_THEME1', 120 | type: 'exponential', 121 | stops: [ 122 | [.1, '#ffffd9'], 123 | [.2, '#edf8b1'], 124 | [.3, '#c7e9b4'], 125 | [.4, '#7fcdbb'], 126 | [.5, '#41b6c4'], 127 | [.6, '#1d91c0'], 128 | [.7, '#225ea8'], 129 | [.9, '#253494'], 130 | [1, '#081d58']] 131 | }, 132 | 'fill-opacity': { 133 | stops:[[0, 0], [8, 0], [10, 0.5]] 134 | } 135 | } 136 | 137 | }, 138 | "county" 139 | ], 140 | [ 141 | { 142 | "id": "county-household", 143 | "type": "fill", 144 | "source": "maps", 145 | "source-layer":"CountiesNew-55jzpj", 146 | "maxzoom": 20, 147 | layout: { 148 | visibility:'none' 149 | }, 150 | paint: { 151 | 'fill-color': { 152 | property: 'RPL_THEME2', 153 | type: 'exponential', 154 | stops: [ 155 | [.1, '#ffffd9'], 156 | [.2, '#edf8b1'], 157 | [.3, '#c7e9b4'], 158 | [.4, '#7fcdbb'], 159 | [.5, '#41b6c4'], 160 | [.6, '#1d91c0'], 161 | [.7, '#225ea8'], 162 | [.9, '#253494'], 163 | [1, '#081d58']] 164 | }, 165 | 'fill-opacity': { 166 | stops:[[0, 0.5], [8, 0.5], [10, 0]] 167 | } 168 | } 169 | }, 170 | "airport-label" 171 | ], 172 | [ 173 | { 174 | "id": "tract-household", 175 | "type": "fill", 176 | "source": "maps", 177 | "source-layer":"TractsNew-3gvy4k", 178 | "minzoom": 0, 179 | layout: { 180 | visibility:'none' 181 | }, 182 | paint: { 183 | 'fill-color': { 184 | property: 'RPL_THEME2', 185 | type: 'exponential', 186 | stops: [ 187 | [.1, '#ffffd9'], 188 | [.2, '#edf8b1'], 189 | [.3, '#c7e9b4'], 190 | [.4, '#7fcdbb'], 191 | [.5, '#41b6c4'], 192 | [.6, '#1d91c0'], 193 | [.7, '#225ea8'], 194 | [.9, '#253494'], 195 | [1, '#081d58']] 196 | }, 197 | 'fill-opacity': { 198 | stops:[[0, 0], [8, 0], [10, 0.5]] 199 | } 200 | } 201 | }, 202 | "county" 203 | ], 204 | [ 205 | { 206 | "id": "county-minority", 207 | "type": "fill", 208 | "source": "maps", 209 | "source-layer":"CountiesNew-55jzpj", 210 | "maxzoom": 20, 211 | layout: { 212 | visibility:'none' 213 | }, 214 | paint: { 215 | 'fill-color': { 216 | property: 'RPL_THEME3', 217 | type: 'exponential', 218 | stops: [ 219 | [.1, '#ffffd9'], 220 | [.2, '#edf8b1'], 221 | [.3, '#c7e9b4'], 222 | [.4, '#7fcdbb'], 223 | [.5, '#41b6c4'], 224 | [.6, '#1d91c0'], 225 | [.7, '#225ea8'], 226 | [.9, '#253494'], 227 | [1, '#081d58']] 228 | }, 229 | 'fill-opacity': { 230 | stops:[[0,0.5],[8,0.5],[10,0]] 231 | } 232 | } 233 | }, 234 | "airport-label" 235 | ], 236 | [ 237 | { 238 | "id": "tract-minority", 239 | "type": "fill", 240 | "source": "maps", 241 | "source-layer":"TractsNew-3gvy4k", 242 | "minzoom": 0, 243 | layout: { 244 | visibility:'none' 245 | }, 246 | paint: { 247 | 'fill-color': { 248 | property: 'RPL_THEME3', 249 | type: 'exponential', 250 | stops: [ 251 | [.1, '#ffffd9'], 252 | [.2, '#edf8b1'], 253 | [.3, '#c7e9b4'], 254 | [.4, '#7fcdbb'], 255 | [.5, '#41b6c4'], 256 | [.6, '#1d91c0'], 257 | [.7, '#225ea8'], 258 | [.9, '#253494'], 259 | [1, '#081d58']] 260 | }, 261 | 'fill-opacity': { 262 | stops:[[0,0],[8,0],[10,0.5]] 263 | } 264 | } 265 | }, 266 | "county" 267 | ], 268 | [ 269 | { 270 | "id": "county-housing", 271 | "type": "fill", 272 | "source": "maps", 273 | "source-layer":"CountiesNew-55jzpj", 274 | "maxzoom": 20, 275 | layout: { 276 | visibility:'none' 277 | }, 278 | paint: { 279 | 'fill-color': { 280 | property: 'RPL_THEME4', 281 | type: 'exponential', 282 | stops: [ 283 | [.1, '#ffffd9'], 284 | [.2, '#edf8b1'], 285 | [.3, '#c7e9b4'], 286 | [.4, '#7fcdbb'], 287 | [.5, '#41b6c4'], 288 | [.6, '#1d91c0'], 289 | [.7, '#225ea8'], 290 | [.9, '#253494'], 291 | [1, '#081d58']] 292 | }, 293 | 'fill-opacity': { 294 | stops:[[0,0.5],[8,0.5],[10,0]] 295 | } 296 | } 297 | }, 298 | "airport-label" 299 | ], 300 | [ 301 | { 302 | "id": "tract-housing", 303 | "type": "fill", 304 | "source": "maps", 305 | "source-layer":"TractsNew-3gvy4k", 306 | "minzoom": 0, 307 | layout: { 308 | visibility:'none' 309 | }, 310 | paint: { 311 | 'fill-color': { 312 | property: 'RPL_THEME4', 313 | type: 'exponential', 314 | stops: [ 315 | [.1, '#ffffd9'], 316 | [.2, '#edf8b1'], 317 | [.3, '#c7e9b4'], 318 | [.4, '#7fcdbb'], 319 | [.5, '#41b6c4'], 320 | [.6, '#1d91c0'], 321 | [.7, '#225ea8'], 322 | [.9, '#253494'], 323 | [1, '#081d58']] 324 | }, 325 | 'fill-opacity': { 326 | stops:[[0,0],[8,0],[10,0.5]] 327 | } 328 | } 329 | }, 330 | "county" 331 | ], 332 | [ 333 | { 334 | "id": "county-hazard", 335 | "type": "fill", 336 | "source": "maps", 337 | "source-layer":"CountiesNew-55jzpj", 338 | "maxzoom": 20, 339 | layout: { 340 | visibility:'none' 341 | }, 342 | paint: { 343 | 'fill-color': { 344 | property: 'TtlHzrd', 345 | stops: [ 346 | [8, '#ffffcc'], 347 | [16, '#ffeda0'], 348 | [24, '#fed976'], 349 | [32, '#feb24c'], 350 | [40, '#fd8d3c'], 351 | [48, '#fc4e2a'], 352 | [56, '#e31a1c'], 353 | [64, '#b10026'], 354 | [72, '#800026']] 355 | }, 356 | 'fill-opacity': 0.5 357 | } 358 | }, 359 | "airport-label" 360 | ], 361 | [ 362 | { 363 | "id": "county-hurricane", 364 | "type": "fill", 365 | "source": "maps", 366 | "source-layer":"CountiesNew-55jzpj", 367 | "maxzoom": 20, 368 | layout: { 369 | visibility:'none' 370 | }, 371 | paint: { 372 | 'fill-color': { 373 | property: 'Hurricn', 374 | stops: [ 375 | [3, '#ffffcc'], 376 | [6, '#ffeda0'], 377 | [9, '#fed976'], 378 | [12, '#feb24c'], 379 | [15, '#fd8d3c'], 380 | [18, '#fc4e2a'], 381 | [21, '#e31a1c'], 382 | [24, '#b10026'], 383 | [27, '#800026']] 384 | }, 385 | 'fill-opacity': 0.5 386 | } 387 | }, 388 | "airport-label" 389 | ], 390 | [ 391 | { 392 | "id": "county-flood", 393 | "type": "fill", 394 | "source": "maps", 395 | "source-layer":"CountiesNew-55jzpj", 396 | "maxzoom": 20, 397 | layout: { 398 | visibility:'none' 399 | }, 400 | paint: { 401 | 'fill-color': { 402 | property: 'Flood', 403 | stops: [ 404 | [3, '#ffffcc'], 405 | [6, '#ffeda0'], 406 | [9, '#fed976'], 407 | [12, '#feb24c'], 408 | [15, '#fd8d3c'], 409 | [18, '#fc4e2a'], 410 | [21, '#e31a1c'], 411 | [24, '#b10026'], 412 | [27, '#800026']] 413 | }, 414 | 'fill-opacity': 0.5 415 | } 416 | }, 417 | "airport-label" 418 | ], 419 | [ 420 | { 421 | "id": "county-hail", 422 | "type": "fill", 423 | "source": "maps", 424 | "source-layer":"CountiesNew-55jzpj", 425 | "maxzoom": 20, 426 | layout: { 427 | visibility:'none' 428 | }, 429 | paint: { 430 | 'fill-color': { 431 | property: 'Hail', 432 | stops: [ 433 | [3, '#ffffcc'], 434 | [6, '#ffeda0'], 435 | [9, '#fed976'], 436 | [12, '#feb24c'], 437 | [15, '#fd8d3c'], 438 | [18, '#fc4e2a'], 439 | [21, '#e31a1c'], 440 | [24, '#b10026'], 441 | [27, '#800026']] 442 | }, 443 | 'fill-opacity': 0.5 444 | } 445 | }, 446 | "airport-label", 447 | "water", 448 | "waterway" 449 | ], 450 | [ 451 | { 452 | "id": "county-earthquake", 453 | "type": "fill", 454 | "source": "maps", 455 | "source-layer":"CountiesNew-55jzpj", 456 | "maxzoom": 20, 457 | layout: { 458 | visibility:'none' 459 | }, 460 | paint: { 461 | 'fill-color': { 462 | property: 'Earthqk', 463 | stops: [ 464 | [3, '#ffffcc'], 465 | [6, '#ffeda0'], 466 | [9, '#fed976'], 467 | [12, '#feb24c'], 468 | [15, '#fd8d3c'], 469 | [18, '#fc4e2a'], 470 | [21, '#e31a1c'], 471 | [24, '#b10026'], 472 | [27, '#800026']] 473 | }, 474 | 'fill-opacity': 0.5 475 | } 476 | }, 477 | "airport-label" 478 | ], 479 | [ 480 | { 481 | "id": "county-tornado", 482 | "type": "fill", 483 | "source": "maps", 484 | "source-layer":"CountiesNew-55jzpj", 485 | "maxzoom": 20, 486 | layout: { 487 | visibility:'none' 488 | }, 489 | paint: { 490 | 'fill-color': { 491 | property: 'Tornado', 492 | stops: [ 493 | [3, '#ffffcc'], 494 | [6, '#ffeda0'], 495 | [9, '#fed976'], 496 | [12, '#feb24c'], 497 | [15, '#fd8d3c'], 498 | [18, '#fc4e2a'], 499 | [21, '#e31a1c'], 500 | [24, '#b10026'], 501 | [27, '#800026']] 502 | }, 503 | 'fill-opacity': 0.5 504 | } 505 | }, 506 | "airport-label" 507 | ], 508 | [ 509 | { 510 | "id": "county-wildfire", 511 | "type": "fill", 512 | "source": "maps", 513 | "source-layer":"CountiesNew-55jzpj", 514 | "maxzoom": 20, 515 | layout: { 516 | visibility:'none' 517 | }, 518 | paint: { 519 | 'fill-color': { 520 | property: 'Wildfir', 521 | stops: [ 522 | [3, '#ffffcc'], 523 | [6, '#ffeda0'], 524 | [9, '#fed976'], 525 | [12, '#feb24c'], 526 | [15, '#fd8d3c'], 527 | [18, '#fc4e2a'], 528 | [21, '#e31a1c'], 529 | [24, '#b10026'], 530 | [27, '#800026']] 531 | }, 532 | 'fill-opacity': 0.5 533 | } 534 | }, 535 | "airport-label" 536 | ] 537 | ] 538 | -------------------------------------------------------------------------------- /static/ccusa_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 15 | 21 | 27 | 34 | 41 | 49 | 56 | 61 | 66 | 72 | 76 | 83 | 90 | 94 | 100 | 104 | 110 | 115 | 120 | 126 | 130 | 133 | 137 | 139 | 141 | 143 | 146 | 148 | 150 | 151 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 49 | 50 | 57 | 58 | 59 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 89 | 90 | 93 | 94 | 95 | 96 | 99 | 100 | 103 | 104 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 135 | 136 | 147 | 148 | 166 | 167 | 185 | 186 | 206 | 207 | 228 | 229 | 252 | 253 | 254 | 256 | 257 | 258 | 259 | 1496799661166 260 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | --------------------------------------------------------------------------------