I want to append a text that can have X number of inline images to an SVG.
The idea is that the text would be interpolated from Test [img1] the total [img2] to Test <img src="img1.png" /> the total <img src="img2.png" />. The interpolation function is already working as intended.
After interpolating the text, I want it to append to the parent SVG properly.
Currently, I have:
// 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');
}
Which appends:
Test [object HTMLImageElement] the total [object HTMLImageElement]
to my parent SVG.
Any way to display the images properly rather than the [object HTMLImageElement] tag?
Edit:
I have thought about having parseDesc return a canvas, however, the Canvas element has the same problem.. Returning [object HTMLImageElement] in place of the image. The code I would be using for a canvas append, if that is easier to append, would be:
// 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();
}
This method, however, feels a LOT more hacky.
Because you are appending as text it is converting html element to string. What you could do is append a foreignObject and use .html, this should append the value returned from parseDesc as html and hence show the image properly.
nodeEnter.append("foreignObject")
.html(d => parseDesc(d))
.attr("y", 131)
.attr("x", 7);
Here is a minimal fiddle showing it working where text and image are showing together in the same line inside a d3 svg.