Search code examples
javascriptnode.jsd3.js

D3.js setup node text font-size base on how many node text there


I do have one parent node, it has 10 children, in the further, it may have 50 or more... So I want the text node font size to change to smaller dynamically according to the node length.

  XXX.append('text')
        .attr('x', d => d.x)
        .attr('y', d => d.y)
        .attr('text-anchor', 'middle')
        .attr('font-size', "1em");

Currently all 1em, so when more nodes, it looks not good...


Solution

  • You can do something like this (see it working in a viz):

    const items = root.descendants();
        const delta = Math.abs(items[1].x - items[2].x) - 8;
        console.log({delta});
      
        g.selectAll('text').data(items)
          .enter().append('g')
          .attr("transform", (d) => "translate("+ (d.x) +","+ (d.y) +")")
          .append('text')
          .attr('text-anchor', 'middle')
          .text(d => d.data.name)
          .each(function(d) {
            const text = select(this);
            let fontSize = 0;
            let width = 0;
            while(width < delta) {
              fontSize++;
              text.attr('font-size', fontSize);
              width = text.node().getBBox().width;
            }
          });