D3旋转地球仪:如何旋转刻度线(网格)?

时间:2015-11-05 13:37:01

标签: javascript d3.js

我正在使用D3在正交投影上对一些JSON数据进行交互式可视化。用户应该能够通过拖动鼠标/触控板来旋转地球。

使用下面的代码,我可以成功地旋转点,但是刻度仍然是静态的。

我尝试在下面制作一个工作片段,但它在嵌入式预览器上的显示方式与在我的机器上的显示方式不同;任何有关如何使这项工作的提示也很感激!



leeroyjenkins = function() {
  var data = [{
    "latitude": 0,
    "longitude": 0,
    "magnitude": "1.0"
  }, {
    "latitude": 10,
    "longitude": 10,
    "magnitude": "2.0"
  }, {
    "latitude": 20,
    "longitude": 20,
    "magnitude": "3.0"
  }, {
    "latitude": 30,
    "longitude": 30,
    "magnitude": "4.0"
  }, {
    "latitude": 40,
    "longitude": 40,
    "magnitude": "5.0"
  }, ]


  main(data);
};


var main = function(points) {


    var width = 600,
      height = 600,
      //rotate = [10, -10],
      time = Date.now();

    var sphere = {
      type: "Sphere"
    };

    var graticule = d3.geo.graticule();


    var projection = d3.geo.orthographic()
      .scale(250)
      .translate([width / 2, height / 2])
      .clipAngle(90);

    var pointpath = function(d, r) {
      var pr = d3.geo.path().projection(projection).pointRadius(r);
      return pr({
        type: "Point",
        coordinates: [d.longitude, d.latitude]
      })
    }

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

    var λ = d3.scale.linear()
      .domain([0, width])
      .range([-180, 180]);

    var φ = d3.scale.linear()
      .domain([0, height])
      .range([90, -90]);

    var drag = d3.behavior.drag().origin(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("path.point").attr("d", function(d) {
          return pointpath(d, d.magnitude * 2.5);
        });
        svg.selectAll("path.graticule").attr("d", path);

      });



    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);

    svg.append("path")
      .datum(graticule)
      .attr("class", "graticule")
      .attr("d", path);

    var point = svg.selectAll("path.point").data(points);

    point.enter()
      .append("path")
      .attr("class", "point")
      .attr("d", function(d) {
        return pointpath(d, 0)
      })
      .transition()
      .delay(function(d, i) {
        return i * 200;
      })
      .duration(200)
      .attr("d", function(d) {
        return pointpath(d, d.magnitude * 2.5)
      });

    svg.call(drag);

  } //end Main

leeroyjenkins();

body {
  background-color: #DDD;
  color: #555;
}
country {
  fill: #ccc;
  stroke: #fff;
  stroke-width: .5px;
  stroke-linejoin: round;
}
graticule {
  fill: none;
  stroke: #EEE;
  stroke-opacity: .3;
  stroke-width: .5px;
}
graticule.outline {
  stroke: #333;
  stroke-opacity: 1;
  stroke-width: 1.5px;
}
div.tooltip {
  position: absolute;
  text-align: center;
  width: 240px;
  height: 60px;
  padding: 2px;
  font: 12px sans-serif;
  background: #FFF;
  border: 0px;
  border-radius: 8px;
  /*pointer-events: none;         */
}
title {
  display: inline-block;
  font-size: 48px;
  line-height: 90px;
  text-align: center;
}
path.point {
  stroke: red;
  fill: red;
}

<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

我相信我确实在我的问题中发布了正确的代码,但是我对预览器的问题意味着我没有注意到它正在运行。

无论如何,我遇到麻烦的部分是:

svg.selectAll("path.graticule").attr("d", path);

我在return pointpath下面的界限。只需将代码放在下面的行上即可。