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

              
                <div id='map'></div>

<div class='map-overlay' id='legend'></div>

<div class='map-overlay' id='county_view'>
  <h2>CRSI_Score:</h2>
  <div id='county_score'>
<p>Hover over a state or county</p> 
  </div>    
</div>

<div id='choro-toggle'>
    <label class='switch-container-county'>
      CRSI Score
      <input id='crsiJenks' type='radio' name='viz-toggle' onchange='toggleCountyHTML()'>
    </label> 
    <label class='switch-container-county'>
      Zones of Course Impact
      <input id='courseJenks' type='radio' name='viz-toggle' onchange='toggleCountyHTML()'>
    </label> 
    <label class='switch-container-county'>
      Combined CRSI and Education Metric
      <input id='combinedJenks' type='radio' name='viz-toggle' onchange='toggleCountyHTML()'>
    </label> 
</div>

<div class="dropdown">
  <button onclick="dropdownButton()" class="dropbtn">Filter Courses by Discipline</button>
  <div id="myDropdown" class="dropdown-content">
   <div id="dropdownOptions" class="dropdown-options"></div>
  </div>
</div> 

<div class = "helpbutton" id="help-button">
  <div class = "contents" id="panel-contents">
<p>CRSI (Climate Resilience Screening Index) characterizes the resilience of socio-ecological systems in the context of governance and risk to natural hazard events. (Taken from the 
<a href="https://nepis.epa.gov/Exe/ZyNET.exe/P100SSN6.txt?ZyActionD=ZyDocument&Client=EPA&Index=2016%20Thru%202020&Docs=&Query=&Time=&EndTime=&SearchMethod=1&TocRestrict=n&Toc=&TocEntry=&QField=&QFieldYear=&QFieldMonth=&QFieldDay=&UseQField=&IntQFieldOp=0&ExtQFieldOp=0&XmlQuery=&File=D%3A%5CZYFILES%5CINDEX%20DATA%5C16THRU20%5CTXT%5C00000005%5CP100SSN6.txt&User=ANONYMOUS&Password=anonymous&SortMethod=h%7C-&MaximumDocuments=1&FuzzyDegree=0&ImageQuality=r75g8/r75g8/x150y150g16/i425&Display=hpfr&DefSeekPage=x&SearchBack=ZyActionL&Back=ZyActionS&BackDesc=Results%20page&MaximumPages=1&ZyEntry=2">EPA</a>
)</p> 
  </div>   
  <button onclick="showhelppanel()" class="helpbtn" id="button">?</button>
</div>

<div class = "univInfo" id="univ-info">
  <div class = "infoContents" id="info-contents"></div>   
</div>


<div class='lgndDens' id='legendDensity'>
    <span style='background:#edf8e9;color:black;'>Less Impact</span>
    <span style='background:#bae4b3;'></span>
    <span style='background:#74c476;'></span>
    <span style='background:#31a354;'></span>
    <span style='background:#006d2c;color:white;'>More Impact</span>
</div>

              
            
!

CSS

              
                body {
  margin: 0;
  padding: 0;
}

#info {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 20vw;
  padding: 1em;
}
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.map-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  background: rgba(255, 255, 255, 0.8);
  margin-left: 10px;
  font-family: Arial, sans-serif;
  overflow: auto;
  border-radius: 5px;
}

#legend {
  display: none;
  padding: 10px;
  left: 255px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  line-height: 18px;
  height: 95px;
  margin-bottom: 25px;
  width: 165px;
}

.lgndDens{
  display: none;
  position:relative;
  margin-left:auto;
  margin-right:auto;
  margin-top: 5px;
  font-family: Arial, sans-serif;
  font-size: 16;
  width: 500px;
  height: 20px;
}
#legendDensity span {
  display:block;
  float: left;
  height:20px;
  width:20%;
  text-align:center;
  font-size:16px;
  color:#808080;
  }
.legend-key {
  display: inline-block;
  border-radius: 20%;
  width: 10px;
  height: 10px;
  margin-right: 5px;
}

#county_view{
  bottom: 0;
  left: 0px;
  height: 150px;
  margin-bottom: 25px;
  width: 250px;
  display: none; 
}

