Использование d3 для создания прямоугольника, который соответствует размеру текста

1

Lars Kotthof имеет хорошее объяснение здесь о том, как создавать SVG элементы, которые соответствуют размеру текста. Тем не менее, я хочу сделать это динамически с данными, вытащенными из JSON или CSV.

JS Fiddle здесь.

    svg.selectAll('rect')
       .data(states.features)
       .enter()
       .append('rect')
          .attrs({
            x: function(d) { return path.centroid(d)[0] - 50; },
            y: function(d) { return path.centroid(d)[1] - 13; },
            'text-anchor': 'middle',
            'width': 100,
            'height': 18,
            'fill': 'rgba(232, 232, 232, 0.8)',
            'opacity': 1,
            'rx': 7,
            'ry': 7
         }); 

    svg.selectAll('text')
       .data(states.features)
       .enter()
       .append('text')
          .text(function(d) { return d.properties.name; })
          .attrs({
            x: function(d) { return path.centroid(d)[0]; },
            y: function(d) { return path.centroid(d)[1]; },
            'text-anchor': 'middle',
            'font-size': '7pt',
            'fill': 'rgb(25,25,25)',
            'opacity': 1
         });   

Я не понимаю, как я могу написать функцию, похожую на Lars, которая создает как <rect> и <text> и использует размеры текста для определения размеров прямоугольника.

  • 0
    Зачем беспокоиться об этом? Почему бы не сделать это таким образом? stackoverflow.com/a/31013492/1038015 измерение не требуется.
  • 0
    Это хорошая идея, но атрибут filter похоже, вызывает проблемы с сглаживанием.
Показать ещё 1 комментарий
Теги:
d3.js
svg
text
rect

1 ответ

2
Лучший ответ

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

svg.selectAll('rect')
   .data(states.features)
   .enter()
   .append('rect')
      .attrs({
        y: function(d) { return path.centroid(d)[1] - 13; },
        'text-anchor': 'middle',
        'width': 100,
        'height': 18,
        'fill': 'rgba(232, 232, 232, 0.8)',
        'opacity': 1,
        'rx': 7,
        'ry': 7
     }); 

svg.selectAll('text')
   .data(states.features)
   .enter()
   .append('text')
      .text(function(d) { return d.properties.name; })
      .attrs({
        x: function(d) { return path.centroid(d)[0]; },
        y: function(d) { return path.centroid(d)[1]; },
        'text-anchor': 'middle',
        'font-size': '7pt',
        'fill': 'rgb(25,25,25)',
        'opacity': 1,
        id: function(d) { return 'text' + d.id }
     });   

svg.selectAll('rect')
    .attr('width', function(d) { return document.getElementById('text'+d.id).getBBox().width; })
    .attr('x', function(d) { return path.centroid(d)[0] - document.getElementById('text'+d.id).getBBox().width / 2; });
  • 0
    Спасибо! Это хорошее решение моего вопроса, так как с filter я получил проблемы сглаживания. Мне любопытно, какое влияние это оказывает на время загрузки, но этот метод поможет мне в решении новых проблем.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню