我想将一个可以有X个内联图像的文本附加到SVG中。
其思想是将文本从Test [img1] the total [img2]
插值到Test <img src="img1.png" /> the total <img src="img2.png" />
。插值函数已按预期工作。
插入文本后,我希望它能正确地附加到父SVG中。
目前,我有:
// 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');
}
附加:
Test [object HTMLImageElement] the total [object HTMLImageElement]
到我的父SVG。
有什么方法可以正确显示图像而不是[object HTMLImageElement]标记吗?
编辑:我曾想过让parseDesc返回一个画布,然而,canvas元素也有同样的问题。。返回[object HTMLImageElement]
以代替图像。如果画布附加更容易,我将使用的代码是:
// 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();
}
然而,这种方法给人的感觉要粗糙得多。
因为您以文本形式追加,所以它将html元素转换为字符串。您可以附加一个foreignObject并使用.html
,这应该将parseDesc
返回的值附加为html,从而正确显示图像。
nodeEnter.append("foreignObject")
.html(d => parseDesc(d))
.attr("y", 131)
.attr("x", 7);
这里有一个最小的小提琴显示它的工作,文本和图像一起显示在d3 svg内的同一行。