Skip to content

Instantly share code, notes, and snippets.

@sabrinamochi
Last active July 10, 2019 05:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sabrinamochi/fc4e82bed4a612144b742d83db991d08 to your computer and use it in GitHub Desktop.
Save sabrinamochi/fc4e82bed4a612144b742d83db991d08 to your computer and use it in GitHub Desktop.
US Unemployment Rate in 2016
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
.popuText,
.explainText,
.colorText,
.reset text,
.city_name {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
.pan rect {
fill: none;
}
.colorText,
.reset text,
.zoom text,
.pan text {
fill: white;
}
.reset rect,
.zoom rect {
fill: black;
opacity: 0.3;
rx: 5;
/*rounded corners*/
ry: 5;
}
.reset:hover rect,
.pan:hover rect,
.zoom:hover rect {
opacity: 0.5;
}
.reset:hover text,
.zoom:hover text,
.pan:hover text {
opacity: 1;
}
</style>
<title> us map </title>
<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>2016 Unemployment Rate Across the U.S.</h1>
<script type="text/javascript">
var dcolor = [1, 2, 3, 4, 5]
var svg1 = d3.select('body')
.append('svg')
.attr('class', 'colorBar')
.attr('width', 1000)
.attr('height', 45);
var colorRect = svg1.selectAll('rect')
.data(dcolor)
.enter()
.append('rect')
.attr('x', function(d, i) {
return i * 100;
})
.attr('y', 20)
.attr('width', 100)
.attr('height', 20);
colorRect.attr('fill', function(d, i) {
if (i == 0) {
return '#d8e0bb';
} else if (i == 1) {
return '#b6cec7';
} else if (i == 2) {
return '#86a3c3';
} else if (i == 3) {
return '#7268a6';
} else if (i == 4) {
return '#6b3074';
}
});
var colorText = svg1.selectAll('text')
.data(dcolor)
.enter()
.append('text')
.attr('class', 'colorText')
.attr('x', function(d, i) {
if (i == 0) {
return '0'
} else if (i == 4) {
return '470'
}
})
.attr('y', 35)
.text(function(d, i) {
if (i == 0) {
return 'low'
} else if (i == 4) {
return 'high'
}
})
.attr('font-style', 'italic')
var explainText = svg1.append('text')
.attr('class', 'explainText')
.text('Unemployment Rate')
.attr('x', 0)
.attr('y', 15)
.attr('fill', 'black')
.attr('font-style', 'italic');
var circleData = [1, 2, 3, 4]
var populationCircle = svg1.selectAll('circle')
.data(circleData)
.enter()
.append('circle')
.attr('cx', function(d, i) {
return 600 + i * 40;
})
.attr('cy', 30)
.attr('r', function(d, i) {
return 4 + i * 3;
})
.style('fill', 'yellow')
.style('opacity', 0.9)
.style('stroke', 'gray')
.style('stroke-opacity', 0.2)
.style('stroke-width', 0.5);
var popuText = svg1.append('text')
.attr('class', 'popuText')
.text('City Population Size')
.attr('x', 595)
.attr('y', 15)
.attr('fill', 'black')
.attr('font-style', 'italic');
var h = 500;
var w = 1000;
var projection = d3.geoAlbersUsa()
.translate([0, 0]);
var path = d3.geoPath()
.projection(projection);
//Create SVG element
var svg2 = d3.select("body")
.append("svg")
.attr('transform', 'translate(0, 0)')
.attr("width", w)
.attr("height", h);
var rowConverter = function(d) {
return {
state: d.state,
rate_medians: parseFloat(d.rate_medians)
};
};
var color = d3.scaleQuantize()
.range(['#d8e0bb', '#b6cec7', '#86a3c3', '#7268a6', '#6b3074']);
// define what to do when dragging
var dragging = function(d) {
// get the present translation offset
var offset = projection.translate();
// d3.event only exists in context, during an event
// dx,dy contain the amount of change in x,y position
//since the preceding drag event
offset[0] += d3.event.dx;
offset[1] += d3.event.dy;
// update projection with new offset
projection.translate(offset);
//update all paths and circles
map.selectAll('path')
.attr('d', path);
map.selectAll('circle')
.attr('cx', function(d) {
return projection([d.lon, d.lat])[0];
})
.attr('cy', function(d) {
return projection([d.lon, d.lat])[1];
});
};
var drag = d3.drag()
.on('drag', dragging);
var zoomed = function(d) {
var offset = projection.translate();
offset[0] = d3.event.transform.x;
offset[1] = d3.event.transform.y;
var newScale = d3.event.transform.k * 2000;
projection.translate(offset)
.scale(newScale);
//update all paths and circles
svg2.selectAll('path')
.attr('d', path);
svg2.selectAll('circle')
.attr('cx', function(d) {
return projection([d.lon, d.lat])[0];
})
.attr('cy', function(d) {
return projection([d.lon, d.lat])[1];
});
};
var zoom = d3.zoom()
.translateExtent([
[-1200, -700],
[1200, 700]
])
.scaleExtent([0.3, 2.0])
.on('zoom', zoomed)
// put all dragable elements in one group
var map = svg2.append('g')
.attr('id', 'map')
.call(zoom) // Bind the zoom behavior
.call(zoom.transform, d3.zoomIdentity // apply the initial transform
.translate(w / 2, h / 2)
.scale(0.45));
map.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', w)
.attr('height', h)
.attr('opacity', 0);
// load in unemployment rate data
d3.csv('https://raw.githubusercontent.com/sabrinamochi/us_unemployment/master/us_unemployment/us_unemployment_rate.csv', rowConverter).then(function(data) {
var dataset = data;
console.table(dataset, ['state', 'rate_medians']);
color.domain([
d3.min(dataset, function(d) {
return d.rate_medians;
}),
d3.max(dataset, function(d) {
return d.rate_medians;
})
]);
// load in GeoJSON data
d3.json('https://raw.githubusercontent.com/alignedleft/d3-book/master/chapter_14/us-states.json').then(function(json) {
// merge the unemployment data and GeoJSON data
for (var i = 0; i < dataset.length; i++) {
var dataState = dataset[i].state;
var dataValue = dataset[i].rate_medians;
// find the corresponding state name
for (var j = 0; j < json.features.length; j++) {
var jsonState = json.features[j].properties.name;
if (dataState == jsonState) {
// Copy the data value into the JSON
json.features[j].properties.value = dataValue;
break;
}
}
}
map.selectAll('path')
.data(json.features)
.enter()
.append('path')
.attr('d', path)
.style('fill', function(d) {
var value = +d.properties.value;
if (value) {
// if value exists
return color(value);
} else {
// if value is undefined
return '#ccc';
}
});
// load in cities data
d3.csv('https://raw.githubusercontent.com/alignedleft/d3-book/master/chapter_14/us-cities.csv').then(function(data) {
map.selectAll('circle')
.data(data)
.enter()
.append('circle')
.attr('cx', function(d) {
return projection([d.lon, d.lat])[0];
})
.attr('cy', function(d) {
return projection([d.lon, d.lat])[1];
})
.attr('r', function(d) {
return Math.sqrt(parseInt(d.population) * 0.00004);
})
.style('fill', 'yellow')
.style('opacity', 0.75)
/*var text = svg2.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('class', 'city_name')
.text(function(d){
if (parseFloat(d.population) > 1000000) {
return d.place;}
})
.attr('x', function (d) {
return projection([d.lon, d.lat])[0];
})
.attr('y', function (d) {
return projection([d.lon, d.lat])[1]-8;})
.style('fill', '#D8D6D8');*/
//createPanButtons();
createScaleButtons();
createResetButton();
});
});
});
var createPanButtons = function() {
// create the clickable groups
// north
var north = svg2.append('g')
.attr('class', 'pan')
.attr('id', 'north');
north.append('rect')
.attr('x', 40)
.attr('y', 0)
.attr('width', w - 80)
.attr('height', 40);
north.append('text')
.attr('x', w / 2)
.attr('y', 25)
.html('&uarr;')
//south
var south = svg2.append('g')
.attr('class', 'pan')
.attr('id', 'south')
south.append('rect')
.attr('x', 40)
.attr('y', h - 40)
.attr('width', w - 80)
.attr('height', 40);
south.append('text')
.attr('x', w / 2)
.attr('y', h - 15)
.html('&darr;');
//west
var west = svg2.append('g')
.attr('class', 'pan')
.attr('id', 'west')
west.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', 40)
.attr('height', h + 40);
west.append('text')
.attr('x', 15)
.attr('y', h / 2)
.html('&larr;');
//east
var east = svg2.append('g')
.attr('class', 'pan')
.attr('id', 'east')
east.append('rect')
.attr('x', w - 40)
.attr('y', 0)
.attr('width', 40)
.attr('height', h + 40);
east.append('text')
.attr('x', w - 25)
.attr('y', h / 2)
.html('&rarr;');
// panning interaction
d3.selectAll('.pan')
.on('click', function() {
var x = 0;
var y = 0;
var direction = d3.select(this).attr('id');
var moveAmount = 50;
switch (direction) {
case 'north':
y += moveAmount;
break;
case 'south':
y -= moveAmount;
break;
case 'east':
x -= moveAmount;
break;
case 'west':
x += moveAmount;
break;
default:
break;
};
map.transition()
.call(zoom.translateBy, x, y);
});
}
var createScaleButtons = function() {
// zoom in button
var zoomIn = svg2.append('g')
.attr('class', 'zoom')
.attr('id', 'in')
.attr('transform', 'translate(' + (w - 140) + ', 290)');
zoomIn.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', 30)
.attr('height', 30);
zoomIn.append('text')
.attr('x', 10)
.attr('y', 20)
.text('+');
var zoomOut = svg2.append('g')
.attr('class', 'zoom')
.attr('id', 'out')
.attr('transform', 'translate(' + (w - 100) + ',290)');
zoomOut.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', 30)
.attr('height', 30);
zoomOut.append('text')
.attr('x', 10)
.attr('y', 20)
.text('-');
d3.selectAll('.zoom')
.on('click', function() {
var scaleFactor;
var direction = d3.select(this).attr('id');
switch (direction) {
case 'in':
scaleFactor = 1.5;
break;
case 'out':
scaleFactor = 0.75;
break;
default:
break;
};
map.transition()
.call(zoom.scaleBy, scaleFactor);
});
};
var createResetButton = function() {
var reset = svg2.append('g')
.attr('class', 'reset')
.attr('transform', 'translate(' + (w - 140) + ',250)');
reset.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', 70)
.attr('height', 30);
reset.append('text')
.attr('x', 15)
.attr('y', 20)
.text('Reset')
d3.select('.reset')
.on('click', function() {
map.transition()
.call(zoom.transform, d3.zoomIdentity // apply the initial transform
.translate(w / 2, h / 2)
.scale(0.45));
});
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment