Выравнивание по центру двух текстовых элементов без перекрытия в прямоугольнике

#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> элемента, если хотите сохранить вертикальное центрирование. . Похоже, он пропал из его демонстрационного фрагмента, поэтому я вернул его обратно.