简体   繁体   English

如何在D3圆包中匹配文本宽度与圆圈大小

[英]How to match text width to circle size in D3 circle pack

Using D3 I display a bunch of circles in different sizes, each filled with text. 使用D3我会显示一堆不同大小的圆圈,每个圆圈都填充文字。 I'm stuck with finding the correct font size so that the text fits correct in the circle, depending of it's size and the length of the text. 我坚持找到正确的字体大小,以便文本在圆圈中适合,取决于它的大小和文本的长度。 Long text should possibly be broken up in more lines. 长篇文章可能会分成更多行。 Here is my code: 这是我的代码:

var data = {
    "name": "",
    "children": [
        { "name": "This is a tag", "value": 242 },
        { "name": "Circle", "value": 162 },
        { "name": "Tree", "value": 80 },
        { "name": "My sentence is very long and needs breaks", "value": 80 },
    ]
}

var diameter = 300,
    format = d3.format(",d");

var bubble = d3.layout.pack()
    .sort(null)
    .size([diameter, diameter])
    .padding(1.5);

var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter)
    .attr("class", "bubble");

d3.json(data, function(error, root) {
  var node = svg.selectAll(".node")
      .data(bubble.nodes(data)
      .filter(function(d) { return !d.children; }))
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

  node.append("circle")
      .attr("r", function(d) { return d.r; })
      .style("fill", function(d) { return '#f88' });

  // text part
  node.append("text")
      .attr("dy", ".3em")
      .style("text-anchor", "middle")
      .style("font-size", function(d) { return Math.round(d.r/3)+'px'; })
      .text(function(d) { return d.name.substring(0, d.r / 3); });
});

d3.select(self.frameElement).style("height", diameter + "px");

I have created a fiddle as well on http://jsfiddle.net/L4nMx/ I think I should calculate the width of the text and modify the font size until it matches the circle's size or something like that. 我在http://jsfiddle.net/L4nMx/上创建了一个小提琴。我想我应该计算文本的宽度并修改字体大小,直到它匹配圆圈的大小或类似的东西。 Or is there any "strech" function to do this the easy way? 或者是否有任何“strech”功能可以轻松实现这一目标?

This solution is fine for me for now. 这个解决方案现在对我来说很好。 It's not accurate maths but fits anyway. 这不是准确的数学,但无论如何都适合。

See it in action on http://jsfiddle.net/L4nMx/3/ http://jsfiddle.net/L4nMx/3/上查看它的实际操作

  .style("font-size", function(d) {
      var len = d.name.substring(0, d.r / 3).length;
      var size = d.r/3;
      size *= 10 / len;
      size += 1;
      return Math.round(size)+'px';
  })
  .text(function(d) {
      var text = d.name.substring(0, d.r / 3);
      return text;
  });

Next step would be to break long text into multiple lines so you could enlarge font sizes in such cases but I didn't manage to solve this. 下一步是将长文本分成多行,这样你就可以在这种情况下扩大字体大小,但我没有设法解决这个问题。 It's not easy in SVG because simple line breaks are not possible. 在SVG中这并不容易,因为简单的换行是不可能的。 Maybe the wrapping solutions from the comments in the question can be added here - somehow... 也许这里可以添加问题评论中的包装解决方案 - 不知何故......

There is this bl.ocks https://bl.ocks.org/mbostock/1846692 有这个bl.ocks https://bl.ocks.org/mbostock/1846692

which is basically 这基本上是

 node.append("circle")
      .attr("r", function(d) { return d.r; });

  node.append("text")
      .text(function(d) { return d.name; })
      .style("font-size", function(d) { return Math.min(2 * d.r, (2 * d.r - 8) / this.getComputedTextLength() * 24) + "px"; })
      .attr("dy", ".35em");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM