javascript - 在 D3 中将地理形状缩放至相似大小

标签 javascript math d3.js computational-geometry cartogram

我正在使用 D3 的 world-countries.json文件来创建世界各国的墨卡托 map ,然后我将其绑定(bind)到一些数据以形成不连续的 map 。唉,加拿大、美国、澳大利亚等国的面积要大得多,这意味着这些国家的一个单位在空间上相当于马耳他等国的几个单位。

我认为我需要做的是规范化 geojson 形状,这样加拿大和马耳他在开始时大小相同。

知道我该怎么做吗?

谢谢!

更新:我尝试将所有路径的宽度和高度显式设置为一个小整数,但这似乎稍后会被转换覆盖。代码如下:

// Our projection.
var xy = d3.geo.mercator(),
    path = d3.geo.path().projection(xy);

var states = d3.select("body")
  .append("svg")
  .append("g")
    .attr("id", "states");

function by_number() {

 function compute_by_number(collection, countries) {

    //update
     var shapes = states
            .selectAll("path")
              .data(collection.features, function(d){ return d.properties.name; });
    //enter       
         shapes.enter().append("path")
              .attr("d", path)
              .attr("width", 5) //Trying to set width here; seems to have no effect.
              .attr("height", 5) //Trying to set height here; seems to have no effect.
              .attr("transform", function(d) { //This works.
                var centroid = path.centroid(d),
                x = centroid[0],
                y = centroid[1];
                return "translate(" + x + "," + y + ")"
                + "scale(" + Math.sqrt(countries[d.properties.name] || 0) + ")"
                + "translate(" + -x + "," + -y + ")";
              })
            .append("title")
              .text(function(d) { return d.properties.name; });
    //exit
 }

 d3.text("../data/country_totals.csv", function(csvtext){
    var data = d3.csv.parse(csvtext);
    var countries = [];
    for (var i = 0; i < data.length; i++) {
        var countryName = data[i].country.charAt(0).toUpperCase() + data[i].country.slice(1).toLowerCase();
        countries[countryName] = data[i].total;
    }

    if (typeof window.country_json === "undefined") {
        d3.json("../data/world-countries.json", function(collection) {          
            window.country_json = collection;
            compute_by_number(collection, countries);           


        });
    } else {
            collection = window.country_json;
            compute_by_number(collection, countries);
    }

  });
} //end by_number

by_number();

最佳答案

您也许可以使用我在此处发布的辅助函数:https://gist.github.com/1756257

这会缩放投影以使给定的 GeoJSON 对象适合给定的边界框。缩放投影而不是使用变换来缩放整个路径的优点之一是笔划可以在 map 上保持一致。

另一个更简单的选择可能是:

  1. 投影路径;
  2. 使用 path.getBBox() 获取每个的边界框(.getBBox() 是原生 SVG 函数,而不是 D3 方法)
  3. 在路径上设置变换,类似于您现在的操作方式,以缩放和平移路径以适合您的边界框。

这有点简单,因为它不涉及投影,但是您需要按倒数 (1/scale) 缩放笔划以保持它们一致(因此您会赢)无法使用 CSS 设置笔画值)。它还需要首先实际渲染路径,然后缩放它 - 这可能会影响复杂几何形状的性能。

关于javascript - 在 D3 中将地理形状缩放至相似大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13877122/

相关文章:

javascript - Firefox 跨域图像被污染

javascript - 按顺序运行 Promise

javascript - Google map 本地搜索 API : How to pass a query?

matlab - 使用Matlab检测两个音频文件中多次点击声音之间的延迟

java - 碰撞检测中出现抖动

javascript - D3中的鼠标事件和画笔

javascript - 无法读取未定义的属性“主体”

javascript - 如何使 JavaScript Math.random 重复?

angular - 在 Angular 2 和 Typescript V2 上使用 D3 V4 时出现打字错误

d3.js - D3 如何从组中选择具有共享属性的多个形状?