#d3.js #svg
#d3.js #svg
Вопрос:
Итак, у нас есть два текстовых элемента в прямоугольнике. Первый текстовый элемент представляет собой значок шрифта, похожий на круг, второй — текст. Теперь мы хотим выровнять это по ЦЕНТРУ прямоугольника так, чтобы сначала был круг, а затем текст (например, точка маркера). Однако как нам это сделать в этом случае
percentageEntering
.append('svg:rect')
.style('fill', '#F3F3F4')
.attr('width', width)
.attr('height', height);
percentageEntering
.append('svg:text')
.attr('x', width / 2)
.attr('y', height / 2)
.attr('dy', '0.35em')
.attr('text-anchor', 'middle')
.attr('font-family', 'Material Icons')
.style('font-size', '20px')
.style('fill', d => this.subBreadcrumbPercentageColors[d.depth])
.text('some_icon');
percentageEntering
.append('svg:text')
.attr('x', width / 2)
.attr('y', height / 2)
.attr('dy', '0.35em')
.attr('text-anchor', 'middle')
.style('font-size', d => {
const size = ((legendData.length - 2) > 0)
? 12 - (legendData.length - 2)
: 12;
return `${size}px`;
})
.text(d => {
return d.quantity ' - ' d.name ((nodeArray.length === 3) ? ' %' : '');
});
Редактировать
После изменений, предложенных @Gerardo, выводится следующее. Итак, сначала мне пришлось добавить
.style('font-family', "'open sans'")
Чтобы в тексте не использовались шрифты значков, также в дополнение к этому (например: — some_icon
представляет значок). Итак, как я могу убедиться, что эти стили не будут перенесены на дочерний элемент? И заметил, что текст не находится по центру по вертикали, для чего, когда я добавляю y
параметр, значок и текст перекрываются.
Ответ №1:
Наиболее простым решением для вашего случая является добавление второго <text>
элемента как <tspan>
. Вот так:
percentageEntering
.append('text')
.attr('x', width / 2)
.attr('y', height / 2)
.attr('dy', '0.35em')
.attr('text-anchor', 'middle')
.attr('font-family', 'Material Icons')
.style('font-size', '20px')
.style('fill', d => this.subBreadcrumbPercentageColors[d.depth])
.text('some_icon')
.append('tspan')
.style('font-size', d => {
const size = ((legendData.length - 2) > 0) ? 12 - (legendData.length - 2) : 12;
return `${size}px`;
})
.text(d => {
return d.quantity ' - ' d.name ((nodeArray.length === 3) ? ' %' : '');
});
Поскольку вы применили text-anchor
к родительскому тексту, все (то есть <text>
элемент и его <tspan>
дочерний элемент) должны располагаться по центру.
Вот демонстрация:
const x = 50,
y = 20,
width = 150,
height = 50;
const svg = d3.select("svg")
const rect = svg.append("rect")
.attr("x", x)
.attr("y", y)
.attr("width", width)
.attr("height", height)
.style("fill", "wheat")
.style("border", "gray");
const text = svg.append("text")
.attr('x', x width / 2)
.attr('y', y height / 2)
.attr('dy', '0.35em')
.attr('text-anchor', 'middle')
.attr('font-family', 'Material Icons')
.style('font-size', '20px')
.style('fill', "red")
.text('u25CF')
.append('tspan')
.style('fill', "darkslategray")
.text(" foo bar baz");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
Комментарии:
1. Не могли бы вы взглянуть на редактирование, которое я опубликовал в основном вопросе, касающемся после применения предложенных вами изменений, которые действительно сработали, но привели к некоторым другим проблемам, требующим решения.
2. @MilindaD Вы должны установить новое семейство шрифтов для элемента tspan, а также удалить атрибут dy.
3. Хорошо, теперь вопрос в том, как мне центрировать элемент по вертикали без добавления
dy
атрибута.4. @MilindaD Я не понимаю: вам просто нужно удалить
dy
атрибут из элемента tspan, он будет находиться в том же вертикальном положении, что и родительский текст.5. Я думаю, возможно, Херардо имел в виду удалить
dy
из элемента, который теперь является<tspan>
. Вы не захотите удалять его из основного<text>
элемента, если хотите сохранить вертикальное центрирование. . Похоже, он пропал из его демонстрационного фрагмента, поэтому я вернул его обратно.