Подтвердить что ты не робот

Карта d3.js(<svg>) Автоматическая установка в родительский контейнер и изменение размера с помощью окна

ОБНОВЛЕНИЕ: я опубликовал и принял полностью работающее решение в разделе ответов. Любой код в этом разделе должен использоваться как ссылка для сравнения с вашим собственным кодом НЕ РАБОТЫ, но не должен использоваться в качестве решения.


Я создаю панель инструментов и использую d3.js, чтобы добавить карту мира, которая будет отображать твиты в реальном времени на основе геолокации.

Файл world.json, указанный в строке d3.json(), можно загрузить ЗДЕСЬ (он называется world-countries.json).

enter image description here

Карта находится на странице как контейнер 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();
});

UPDATE: я масштабировал карту до приемлемого размера (для моего конкретного размера браузера), но по-прежнему не масштабируется и не фокусируется, когда я изменяю размер окна. ЕСЛИ, однако, я изменяю размер окна, а затем удаляю обновление, затем карта будет центрирована после перезагрузки страницы. Однако, поскольку масштаб статичен, он не масштабируется должным образом.

enter image description here

4b9b3361

Ответ 1

ПОЛНОЕ РЕШЕНИЕ:

Здесь решение, которое изменит размер карты ПОСЛЕ того, как пользователь освободит край окна, чтобы изменить его размер, и центрируйте его в родительском контейнере.

<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 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);
});

Ответ 2

Объектом выделения является многомерный массив, хотя в большинстве случаев он, вероятно, будет иметь только один объект. Этот объект имеет поле "clientWidth", в котором указывается, насколько широка его родительская.

Итак, вы можете сделать это:

var selection = d3.select("#chart"); 
width = selection[0][0].clientWidth;

Ответ 3

Это должно работать:

<svg 
    xmlns="http://www.w3.org/2000/svg"
    width="860"
    height="500"
    viewBox="0 0 860 500"
    preserveAspectRatio="xMinYMin meet">

Ответ 4

Наилучшим вариантом является совместное использование соотношения сторон при нормальном определении ширины и высоты графика d3. Это помогло мне во многих моих графических работах.
Шаг 1. Динамически получить высоту div, к которой должен быть добавлен граф.
Шаг 2: Объявите ширину как соотношение сторон по отношению к динамически пойманной высоте.

var graph_div = document.getElementById(graph.divId);
graph.height = graph_div.clientHeight;
graph.width = (960/1200)*graph.height;