block by fil 1b574a4185a04273de47b49591243102

Earthquake Map with fisheye (polar)

Full Screen

forked from pnavarrc‘s block: Earthquake Map

forked from jonpage‘s block: Earthquake Map

forked from jgondin‘s block: Earthquake Map

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>Earthquake Map</title>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
  <script src="fisheye.js"></script>
</head>
<body>

  <style>
  body {
    margin: 0;
  }

  svg {
    background-color: #111;
    cursor: pointer;
  }

  .land {
    fill: #333;
    stroke: #555;
    stroke-width: 1;
  }

  .earthquake {
    fill-opacity: 0.6;
  }
  </style>

  <div id="map-container"></div>

  <script>

    // Set the dimensions of the map
    var width  = 960,
        height = 480;

    // Create a selection for the container div and append the svg element
    var div = d3.select('#map-container'),
        svg = div.append('svg');

    svg.append('g').classed('map', true);
    svg.append('g').classed('dots', true);

    // Set the size of the SVG element
    svg.attr('width', width).attr('height', height);

    // Create and configure a geographic projection
    var _projection = d3.geo.equirectangular()
      .translate([width / 2, height / 2]);

                        var fisheye = d3.fisheye();

                        // to start, unclutter JAPAN
                        var DEG = 180 / Math.PI,
                            JAPAN = [138, 36],
                            RADIUS = 30,
                            POWER = 1.5;
                        fisheye.center(JAPAN).radius(RADIUS).power(POWER);

                        var projection = d3.geo.projection(function (λ, φ) {
                                λ *= DEG, φ *= DEG;
                                [λ, φ] = fisheye([λ, φ]);
                                var p = _projection([λ, φ]);
                                return [p[0], -p[1]];
                            })
                            .scale(1)
                            .translate([width / 2, height / 2]);


    
    
    // Create and configure a path generator
    var pathGenerator = d3.geo.path()
      .projection(projection);
    
    var land = circles = svg.select('nada');
    svg.on("mousemove", function() {
      fisheye.center(_projection.invert(d3.mouse(this)));
      land.attr('d', pathGenerator);
      circles
        .attr('cx', function(d) { return projection(d.coords)[0]; })
        .attr('cy', function(d) { return projection(d.coords)[1]; });
    });


    // Retrieve the geographic data asynchronously
    d3.json('land.geojson', function(err, data) {

      // Throw errors on getting or parsing the file
      if (err) { throw err; }

      // Land
      land = svg.select('g.map').selectAll('path.land').data([data]);

      land.enter().append('path').classed('land', true);
      land.attr('d', pathGenerator);
      land.exit().remove();

    });


    // Load the Earthquake data
    // //earthquake.usgs.gov/earthquakes/search/
    // //earthquake.usgs.gov/earthquakes/map/doc_aboutdata.php
    d3.csv('earthquakes.csv', function(err, csvdata) {

      if (err) { throw err; }

      // Parse the data
      csvdata.forEach(function(d) {
        d.coords = [+d.longitude, +d.latitude];
        d.magnitude = +d.mag;
      });

      csvdata.sort(function(a, b) {
        return a.magnitude > b.magnitude ? -1 : 1;
      });

      // Radius scale
      var rScale = d3.scale.sqrt()
        .domain(d3.extent(csvdata, function(d) { return d.magnitude; }))
        .range([1, 10]);

      var cScale = d3.scale.sqrt()
        .domain(rScale.domain())
        .range(['#ECD078', '#C02942']);

      circles = svg.select('g.dots').selectAll('circle.earthquake').data(csvdata);

      circles.enter().append('circle')
        .classed('earthquake', true);

      circles
        .attr('r', function(d) { return rScale(d.magnitude); })
        .attr('cx', function(d) { return projection(d.coords)[0]; })
        .attr('cy', function(d) { return projection(d.coords)[1]; })
        .attr('fill', function(d) { return cScale(d.magnitude); });

      circles.exit().remove();
    });

  </script>

</body>
</html>

fisheye.js

(function() {
  d3.fisheye = function() {
    var radius = 200,
        power = 2,
        k0,
        k1,
        center = [0, 0];

    function fisheye(d) {
      var dx = d[0] - center[0],
          dy = d[1] - center[1],
          dd = Math.sqrt(dx * dx + dy * dy);
      if (dd >= radius) return d;
      var k = k0 * (1 - Math.exp(-dd * k1)) / dd * .75 + .25;
      return [center[0] + dx * k, center[1] + dy * k];
    }

    function rescale() {
      k0 = Math.exp(power);
      k0 = k0 / (k0 - 1) * radius;
      k1 = power / radius;
      return fisheye;
    }

    fisheye.radius = function(_) {
      if (!arguments.length) return radius;
      radius = +_;
      return rescale();
    };

    fisheye.power = function(_) {
      if (!arguments.length) return power;
      power = +_;
      return rescale();
    };

    fisheye.center = function(_) {
      if (!arguments.length) return center;
      center = _;
      return fisheye;
    };

    return rescale();
  };
})();