/* dropdown stuff */
.dropbtn {
  /* Dropdown Button */
  background-color: #3498DB;
  color: white;
  padding: 16px;
  font-size: 16px;
  border: none;
  cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
  /* Dropdown button on hover & focus */
  background-color: #2980B9;
}
.optionPicked {
  /* Dropdown button options*/
  background-color: #f1f1f1;
  color: black;
  padding: 12px;
  font-size: 12px;
  border: none;
  cursor: pointer;
  text-allign: left;
  width: 100%;
  padding-left: 6px;
}
.optionPicked:hover, .dropbtn:focus {
  /* Dropdown button on hover & focus */
  background-color: #2980B9;
}
.dropdown {
  /* The container <div> - needed to position the dropdown content */
  position: relative;
  display: inline-block;
}
.dropdown-content {
  /* Dropdown Content (Hidden by Default) */
  display: none;
  position: absolute;
  background-color: #f1f1f1;
  min-width: 160px;
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
  z-index: 1;
}
.dropdown-content a {
  /* Links inside the dropdown */
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}
.dropdown-content a:hover {background-color: #ddd}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;}

#choro-toggle {
  position: absolute;
  top: 15px;
  right: 10px;
  display: flex;
  border-radius: 3px;
  background-color: rgb(255, 255, 255);
  padding: 10px;
  z-index: 10;
  display: flex;
  flex-flow: column;
  justify-content: space-between;
}

.switch-container-state {
  display: flex;
  flex-flow: row;
  justify-content: space-between;
}

.switch-container-county {
  display: flex;
  flex-flow: row;
  justify-content: space-between;
}

.switch {
  margin-left: 3px;
}

.helpbutton {
  display: none;
  position: absolute;
  bottom: 150px;
  left: 217px;
  margin-left: 10px;
  font-family: Arial, sans-serif;
  overflow: auto;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.8);
}

#panel-contents{
  display: none;
  bottom: 0;
  left: 200px;
  height: 100px;
  margin-bottom: 55px;
  margin-top: 2px;
  margin-left: 3px;
  width: 260px;
}

.popups {
  height: 350px;
  width: 225px;
  overflow: auto;
  border-radius:0;
}

              
            
!

JS

              
                
mapboxgl.accessToken =
  "pk.eyJ1Ijoia3N0b2xsZXJnbXUiLCJhIjoiY2tnYjZjOTMxMGUxbDJ6cHFjc3o1YW9qbCJ9.HQ3upfkvBrNlP7mup40JSQ";

//create map
var map = new mapboxgl.Map({
  container: "map",
  style: "mapbox://styles/mapbox/dark-v9",
  center: [-93.81, 38.6755],
  zoom: 3,
  pitch: 0,
  bearing: 0,
  container: "map",
  antialias: true
});



//these functions pertain to the dropdown menu, not sure why they have to be out here, but they do
function dropdownButton() {  
    document.getElementById("myDropdown").classList.toggle("show");
  };

function populatePopup() {  
    document.getElementById("infoContents");
  };

function showhelppanel() {   
  window.addEventListener('click', function(showhelppanel) {
    var panel = document.getElementById("panel-contents");
    //opens and closes dropdown menu if button clicked
   if (showhelppanel.target.matches('.helpbtn')) {       
      panel.style.display = 'block';
      console.log("showing panel");
   }
    else {
      panel.style.display = 'none';
      console.log("hiding panel");
    }
   });
 };


function toggleCountyHTML() {   
  window.addEventListener('change', function(toggleCountyHTML) {
    var countyElement = document.getElementById('county_view');
    var helpButton = document.getElementById('help-button');
    var legend = document.getElementById("legend");
    var densLegend = document.getElementById('legendDensity')
    if (document.getElementById('crsiJenks').checked){    
      countyElement.style.display = 'block';
      helpButton.style.display = 'block';
      legend.style.display = 'block';
      legend.style.left = '255px';
      densLegend.style.display = 'none';
    }
    else if (document.getElementById('courseJenks').checked) {
      densLegend.style.display = "block";
      countyElement.style.display = 'none';
      helpButton.style.display = 'none';
      legend.style.display = 'none';
    }
    else {
      densLegend.style.display = "none";
      countyElement.style.display = 'none';
      helpButton.style.display = 'none';
      legend.style.display = 'none';
    }                     
  }); 
};




