Meteorite Strikes (D3)

In this example below you will see how to do a Meteorite Strikes (D3) with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by robert77, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright robert77 ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Meteorite Strikes (D3)</title>
  <script src="https://unpkg.com/topojson@3"></script>
  
  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <div id="app"></div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js'></script>
<script src='https://unpkg.com/topojson@3.0.2/dist/topojson.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/robert77/meteorite-strikes-d3-wPmPgL */
* {
  margin: 0;
  padding: 0;
}

html {
  box-sizing: border-box;
  height: 100%;
  font-family: 'Lucida Console', monospace;
}

body {
  min-height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  background: rgba(100, 100, 100, 0.33);
}

.header {
  font-size: 40px;
  font-weight: bold;
  margin: 80px 0;
}

.footer {
  font-size: 30px;
  margin: 80px 0;
  text-align: center;
}

#app {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 1800px;
  height: 1000px;
}

svg {
  background: #5675b9;
  border: 2px solid #ddd;
  box-shadow: 2px 2px 2px 2px #ddd;
}

.land {
  fill: #4ca377;
}

.boundary {
  fill: none;
  stroke: #fff;
  stroke-width: 0.5px;
}

.country {
  fill: #4ca377;
  stroke: #c8c8c8;
}

.country:hover {
  stroke-width: 2;
}

.meteorite {
  opacity: .5;
  cursor: pointer;
}

.tooltip {
  position: absolute;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.25), 0 2px 12px 0 rgba(0, 0, 0, 0.175);
  font-size: 14px;
  background: rgba(250, 250, 250, 0.75);
  text-align: center;
}
.tooltip p {
  margin: 4px 0;
}


/*Downloaded from https://www.codeseek.co/robert77/meteorite-strikes-d3-wPmPgL */
var width = 1200;
var height = 1000;
var margin = {
  top: 50,
  bottom: 50,
  left: 50,
  right: 50

  /* https://github.com/d3/d3-queue
     https://bl.ocks.org/mbostock/1696080
  A queue evaluates zero or more deferred asynchronous tasks with configurable concurrency: you control how many tasks run at the same time. When all the tasks complete, or an error occurs, the queue passes the results to your await callback
  */
};d3.queue(1).defer(d3.json, "https://unpkg.com/world-atlas@1/world/110m.json").defer(d3.json, "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json").awaitAll(ready);

function ready(error, results) {
  if (error) {
    console.log(error);
  } else {
    var zoomer = function zoomer() {
      svg.style("stroke-width", 1.5 / d3.event.transform.k + "px").attr("transform", d3.event.transform);
    };

    var svg = d3.select("#app").append("svg").attr('height', height + margin.top + margin.bottom).attr('width', width + margin.left + margin.right);

    //convert globe to be flat
    var projection = d3.geoMercator().scale(200).translate([width / 2, height / 2]); //center

    //bind path with projection
    var path = d3.geoPath().projection(projection);

    var zoom = d3.zoom().scaleExtent([1, 8]).on("zoom", zoomer);

    var worldJSON = results[0];
    var meteorJSON = results[1];
    /* topojson.feature converts raw geo data to useable data */

    //extract array of countries objects from the topojson file
    var countries = topojson.feature(worldJSON, worldJSON.objects.countries).features; //feature takes root of data & specific data looking for

    //render initial svg of countries
    svg.selectAll('.country') //selectAll() statement creates the group that will later be filled with element
    .data(countries) // bind the data to the DOM element specified in selectAll()
    .enter() //matches the selectAll statement with the number of elements in the array/object, and determines the number of elements that will need to be created
    .append('path') //determines which of the SVG basic shapes you’ll use
    .attr('class', 'country').attr('d', path); //path only requires d attribute

    var meteorArray = meteorJSON.features;

    var meteorites = svg.selectAll('.meteorite').data(meteorArray).enter().append('circle').attr('class', 'meteorite').attr('transform', function (d) {
      return d.geometry ? "translate(" + projection([d.geometry.coordinates[0], d.geometry.coordinates[1]]) + ")" : null;
    }).attr('r', function (d) {
      if (d.properties.mass > 12500000) {
        return d.properties.mass / 250000;
      } else if (d.properties.mass > 10000) {
        return d.properties.mass / 50000;
      } else if (d.properties.mass > 5000) {
        return 5;
      } else if (d.properties.mass > 2500) {
        return 4;
      } else if (d.properties.mass > 1000) {
        return 2;
      } else if (d.properties.mass > 500) {
        return 1.5;
      } else {
        return 1;
      }
    }).style('fill', function (d) {
      if (d.properties.mass > 2500000) {
        return 'orange';
      } else if (d.properties.mass > 500000) {
        return 'purple';
      } else if (d.properties.mass > 5000) {
        return 'yellow';
      } else if (d.properties.mass > 2500) {
        return 'blue';
      } else if (d.properties.mass > 1000) {
        return 'green';
      } else if (d.properties.mass > 500) {
        return 'teal';
      } else {
        return 'gray';
      }
    }).style('stroke', 'white').style('stroke-width', 2);

    svg.call(zoom);

    var tooltip = d3.select('body').append('div').attr('class', 'tooltip').style('opacity', 0);

    meteorites.on('mouseover', function (d) {
      d3.select(this).transition().duration(200).style('opacity', 1).style('stroke-width', 3);
      tooltip.html('<p> date: ' + new Date(d.properties.year).toDateString() + '<p> name: ' + d.properties.name + '<p> mass: ' + d.properties.mass).style('left', d3.event.pageX + 10 + 'px').style('top', d3.event.pageY - 20 + 'px').transition().duration(250).style('opacity', 1);
    }).on('mouseleave', function (d) {
      d3.select(this).transition().duration(250).style('opacity', .5);
      tooltip.transition().duration(500).style('opacity', 0);
    });

    var header = d3.select('body').insert('p', '#app').attr('class', 'header').html('Global Meteorite Strikes');

    var footer = d3.select('body').append('p').attr('class', 'footer').html('<p> Data Source: ' + 'https://raw.githubusercontent.com/FreeCoDeCamp/ProjectReferenceData/master/meteorite-strike-data.json');
  }
}

Comments