37

更新:回答セクションに完全に機能するソリューションを投稿して受け入れました。このセクションのコードは、独自の非動作コードと比較するための参照として使用されますが、解決策としては使用されません。


ダッシュボードを作成し、d3.jsを使用して、地理的位置に基づいてリアルタイムでツイートをプロットする世界地図を追加しています。

d3.json ()行で参照されているworld.jsonファイルは、ここからダウンロードできます(world-countries.jsonと呼ばれます)。

ここに画像の説明を入力してください

マップはSVGコンテナーとしてページ上にあり、d3を使用してレンダリングされます。

以下は、関連するコードスライスです。

<div id="mapContainer">
    <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="500"></svg>
</div>

#mapContainer svg {
    display:block;
    margin:0 auto;
}
#mapContainer path {
  fill:#DDD;
  stroke:#FFF;
}

// generate US plot
function draw() {
    var map = d3.select("svg");
    var width = $("svg").parent().width();
    var height = $("svg").parent().height();

    var projection = d3.geo.equirectangular().scale(185).translate([width/2, height/2]);
    var path = d3.geo.path().projection(projection);
    d3.json('plugins/maps/world.json', function(collection) {
        map.selectAll('path').data(collection.features).enter()
            .append('path')
            .attr('d', path)
            .attr("width", width)
            .attr("height", height);
    });
}
draw();
latestLoop();

$(window).resize(function() {
    draw();
});

更新:マップを(特定のブラウザーサイズに対して)許容可能なサイズに拡大縮小しましたが、ウィンドウのサイズを変更しても拡大縮小および中央揃えされません。ただし、ウィンドウのサイズを変更してから[更新]をクリックすると、ページが再読み込みされるとマップが中央に配置されます。ただし、スケールは静的であるため、適切にスケーリングされません。

ここに画像の説明を入力してください

4

5 に答える 5

29

完全な解決策:

これは、ユーザーがウィンドウの端を離してサイズを変更した後にマップのサイズを変更し、親コンテナーの中央に配置するソリューションです。

<div id="mapContainer"></div>

function draw(ht) {
    $("#mapContainer").html("<svg id='map' xmlns='http://www.w3.org/2000/svg' width='100%' height='" + ht + "'></svg>");
    map = d3.select("svg");
    var width = $("svg").parent().width();
    var height = ht;

    // I discovered that the unscaled equirectangular map is 640x360. Thus, we
    // should scale our map accordingly. Depending on the width ratio of the new
    // container, the scale will be this ratio * 100. You could also use the height 
    // instead. The aspect ratio of an equirectangular map is 2:1, so that's why
    // our height is half of our width.

    projection = d3.geo.equirectangular().scale((width/640)*100).translate([width/2, height/2]);
    var path = d3.geo.path().projection(projection);
    d3.json('plugins/maps/world.json', function(collection) {
        map.selectAll('path').data(collection.features).enter()
            .append('path')
            .attr('d', path)
            .attr("width", width)
            .attr("height", width/2);
    });
}
draw($("#mapContainer").width()/2);

$(window).resize(function() {
    if(this.resizeTO) clearTimeout(this.resizeTO);
    this.resizeTO = setTimeout(function() {
        $(this).trigger('resizeEnd');
    }, 500);
});

$(window).bind('resizeEnd', function() {
    var height = $("#mapContainer").width()/2;
    $("#mapContainer svg").css("height", height);
    draw(height);
});
于 2013-01-12T23:33:02.903 に答える
8

これはうまくいくはずです:

<svg 
    xmlns="http://www.w3.org/2000/svg"
    width="860"
    height="500"
    viewBox="0 0 860 500"
    preserveAspectRatio="xMinYMin meet">
于 2013-01-10T20:12:51.900 に答える