//university data
fetch(
  "https://james-v220.carto.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM ncse_course_info"
)
  .then(response => {
    return response.json(); //check whether the reply is json
  })
  .then(uni_data => {   
  map.once('load', function() {
      
      //loads university point data     
    map.addSource('uni', {       
      type: 'geojson',      
      data: uni_data   
    });
    
      //manages appearance of points   
     var uni_stepped = map.addLayer({      
       id: "university_point",
       type: "circle",
       source: "uni",
       paint: {
        "circle-color": '#59B7FF',
         "circle-radius": 8,
         "circle-stroke-width": 1,
         "circle-stroke-color": '#FFFFFF'       
       }
      });   

      //popup stuff
      var popup = new mapboxgl.Popup({
        closeButton: false,
        closeOnClick: false
      });
      //when we hover over a point, we get the location and property of the point
      map.on("mouseenter", "university_point", function(e) {
        map.getCanvas().style.cursor = "pointer";
        var coordinates = e.features[0].geometry.coordinates.slice();
        var description = e.features[0].properties.uni_name;               
        //populates the popup and set its coordinates and contents(?)
        popup
          .setLngLat(coordinates)
          .setHTML(description)
          .addTo(map);
      });
      map.on("mouseleave", "university_point", function() {
        map.getCanvas().style.cursor = "";
        popup.remove();
      });
      //pop up stuff
      var popupInfo = new mapboxgl.Popup({
       closeButton: true,
       closeOnClick: true,
       className: 'popups'
      });
      //when a point is clicked, generate another popup with available courses
      map.on('click', 'university_point', function(e) {
        var coordinates = e.features[0].geometry.coordinates.slice();
        var termContainer = []
        console.log(e.features.length);
        //checks if a university offers more than one course
        if (e.features.length > 1) {
          //if it does, loop through the courses and put them into an array
          for (var i = 0; i < e.features.length; i++) {
            var term = '<li>' + e.features[i].properties.res_courses + '</li>';
            termContainer.push(term); 
          }
           popupInfo
          .setLngLat(coordinates)
          .setHTML('<h3><b>Classes Offered:</b></h3>' + '<ul>' + termContainer.join('') + '</ul>')
          .addTo(map); 
         }
        else {
          var term = e.features[0].properties.res_courses;
           popupInfo
          .setLngLat(coordinates)
          .setHTML('<h3><b>Class Offered:</b></h3>' + '<ul><li>' + term + '</li></ul>')
          .addTo(map);    
        }         
      });
     
      //this function pertains to sorting unique values out so that duplicates do not occur in the dropdown
      function onlyUnique(value, index, self) {
      return self.indexOf(value) === index;    
      } 
       //dropdown controls - has to be here because this popup deals with data from this query
      window.addEventListener("click", function(dropdownButton) {
        //if the main dropdown button is clicked, creates an array of all unique values in the ncse_desc
        var checkIfPopulated = document.getElementsByClassName("optionPicked");  
        if (dropdownButton.target.matches('.dropbtn') && checkIfPopulated.length == 0){
          var storedStrings = [];
           //this loop iterates through data and outputs an array of unique class descriptions   
          for (var i = 0; i < uni_data.features.length; i++) {     
            var term = uni_data.features[i].properties.ncse_desc;    
            storedStrings.push(term);     
            var uniqueStrings = storedStrings.filter(onlyUnique);           
          }
          //this loop goes through the created array and makes buttons to populate dropdown    
          for (var i = 0; i < uniqueStrings.length; i++){    
            var option = document.createElement("button");      
            var text = document.createTextNode(uniqueStrings[i]);     
            option.setAttribute("class", "optionPicked"); 
            option.value = uniqueStrings[i];     
            option.appendChild(text);      
            console.log(option);
            document.getElementById("dropdownOptions").appendChild(option);   
          }      
        }
         //if a dropdown sub-button is clicked, this section filters out the data according to what is picked  
        else if (dropdownButton.target.matches('.optionPicked')) {   
          var term = event.target.value;         
          console.log(term);    
          var filteredFeatures = uni_data.features.filter(function(feature) {
             //null check because got an error otherwise     
            if (feature.properties.ncse_desc != null) {        
              return feature.properties.ncse_desc.includes(term);                
            };       
          });     
          var filteredFeatureCollection = {       
            type: "FeatureCollection",      
            features: filteredFeatures     
          };    
          map.getSource("uni").setData(filteredFeatureCollection);
        } 
        else {   
          console.log('data reset');     
          map.getSource("uni").setData(uni_data);   
        };        
      });   
    }); 
}); 

