Difference between revisions of "Team:SJTU-BioX-Shanghai/HP test page"

Line 16: Line 16:
 
li{margin-bottom:0;}
 
li{margin-bottom:0;}
 
</style>
 
</style>
 +
 +
 +
 +
  
 
<!DOCTYPE html>
 
<!DOCTYPE html>
 
<meta charset="utf-8">
 
<meta charset="utf-8">
<title>Geographic Bounding Boxes</title>
 
 
<style>
 
<style>
@import url(../maps.css?85b2875);
+
 
#map svg {
+
h1 {
   cursor: move;
+
   position: absolute;
}
+
   top: 500px;
path {
+
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   fill: none;
+
   font-size: 18px;
   stroke: #000;
+
   text-align: center;
}
+
   width: 960px;
.background {
+
  stroke: none;
+
  fill: #eef;
+
}
+
.land {
+
  stroke-width: .75px;
+
  pointer-events: all;
+
}
+
.graticule {
+
  stroke: #333;
+
   stroke-width: .25px;
+
}
+
.bounds {
+
  fill: #f00;
+
   fill-opacity: .25;
+
   stroke: #000;
+
  stroke-width: 1px;
+
  pointer-events: none;
+
}
+
.country:hover .bounds {
+
  stroke-width: 2px;
+
}
+
.country:hover .land {
+
  stroke-width: 1px;
+
}
+
.outline {
+
  stroke: #000;
+
  stroke-width: 1.5px;
+
  fill: none;
+
}
+
.antimeridian {
+
  stroke-dasharray: 5 5;
+
 
}
 
}
  
.example path.Polygon {
 
  fill: url(#hatch);
 
}
 
.example text {
 
  font-size: 11px;
 
  font-family: sans-serif;
 
}
 
 
</style>
 
</style>
 +
<h1></h1>
 +
<script src="//d3js.org/d3.v3.min.js"></script>
 +
<script src="//d3js.org/queue.v1.min.js"></script>
 +
<script src="//d3js.org/topojson.v1.min.js"></script>
 +
<script>
  
<p class="breadcrumbs"><a href="http://www.jasondavies.com/">Jason Davies</a> → <a href="../">Maps</a>
+
var width = 960,
 +
    height = 960;
  
<h1>Geographic Bounding Boxes</h1>
+
var projection = d3.geo.orthographic()
<div id="map"></div>
+
    .translate([width / 2, height / 2])
 +
    .scale(width / 2 - 20)
 +
    .clipAngle(90)
 +
    .precision(0.6);
  
<div class="wrapper">
+
var canvas = d3.select("body").append("canvas")
  <p class="caption">A geographic bounding box for each country (including semi-independent regions) from Natural Earth’s <a href="http://www.naturalearthdata.com/downloads/110m-cultural-vectors/110m-admin-0-countries/">1:110m Cultural Vectors</a>.
+
    .attr("width", width)
 +
    .attr("height", height);
  
  <p>A <a href="http://en.wikipedia.org/wiki/Minimum_bounding_box">minimum bounding box</a> in <i>geographic coordinates</i> is an area defined by minimum and maximum longitudes and latitudes.
+
var c = canvas.node().getContext("2d");
  <p>Computing bounding boxes in 2D is simple: track the minimum and maximum x- and y-coordinates point by point.
+
  Assuming line segments are straight for both polylines and polygons, nothing else needs to be done.
+
  <p>Why doesn’t this work for a sphere?
+
  
  <h2>The Antimeridian</h2>
+
var path = d3.geo.path()
  <p>Imagine a set of points clustered around the antimeridian at 180°E.
+
    .projection(projection)
  A 2D algorithm will find a bounding box with longitudes extending all the way from around -180° to around +180°, even if the true <i>minimum</i> bounding box has a much smaller width.
+
    .context(c);
  <p>A better approach is to compute the true minimum-width bounding box, even if it crosses the antimeridian.
+
  <div class="example"></div>
+
  
  <h2>Line Segments</h2>
+
var title = d3.select("h1");
  <p>D3 treats line segments as great-circle arcs: two successive points define the minor arc of the great circle going through those points.
+
  <p>Here we need to be even more careful than for points, since it matters whether or not the line crosses the antimeridian.
+
  <div class="example"></div>
+
  
  <p>In addition, intermediate points between the segment endpoints may have latitudes extending beyond the maximum or minimum endpoint latitude.
+
queue()
  <div class="example"></div>
+
    .defer(d3.json, "/mbostock/raw/4090846/world-110m.json")
 +
    .defer(d3.tsv, "/mbostock/raw/4090846/world-country-names.tsv")
 +
    .await(ready);
  
  <h2>Polygons</h2>
+
function ready(error, world, names) {
  <p>A polygon may contain any number of holes, and the location of its interior depends on the winding order of its vertices.
+
   if (error) throw error;
   <p>In D3, if a polygon’s vertices wind around a point in a counter-clockwise direction, this means the point is outside the polygon.
+
  Otherwise, it is inside <span id="inside"></span>.
+
  <div class="example"></div>
+
  
   <p>If a polygons vertices wind around either pole, this means the longitudes have maximum extent from 180°W to +180°E.
+
   var globe = {type: "Sphere"},
  <div class="example"></div>
+
      land = topojson.feature(world, world.objects.land),
 +
      countries = topojson.feature(world, world.objects.countries).features,
 +
      borders = topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }),
 +
      i = -1,
 +
      n = countries.length;
  
   <p>Lastly, a polygon may contain either pole, even if its vertices do not extend to the pole, in which case the latitude extent is extended to the pole.
+
   countries = countries.filter(function(d) {
   <div class="example"></div>
+
    return names.some(function(n) {
 +
      if (d.id == n.id) return d.name = n.name;
 +
    });
 +
  }).sort(function(a, b) {
 +
    return a.name.localeCompare(b.name);
 +
   });
  
   <h2>Further Reading</h2>
+
   (function transition() {
  <p>The described behaviour is supported by <code>d3.geo.bounds</code> as of <a href="http://d3js.org">D3</a> version <a href="https://github.com/mbostock/d3/releases/tag/v3.1.7">3.1.7</a>.
+
    d3.transition()
</div>
+
        .duration(1250)
 +
        .each("start", function() {
 +
          title.text(countries[i = (i + 1) % n].name);
 +
        })
 +
        .tween("rotate", function() {
 +
          var p = d3.geo.centroid(countries[i]),
 +
              r = d3.interpolate(projection.rotate(), [-p[0], -p[1]]);
 +
          return function(t) {
 +
            projection.rotate(r(t));
 +
            c.clearRect(0, 0, width, height);
 +
            c.fillStyle = "#ccc", c.beginPath(), path(land), c.fill();
 +
            c.fillStyle = "#f00", c.beginPath(), path(countries[i]), c.fill();
 +
            c.strokeStyle = "#fff", c.lineWidth = .5, c.beginPath(), path(borders), c.stroke();
 +
            c.strokeStyle = "#000", c.lineWidth = 2, c.beginPath(), path(globe), c.stroke();
 +
          };
 +
        })
 +
      .transition()
 +
        .each("end", transition);
 +
  })();
 +
}
  
<script src="../../d3.min.js?94db87"></script>
+
d3.select(self.frameElement).style("height", height + "px");
<script src="../topojson.min.js?1.1.1"></script>
+
<script src="app.min.js"></script>
+
  
 +
</script>
  
  
 
</html>
 
</html>

Revision as of 22:00, 13 August 2018