Estoy trabajando en un visor de planos de planta, donde uno debería poder seleccionar ciertas habitaciones de dicho plano. Estoy tratando de resolver esto con la ayuda de un archivo svg. Hasta este punto, siempre generaba y agregaba el svg al DOM, directamente en javascript y agregaba toda la funcionalidad de d3.js junto con él (zoom, pan). Ahora estoy tratando de lograr el mismo resultado con un archivo svg externo (que tiene la misma estructura). Lo que aún funciona es simplemente agregar este archivo svg ahora externo al DOM, pero no puedo agregar la funcionalidad d3.zoom.
mi estructura de archivo svg: <svg><g><image></image>{<polygon><title><title></polygon><text></text>, ...}</g></svg>
la etiqueta de imagen agrega un plano de planta png, las etiquetas dentro de los corchetes {} son valores para cada habitación individual (lo que hace posible seleccionar una)
cargando un archivo externo (al intentar agregar la función de zoom):
var svg, g; d3.xml('test.svg').then(function (data) { var svgNode = data.getElementsByTagName("svg")[0]; document.getElementById("svg-viewer-foreground-3").appendChild(svgNode); svg = d3.select("svg").call(zoom); g = svg.select("g"); }); let zoom = d3.zoom().on('zoom', zoomed); function zoomed() { g.attr("transform", d3.event.transform); }Entonces, ¿cómo hago esto correctamente?
Estoy feliz de agregar información adicional si es necesario. (Esta es la primera vez que hago una pregunta, así que una posible explicación de los errores de mi parte)
Ok, no formulé mi pregunta de manera muy específica, pero yo mismo encontré una solución. Tal vez sea útil para alguien.
En resumen, el problema que encontré fue que no podía cargar un archivo SVG externo en el DOM, mientras podía usar la funcionalidad de zoom d3.js. O más en detalle, no pude llamar a zoom en el nodo <svg> que logré usando d3.xml.
Entonces, mi solución fue simplemente crear un nuevo nodo svg, agregar los atributos del nodo svg cargado desde el archivo y luego agregar todos los nodos secundarios:
d3.xml(path).then(function (data) { // attributes have to be set manually var svgNode = data.getElementsByTagName("svg")[0]; svg = d3.select('#div-id').append("svg") .attr("width", svgNode.getAttribute("width")) .attr("height", svgNode.getAttribute("height")) .attr("id", svgNode.getAttribute("id")) .attr("class", svgNode.getAttribute("class")) .attr('viewBox', svgNode.getAttribute("viewBox")) .call(zoom); document.getElementById("svg-id").appendChild(data.getElementsByTagName("g")[0]); }); var zoom = d3.zoom().on('zoom', handleZoom); function handleZoom() { d3.select('g') .attr('transform', d3.event.transform); }Esto funcionó para mí, pero bien puede haber una solución mucho más elegante. (Ah, y usé d3v5)