//county data
fetch(
  "https://james-v220.carto.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM counties_simple"
)
 .then(response => {
    return response.json(); //check whether the reply is json
  })
 .then(county_data => {
    map.on('load', function() {
     //loads county crsi data and choropleth
     map.addSource('counties', {
        type: 'geojson',
        data: county_data
      });
      // appearance stuff
     var crsiJenks = map.addLayer({          
       id: 'crsiJenks',           
       type: 'fill',        
       source: 'counties',        
       layout: {       
         visibility: "none"        
       },        
       paint: {         
         'fill-color': [          
           'step',       
           ['get', 'crsi_jenks'],        
           '#247F41',      
           2,      
           '#97C464',      
           4,     
           '#E0F9A4',         
           6,       
           '#EAA157',      
           8,     
           '#A01315'      
         ],     
         'fill-opacity': 1,      
         'fill-outline-color': '#cfe3e7'        
       }
      });
          
      var combined_jenks = map.addLayer({    
        id: 'combinedJenks',   
        type: 'fill',
        source: 'counties', 
        layout: {      
          visibility: "none"
        },
        paint: {
         'fill-color': [          
           'step',       
           ['get', 'combined_jenks'],       
           '#247F41',      
           10,      
           '#97C464',    
           12,         
           '#E0F9A4',     
           14,     
           '#EAA157',             
           16,      
           '#A01315'     
         ],    
          'fill-opacity': 1,  
          'fill-outline-color': '#cfe3e7'         
        } 
      });
      
   var course_density = map.addLayer({
        id: 'courseJenks',   
        type: 'fill',
        source: 'counties',
        layout: {      
          visibility: "none"
        },
        paint: {
        
          'fill-color': [
         
            'step',     
            ['get', 'course_jenks'],      
            '#006d2c',     
            2,     
            '#31a354',      
            4,      
            '#74c476',      
            6,       
            '#bae4b3',    
            8,      
            '#edf8e9'      
          ],       
          'fill-opacity': 1,    
          'fill-outline-color': '#cfe3e7'    
        }
   });   
    
     //updates html with crsi score on mouse move
     map.on('mousemove', function(e) {
       var counties = map.queryRenderedFeatures(e.point, {
       layers: ['crsiJenks'] 
      });
       var countyElement = document.getElementById('county_view');
       if (counties.length > 0) {
        document.getElementById('county_score').innerHTML = '<h3><strong>' + counties[0].properties.crsi+'</strong></h3><p><strong>' + counties[0].properties.name;
       } 
       else {
       document.getElementById('county_score').innerHTML = '<p>Hover over a state or county</p>';  
       }    
     });

      var layers = ['<(-0.347)', '(-0.347)-4.086', '4.086-10.238', '10.238-65.844', '>65.844'];
      var colors = ['#A01315', '#EAA157', '#E0F9A4', '#97C464', '#247F41'];

      for (i = 0; i < layers.length; i++) {
        var layer = layers[i];
        var color = colors[i];
        var item = document.createElement('div');
        var key = document.createElement('span');
        key.className = 'legend-key';
        key.style.backgroundColor = color;

        var value = document.createElement('span');
        value.innerHTML = layer;
        item.appendChild(key);
        item.appendChild(value);
        legend.appendChild(item);
      }
      
      //choro-toggle
      var layer = document.getElementById("choro-toggle");
      var toggles = layer.getElementsByTagName("input");

      function switchLayer(layer) {
        var possibleLayers = ['crsiJenks', 'courseJenks', 'combinedJenks'];
        var clickedLayersLabel = layer.target.id; 
        //console.log(clickedLayersLabel);
        var clickedLayers = clickedLayersLabel; 
        possibleLayers.splice (possibleLayers.indexOf(clickedLayers), 1);
        //console.log(clickedLayers);
        var visibility = map.getLayoutProperty(clickedLayers, "visibility"); 
        //console.log(visibility);
        if (visibility === "visible") {
          map.setLayoutProperty(clickedLayers, "visibility", "none");
          for (var i = 0; i < possibleLayers.length; i++) {
            map.setLayoutProperty(possibleLayers[i], "visibility", "none");
          }  
        } else {
          map.setLayoutProperty(clickedLayers, "visibility", "visible");
          for (var i = 0; i < possibleLayers.length; i++) {
            map.setLayoutProperty(possibleLayers[i], "visibility", "none");
          }  
        }
       } 
       for (var i = 0; i < toggles.length; i++) {
       toggles[i].onclick = switchLayer;  
      }  
    });  
  });


              
            
!
999px

Console