2017-09-15 26 views
1

Lars Kotthof对如何创建对应于文本大小的SVG元素有一个很好的解释here。不过,我正在使用从JSON或CSV中提取的数据动态地执行此操作。使用d3生成符合文本大小的矩形

JS Fiddle here

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

我不抓这个概念是我怎么可以编写一个函数,类似于拉斯的,创建两个<rect><text>并使用文本的尺寸来确定矩形的尺寸。

+0

为什么要这样呢?为什么不这样做? https://stackoverflow.com/a/31013492/1038015无需测量。 –

+0

这是一个好主意,但'filter'属性似乎会导致反锯齿问题。 –

+0

我想还有另一个答案,你可以尝试在同样的问题,如果你得到反锯齿问题。 –

回答

2

这是一个解决方案和相关JS Fiddle。基本上我为每个矩形和文本分配了相应的ID,然后在生成文本之后,根据文本调整了矩形大小。此外,文本的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'解决方案一样,我得到了反锯齿问题。我很好奇这会对加载时间产生什么样的影响,但这种方法对于我解决新问题会有帮助。 –