Mapping US states with D3


Data by state

Select a state below to find out some data, adjusted for each state's labor force/population etc, as of some date.

Loading map

Legend

75+

50-75

25-50

0-25

Variable: 6.45%

Graphic by YOUR NAME

A basic, clean D3 map for applications and illustrations about the U.S. using state shapefiles.

Click a state and pull data from a related JSON file. This choropeth version colors states according to predefined categories.

Embed tag

Jump to the Require JS module

<style type="text/css">
.us_state {
    stroke: #fff;
    stroke-width:1;
}
.us_state:hover {
    stroke:#a6a8ab;
    stroke-width:1;
}
.selected {
    stroke:#a6a8ab;
    stroke-width:1;
}
#svg {
    width:100%;
    max-height: 100%;
}
svg {
    position: absolute;
    top: 0;
    left: 0;
}
.map_container {
    height: 0;
    padding-top: 65%;
    position: relative;
}
.maplegend {
        border:0;
        padding:0;
        text-align: center;
        font-size:12px;
        float:right;
        width:30px;
        height:15px;
        border-top:1px solid #a6a8ab;
        border-bottom:1px solid #a6a8ab;
}
.maplegend-a {
        border:0;
        padding:0;
        text-align: center;
        font-size:12px;
        float:right;
        width:30px;
        height:15px;
        border-top:1px solid #a6a8ab;
        border-left:1px solid #a6a8ab;
        border-bottom:1px solid #a6a8ab;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<div style="clear:both;">
    <hr />
    <h4>Data by state</h4>
    <p>Select a state below to find out some data, adjusted for each state's labor force/population etc, as of some date.</p> 
    <select style="margin-top:10px;" id="state_select"> 
        <option value="Alabama">Alabama</option> 
        <option value="Alaska">Alaska</option> 
        <option value="Arizona">Arizona</option> 
        <option value="Arkansas">Arkansas</option> 
        <option value="California">California</option> 
        <option value="Colorado">Colorado</option> 
        <option value="Connecticut">Connecticut</option> 
        <option value="Delaware">Delaware</option>
        <option value="Florida">Florida</option> 
        <option value="Georgia">Georgia</option> 
        <option value="Hawaii">Hawaii</option> 
        <option value="Idaho">Idaho</option> 
        <option value="Illinois">Illinois</option> 
        <option value="Indiana">Indiana</option> 
        <option value="Iowa">Iowa</option> 
        <option value="Kansas">Kansas</option> 
        <option value="Kentucky">Kentucky</option> 
        <option value="Louisiana">Louisiana</option> 
        <option value="Maine">Maine</option> 
        <option value="Maryland">Maryland</option> 
        <option value="Massachusetts">Massachusetts</option> 
        <option value="Michigan">Michigan</option> 
        <option value="Minnesota">Minnesota</option> 
        <option value="Mississippi">Mississippi</option> 
        <option value="Missouri">Missouri</option> 
        <option value="Montana">Montana</option> 
        <option value="Nebraska">Nebraska</option> 
        <option value="Nevada">Nevada</option> 
        <option value="New Hampshire">New Hampshire</option> 
        <option value="New Jersey">New Jersey</option> 
        <option value="New Mexico">New Mexico</option> 
        <option value="New York">New York</option> 
        <option value="North Carolina" selected="selected">North Carolina</option> 
        <option value="North Dakota">North Dakota</option>
        <option value="Ohio">Ohio</option>  
        <option value="Oklahoma">Oklahoma</option> 
        <option value="Oregon">Oregon</option> 
        <option value="Pennsylvania">Pennsylvania</option> 
        <option value="Rhode Island">Rhode Island</option> 
        <option value="South Carolina">South Carolina</option> 
        <option value="South Dakota">South Dakota</option> 
        <option value="Tennessee">Tennessee</option> 
        <option value="Texas">Texas</option> 
        <option value="Utah">Utah</option> 
        <option value="Vermont">Vermont</option> 
        <option value="Virginia">Virginia</option> 
        <option value="Washington">Washington</option> 
        <option value="West Virginia">West Virginia</option> 
        <option value="Wisconsin">Wisconsin</option> 
        <option value="Wyoming">Wyoming</option>
    </select>
    <div class="map-loading" style="height:225px;">
        <h3 style="text-align:center;margin-top:40px;margin-bottom:10px;text-transform:uppercase;">Loading map</h3>
        <img src="http://wwwcache.wral.com/presentation/v3/images/widgets/wait_popup/spinner.gif" style="width:31px;margin:auto;display:block;" />
    </div>
    <div id="map" style="margin-bottom:0px; display:none;">
    </div>
    <div style="margin:0;">
        <div style="margin:0;padding-top:0px;display:block;">
            <div style="float:right;padding-bottom:30px;">
                <div style="text-align:center;text-transform:uppercase;font-size:12px;padding:0;">
                    Legend
                </div>
                <div>
                    <div class="maplegend" style="background-color:#3182bd;"><br />18+</div>
                    <div class="maplegend" style="background-color:#9ecae1;"><br />7-18</div>
                    <div class="maplegend" style="background-color:#deebf7;"><br />3-7</div>
                    <div class="maplegend-a" style="background-color:#eff3ff;"><br />0-3</div>
                </div>
            </div>
        </div>
        <div>
            <h4 class="top-var">Variable: <span style="color:#333;"><span id="variable">6.45</span>%</span></h4>
        </div>
        <div class="attr">
            Graphic by YOUR NAME
        </div>
    </div>
    <hr />
</div>

RequireJS Module

Jump to the Embed tag

require(
  ['jquery','lodash','http://d3js.org/d3.v3.min.js','http://d3js.org/topojson.v1.min.js'],

  function($, _) {

    //establish several global variables
    //this includes display versions of state names
    var state = "North_Carolina";
    var stats;
    var state_display = "North Carolina";

    //set initial height, width
    var width = 600,
    height = 400;

    //set the projection, scale and other map parameters 
    //and establish the drawing path
    var projection = d3.geo.albersUsa()
    .scale(820)
    .translate([300,190]);
    var path = d3.geo.path().projection(projection);

    //creates responsive resizing
    //more details:
    //http://stackoverflow.com/questions/20885164/how-to-create-a-responsive-map-using-d3
    var svg = d3.select("#map")
    .append("div")
    .attr("id","svg")
    .append("div")
    .attr("class","map_container")
    .append("svg")
    .attr("viewBox","0 0 " + width + " " + height)
    .attr("preserveAspectRatio","xMinYMin");

    d3.json("/news/national_world/data_set/14437972/?dsi_id=states&version=jsonObj", function(error, us) {
      svg.selectAll(".us_state")
      .data(topojson.feature(us, us.objects.states).features)
      .enter().append("path")
      .attr("class", function(d) {
        if(d.properties.name == "North Carolina"){return "us_state " + d.properties.name + " selected"}
          else if(d.properties.name == "Puerto Rico"){return "hidden"}
            else{return "us_state"}
          })
      .attr("id", function(d) {return d.properties.name.split(' ').join('_')})
      .attr("d", path)
      .on("click", function(d) {
        d3.selectAll(".selected").classed("selected", false);
        d3.select(this).classed("selected", true);
        svg.selectAll("path").sort(function (a, b) { // select the parent and sort the path's
        if (a != d) return -1;               // a is not the clicked element, send "a" to the back
        else return 1;                             // a is the clicked element, bring "a" to the front
      });
      });
      run_rural();
      bindClicks();
    });

    //workaround for making sure path appears on top
    jQuery.fn.d3Click = function () {
      this.each(function (i, e) {
        var evt = document.createEvent("MouseEvents");
        evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        e.dispatchEvent(evt);
      });
    };

    function run_rural(){
      var rural_stats = (function(){
        $.ajax({
          'async': true,
          'global': false,
          'url': 'news/national_world/data_set/14614951/?dsi_id=rural-hospitals&version=jsonObj',
          'dataType': "json",
          'success': function (data) {
            rural_stats = data;
            stats = rural_stats;
            parseData();
            $('.map-loading').css('display','none');
            $('#map').css('display','block');
          }
        });
        return rural_stats;
      })();
    }

    //user-defined function to set choropeth colors
    function parseData(){
      for (j=0; j < stats.length; j++){
            variable = parseFloat(stats[j]['Percent Vulnerable']);
            id_name = '#'+stats[j].State.replace(/ /g,"_");
            if (id_name == "#DC"){
              //ignore because there's no visible shapefile for
              //the District of Columbia
            }
            else {
              switch (true){
                //case for 0 to 3
                case (variable < 3 ):
                  $(id_name).css('fill','#eff3ff');
                  break;
                //case for 3 to 7
                case (variable >= 3 && variable < 7 ):
                  $(id_name).css('fill','#deebf7');
                  break;
                //case for 7 to 18
                case (variable >= 7 && variable < 18 ):
                  $(id_name).css('fill','#9ecae1');
                  break;
                //case for 18 or more
                case (variable >= 18 ):
                  $(id_name).css('fill','#3182bd');
                  break;
                //if there's not matching category, report it to the console
                default:
                  console.log("ERROR: no color category")
                  break;
              }
            }
          }
    }

    //Event listeners for clicking path
    function bindClicks(){
      $('path').click(function(e){
        e.preventDefault();
        state = $(this).attr('id');
        state_display = state.replace(/_/g," ");
        $('#state_select').val(state_display);
        var i = 0;
        while(stats[i].State != state_display){
          i++;
        }
        document.getElementById("variable").innerHTML = stats[i]['Percent Vulnerable'];
      });
    }

    //defines what happens when the user selects a dropdown item
    $('#state_select').change(function(e){
      e.preventDefault();
      //get the state selected in the dropdown
      state_display = $(this).val();
      state = state_display.replace(/ /g,"_");
      var i = 0;
      //find the index value of the state in our data
      while(stats[i].State != state_display){
        i++;
      }
      //reset all the county paths to remove the 'selected' class
      $('path').attr('class','us_state');
      //add the selected class back to the specified county path
      $('#'+ state).attr('class','us_state selected');
      //change the value of the variable parameter
      document.getElementById("variable").innerHTML = stats[i]['Percent Vulnerable'];
      //Invoke d3 command for making sure path is properly shaded
      $('#'+state).d3Click();
    });

  }
);