Карта 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]()
Ответы
Ответ 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;