|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
body { background: transparent; } |
|
path { stroke: #333; stroke-width: 1; } |
|
path:hover { stroke-width: 3; } |
|
#console { |
|
font-size: 11px; |
|
font-family: "Courier", "fixed-width"; |
|
width: 400px; |
|
height: 150px; |
|
position: fixed; |
|
top: 0; |
|
left: 0; |
|
padding: 4px; |
|
overflow: auto; |
|
background-color: white; |
|
border: 2px solid black; |
|
} |
|
#console p { |
|
margin-top: 1px; |
|
margin-bottom: 0 |
|
} |
|
svg { |
|
border: 5px solid red; |
|
} |
|
</style> |
|
<body> |
|
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script> |
|
<!-- <script src="http://d3js.org/queue.v1.min.js"></script> --> |
|
|
|
<script src="//d3js.org/topojson.v1.min.js"></script> |
|
|
|
<div id="console"></div> |
|
|
|
<svg id="zoomy-map" width="400" height="300"></svg> |
|
|
|
<script> |
|
d3.select('#console').append('p').text('v0.1') |
|
var width = 960 |
|
var height = 600 |
|
var padding = 20 |
|
|
|
var allData = [] |
|
|
|
var color = d3.scale.threshold() |
|
.domain([0.028, 0.038, 0.048, 0.058, 0.068, 0.078]) |
|
.range(['#4d9221', '#a1d76a', '#e6f5d0', '#f7f7f7', '#fde0ef', '#e9a3c9', '#c51b7d']) |
|
|
|
var projection = d3.geo.albers() |
|
.precision(0) |
|
.scale(height * 2).translate([width / 2, height / 2]) |
|
|
|
var path = d3.geo.path().projection(projection) |
|
|
|
var svg = d3.select('#zoomy-map') |
|
//.append('svg') |
|
.attr('width', width) |
|
.attr('height', height) |
|
|
|
d3.select('#console').append('p').text('width '+width) |
|
d3.select('#console').append('p').text('height '+height) |
|
|
|
|
|
/* |
|
queue() |
|
.defer(d3.csv, 'data.csv', function (d) { |
|
return { |
|
id: +(d.state + d.county), |
|
state: d.state, |
|
county: d.county, |
|
unemployment: +d.unemployment |
|
} |
|
}) |
|
.defer(d3.json, 'us-states.json') |
|
.defer(d3.json, 'us-counties.json') |
|
.awaitAll(initialize) |
|
*/ |
|
|
|
d3.csv('data.csv', function(error, data){ |
|
d3.select('#console').append('p').text('data.csv loaded') |
|
allData.push(data) |
|
|
|
|
|
d3.json('us-states.json', function(error, data){ |
|
d3.select('#console').append('p').text('us-states.json loaded') |
|
allData.push(data) |
|
|
|
d3.json('us-counties.json', function(error, data){ |
|
d3.select('#console').append('p').text('us-counties.json loaded') |
|
|
|
allData.push(data) |
|
allData[0].forEach(function(d,i){ |
|
if(i<10){ console.log('foreach d', d)} |
|
allData[0][i] = { |
|
'id': +(d.state + d.county), |
|
'county': d.county, |
|
'state': d.state, |
|
'unemployment': +d.unemployment |
|
} |
|
}) |
|
|
|
d3.select('#console').append('p').text('allData[0] length: '+allData[0].length) |
|
|
|
d3.select('#console').append('p').text('allData[1] length: '+allData[1].arcs.length) |
|
|
|
d3.select('#console').append('p').text('allData[2] length: '+allData[2].arcs.length) |
|
|
|
console.log('======> alldata', allData) |
|
initialize({},allData) |
|
}) |
|
}) |
|
}) |
|
|
|
function initialize(error, results) { |
|
//if (error) { throw error } |
|
|
|
d3.select('#console').append('p').text('running initialize()') |
|
|
|
var data = results[0] |
|
var states = topojson.feature(results[1], results[1].objects.states).features |
|
var counties = topojson.feature(results[2], results[2].objects.counties).features |
|
|
|
console.log('states -->', states) |
|
|
|
states.forEach(function (f,i) { |
|
|
|
if(i<5){ |
|
//d3.select('#console').append('p').text('state data '+JSON.stringify(f)) |
|
//console.log('--> f ',f, 'f.id', f.id) |
|
//console.log('--> data find', data.find(function (d,i) { |
|
//if(i<10){ console.log('--> find d', d)} |
|
//return d.id === f.id |
|
//})) |
|
} |
|
f.properties = data.find(function (d) { return d.id === f.id }) |
|
}) |
|
|
|
console.log('states after foreach ==>', states) |
|
|
|
counties.forEach(function (f) { |
|
f.properties = data.find(function (d) { return d.id === f.id }) || {} |
|
}) |
|
|
|
var statePaths = svg.selectAll('.state') |
|
.data(states) |
|
.enter().append('path') |
|
.attr('class', 'state') |
|
.attr('d', path) |
|
.style('fill', function (d) { |
|
//console.log(d) |
|
return color(d.properties.unemployment) |
|
}) |
|
.on('click', function (d) { stateZoom(d.id) }) |
|
|
|
function usZoom() { |
|
alert("US Zoom"); |
|
var t = d3.transition().duration(800) |
|
|
|
projection.scale(height * 2).translate([width / 2, height / 2]) |
|
|
|
statePaths.transition(t) |
|
.attr('d', path) |
|
.style('fill', function (d) { return color(d.properties.unemployment) }) |
|
|
|
svg.selectAll('.county') |
|
.data([]) |
|
.exit().transition(t) |
|
.attr('d', path) |
|
.style('opacity', 0) |
|
.remove() |
|
} |
|
|
|
function stateZoom(id) { |
|
alert("State Zoom"); |
|
var state = states.find(function (d) { return d.id === id }) |
|
var stateCounties = counties.filter(function (d) { |
|
return d.id > id && d.id < id + 1000 |
|
}) |
|
|
|
var t = d3.transition().duration(800) |
|
|
|
var countyPaths = svg.selectAll('.county') |
|
.data(stateCounties, function (d) { return d.id }) |
|
|
|
var enterCountyPaths = countyPaths.enter().append('path') |
|
.attr('class', 'county') |
|
.attr('d', path) |
|
.style('fill', function (d) { return color(d.properties.unemployment) }) |
|
.style('opacity', 0) |
|
.on('click', function () { usZoom() }) |
|
|
|
projection.fitExtent( |
|
[[padding, padding], [width - padding, height - padding]], |
|
state |
|
) |
|
|
|
statePaths.transition(t) |
|
.attr('d', path) |
|
.style('fill', '#444') |
|
|
|
enterCountyPaths.transition(t) |
|
.attr('d', path) |
|
.style('opacity', 1) |
|
|
|
countyPaths.exit().transition(t) |
|
.attr('d', path) |
|
.style('opacity', 0) |
|
.remove() |
|
} |
|
} |
|
|
|
</script> |
|
</body> |