【发布时间】:2019-12-01 20:34:34
【问题描述】:
我正在使用 d3v4 构建地图。我正在使用 Robinson 投影、d3 的缩放行为进行平移和缩放,以及 css 转换来实际定位 svg 元素本身。给定一个经纬度对,我想使用当前缩放使地图居中。
我已经看到了很多关于如何在 d3 中居中地图以及如何附加缩放行为的示例,但到目前为止,每个示例都是
- 使用旧版本的 d3
- 不使用缩放行为(例如https://bl.ocks.org/mbostock/2206489)
- 操纵投影本身而不是使用 css 变换 (https://bl.ocks.org/mbostock/2206340)
- 根本不使用地图投影 (https://bl.ocks.org/catherinekerr/b3227f16cebc8dd8beee461a945fb323)
给定一个纬度/经度对,我可以使用我的投影来获得非翻译、非缩放 svg 上的 X/Y。如何从该点创建转换以使其在视图中居中?
我的地图设置:
const {clientHeight: height, clientWidth: width} = div;
svg.setAttribute("width", `${width}`);
svg.setAttribute("height", `${height}`);
// projection
this.projection = geoRobinson()
// center and scale to container properly
.translate([width / 2, height / 2])
.scale((width - 1) / 2 / Math.PI);
// calculate zoom limits
const actualHeight = width / ratio;
const verticalExtent = (actualHeight - height) / 2;
// setup mouse listeners for panning and zooming on svg.
this.zoomBehavior = zoom<SVGSVGElement, any>()
// set min and max zoom factor
.scaleExtent([0.75, 8]) // based on playing around with numbers until it looked pleasing
// transform map on zoom and pan
.on("zoom", () => {
const currentTransform = this.state.transform;
const newTransform: ZoomTransform = d3event.transform;
if (
!currentTransform ||
hasChanged(currentTransform.x, newTransform.x) ||
hasChanged(currentTransform.y, newTransform.y) ||
hasChanged(currentTransform.k, newTransform.k)
) {
this.setState({ // updates the css transform of the SVG map
transform: newTransform,
});
}
});
// apply zoom behavior to whole svg
const svgSelection = select(svg);
svgSelection.call(this.zoomBehavior)
我查看了zoomBehavior.translateTo() 和其他函数,但我不知道如何转换为它们使用的任何单位。
【问题讨论】: