Projection orthographique et rotation

Température moyenne par pays

Globe 3D des moyennes de températures terrestre avec D3.js

Retour

Code Javascript

const width = 960, height = 540;

const projection = d3.geoOrthographic()
.scale(250)
.translate([width / 2, height / 2])
.clipAngle(90) // without this options countries on the other side are visible
.precision(.1)
.rotate([0,0,0]);

const path = d3.geoPath()
.projection(projection);

const svg = d3.select("#graph").append("svg")
.attr("id", "world")
//.attr("width", width)
//.attr("height", height)
.attr("viewBox", "0 0 "+width+" "+height);

// Append all meridians and parallels
const graticule = d3.geoGraticule();
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);

d3.json(window.location.origin+"/storage/datas/5fca5a18522f4-world-countries.json").then(function(collection) {
  var countries = svg.selectAll("path")
  .data(collection.features)
  .enter().append("path")
  .attr("d", path)
  .attr("class", "country")
  .attr("id", d => d.id);
  
  d3.csv(window.location.origin+"/storage/datas/5fca59bc32d22-world-temperature.csv").then(function(data) {
    // 60 is the number of class in temperature.css
    var quantile = d3.scaleQuantile().domain([
      d3.min(data, e => e.temperature),
      d3.max(data, e => +e.temperature)])
      .range(d3.range(60));
      
      var legend = svg.append('g')
      .attr('transform', 'translate(135, 50)')
      .attr('id', 'legend');
      
      legend.selectAll('.colorbar')
      .data(d3.range(60))
      .enter().append('rect')
      .attr('y', d => d * 5 + 'px')
      .attr('height', '5px')
      .attr('width', '20px')
      .attr('x', '0px')
      .attr("class", d => "temperature-" + d);
      
      legendScale = d3.scaleLinear()
      .domain([d3.min(data, e => +e.temperature), d3.max(data, e => +e.temperature)])
      .range([0, 60 * 5]);
      
      svg.append("g")
      .attr('transform', 'translate(125, 50)')
      .call(d3.axisLeft(legendScale).ticks(10));
      
      data.forEach(function(e,i) {
        d3.select("#" + e.country)
        .attr("class", d => "country temperature-" + quantile(+e.temperature));
      });
    });
  });
  
  const λ = d3.scaleLinear()
  .domain([0, width])
  .range([-180, 180]);
  
  const φ = d3.scaleLinear()
  .domain([0, height])
  .range([90, -90]);
  
  var drag = d3.drag().subject(function() {
    var r = projection.rotate();
    return {
      x: λ.invert(r[0]),
      y: φ.invert(r[1])
    };
  }).on("drag", function() {
    projection.rotate([λ(d3.event.x), φ(d3.event.y)]);
    
    svg.selectAll(".graticule")
    .datum(graticule)
    .attr("d", path);
    
    svg.selectAll(".country")
    .attr("d", path);
  });
  
  svg.call(drag);