【问题标题】:Scaling geographic shapes to a similar size in D3在 D3 中将地理形状缩放到相似的大小
【发布时间】:2015-09-08 04:26:12
【问题描述】:

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

我认为我需要做的是规范化 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();

【问题讨论】:

  • 我想你可以先计算不同形状的边界框,然后对宽度或高度进行归一化(或两者都有一些逻辑)。
  • 请原谅我的极其愚蠢的问题——对于 d3.js 来说非常新——但是如何计算 d3 中路径的边界框?

标签: javascript math d3.js computational-geometry cartogram


【解决方案1】:

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

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

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

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

这有点简单,因为它不涉及投影,但您需要按逆向 (1/scale) 缩放笔画以保持一致(因此您将无法设置笔画CSS 的值)。它还需要先实际渲染路径,然后对其进行缩放——这可能会影响复杂几何图形的性能。

【讨论】:

  • 这很有帮助,我会试一试!谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多