Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <h1>Computer and Mathematical Occupations: May 2014 <a href="http://www.bls.gov/oes/current/oes150000.htm" target="blank">[source]</a></h1>
              
            
!

CSS

              
                $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;
  }
}
              
            
!

JS

              
                // 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 }
    ]
  }
}
              
            
!
999px

Console