如何使用 d3 和 geojson 路径数据缩放我的地图以适应我的 svg 大小
How can I scale my map to fit my svg size with d3 and geojson path data
我正在尝试创建一个 d3 SVG 来绘制纽约州地图并对其进行缩放以使其适合我的 SVG 大小,我遇到的问题是当我使用 .fitSize([height, width], mapObject)
它时控制台中只有 returns 个 NaN
错误。
我正在使用topoJSON file of NYS
我可以在不缩放的情况下显示地图,当然,它没有优化,需要缩放
我已经尝试过中所说的,但我还没有找到正确的解决方案
var map = d3.json('./ny.json')
Promise.all([map]).then(data => {
var height = 800;
var width = 800;
var mapData = data[0]
// original geoJSON to that works without scaling
// var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
//
var geoData = topojson.feature(mapData, {
type:"GeometryCollection",
geometries: mapData.objects["cb_2015_new_york_county_20m"].geometries,
})
var projection = d3.geoMercator()
.fitSize([width, height], geoData)
var path = d3.geoPath()
.projection(projection)
d3.select('svg')
.attr('height', height)
.attr('width', width)
.selectAll('.county')
.data(geoData)
.enter()
.append('path')
.classed('.county', true)
.attr('d', path)
})
我很确定这是我的格式错误,但我不确定 .fitSize()
或 .fitExtent()
试图与哪些数据进行比较。
现在我收到的代码站点没有错误输出到控制台,但我也没有数据附加到 SVG
问题是 fitSize 需要一个 geojson object 而 selectAll.data() 需要一个 array,你正在使用一个这两个都在 geoData
中。这留下了两个解决方案:
方案一:
如果我们使用
var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
var projection = d3.geoMercator()
.fitSize([width, height], geoData)
我们收到 NaN 错误,因为投影设置不正确,因为我们没有传递 geojson 对象,只是一组 geojson 对象。我们可以通过使用 geoData
制作一个特征集合并将其传递给 fitSize:
来解决这个问题
var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
var projection = d3.geoMercator()
.fitSize([width, height], {type:"FeatureCollection", features: geoData})
现在我们将 geojson 特征集合传递给 fitSize,我们都在进行投影,由于 geoData
仍然是一个数组,我们可以将其传递给 selectAll.data() 不变.
方案二:
如果我们使用:
var geoData = topojson.feature(mapData, {
type:"GeometryCollection",
geometries: mapData.objects["cb_2015_new_york_county_20m"].geometries,
})
我们得到一个 geojson 对象,projection.fitSize 有效,但 selectAll().data(geoData)
没有添加任何特征,因为它不是数组 - 输入选择为空。我们可以用 selectAll().data(geoData.features)
代替来解决这个问题,并为每个特征输入一个路径(或者我们可以使用 .data([geoData])
为所有路径输入一个特征)。
两个块都以正确的比例绘制 - 地图超出了块边界,因为我没有改变您的 800x800 尺寸
我正在尝试创建一个 d3 SVG 来绘制纽约州地图并对其进行缩放以使其适合我的 SVG 大小,我遇到的问题是当我使用 .fitSize([height, width], mapObject)
它时控制台中只有 returns 个 NaN
错误。
我正在使用topoJSON file of NYS
我可以在不缩放的情况下显示地图,当然,它没有优化,需要缩放
我已经尝试过
var map = d3.json('./ny.json')
Promise.all([map]).then(data => {
var height = 800;
var width = 800;
var mapData = data[0]
// original geoJSON to that works without scaling
// var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
//
var geoData = topojson.feature(mapData, {
type:"GeometryCollection",
geometries: mapData.objects["cb_2015_new_york_county_20m"].geometries,
})
var projection = d3.geoMercator()
.fitSize([width, height], geoData)
var path = d3.geoPath()
.projection(projection)
d3.select('svg')
.attr('height', height)
.attr('width', width)
.selectAll('.county')
.data(geoData)
.enter()
.append('path')
.classed('.county', true)
.attr('d', path)
})
我很确定这是我的格式错误,但我不确定 .fitSize()
或 .fitExtent()
试图与哪些数据进行比较。
现在我收到的代码站点没有错误输出到控制台,但我也没有数据附加到 SVG
问题是 fitSize 需要一个 geojson object 而 selectAll.data() 需要一个 array,你正在使用一个这两个都在 geoData
中。这留下了两个解决方案:
方案一:
如果我们使用
var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
var projection = d3.geoMercator()
.fitSize([width, height], geoData)
我们收到 NaN 错误,因为投影设置不正确,因为我们没有传递 geojson 对象,只是一组 geojson 对象。我们可以通过使用 geoData
制作一个特征集合并将其传递给 fitSize:
var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
var projection = d3.geoMercator()
.fitSize([width, height], {type:"FeatureCollection", features: geoData})
现在我们将 geojson 特征集合传递给 fitSize,我们都在进行投影,由于 geoData
仍然是一个数组,我们可以将其传递给 selectAll.data() 不变.
方案二:
如果我们使用:
var geoData = topojson.feature(mapData, {
type:"GeometryCollection",
geometries: mapData.objects["cb_2015_new_york_county_20m"].geometries,
})
我们得到一个 geojson 对象,projection.fitSize 有效,但 selectAll().data(geoData)
没有添加任何特征,因为它不是数组 - 输入选择为空。我们可以用 selectAll().data(geoData.features)
代替来解决这个问题,并为每个特征输入一个路径(或者我们可以使用 .data([geoData])
为所有路径输入一个特征)。
两个块都以正确的比例绘制 - 地图超出了块边界,因为我没有改变您的 800x800 尺寸