Search code examples
javascriptd3.jspositiontreemap

Adding text to a rectangle


Is it possible to add a piece of text in the centre of multiple rectangles in a D3 treemap chart? So what i'm after is something like this:

enter image description here

As you can see by the picture, I want to have text appear once in the middle of each “section” (different colours) on the chart. Is it possible to do this with D3? If so how would I achieve it.

Currently I've managed to have it appear on each individual rectangle, like so:

 cell.append("svg:text")
      .attr("x", function(d) { return d.dx / 2; })
      .attr("y", function(d) { return d.dy / 2; })
      .attr("dy", ".35em")
      .text("test")
       .style("opacity", function(d) { console.log(this.getComputedTextLength());d.w = this.getComputedTextLength(); return d.dx > d.w ? 1 : 0; });

Full code is here: http://jsfiddle.net/noobiecode/9ev9qjt3/74/

Any help will be appreciated.


Solution

  • For appending these texts, we first need to find the corresponding data. Right now, nodes have data regarding all the different depths (parents and children), but for these texts we only need the data for the second depth (depth == 2).

    So, we first get the data:

    var parents = treemap.nodes(root)
        .filter(function(d) { return d.depth == 2 });
    

    It gives us an array with three objects, so we are in the right way. This array (parents) have all we need to position the texts (x, y, dx, dy, name).

    Then, we bind this data to the texts:

    var parentsText = svg.selectAll(".parentsText")
        .data(parents)
        .enter()
        .append("text");
    

    After that, we append the texts:

    parentsText.attr("text-anchor", "middle")
         .attr("dominant-baseline", "central")
         .attr("x", function(d){ return d.x + d.dx/2})
         .attr("y", function(d){ return d.y + d.dy/2})
         .text(function(d){ return d.name})
         .attr("class", "parentText");
    

    And this is the resulting fiddle: http://jsfiddle.net/gerardofurtado/9ev9qjt3/94/

    You can also have the texts for each individual rectangle and for the group (but, in that case, you may want to move away some overlapping texts): http://jsfiddle.net/gerardofurtado/9ev9qjt3/95/