d3.js - Logro de zoom animado con d3 y Leaflet
(1)
El uso de d3 para trazar artefactos SVG en la parte superior de un mapa de Folleto es una forma sencilla de obtener un controlador de mapa sólido combinado con la fuerza de d3. Existen numerosos ejemplos y guías sobre cómo lograr esto y los dos enfoques principales parecen ser:
Anexando un nuevo elemento SVG en el "panel de superposición" del Folleto como lo demuestra Bostock aquí: http://bost.ocks.org/mike/leaflet/
Implementando una capa de mosaico vectorial personalizada que se engancha al ecosistema de capa de mosaico nativo de Folletos, como lo demuestra Nelson Minar aquí: http://bl.ocks.org/NelsonMinar/5624141
El primer enfoque evita los acercamientos basados en la escala de los Folletos al adjuntar una clase de folleto para que cualquier elemento d3 quede oculto mientras se lleva a cabo la escala. Cuando finaliza la animación de zoom, las coordenadas del elemento se vuelven a calcular y se vuelven a dibujar, y luego se elimina la clase oculta para exponer los elementos nuevamente. Esto funciona, pero brinda una experiencia de acercamiento / alejamiento menos limpia que con la capa GeoJSON nativa de Leaflet, ya que esta última admite el acercamiento animado.
El segundo enfoque no contiene ningún código específico de implementación que aborde el comportamiento del zoom, ¡pero de alguna manera funciona! Los elementos d3 se escalan durante el zoom animado y luego se reemplazan cuidadosamente con los siguientes vectores de niveles de zoom.
Lo que me gustaría lograr es una combinación de los dos. Me gustaría trazar vectores no basados en mosaicos basados en Geo / TopoJSON que se animan durante el acercamiento / alejamiento. Jugué con diferentes clases css de folletos, diferentes ganchos de eventos, adjuntando y / o reutilizando los elementos SVG de muchas maneras, pero aún no he logrado un comportamiento similar al comportamiento experimentado al usar el vector GeoJSON nativo de Leaflet. capa. La razón por la que no quiero usar la capa nativa es porque quiero usar muchas otras funcionalidades de d3 que simplemente no forman parte de la implementación de Leaflet.
Pregunta: ¿Alguien ha logrado un zoom animado al combinar Leaflet y d3 utilizando vectores no basados en mosaicos? ¿Si es así, cómo?
Ejemplo
Creo que this es una de las mejores soluciones que he encontrado para combinar Leaflet y d3, de ZJONSSON .
d3 + integración de folletos
En este ejemplo, el mapa del Folleto se inicia como SVG aquí map._initPathRoot()
, con el SVG seleccionado luego usando d3 var svg = d3.select("#map").select("svg"), g = svg.append("g");
, tras lo cual se puede tener toda la diversión d3.
En este ejemplo, el mapa mapa de eventos map.on("viewreset", update);
se utiliza para llamar a la update
y la transición de la capa d3 en el viewreset
mapa. Después de esto, las opciones de transición d3 determinarán cómo reacciona la capa d3 al evento de acercamiento / zoom del mapa del Folleto.
De esta manera, tiene el alcance completo de las bibliotecas de folletos de d3 + sin la molestia de calcular los límites de los mapas, etc., ya que esto se maneja muy bien con los folletos.
Animación vectorial de zoom
Para la animación, la última versión de Leaflet incluye una opción de animación Pan y Zoom . Si bien esto no es tan personalizable como d3, ¡siempre puede editar el código de src del Folleto para modificar la duración de la transición! Las capas vectoriales GeoJSON del Folleto ( L.geoJson
) no necesitarán actualizarse en un evento de mapa del Folleto (en update
), ya que ya se agregaron al mapa como SVG y son manejadas por Folleto.
Tenga en cuenta que si implementa L.geoJson
, esto también significa que no necesitará map._initPathRoot()
, ya que el Folleto agregará la capa al mapa como SVG, por lo que solo puede seleccionar d3.select
.
También es posible agregar una variable className
en las opciones de capa L.geoJson
para que pueda d3.select
estilo a través de CSS o d3.select
una característica a través de un ID de clase único asignado durante Leaflet onEachFeature
.