我试图用我从这个API带来的GEOJSON数据在SVG中绘制一张地图,SVG路径充满了数据,然而,SVG是空白的,执行下面的代码可以看到。注意document.write
,数据被正确返回。
var svg = d3.select("svg")
d3.json('https://api.mocki.io/v1/d214eb47')
.then(data => {
svg.append('g')
.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('d', d3.geoPath().projection(d3.geoMercator()))
document.write(JSON.stringify(data));
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.0/d3.min.js"></script>
<svg width="600" height="600"></svg>
我用另一个GEOJSON file测试了它,并设法在SVG中绘制,如执行以下代码所示:
const link = "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson";
var svg = d3.select("svg")
d3.json(link)
.then(data => {
svg.append("g")
.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d", d3.geoPath()
.projection(d3.geoMercator())
)
//document.write('data ', JSON.stringify(data))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.0/d3.min.js"></script>
<svg width="600" height="600"></svg>
有人知道第一个代码片段出了什么问题吗?
发布于 2021-03-25 00:11:16
数据中没有问题,这里的问题只是您试图绘制一个非常小的区域(旧金山),而不是您的第二个示例中的世界地图。也就是说,您应该设置投影的scale
和center
。在您的案例中:
const projection = d3.geoMercator()
.scale(100000)
.center([-122.3, 37.75])
生成的代码如下:
var svg = d3.select("svg");
const projection = d3.geoMercator()
.scale(100000)
.center([-122.3, 37.75])
d3.json('https://api.mocki.io/v1/d214eb47')
.then(data => {
svg.append('g')
.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('d', d3.geoPath().projection(projection))
})
path {
fill: wheat;
stroke: darkslateblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.0/d3.min.js"></script>
<svg width="600" height="600"></svg>
但只需将fitExtent
与您的SVG宽度和高度一起使用就更简单了:
const projection = d3.geoMercator()
.fitExtent([
[0, 0],
[600, 600]
], data)
下面是生成的代码:
var svg = d3.select("svg");
d3.json('https://api.mocki.io/v1/d214eb47')
.then(data => {
const projection = d3.geoMercator()
.fitExtent([
[0, 0],
[600, 600]
], data)
svg.append('g')
.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('d', d3.geoPath().projection(projection))
})
path {
fill: wheat;
stroke: darkslateblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.0/d3.min.js"></script>
<svg width="600" height="600"></svg>
发布于 2021-03-25 00:18:18
您的GeoJSON文件有非常小的显示区域,但在给定的投影和默认的SVG viewBox中几乎没有大小的形状。
检查我是如何使用您的地理数据找到SVG G元素的边界的。然后我用它来定义SVG的viewBox属性。如果未设置SVG的宽度或高度,则SVG将扩展到可用的“容器”大小。因此,如果愿意,您可以添加周围的DIV元素并设置其大小(在容器中适合SVG,从而在布局中适合SVG)。
更新:您甚至可以稍后使用javascript使用getBBox()函数的返回值来更改SVG viewBox属性。另一种答案中的另一种可能性当然也很大(适合您的SVG范围)。
var svg = d3.select("svg");
const link = "https://api.mocki.io/v1/d214eb47";
//const link = "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson";
d3.json(link)
.then(data => {
svg.append('g')
.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('d', d3.geoPath().projection(d3.geoMercator()));
//console.log(data.features);
console.log(document.getElementsByTagName("g")[0].getBBox());
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.6.0/d3.min.js"></script>
<svg viewBox="152.95315551757812 140.7493133544922 0.421722412109375 0.4228363037109375"></svg>
https://stackoverflow.com/questions/66789452
复制相似问题