d3.js地图(< svg>)自动适合到父容器中,并使用窗口调整大小 [英] d3.js Map (<svg>) Auto Fit into Parent Container and Resize with Window
问题描述
更新:我已在答案部分发布并接受了一个完全正常的解决方案。此部分中的任何代码都将用作与您自己的NON-WORKING代码进行比较的参考,但不能用作解决方案。
我正在建立一个仪表板,并使用d3.js添加一个世界地图,将根据地理位置实时绘制tweets。
d3.json()行中引用的 world.json 文件是可下载的 此处 (称为 world-countries.json )。
地图在页面上作为SVG容器,并使用d3呈现。
下面是相关的代码片。
< div id =mapContainer>
< svg xmlns =http://www.w3.org/2000/svgwidth =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();
});
更新:我已将地图缩放至可接受的大小(针对特定浏览器大小)仍然不会缩放和中心,当我改变窗口的大小。如果,然后,我调整窗口大小,然后点击刷新,然后地图将被重新加载页面的中心。但是,由于比例尺是静态的,因此未正确缩放。
COMPLETE SOLUTION:
$ b
这里的解决方案将调整地图大小后,用户已经释放窗口的边缘以调整其大小,并将其居中在父容器中。
< div id =mapContainer>< / div>
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;
//我发现未缩放的等长矩形地图是640x360。因此,我们
//应该相应地缩放我们的地图。根据新的
//容器的宽度比例,比例将是这个比率* 100.你也可以使用height
//。等长方形地图的宽高比是2:1,所以这就是为什么
//我们的高度是我们宽度的一半。
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);
});
UPDATE: I have posted and accepted a fully working solution in the answers section. Any code in this section is to be used as reference for comparison to your own NON-WORKING code, but is not to be used as the solution.
I'm building a dashboard and using d3.js to add a world map that will plot tweets in real time based on geo location.
The world.json file referenced in the d3.json() line is downloadable HERE (it's called world-countries.json).
The map is on the page as an SVG container and is rendered using d3.
Below are the relevant code slices.
<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: I have scaled the map to an acceptable size (for my particular browser size), but it still will not scale and center when I change the size of the window. IF, however, I resize the window, then hit refresh, then the map will be centered once the page is reloaded. However, since the scale is static, it is not scaled properly.
COMPLETE SOLUTION:
Here's the solution which will resize the map AFTER the user has released the edge of the window to resize it, and center it in the parent container.
<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);
});
这篇关于d3.js地图(< svg>)自动适合到父容器中,并使用窗口调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!