angular.module('app', ['ui.grid'])

.run(function (StateData) {
  StateData.init();
})

.controller('MainCtrl', function (StateData) {
  var vm = this;
  
  vm.reset = reset;
  vm.stateClicked = stateClicked;
  vm.gridOptions = {
    columnDefs: [{ field: '0', name: 'county' },
        { field: '1', name: 'population', displayName: 'Total Population', type: 'number', cellFilter: 'number' },
        { field: '2', name: 'housing', displayName: 'Housing Units', type: 'number', cellFilter: 'number' }]
  };
  
  ////////////
  
  // Initialize our data source
  // Reset the data source in a timeout so we can see the loading message
  function reset() {
    vm.state = '';
    vm.gridOptions.data = [];
  }
  
  function stateClicked(state) {
    vm.loading = true;
    StateData.getState(state)
      .then(function (data) {
        vm.state = state;
        vm.gridOptions.data = data;
      })
      .finally(function () {
        vm.loading = false;
      });
  }
})

.service('StateData', function ($http) {
  var fipsCodes = {};
  
  var s = {
    data: [],
    columnDefs: [],
    
    init: function() {
      // Get fips codes mappings
      $http.get('fips.json')
        .success(function (data) {
          fipsCodes = data;
        });
    },
    
    setColumnDefs: function () {
      s.columnDefs = [
        { field: '0', name: 'county' },
        { field: '1', name: 'population', displayName: 'Total Population', cellFilter: 'number' },
        { field: '2', name: 'housing', displayName: 'Housing Units', cellFilter: 'number' }
      ];
    },
    
    getState: function (state) {
      // s.columnDefs = null;
      // s.data = null;
      
      if (!state) {
        return;
      }
      
      // Get state fips code
      var fips = fipsCodes[state];
      
      return $http.get('http://api.census.gov/data/2010/sf1?get=NAME,P0010001,H00010001&for=county:*&in=state:' + fips)
        .then(function (data) {
          // [["NAME","P0010001","H00010001","state","county"],
          // ["Alameda County","1510271","582549","06","001"],
          data = data.data;
          
          // Remove header line
          data.shift();
          return data;
        });
    }
  };
  
  return s;
})

.directive('gridMap', function () {
  return {
    scope: {
      click: '&'
    },
    link: function ($scope, $elm, $attrs) {
      $elm.addClass('grid-map');
      $elm.usmap({
        stateHoverStyles: { fill: '#5cb85c' },
        click: function(event, data) {
          $scope.$apply(function () {
            $scope.click({state: data.name});
          });
        }
      });
    }
  };
});
body {
  padding: 10px;
}

.grid {
  width: 100%;
  height: 350px;
}

.grid-msg-overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  background: rgba(0, 0, 0, 0.4);
}

.grid-msg-overlay .msg {
  opacity: 1;
  position: absolute;
  top: 20%;
  left: 20%;
  width: 60%;
  height: 50%;
  background-color: #eee;
  border-radius: 4px;
  border: 1px solid #555;
  text-align: center;
  font-size: 24px;
  display: table;
}

.grid-msg-overlay .msg span {
  display: table-cell;
  vertical-align: middle;
}

