d3 Масштабируемая древовидная карта - динамическая ширина текста на родительскую ширину - PullRequest
2 голосов
/ 07 марта 2019

Я использую шаблон древовидной карты, найденный здесь .

В его нынешнем виде я немного изменил код, чтобы я мог показывать больше информации, а такжевключите перенос текста для описаний, которые работают долго.При этом я заменил следующие теги ptext и tspan на foreignObject и xhtml:div, показанные ниже:

Заменили

var t = g.append("text")
    .attr("class", "ptext")
    .attr("dy", ".75em")

t.append("tspan")
    .text(function(d) { return d.key; });
t.append("tspan")
    .attr("dy", "1.0em")
    .text(function(d) { return formatNumber(d.value); });
t.call(text);

на

var t = g.append("foreignObject")
    .attr("class", "foreignobj");

t.append("xhtml:div")
    .html(function (d) {
        if (d.status != null) return "<p>Name: " + d.key + "</p>";
        else return d.key;
    })
    .attr("class", "textdiv");

t.append("xhtml:div")
    .html(function (d) {
        if (d.status != null) return "<p>Status: " + d.status + "</p>";
        else return "";
    })
    .attr("class", "textdiv");

t.append("xhtml:div")
    .html(function (d) {
        if (d.description != null) return "<p>Description: " + d.description + "</p>";
        else return "";
    })
    .attr("class", "textdiv");

Таким образом, теперь текст можно переносить, однако ширина foreignObject не равна ширине родительского элемента, поэтому текстовая область мала и перекрывается с другими <rect> областями, если имя /статус / описание достаточно длинное и текст переносится.

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

var t = g.append("foreignObject")
                .attr("class", "foreignobj")
                .attr("width", $(this).parent().attr("width"));

Я также попытался найти ближайший тег <rect> и извлечь из него ширину, получить externalWidth и несколько других попыток.безрезультатно.

Мне интересно, как ширину foreignObject можно установить равной ширине родительского элемента, чтобы текст переносился только по краю поля?

1 Ответ

0 голосов
/ 02 апреля 2019

Мне удалось выяснить это, изменив следующий код в функции text() в нижней части скрипта:

function text(text) {
    text.selectAll("foreignobj")
        .attr("x", function(d) { return x(d.x) + 6; });
    text.attr("x", function(d) { return x(d.x) + 6; })
        .attr("y", function(d) { return y(d.y) + 6; })
        // Added the following line
        .attr("width", function(d) { return x(d.x + d.dx) - x(d.x) - 6; });
}
...