我对D3地图非常陌生,我一直在尝试使用svg滤镜创建具有阴影效果的自适应D3地图。
示例代码由Mike Bostock(drop shadow)和Darren Jaworski(responsive projection)的代码块改编而成。您可以在Codepen上查看示例代码。以下是我的JS代码:
var width = parseInt(d3.select('#mapContainer').style('width'))
,height = width/960*600;
var svg = d3.select("svg")
.attr("width", width)
.attr("height",height);
var defs = svg.select("defs");
d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
if (error) throw error;
var path = d3.geoPath();
var projection = d3.geoIdentity()
.scale(width)
.translate([width / 2, height / 2])
.fitSize([width, height],topojson.feature(us, us.objects.states));
defs.append("path")
.attr("id", "nation")
.attr("d", path(topojson.feature(us, us.objects.nation)));
svg.append("use")
.attr("xlink:href", "#nation")
.attr("fill-opacity", 0.2)
.attr("filter", "url(#blur)");
svg.append("use")
.attr("xlink:href", "#nation")
.attr("fill", "#fff");
svg.append("path")
.attr("fill", "none")
.attr("stroke", "#777")
.attr("stroke-width", 0.70)
.attr("d", path(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })));
// resize event
d3.select(window)
.on("resize", resize);
// function to resize map
function resize() {
// adjust things when the window size changes
width = parseInt(d3.select('#mapContainer').style('width'));
//console.log(parseInt(d3.select('#mapContainer').style('width')));
height = width/960*600;
svg.attr('width', width).attr('height', height);
// update projection
projection
.scale(width)
.translate([width / 2, height / 2])
.fitSize([width, height],topojson.feature(us, us.objects.states));
// resize the map
svg.selectAll('path').attr('d', path);
svg.select('.land').attr('d', path);
svg.select('.state').attr('d', path);
}
});
在示例中,调整大小功能似乎不起作用。在调整窗口大小时,地图将消失,附加在其上的svg过滤器也将消失。
有人可以启发我解决问题吗?如果有人可以提供修复程序?
非常感谢您的帮助!
我用@ rioV8的很好的答案更新了codepen on Responsive US D3 Map with Drop Shadow。
答案 0 :(得分:1)
您是否曾经考虑过连接投影仪和路径生成器?
var path = d3.geoPath(projection);
还可以在resize方法中设置路径。标记2个路径元素
svg.select('#nation').attr('d', path(topojson.feature(us, us.objects.nation)));
svg.select('#nation2').attr('d', path(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; })));
体内的负担一定要去
<body>
没有类别为land
或state
的标签
//svg.select('.land').attr('d', path);
//svg.select('.state').attr('d', path);
为什么调用投影size
和translate
,如果您调用fitSize
这是脚本代码
var width = parseInt(d3.select('#mapContainer').style('width')) - 50
,height = width/960*600;
var svg = d3.select("svg")
.attr("width", width + 50)
.attr("height",height);
var defs = svg.select("defs");
d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
if (error) throw error;
var topoFeatureStates = topojson.feature(us, us.objects.states);
var projection = d3.geoIdentity()
.fitSize([width, height], topoFeatureStates);
var path = d3.geoPath(projection);
defs.append("path")
.datum(topojson.feature(us, us.objects.nation))
.attr("id", "nation")
.attr("d", path);
svg.append("use")
.attr("xlink:href", "#nation")
.attr("fill-opacity", 0.2)
.attr("filter", "url(#blur)");
svg.append("use")
.attr("xlink:href", "#nation")
.attr("fill", "#fff");
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))
.attr("fill", "none")
.attr("stroke", "#777")
.attr("stroke-width", 0.70)
.attr("d", path);
// function to resize map
function resize() {
// adjust things when the window size changes
width = parseInt(d3.select('#mapContainer').style('width')) - 50;
//console.log(parseInt(d3.select('#mapContainer').style('width')));
height = width/960*600;
svg.attr('width', width + 50).attr('height', height);
// update projection
projection
.fitSize([width, height], topoFeatureStates);
// resize the map
svg.selectAll('path').attr('d', path);
}
// resize event
d3.select(window).on("resize", resize);
});
修改
想知道为什么调整大小后的path
不起作用,请再看一下响应示例。它将topojson
的结果作为基准附加到path
。
修改了代码以进行相同的操作。