block by nitaku 8e89ad874d18e9abc260

OpeNER - Places with categories (d3.js)

Full Screen

index.js

// Setup
var width = 960;
var height = 500;

var radius = 2.5;

var svg = d3.select('svg');

// append a group for zoomable content
var zoom_group = svg.append('g');

// define a zoom behavior
var zoom = d3.behavior.zoom()
    .scaleExtent([1,4]) // min-max zoom
    .on('zoom', function() {
      // whenever the user zooms,
      // modify translation and scale of the zoom group accordingly
      zoom_group.attr('transform', 'translate('+zoom.translate()+')scale('+zoom.scale()+')');
      
      // semantic zooming
      zoom_group.selectAll('.place')
        .attr('r', radius/zoom.scale());
    });

// bind the zoom behavior to the main SVG
svg.call(zoom);

// Lambert equal-area projection - EU standard for statistical maps
projection = d3.geo.azimuthalEqualArea()
  .clipAngle(180 - 1e-3)
  .scale(160000)
  .rotate([-10.277475, -42.789034, 0])
  .translate([width / 2, height / 2])
  .precision(0.1);

path_generator = d3.geo.path()
  .projection(projection);

var graticule = d3.geo.graticule()
    .step([1,1])
    .extent([0, 20, 30, 60]);
    
// draw the graticule
zoom_group.append('path')
    .datum(graticule)
    .attr('class', 'graticule')
    .attr('d', path_generator);

var colorify = d3.scale.category10()
  .domain(['restaurant', 'attraction', 'poi', 'accommodation']);


var data_url = 'http://wafi.iit.cnr.it/openervm/api/getPlacesByArea?S=42.666&N=42.912&W=10&E=10.5';
var geo_url = 'http://wafi.iit.cnr.it/webvis/italiastat/data/istat/2011/reg2011.topo.json';

d3.json(geo_url, function(geo) {
  var regions = topojson.feature(geo, geo.objects.reg2011);
  
  zoom_group.selectAll('.region')
        .data(regions.features)
      .enter().append('path')
        .attr('class', 'region')
        .attr('d', path_generator);
  
  d3.json(data_url, function(data) {
    
    zoom_group.selectAll('.place')
        .data(data)
      .enter().append('circle')
        .attr('class', 'place')
        .attr('r', radius)
        .attr('fill', function(d){return colorify(d.category);})
        .attr('transform', function(d){
          var p = projection([d.lng, d.lat]);
          return 'translate('+p[0]+','+p[1]+')';
        });
    
  });

});

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="description" content="OpeNER - Places with categories (d3.js)" />
    <title>OpeNER - Places with categories (d3.js)</title>
    <link rel="stylesheet" href="index.css">
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script src="//d3js.org/topojson.v1.min.js"></script>
</head>
<body>
  <svg height="500" width="960"></svg>
  
  <script src="index.js"></script>
</body>
</html>

index.css

body {
    background: #272822;
    margin: 0;
    padding: 0;
}
svg {
    background: #ADD2EF;
}

.region {
  fill: white;
  stroke: #ADD2EF;
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
.graticule {
  fill: none;
  stroke-width: 1px;
  stroke: gray;
  vector-effect: non-scaling-stroke;
}