SVG中的HTML元素未显示

swe*_*edo 9 javascript svg d3.js

我和foreignObjectSVG 一起讨厌.我想在一个内部添加文本rect,并获得自动文本换行我选择使用HTML.foreignObject可以在这里找到描述.

我正在使用D3,这是我的数据:

var cds = [
{"uid":"U12","sid":"16","statement":"Movies","x":10,"y":10},
{"uid":"U20","sid":"17","statement":"Food","x":10,"y":170},
{"uid":"U22","sid":"15","statement":"Sport","x":10,"y":330}
];
Run Code Online (Sandbox Code Playgroud)

我为每个数据添加一张卡片,并希望显示数据中的"语句".

var cardsize = { width : 150, height : 150 };

var svg = d3.select("body").append("svg:svg")
    .attr("width", 170)
    .attr("height", 490);

var card =  svg.selectAll("rect")
    .data(cds)
    .enter().append("svg:g")
    .attr("class", "card")
    .attr("transform", function(d,i) { 
        d.x = 10;
        d.y = 10+i*(10+cardsize.height);
        return "translate(" + d.x + "," + d.y + ")";
    });

card.append("svg:rect")
    .attr('width', cardsize.width)
    .attr('height', cardsize.height)

card.append("svg:foreignObject")
    .attr('width', cardsize.width)
    .attr('height', cardsize.height)
    .append('p')
    .attr("class","statement")
    .text(function(d) { return d.statement; });
Run Code Online (Sandbox Code Playgroud)

卡的输出是这样的:

<g class="card" transform="translate(10,330)">
    <rect width="150" height="150"></rect>
    <foreignObject width="150" height="150"><
        p class="statement">Sport</p>
    </foreignObject>
</g>
Run Code Online (Sandbox Code Playgroud)

我无法在我测试的(mac)浏览器中看到该文本(Safari 6.0.2,Chrome 25.0.1364.99,Firefox 18.0.2).W3的验证器不喜欢输出,并为每张卡给我这个错误:

在此上下文中,元素foreignObject不允许作为元素g的子元素.

所以我的问题是,问题出在哪里,为什么不允许foreignObject作为g元素的子元素?

我也想知道为什么.html(function(d) { return d.statement; });不起作用(没有输出).但.text(function(d) { return d.statement; });工作正常吗?

这是一个小提琴.

Chr*_*che 15

简短的回答

在foreignObject中的所有标记中指定命名空间:替换.append("p").append("xhtml:p"),它将起作用:http://jsfiddle.net/EHzcR/2/


答案很长

在异物的上下文中,<p></p>不被认为是xhtml段落.为什么?仅仅因为命名空间xhtml不包含在foreignObject上下文中(foreignObject可能包含任何内容(xml例如格式化数据),因此如果您没有明确说出它,则不会将输入视为html.).

因此,p标记被视为自定义标记,而不是xhtml标记.因此,由于Web浏览器无法识别p它知道的标签中的标签,因此它只是不解释它及其内容,即使它存在,也不会抛出错误,因为这个内容可能完全是有效,只是不直接使用.

这是有趣的看到你始终指定的命名空间svg,即使是没有必要的,如何我们都忘记了p,div......也有一个非常流行的命名空间.

selection.html()函数不起作用,因为在它的实现中它使用.innerHTML()元素的函数,但是在这里,foreignObject,不是一个html元素,没有这样的函数.