.grid-map-container {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.grid-map {
  position: absolute;
  top: 32px;
  bottom: 0;
  width: 100%;
}
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <script data-require="jquery@*" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
    <script data-require="raphael@*" data-semver="2.1.0" src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
    <script src="https://cdn.rawgit.com/NewSignature/us-map/v1.0.1/jquery.usmap.js"></script>
    <link data-require="font-awesome@*" data-semver="4.3.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" />
    <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js"></script>
    <!--<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-touch.js"></script>-->
    <script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
    <link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css" />
    <link rel="stylesheet" href="main.css" type="text/css" />
  </head>

  <body>
    <div ng-controller="MainCtrl as vm">
      <button type="button" class="btn btn-success" ng-click="vm.reset()">Reset</button>
      <br />
      <h2 class="text-center">{{ vm.state }}</h2>
      <div id="grid1" ui-grid="vm.gridOptions" class="grid">
        <div class="grid-msg-overlay" ng-show="vm.loading">
          <div class="msg">
            <span>
              Loading Data...
              <i class="fa fa-spinner fa-spin"></i>
            </span>
          </div>
        </div>
        <div class="grid-map-container" ng-show="!vm.loading && !vm.gridOptions.data.length">
          <!-- <h3 class="text-center">Pick a State</h3> -->
          <div grid-map click="vm.stateClicked(state)"></div>
        </div>
      </div>
    </div>
    
    <br>
    
    <div class="text-center">
      <small>This product uses the Census Bureau Data API but is not endorsed or certified by the Census Bureau.</small>
    </div>
    
    <script src="app.js"></script>
  </body>

</html>
[
  {
    "name": "Small Guthrie",
    "age": 20
  },
  {
    "name": "Robert Ashley",
    "age": 53
  },
  {
    "name": "Danielle Powers",
    "age": 56
  },
  {
    "name": "Rosetta Howard",
    "age": 77
  },
  {
    "name": "Ofelia Williamson",
    "age": 60
  },
  {
    "name": "Angelica Grant",
    "age": 21
  },
  {
    "name": "Beasley Bullock",
    "age": 37
  },
  {
    "name": "Mcfadden Kelley",
    "age": 28
  },
  {
    "name": "Conner Cleveland",
    "age": 33
  },
  {
    "name": "Jeannie Foreman",
    "age": 52
  },
  {
    "name": "Langley Clark",
    "age": 37
  },
  {
    "name": "Wood Chan",
    "age": 79
  },
  {
    "name": "Mavis Tate",
    "age": 23
  },
  {
    "name": "Morrison Oneil",
    "age": 68
  },
  {
    "name": "Luella Macdonald",
    "age": 32
  },
  {
    "name": "Bonnie Brennan",
    "age": 73
  },
  {
    "name": "Iris Holloway",
    "age": 79
  },
  {
    "name": "Bridges Stein",
    "age": 53
  },
  {
    "name": "Sanders Ward",
    "age": 34
  },
  {
    "name": "Trevino Parsons",
    "age": 20
  },
  {
    "name": "Hogan Weaver",
    "age": 18
  },
  {
    "name": "Hayes Fitzgerald",
    "age": 51
  },
  {
    "name": "Leonard Bentley",
    "age": 59
  },
  {
    "name": "Pace Pratt",
    "age": 42
  },
  {
    "name": "Clarke Page",
    "age": 77
  },
  {
    "name": "Carolina Rosa",
    "age": 44
  },
  {
    "name": "Kasey Blair",
    "age": 21
  },
  {
    "name": "Farrell Beasley",
    "age": 28
  },
  {
    "name": "Sellers Kemp",
    "age": 52
  },
  {
    "name": "Winifred Fulton",
    "age": 48
  }
]
{
   "AL": "01",
   "AK": "02",
   "AZ": "04",
   "AR": "05",
   "CA": "06",
   "CO": "08",
   "CT": "09",
   "DE": "10",
   "DC": "11",
   "FL": "12",
   "GA": "13",
   "HI": "15",
   "ID": "16",
   "IL": "17",
   "IN": "18",
   "IA": "19",
   "KS": "20",
   "KY": "21",
   "LA": "22",
   "ME": "23",
   "MD": "24",
   "MA": "25",
   "MI": "26",
   "MN": "27",
   "MS": "28",
   "MO": "29",
   "MT": "30",
   "NE": "31",
   "NV": "32",
   "NH": "33",
   "NJ": "34",
   "NM": "35",
   "NY": "36",
   "NC": "37",
   "ND": "38",
   "OH": "39",
   "OK": "40",
   "OR": "41",
   "PA": "42",
   "RI": "44",
   "SC": "45",
   "SD": "46",
   "TN": "47",
   "TX": "48",
   "UT": "49",
   "VT": "50",
   "VA": "51",
   "WA": "53",
   "WV": "54",
   "WI": "55",
   "WY": "56",
   "AS": "60",
   "GU": "66",
   "MP": "69",
   "PR": "72",
   "UM": "74",
   "VI": "78"
}