How to match text width to circle in circle D3

Using D3, I show a bunch of circles of different sizes, each of which is filled with text. I'm stuck in finding the right font size so that the text matches the correct one in a circle, depending on its size and the length of the text. Long text should be divided into several 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(" + dx + "," + dy + ")"; }); node.append("circle") .attr("r", function(d) { return dr; }) .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(dr/3)+'px'; }) .text(function(d) { return d.name.substring(0, dr / 3); }); }); d3.select(self.frameElement).style("height", diameter + "px"); 

I also created a fiddle at http://jsfiddle.net/L4nMx/ I think I should calculate the width of the text and change the font size until it matches the size of the circle or something like that. Or is there a stretch function to do this in a simple way?

+6
source share
2 answers

This solution is excellent for me now. This is not exact math, but it is suitable anyway.

Take a look at the action http://jsfiddle.net/L4nMx/3/

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

The next step is to break the long text into several lines so that you can increase the font size in such cases, but I could not solve it. This is not easy in SVG because simple line breaks are not possible. Maybe the wrapping solutions from the comments in the question can be added here - somehow ...

+6
source

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

which is basically

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

Source: https://habr.com/ru/post/969574/


All Articles