Quiero agregar un texto que pueda tener una cantidad X de imágenes en línea a un SVG.
La idea es que el texto se interpole de Test [img1] the total [img2]
a Test <img src="img1.png" /> the total <img src="img2.png" />
. La función de interpolación ya está funcionando según lo previsto.
Después de interpolar el texto, quiero que se agregue correctamente al SVG principal.
Actualmente, tengo:
// Desc nodeEnter.append("text") .text(d => parseDesc(d)) .attr("y", 131) .attr("x", 7); ... function parseDesc(d) { const interpolate = (string, values) => string.replace(/\[([^\]]*)\]/g, (match, offset) => { ... }); ... return interpolate(d.data.description, replacements).replaceAll("\\n","<br/>").split('\n'); }
que anexa:
Test [object HTMLImageElement] the total [object HTMLImageElement]
a mi padre SVG.
¿Alguna forma de mostrar las imágenes correctamente en lugar de la etiqueta [object HTMLImageElement]?
Editar: He pensado en hacer que parseDesc devuelva un lienzo, sin embargo, el elemento Canvas tiene el mismo problema. Devolver [object HTMLImageElement]
en lugar de la imagen. El código que usaría para agregar un lienzo, si es más fácil de agregar, sería:
// Desc nodeEnter.append("svg:image") .attr("xlink:href", d => parseDesc(d)) .attr("y", 131) .attr("x", 7); ... function parseDesc(d) { const interpolate = (string, values) => string.replace(/\[([^\]]*)\]/g, (match, offset) => { ... }); ... var canvas = document.createElement("canvas"); canvas.width = 115; canvas.height = 65; var ctx = canvas.getContext('2d'); ctx.font = "bolder 9.4pt"; const x = 10; const y = 10; const lineheight = 1.6; const lines = interpolate(d.data.description, replacements).replaceAll("\\n","<br/>").split('\n'); for (var i = 0; i<lines.length; i++) ctx.fillText(lines[i], x, y + (i * lineheight)); return canvas.toDataURL(); }
Este método, sin embargo, se siente MUCHO más complicado.
Debido a que está agregando como texto, está convirtiendo el elemento html en una cadena. Lo que podría hacer es agregar un objeto extranjero y usar .html
, esto debería agregar el valor devuelto por parseDesc
como html y, por lo tanto, mostrar la imagen correctamente.
nodeEnter.append("foreignObject") .html(d => parseDesc(d)) .attr("y", 131) .attr("x", 7);
Aquí hay un violín mínimo que muestra que funciona donde el texto y la imagen se muestran juntos en la misma línea dentro de un d3 svg.