2015-07-10 99 views
1

我繼承了一些泡泡圖代碼,我需要添加泡沫圖表標籤的文字換行。d3.js如何申請文字換行

如何在這裏應用此處的答案How to linebreak an svg text within javascript??我不明白如何讓d3更改解決方案中給出的svg標記。

這裏是我的代碼:

  function renderBubbles(root) { 
       var diameter = element[0].offsetWidth * .6, 
        format = d3.format(",d"), 
        color = d3.scale.category20c(); 

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

       var svg = d3.select(element[0]).append("svg") 
        .attr("width", diameter) 
        .attr("height", diameter) 
        .attr("class", "bubble"); 


       var node = svg.selectAll(".node") 
        .data(bubble.nodes(classes(root)) 
         .filter(function (d) { 
          return !d.children; 
         })) 
        .enter().append("g") 
        .attr("class", "node") 
        .attr("transform", function (d) { 
         return "translate(" + d.x + "," + d.y + ")"; 
        }) 
        .on('mouseover', function (d) { 
         var nodeSelection = d3.select(this).style({opacity: '0.5'}); 
        }) 
        .on('mouseout', function (d) { 
         var nodeSelection = d3.select(this).style({opacity: '1'}); 
        }) 
        .on("click", function (d) { 
         $log.debug(d); 
        }) 


       node.append("title") 
        .text(function (d) { 
         return d.className + ": " + format(d.value); 
        }); 

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


       node.append("text") 
        .attr("dy", ".3em") 
        .style("text-anchor", "middle") 
        .text(function (d) { 
         return d.className.substring(0, d.r/3); 
        }); 

// Returns a flattened hierarchy containing all leaf nodes under the root. 
       function classes(root) { 
        var classes = []; 

        function recurse(name, node) { 
         if (node.children) node.children.forEach(function (child) { 
          recurse(node.name, child); 
         }); 
         else classes.push({packageName: name, className: node.name, value: node.size}); 
        } 

        recurse(null, root); 
        return {children: classes}; 
       } 


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

這裏給出的解決方案:

<g transform="translate(123 456)"><!-- replace with your target upper left corner coordinates --> 
    <text x="0" y="0"> 
    <tspan x="0" dy="1.2em">very long text</tspan> 
    <tspan x="0" dy="1.2em">I would like to linebreak</tspan> 
    </text> 
</g> 
+2

這是應用包裝的[d3示例](http://bl.ocks.org/mbostock/7555321)。 – Mark

+0

我沒有遵循這一點,但我會努力在w/e上升級我的d3知識,以便我能夠弄明白。 :) 謝謝! – metalaureate

回答

0

給這一個嘗試。這是拉斯的解決方案,它不是我自己的。但它在我的項目中效果很好:

... 
yoursvg.append("text") 
        .attr('x', function(d){ 
         return path.centroid(d)[0]; 
        }) 
        .attr('y', function(d){ 
         return path.centroid(d)[1] + 4; 
        }) 
        .each(function (d) { 
         var arr = d.properties.eventname.split(" "); 
         if (arr != undefined) { 
          for (var i = 0; i < arr.length; i++) { 
           d3.select(this).append("tspan") 
            .text(function(){ 
             return arr[i]; 
            ) 
            .attr("y", path.centroid(d)[1] + i*8 + 8) 
            .attr("x", path.centroid(d)[0]) 
            .attr("text-anchor", "middle"); 
          } 
         } 
        }); 
+0

欣賞幫助。 'path'是未定義的,在最內部的.text函數中有一些搞砸的語法(無法訪問的代碼)。 – metalaureate

+1

確實的路徑不適合你,因爲你似乎沒有使用地圖。因爲你不分享小提琴,所以很難直接幫助你。只需用你自己的抽象來替換x和y。 – kwoxer

0

@Mark謝謝。

node.append("text") 
.attr("dy", ".3em") 
.style("text-anchor", "middle") 
.text(function (d) { 
    return d.className.substring(0, d.r/2); 
}).call(wrap,0) 

function wrap(text, width) { 
     text.each(function() { 
      var text = d3.select(this), 
       words = text.text().split(/\s+/).reverse(), 
       word, 
       line = [], 
       lineNumber = 0, 
       lineHeight = 1, // ems 
       y = text.attr("y")-((words.length+1)*4), 
       dy = parseFloat(text.attr("dy")), 
       tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); 
      while (word = words.pop()) { 
       line.push(word); 
       tspan.text(line.join(" ")); 
       if (tspan.node().getComputedTextLength() > width) { 
        line.pop(); 
        tspan.text(line.join(" ")); 
        line = [word]; 
        tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); 
       } 
      } 
     }); 
    }