使用 d3 在 Leaflet map 上绘制 SVG 工件是一种获得实体 map Controller 并结合 d3 优势的简单方法。有许多示例和指南说明如何实现这一目标,两种主要方法似乎是:
在 Leaflet 的“覆盖 Pane ”上附加一个新的 SVG 元素,如 Bostock 所示:http://bost.ocks.org/mike/leaflet/
实现一个 Hook 到 Leaflet 原生切片层生态系统的自定义矢量切片层,如 Nelson Minar 所示:http://bl.ocks.org/NelsonMinar/5624141
第一种方法通过附加传单类来避免传单基于比例的缩放,以便在缩放时隐藏任何 d3 元素。当缩放动画结束时,将重新计算并重新绘制元素坐标,然后删除隐藏类以再次暴露元素。这可行,但与 Leaflet 的原生 GeoJSON 层相比,提供的放大/缩小体验不太清晰,因为后者支持动画缩放。
第二种方法不包含任何解决缩放行为的特定于实现的代码,但无论如何都可以工作! d3 元素在动画缩放期间进行缩放,然后巧妙地替换为下一个缩放级别向量。
我想要实现的是两者的结合。我想绘制基于 Geo/TopoJSON 的非基于图 block 的矢量,这些矢量在放大/缩小期间动画。我尝试过使用不同的 leaflet css 类、不同的事件 Hook ,以及以多种方式附加和/或重用 SVG 元素,但尚未实现与使用 Leaflet 的 native GeoJSON 向量时所经历的行为类似的行为层。我不想使用 native 层的原因是我想利用大量其他 d3 功能,而这些功能根本不是 Leaflet 实现的一部分。
问题:有人在使用非基于图 block 的矢量组合 Leaflet 和 d3 时实现了动画缩放吗?如果是这样 - 怎么办?
最佳答案
示例
我认为this是我发现的结合 Leaflet 和 d3 的最佳解决方案之一,作者:ZJONSSON .
d3 + 传单集成
在此示例中,Leaflet map 在 map._initPathRoot()
处以 SVG 形式启动,然后使用 d3 var svg = d3.select("#map") 选择 SVG。选择(“svg”),
g = svg.append("g");
,之后就可以享受所有 d3 的乐趣了。
在此示例中,Leaflet map 事件 map.on("viewreset", update);
用于调用 update
并转换 map 上的 d3 图层查看重置
。此后,d3 过渡选项将确定 d3 图层对 Leaflet map 平移/缩放事件的 react 。
通过这种方式,您可以获得 d3 + Leaflet 库的完整范围,而无需计算 map 边界等麻烦,因为 Leaflet 可以很好地处理这些问题。
动画矢量缩放
对于动画,最新的 Leaflet 版本包括 Pan and Zoom animation选项。虽然这不像 d3 那样可定制,但您始终可以编辑 Leaflet src 代码来更改过渡持续时间! Leaflet GeoJSON 矢量图层 (L.geoJson
) 不需要在 Leaflet map 事件上更新(在 update
中),因为它们已经作为 SVG 添加到 map 中,并且由Leaflet处理。
请注意,如果实现L.geoJson
,这也意味着您不需要map._initPathRoot()
,因为Leaflet会将图层作为SVG添加到 map 中,所以你可以d3.select
它。
还可以在L.geoJson
图层选项中添加className
变量,以便您可以通过CSS或d3.select
设置样式通过在 Leaflet onEachFeature
期间分配的唯一类 ID 的功能。
关于d3.js - 用d3和Leaflet实现动画缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21216347/