0

D3のworld-countries.jsonファイルを使用して、世界の国のメルカトル図法を作成します。これを、連続していないカルトグラムのデータにバインドします。残念ながら、カナダ、米国、オーストラリアなどのサイズがはるかに大きいということは、これらの国の1つの単位が、たとえばマルタの複数の単位と空間的に同等であることを意味します。

私がする必要があると思うのは、最初はカナダとマルタが同じサイズになるように、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();
4

1 に答える 1

3

ここに投稿したヘルパー関数を使用できる場合があります: https://gist.github.com/1756257

これにより、特定の GeoJSON オブジェクトが特定の境界ボックスに収まるように投影がスケーリングされます。変換を使用してパス全体をスケーリングするのではなく、投影をスケーリングする利点の 1 つは、ストロークがマップ全体で一貫していることです。

別のより簡単なオプションは次のとおりです。

  1. パスを投影します。
  2. path.getBBox()それぞれのバウンディング ボックスを取得するために使用します ( .getBBox()D3 メソッドではなく、ネイティブ SVG 関数です)。
  3. 現在の方法と同様に、パスに変換を設定して、バウンディング ボックスに合わせてパスをスケーリングおよび変換します。

これはプロジェクションを含まないため、少し単純ですが、1/scale一貫性を保つためにストロークを逆数 ( ) でスケーリングする必要があります (したがって、CSS でストロークの値を設定することはできません)。また、最初にパスを実際にレンダリングしてからスケーリングする必要があります。これは、複雑なジオメトリのパフォーマンスに影響を与える可能性があります。

于 2012-12-14T22:23:21.007 に答える