<h1>Computer and Mathematical Occupations: May 2014 <a href="http://www.bls.gov/oes/current/oes150000.htm" target="blank">[source]</a></h1>
$stroke-width: 4;
$scale: 2;
.svg {
position: absolute;
top: 50%; left: 50%;
transform: translate3d(-50%,-50%, 0);
g {
cursor: pointer;
polygon {
stroke: white;
stroke-width: $stroke-width;
transform: scale(1);
opacity: 0.5;
transition: opacity 200ms ease-in;
}
text {
text-anchor: middle;
alignment-baseline: middle;
transition: opacity 200ms ease-in;
}
text:not(.data) {
fill: white;
}
text.data {
fill: hsl(180,60%,60);
font-weight: 100;
&.title {
font-size: 20px;
fill: hsl(180,60%,30);
}
}
.state-name, .data { opacity: 0; }
.state-abbr { opacity: 1; }
&.hover {
.state-name, .data { animation: fade-in 300ms ease-in 200ms forwards; }
.state-abbr { animation: fade-out 300ms ease-in 200ms forwards; }
polygon {
opacity: 1;
transition: fill 200ms ease-in;
animation: scale-polygon 300ms ease-in forwards;
}
}
}
}
@keyframes scale-polygon {
from { transform: scale(1); stroke-width: $stroke-width; }
to { transform: scale($scale); stroke-width: $stroke-width / $scale; }
}
@keyframes fade-in { to { opacity: 1; } }
@keyframes fade-out { to { opacity: 0; } }
h1 {
color: #999;
font-weight: 100;
text-align: center;
font-size: 1em;
position: fixed;
top: 0;
left: 0; width: 100%;
z-index: 1;
background: rgba(255,255,255,0.8);
padding: 0.6em 0;
a {
color: hsl(180,60%,70);
text-decoration: none;
font-size: 0.7em;
}
}
View Compiled
// launchpad
function initializeMap() {
// creating base svg
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
// hexagon shape variables
var hex_di = 100,
// radius
hex_rad = hex_di / 2,
// apothem
hex_apo = hex_rad * Math.cos(Math.PI / 6),
// matrix defining state placement
states_grid = usStateMatrix(),
// data
states_data = usStateData(),
// rows we'll generate
rows = states_grid.length,
// columns we'll generate
cols = states_grid[0].length,
// stroke width around hexagon
stroke = 4,
// the hover state zoom scale
scale = 2,
// initial x
x = hex_rad * scale / 2 + stroke * scale,
// initial y
y = hex_rad * scale + stroke * scale,
// side length in pixels
side = Math.sin(Math.PI / 6) * hex_rad,
// height of map in pixels
height = (hex_di - side) * rows + side + hex_rad * scale + stroke * scale,
// width of map in pixels
width = (hex_apo * 2) * cols + hex_rad * scale + stroke * scale;
// svg attributes
svg.setAttribute("class", "svg");
svg.setAttribute("width", "100%");
svg.setAttribute("height", "100%");
svg.setAttribute("viewBox", "0 0 " + width + " " + height);
// loop variables
var offset = false,
// parsing state data
states = states_data.states,
data = states_data.data,
// initial state index
state_index = 0;
// getting range of data defaults
var hourly_mean_wage_max = 0,
hourly_mean_wage_min = 100,
annual_mean_wage_max = 0,
annual_mean_wage_min = 100000,
jobs_per_1000_max = 0,
jobs_per_1000_min = 10;
// for each data find max and min
for(var d = 0; d < data.length; d++) {
hourly_mean_wage_max = Math.max(hourly_mean_wage_max, data[d].hourly_mean_wage);
hourly_mean_wage_min = Math.min(hourly_mean_wage_min, data[d].hourly_mean_wage);
annual_mean_wage_max = Math.max(annual_mean_wage_max, data[d].annual_mean_wage);
annual_mean_wage_min = Math.min(annual_mean_wage_min, data[d].annual_mean_wage);
jobs_per_1000_max = Math.max(jobs_per_1000_max, data[d].jobs_per_1000);
jobs_per_1000_min = Math.min(jobs_per_1000_min, data[d].jobs_per_1000);
}
// getting differences in range
var hourly_mean_wage_dif = hourly_mean_wage_max - hourly_mean_wage_min,
annual_mean_wage_dif = annual_mean_wage_max - annual_mean_wage_min,
jobs_per_1000_dif = jobs_per_1000_max - jobs_per_1000_min;
// draw grid
for(var i = 0; i < states_grid.length; i++) {
var loop_x = offset ? hex_apo * 2 : hex_apo;
var loc_x = x;
for(var s = 0; s < states_grid[i].length; s++) {
// grid plot in 0 and 1 array
var grid_plot = states_grid[i][s];
// if we have a plot in the grid
if (grid_plot != 0) {
// get the state
var state = states[state_index];
// lookup data for state
for(var d = 0; d < data.length; d++) {
if (data[d].state == state.abbr) {
state.data = data[d];
}
}
// ratio for fill on polygon
var ratio = (state.data.annual_mean_wage - annual_mean_wage_min) / annual_mean_wage_dif;
// create the hex group
var hexGroup = getHexGroup(svg, loc_x + loop_x , y, hex_rad, state, ratio, width, state.data);
// have to reappend element on hover for stacking
hexGroup.addEventListener("mouseenter", function () {
var self = this;
self.setAttribute("class", "hover");
self.remove();
svg.appendChild(self);
});
// clear class
hexGroup.addEventListener("mouseleave", function () {
this.setAttribute("class", "");
});
// append the hex to our svg
svg.appendChild(hexGroup);
// increase the state index reference
state_index++;
}
// move our x plot to next hex position
loc_x += hex_apo * 2;
}
// move our y plot to next row position
y += hex_di * 0.75;
// toggle offset per row
offset = !offset;
}
// add svg to DOM
document.body.appendChild(svg);
}
// run the initialization script
initializeMap();
// individual hex calculations
function getHexGroup(svg,x,y,r,state,ratio,width,data) {
var svgNS = svg.namespaceURI, // svgNS for creating svg elements
group = document.createElementNS(svgNS, "g"),
hex = document.createElementNS(svgNS, "polygon"),
abbr = document.createElementNS(svgNS, "text"),
name = document.createElementNS(svgNS, "text"),
pi_six = Math.PI/6,
cos_six = Math.cos(pi_six),
sin_six = Math.sin(pi_six);
// hexagon polygon points
var hex_points = [
[x, y - r].join(","),
[x + cos_six * r, y - sin_six * r].join(","),
[x + cos_six * r, y + sin_six * r].join(","),
[x, y + r].join(","),
[x - cos_six * r, y + sin_six * r].join(","),
[x - cos_six * r, y - sin_six * r].join(",")
]
// hexagon fill based on ratio
var fill = "hsl(180,60%," + ((1 - ratio) * 60 + 20) + "%)";
hex.setAttribute("points", hex_points.join(" "));
hex.setAttribute("fill", fill);
hex.style.webkitTransformOrigin = hex.style.transformOrigin = x + 'px ' + y + 'px';
abbr.setAttribute("class", "state-abbr");
abbr.setAttribute("x", x);
abbr.setAttribute("y", y);
abbr.textContent = state.abbr;
name.setAttribute("class", "state-name");
name.setAttribute("x", x);
name.setAttribute("y", y);
name.textContent = state.name;
// loop through data points
var index = 1,
// lineheight of data text
line_height = 20,
// starting y of data
start_y = 60;
for(var key in data) {
var text = document.createElementNS(svgNS, "text");
text.setAttribute("x", width / 2);
text.setAttribute("y", index * line_height + start_y);
if(key != 'state') {
text.setAttribute("class", "data");
text.textContent = keyToName(key) + ": " + data[key];
} else {
text.setAttribute("class", "data title");
text.textContent = state.name;
}
group.appendChild(text);
index++;
}
group.appendChild(hex);
group.appendChild(abbr);
group.appendChild(name);
return group;
}
function keyToName(str) {
return str.replace(/_/g,' ')
.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
}
function usStateMatrix() {
return [
[1,0,0,0,0,0,0,0,0,0,0,1],
[0,0,0,0,0,0,0,0,0,1,1,0],
[0,1,1,1,1,1,0,1,0,1,1,1],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,0,0,0],
[1,0,0,0,1,0,0,1,0,0,0,0]
]
}
function usStateData() {
return {
states: [
{ abbr: "AK", name: "Alaska" },
{ abbr: "ME", name: "Maine"},
{ abbr: "VT", name: "Vermont" },
{ abbr: "NH", name: "New Hampshire"},
{ abbr: "WA", name: "Washington" },
{ abbr: "MT", name: "Montana" },
{ abbr: "ND", name: "North Dakota" },
{ abbr: "MN", name: "Minnesota" },
{ abbr: "WI", name: "Wisconsin" },
{ abbr: "MI", name: "Michigan" },
{ abbr: "NY", name: "New York" },
{ abbr: "MA", name: "Massachusetts" },
{ abbr: "RI", name: "Rhode Island"},
{ abbr: "ID", name: "Idaho" },
{ abbr: "WY", name: "Wyoming" },
{ abbr: "SD", name: "South Dakota" },
{ abbr: "IA", name: "Iowa" },
{ abbr: "IL", name: "Illinois" },
{ abbr: "IN", name: "Indiana" },
{ abbr: "OH", name: "Ohio" },
{ abbr: "PA", name: "Pennsylvania" },
{ abbr: "NJ", name: "New Jersey" },
{ abbr: "CT", name: "Connecticut"},
{ abbr: "OR", name: "Oregon" },
{ abbr: "NV", name: "Nevada" },
{ abbr: "CO", name: "Colorado" },
{ abbr: "NE", name: "Nebraska" },
{ abbr: "MO", name: "Missouri" },
{ abbr: "KY", name: "Kentucky" },
{ abbr: "WV", name: "West Virgina" },
{ abbr: "VA", name: "Virginia" },
{ abbr: "MD", name: "Maryland" },
{ abbr: "DE", name: "Delaware"},
{ abbr: "CA", name: "California" },
{ abbr: "UT", name: "Utah" },
{ abbr: "NM", name: "New Mexico" },
{ abbr: "KS", name: "Kansas" },
{ abbr: "AR", name: "Arkansas" },
{ abbr: "TN", name: "Tennessee" },
{ abbr: "NC", name: "North Carolina" },
{ abbr: "SC", name: "South Carolina" },
{ abbr: "DC", name: "District of Columbia"},
{ abbr: "AZ", name: "Arizona" },
{ abbr: "OK", name: "Oklahoma" },
{ abbr: "LA", name: "Louisiana" },
{ abbr: "MS", name: "Mississippi" },
{ abbr: "AL", name: "Alabama" },
{ abbr: "GA", name: "Georgia"},
{ abbr: "HI", name: "Hawaii" },
{ abbr: "TX", name: "Texas" },
{ abbr: "FL", name: "Florida" }
],
// Computer and Mathematical Occupations May 2014
// http://www.bls.gov/oes/current/oes150000.htm
data: [
{ state: "AL", hourly_mean_wage: 25.6, annual_mean_wage: 53250, jobs_per_1000: 0.348 },
{ state: "AK", hourly_mean_wage: 28.78, annual_mean_wage: 59870, jobs_per_1000: 0.284 },
{ state: "AZ", hourly_mean_wage: 30.93, annual_mean_wage: 64340, jobs_per_1000: 0.988 },
{ state: "AR", hourly_mean_wage: 28.27, annual_mean_wage: 58810, jobs_per_1000: 0.432 },
{ state: "CA", hourly_mean_wage: 38.23, annual_mean_wage: 79520, jobs_per_1000: 1.255 },
{ state: "CO", hourly_mean_wage: 29.71, annual_mean_wage: 61800, jobs_per_1000: 1.231 },
{ state: "CT", hourly_mean_wage: 33.03, annual_mean_wage: 68710, jobs_per_1000: 0.803 },
{ state: "DE", hourly_mean_wage: 39.15, annual_mean_wage: 81440, jobs_per_1000: 0.917 },
{ state: "DC", hourly_mean_wage: 37.84, annual_mean_wage: 78710, jobs_per_1000: 1.845 },
{ state: "FL", hourly_mean_wage: 29.19, annual_mean_wage: 60720, jobs_per_1000: 0.989 },
{ state: "GA", hourly_mean_wage: 35.96, annual_mean_wage: 74790, jobs_per_1000: 0.739 },
{ state: "HI", hourly_mean_wage: 35.46, annual_mean_wage: 73760, jobs_per_1000: 0.557 },
{ state: "ID", hourly_mean_wage: 24.18, annual_mean_wage: 50300, jobs_per_1000: 1.243 },
{ state: "IL", hourly_mean_wage: 31.33, annual_mean_wage: 65160, jobs_per_1000: 0.714 },
{ state: "IN", hourly_mean_wage: 25.96, annual_mean_wage: 53990, jobs_per_1000: 0.666 },
{ state: "IA", hourly_mean_wage: 29.43, annual_mean_wage: 61200, jobs_per_1000: 0.569 },
{ state: "KS", hourly_mean_wage: 27.83, annual_mean_wage: 57880, jobs_per_1000: 0.692 },
{ state: "KY", hourly_mean_wage: 24.62, annual_mean_wage: 51220, jobs_per_1000: 0.494 },
{ state: "LA", hourly_mean_wage: 24, annual_mean_wage: 49920, jobs_per_1000: 0.343 },
{ state: "ME", hourly_mean_wage: 24.81, annual_mean_wage: 51600, jobs_per_1000: 0.639 },
{ state: "MD", hourly_mean_wage: 36.28, annual_mean_wage: 75460, jobs_per_1000: 1.548 },
{ state: "MA", hourly_mean_wage: 37.1, annual_mean_wage: 77170, jobs_per_1000: 1.192 },
{ state: "MI", hourly_mean_wage: 29.21, annual_mean_wage: 60760, jobs_per_1000: 0.527 },
{ state: "MN", hourly_mean_wage: 31.91, annual_mean_wage: 66380, jobs_per_1000: 1.151 },
{ state: "MS", hourly_mean_wage: 26.51, annual_mean_wage: 55140, jobs_per_1000: 0.279 },
{ state: "MO", hourly_mean_wage: 27.71, annual_mean_wage: 57630, jobs_per_1000: 0.571 },
{ state: "MT", hourly_mean_wage: 23.44, annual_mean_wage: 48750, jobs_per_1000: 1.195 },
{ state: "NE", hourly_mean_wage: 27.67, annual_mean_wage: 57550, jobs_per_1000: 1.017 },
{ state: "NV", hourly_mean_wage: 28.26, annual_mean_wage: 58780, jobs_per_1000: 0.56 },
{ state: "NH", hourly_mean_wage: 26.9, annual_mean_wage: 55950, jobs_per_1000: 1.254 },
{ state: "NJ", hourly_mean_wage: 33.55, annual_mean_wage: 69780, jobs_per_1000: 0.609 },
{ state: "NM", hourly_mean_wage: 28.98, annual_mean_wage: 60280, jobs_per_1000: 0.439 },
{ state: "NY", hourly_mean_wage: 36.15, annual_mean_wage: 75180, jobs_per_1000: 1.017 },
{ state: "NC", hourly_mean_wage: 30.95, annual_mean_wage: 64370, jobs_per_1000: 0.709 },
{ state: "ND", hourly_mean_wage: 24.24, annual_mean_wage: 50410, jobs_per_1000: 0.488 },
{ state: "OH", hourly_mean_wage: 29.44, annual_mean_wage: 61230, jobs_per_1000: 0.803 },
{ state: "OK", hourly_mean_wage: 25.84, annual_mean_wage: 53740, jobs_per_1000: 0.443 },
{ state: "OR", hourly_mean_wage: 33.29, annual_mean_wage: 69250, jobs_per_1000: 1.708 },
{ state: "PA", hourly_mean_wage: 29.67, annual_mean_wage: 61710, jobs_per_1000: 0.694 },
{ state: "RI", hourly_mean_wage: 33.3, annual_mean_wage: 69260, jobs_per_1000: 0.74 },
{ state: "SC", hourly_mean_wage: 27.7, annual_mean_wage: 57620, jobs_per_1000: 0.451 },
{ state: "SD", hourly_mean_wage: 29.82, annual_mean_wage: 62020, jobs_per_1000: 0.664 },
{ state: "TN", hourly_mean_wage: 27.39, annual_mean_wage: 56980, jobs_per_1000: 0.503 },
{ state: "TX", hourly_mean_wage: 32.21, annual_mean_wage: 66990, jobs_per_1000: 0.85 },
{ state: "UT", hourly_mean_wage: 28.12, annual_mean_wage: 58490, jobs_per_1000: 1.559 },
{ state: "VT", hourly_mean_wage: 31.53, annual_mean_wage: 65570, jobs_per_1000: 1.577 },
{ state: "VA", hourly_mean_wage: 38.79, annual_mean_wage: 80690, jobs_per_1000: 1.233 },
{ state: "WA", hourly_mean_wage: 39.62, annual_mean_wage: 82420, jobs_per_1000: 1.659 },
{ state: "WV", hourly_mean_wage: 20.64, annual_mean_wage: 42940, jobs_per_1000: 0.371 },
{ state: "WI", hourly_mean_wage: 27.14, annual_mean_wage: 56450, jobs_per_1000: 0.759 },
{ state: "WY", hourly_mean_wage: 25.06, annual_mean_wage: 52130, jobs_per_1000: 0.444 }
]
}
}
This Pen doesn't use any external CSS resources.