HTML-элемент внутри SVG не отображается [дубликат]

этот вопрос уже есть ответ здесь:

Я борюсь с foreignObject в SVG. Я хочу добавить текст внутри 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}
];

я добавляю карту для каждого datum и хочу отобразить "оператор" из данных.

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; });

выход карты таков:

<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>

Я не вижу текст в (mac) браузерах, которые я тестировал (Safari 6.0.2, Chrome 25.0.1364.99, Firefox 18.0.2). В3-х валидатор не нравится вывод, и дайте мне эту ошибку для каждого карточка:

элемент foreignObject не разрешен как дочерний элемент элемента g в этом контексте.

Итак, мой вопрос в том, где проблема, и почему foreignObject не разрешен как ребенок g элемент?

мне также интересно, почему .html(function(d) { return d.statement; }); не работает (нет выхода). Но!--8--> нормально работает?

здесь скрипка.

2 ответов


короткий ответ:

укажите пространство имен во всех тегах в foreignObject: replace .append("p") by .append("xhtml:p") и это будет работать:http://jsfiddle.net/EHzcR/2/


ответ

в контексте посторонних предметов, <p></p> не признан xhtml абзац. Почему? Просто потому, что пространство имен xhtml - это не входит в foreignObject контекст (a foreignObject может содержать что угодно (xml сформированные данные, например) так он не рассматривает ввод как html, если вы явно не говорите об этом.).

так p тег рассматривается как пользовательский тег, а не как xhtml - тег. Таким образом, поскольку веб-браузер не распознает тег p в тегах, которые он знает, поэтому он просто не интерпретирует его и его содержимое, даже если оно существует, оно не будет выдавать ошибку, потому что это содержимое может быть полностью действительным, просто не для его прямого использования.

интересно видеть, что вы всегда указываете пространство имен svg даже если это не нужно и как мы все забываем, что p, div... также очень популярных имен.

на selection.html() функция не работает, потому что в его реализация использует .innerHTML() функция элемента, но здесь foreignObject, не являющийся html-элементом, не имеет такой функции.


Я не могу сказать по вашему вопросу, действительно ли вы можете просматривать текст в foreignObjects? (И если ваш ответ "да", то какой браузер вы используете?).

Я с нетерпением жду других ответов здесь, потому что метод ниже не кажется мне оптимальным, но он получает большую часть пути.

использование Chrome и попытка создать <body xmlns="http://www.w3.org/1999/xhtml"> тег внутри foreignObject в соответствии с пример W3C, а потом <p> внутри <body>, оставил текст не видимым для меня. Но тогда просто выходите из внутреннего <body> out и добавление класса в стиль foreignObject привели к желаемому результату.

http://jsfiddle.net/6B4zs/5/

обновлены разделы код ниже:

раздел D3 для добавления текста foreignObject

svg.selectAll("foreignObject")
    .data(cds)
    .enter()
  .append("foreignObject")
    .attr("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility")
    .attr('width', cardsize.width)
    .attr('height', cardsize.height)
    .attr("x", 10)
    .attr("y", function (d, i) { return 10 + i * (10 + cardsize.height) })
    .attr("class", "fo-text")
    .text(function (d) { return d.statement; });

в CSS

.fo-text {
    padding: 5px 10px;  
    font: 300 14px "Helvetica Neue", sans-serif;
    color: #000;
}