<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> <title>USA County Population Change over 25 Years</title> <link rel="stylesheet" href="https://js.arcgis.com/3.46/esri/css/esri.css"> <style> html, body, #mainWindow { height: 100%; width: 100%; margin: 0; padding: 0; } body { background-color: white; overflow: hidden; font-family: "Trebuchet MS"; } #loading { background: #fff; height: 100%; overflow: hidden; position: absolute; width: 100%; z-index: 100; } #loadingMessage { color: #000; margin: 0 auto; padding: 150px 0 0 0; text-align: center; width: 200px; } .shadow { -moz-box-shadow: 0 0 5px #888; -webkit-box-shadow: 0 0 5px #888; box-shadow: 0 0 5px #888; } #map { background-color: white; } #feedback { background: #fff; color: #000; font-family: arial; height: auto; left: 30px; margin: 5px; padding: 10px; position: absolute; text-align: center; top: 30px; visibility: hidden; width: 200px; z-index: 10; } #currentYear { display: inline-block; height: 25px; text-align: center; width: 50px; } #play, #pause { cursor: pointer; display: none; width: 50px; } #legend { padding: 10px 0 0 0; } #legend table table td { text-align: left; } /* animate color transition when years change */ #counties_layer path { transition: fill 1.15s, fill-opacity 1.15s, stroke 1.15s, stroke-opacity 1.15s; -webkit-transition: fill 1.15s, fill-opacity 1.15s, stroke 1.15s, stroke-opacity 1.15s; } #counties_layer path[data-relgrowth="no-data"] { stroke: rgb(255, 255, 255); stroke-width: 1pt; stroke-opacity: 1; } #counties_layer path[data-relgrowth="zero-or-less"] { fill: rgb(175, 141, 195); /* purple */ fill-opacity: 1; stroke: rgb(175, 141, 195); stroke-width: 1pt; stroke-opacity: 1; } #counties_layer path[data-relgrowth="lt-US"] { fill: rgb(225, 236, 231); /* light */ fill-opacity: 1; stroke: rgb(225, 236, 231); stroke-width: 1pt; stroke-opacity: 1; } #counties_layer path[data-relgrowth="gt-US"] { fill: rgb(127, 191, 123); /* green */ fill-opacity: 1; stroke: rgb(127, 191, 123); stroke-width: 1pt; stroke-opacity: 1; } </style> <script src="https://js.arcgis.com/3.46/"></script> <script> require([ "esri/map", "esri/layers/FeatureLayer", "esri/dijit/Legend", "esri/InfoTemplate", "esri/renderers/ClassBreaksRenderer", "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol", "dojo/_base/array", "esri/Color", "dojo/_base/fx", "dojo/_base/lang", "dojo/Deferred", "dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/number", "dojo/on", "dojo/parser", "dojo/string", "dojox/data/CsvStore", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!" ], function (Map, FeatureLayer, Legend, InfoTemplate, ClassBreaksRenderer, SimpleFillSymbol, SimpleLineSymbol, arrayUtils, Color, fx, lang, Deferred, dom, domConstruct, domStyle, number, on, parser, string, CsvStore){ parser.parse(); var map, layer, currentYear = 1971, currentUSPgr, timer; map = new Map("map", { basemap: "gray-vector", center: [-104.16, 39.342], zoom: 3, slider: false }); map.on("load", function (){ loadCSV().then(function (csvData){ setYear = lang.hitch(csvData, setYear); setYear(1971); layer = addCounties(csvData); }); }); // set up play/pause buttons on(dom.byId("pause"), "click", function (){ domStyle.set(this, "display", "none"); domStyle.set("play", "display", "inline-block"); pause(); }); on(dom.byId("play"), "click", function (){ domStyle.set(this, "display", "none"); domStyle.set("pause", "display", "inline-block"); play(); }); function addCounties(csvData){ var content = "<b>FIPS</b>: ${FIPS} \ <br><b>Percent Change</b>: ${RATE}"; // \ // <br><National Average: ${NATLAVG}"; var infoTemplate = new InfoTemplate("${NAME} County", content); var counties = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Census_Counties_20m/FeatureServer/0", { id: "counties", infoTemplate: infoTemplate, outFields: ["NAME", "FIPS"], styling: false }); counties.on("load", function (){ on.once(counties, "update-end", function (){ var renderer = createRenderer(currentYear, "FIPS", csvData); counties.setRenderer(renderer); createLegend(counties); domStyle.set("pause", "display", "inline-block"); play(); }); fadeOutLoading(); }); if (counties.surfaceType === "svg") { counties.on("graphic-draw", function (evt){ var attrs = evt.graphic.attributes; var joinKey = attrs && attrs.FIPS; var relgrowth = "no-data"; if (joinKey && csvData[joinKey] && csvData[joinKey][currentYear]) { var countyPgr = getGrowthRate(csvData[joinKey][currentYear - 1], csvData[joinKey][currentYear], 1); relgrowth = (countyPgr <= 0) ? "zero-or-less" : (countyPgr <= currentUSPgr) ? "lt-US" : "gt-US"; } attrs.RATE = number.round(countyPgr, 2) + "%"; evt.graphic.getNode().setAttribute("data-relgrowth", relgrowth); }); } map.addLayer(counties); return counties; } function loadCSV(){ var dfd = new Deferred(); var csvStore = new CsvStore({ url: "county_population.csv" }); csvStore.fetch({ onComplete: function (items, request){ //process csv data and create in memory object store. var store = request.store; var minYearPopulation = 1970; var maxYearPopulation = 2006; var counties = {}; counties.minVal = Infinity; counties.maxVal = -Infinity; arrayUtils.forEach(items, function (item){ var countyFips = store.getValue(item, "county_fips"); var stateFips = store.getValue(item, "state_fips"); var fips = string.pad(stateFips, 2, "0") + string.pad(countyFips, 3, "0"); var population = {}; population.maxVal = -Infinity; for (var year = minYearPopulation; year <= maxYearPopulation; year++) { var fieldName = "pop" + year; var popValue = parseInt(store.getValue(item, fieldName), 10); population[year] = popValue; population.maxVal = (popValue > population.maxVal) ? popValue : population.maxVal; counties.minVal = (popValue < counties.minVal) ? popValue : counties.minVal; counties.maxVal = (popValue > counties.maxVal) ? popValue : counties.maxVal; } counties[fips] = population; }); dfd.resolve(counties); }, onError: function (err){ console.log("Error loading CSV: ", err.message, err); } }); return dfd; } function getGrowthRate(pt1, pt2, t2_t1){ return ((Math.log(pt2) - Math.log(pt1)) / (t2_t1)) * 100; } function setYear(year){ var csvData = this; currentYear = year; currentUSPgr = getGrowthRate(csvData["00000"][currentYear - 1], csvData["00000"][currentYear], 1); dom.byId("currentYear").innerHTML = currentYear; if (layer) { layer.renderer._currentYear = year; addBreaks(layer.renderer); layer.redraw(); var sel = map.infoWindow.getSelectedFeature(); if (sel && map.infoWindow.isShowing) { map.infoWindow.setFeatures([sel]); } } } function changeYear(incr){ var year; if (incr < 1) { year = (currentYear === 1971) ? 2006 : currentYear + incr; setYear(year); } else if (incr > 0) { year = (currentYear === 2006) ? 1971 : currentYear + incr; setYear(year); } } function play(){ if (!timer) { timer = setInterval(function (){ changeYear(1); }, 1250); } } function pause(){ clearInterval(timer); timer = null; } function createRenderer(startYear, joinField, data){ // renderer is used for the legend var renderer = new ClassBreaksRenderer(null, "FIPS"); renderer._currentYear = startYear; renderer._data = data; addBreaks(renderer); // console.log("renderer with breaks", renderer); return renderer; } function createLegend(layer){ var legendDijit = new Legend({ map: map, layerInfos: [ { "layer": layer, "title": "Population Change" } ] }, "legend"); legendDijit.startup(); domStyle.set("feedback", "visibility", "visible"); } function addBreaks(renderer){ // console.log("addBreaks", renderer); var currentYear = renderer._currentYear, data = renderer._data, totalGrowth = getGrowthRate(data['00000'][currentYear], data['00000'][currentYear - 1], 1), roundedTotalGrowth = number.round(totalGrowth, 2); renderer.clearBreaks(); var negative = [175, 141, 195]; var flat = [225, 236, 231]; var positive = [127, 191, 123]; renderer.addBreak({ minValue: -Infinity, maxValue: 0, symbol: new SimpleFillSymbol().setColor(new Color(negative)) .setOutline(new SimpleLineSymbol().setColor(new Color(negative))), label: "Decrease" }); renderer.addBreak({ minValue: 0, maxValue: roundedTotalGrowth, symbol: new SimpleFillSymbol().setColor(new Color(flat)) .setOutline(new SimpleLineSymbol().setColor(new Color(flat))), label: "Flat" }); renderer.addBreak({ minValue: roundedTotalGrowth, maxValue: Infinity, symbol: new SimpleFillSymbol().setColor(new Color(positive)) .setOutline(new SimpleLineSymbol().setColor(new Color(positive))), label: "Increase" }); } function fadeOutLoading(){ var fade = fx.fadeOut({ node: "loading", onEnd: function (){ domConstruct.destroy(dom.byId("loading")); } }); fade.play(); } }); </script> </head> <body> <div id="loading"> <div id="loadingMessage"> Loading County and Population Data <br> <img src="assets/loading_gray_circle.gif"> </div> </div> <div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="'design': 'headline', 'gutters': false"> <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="'region': 'center'"> <div id="feedback" class="shadow"> Year: <span id="currentYear">...</span> | <span id="play">Play</span> <span id="pause">Pause</span> <div id="legend"></div> </div> </div> </div> </body> </html>