D3 Globe在更高分辨率下的生涩变焦行为

时间:2019-05-15 11:24:25

标签: d3.js

我目前正尝试制作一个可拖动和缩放的地球仪,其示例如下:https://bl.ocks.org/sarah37/d8a1722f7d9f2a40eb07a3e99bf3c0be。麻烦的是,我不想使用110m来尝试使用5000万个国家/地区轮廓(我希望我的几个观众希望看到110m的国家看起来过于简单)。

我已经成功加载了数据,但是缩放和平移非常困难,并且存在明显的滞后。

在简单地加载SVG(例如https://bl.ocks.org/RomyRatolojanahary/48b74dfcae890cb6b7e8c503e0246c15)并缩放页面时,我不会遇到任何这种麻烦。

这仅仅是技术的限制吗?在缩放和平移发生时是否需要绘制SVG?我真的很想用D3代替传单或类似的东西,而且我真的想把它当作一个旋转的地球仪。

这是我的D3代码:

// width and height
var w = document.documentElement.clientWidth;
var h = document.documentElement.clientHeight;
// var w = 960;
// var h = 500;

// scale globe to size of window
var scl = Math.min(w, h)/2.5; 

// map projection
var projection = d3.geoOrthographic()
        .scale(scl)
        .translate([ w/2, h/2 ])
        .clipAngle(90);

// path generator
var path = d3.geoPath()
  .projection(projection)
  .pointRadius(3);

// append svg
var svg = d3.select("#svgDiv")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

// append g element for map
var map = svg.append("g");

// enable drag
var drag = d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged);

var gpos0, o0, gpos1, o1;
svg.call(drag);

// enable zoom
var zoom = d3.zoom()
    .scaleExtent([0.75, 50]) //bound zoom
    .on("zoom", zoomed);

svg.call(zoom);

// load topojson
d3.json("world-50m.json", function(json) {
    map.append("path")
    .datum({type: "Sphere"})
    .attr("class", "ocean")
    .attr("d", path);

    map.append("path")
    .datum(topojson.merge(json, json.objects.countries.geometries))
    .attr("class", "land")
    .attr("d", path);

    map.append("path")
    .datum(topojson.mesh(json, json.objects.countries, function(a, b) { return a !== b; }))
    .attr("class", "boundary")
    .attr("d", path);
});
//Add the city data as a JSON
 d3.json('places.json', function(data) {
   map.append("g")
     .selectAll("text")
     .data(data.features)
     .enter()
     .append("path")
     .attr("class", "point")
     .attr("fill","red")
     .attr("d", path);
 });


// functions for dragging
function dragstarted() {
    gpos0 = projection.invert(d3.mouse(this));
    o0 = projection.rotate();
}

function dragged() {
    gpos1 = projection.invert(d3.mouse(this));
    o0 = projection.rotate();
    o1 = eulerAngles(gpos0, gpos1, o0);
    projection.rotate(o1);
    map.selectAll("path").attr("d", path);
}

// functions for zooming
function zoomed() {
    projection.scale(d3.event.transform.translate(projection).k * scl)
    map.selectAll("path").attr("d", path);
}

在110m处,缩放和平移非常平滑,但是在50m处,缩放变得几乎不可用。

是否有解决此问题的精妙解决方案?

我也确实看过这个项目,https://bost.ocks.org/mike/simplify/,但是随着线变得越来越复杂,我看不出有什么方法可以防止这种混乱。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

我能够找到自己的问题的解决方案。我将其张贴在这里,以防其他人遇到相同的问题: https://bl.ocks.org/curran/0bb64d8f56042e2480c908b0985f063b

相关问题