2013-04-18 63 views
2

我正在製作使用d3.js的旭日圖創作工具,並試圖複製this page上的標籤翻轉方式,以便它們永遠不會顛倒。問題是我將使用rotatetransform屬性,但這已經用於定位標籤。這是目前我的代碼:如何旋轉我的文本標籤,使其不能顛倒(SVG)?

svg.selectAll("text") 
    .data(partition.nodes) 
    .enter() 
    .append("text") 
    .attr("transform", function(d) { return "rotate(" + ((d.x + d.dx/2 - Math.PI/2)/Math.PI * 180) + ")"; }) 
    .attr("x", function(d) { return Math.sqrt(d.y); }) 
    .attr("dx", "6") // margin 
    .attr("dy", ".35em") // vertical-align 
    .text(function(d) { return d.name;}); 

我發現tspanrotate屬性,但是這竟然是一個紅色的鯡魚,因爲它旋轉的單個字母。我的基礎是this page

在此先感謝!

回答

2

一種選擇是將文本嵌套到組中。除了使用「x」屬性之外,該組將大部分定位爲您正在定位文本,除了現有的rotate指令之外,您還可以使用transform屬性和translate。請注意,轉換的順序很重要。你需要先旋轉然後翻譯。

然後,您將本地轉換應用到組內的文本。即如果需要翻轉,它會旋轉180度。通過這種方式,文本不需要移動到位置 - 小組負責處理 - 但是在翻轉時它可能需要進行小的局部調整(在此情況下,ir可能必須正確對齊) )。

下面的代碼應該或多或少地去做,儘管我不可能在沒有工作的jsFiddle的情況下測試和調整它。

svg.selectAll("g.label") 
    .data(partition.nodes) 
    .enter() 
    .append("g") 
    .attr("class", "label") 
    .attr("transform", function(d) { 
    // First, rotate the group (not the text) and then translate it 
    // by the same amount that used to be applied via "x" attr 
    return 
     "rotate(" + ((d.x + d.dx/2 - Math.PI/2)/Math.PI * 180) + ") " + 
     "translate(" + Math.sqrt(d.y) + ")"; 
    }) 
    .each(function(d, i) { 
    d3.select(this) // select the containing group (which was just created above) 
     .append('text') // append text inside the group 
     .attr("dx", "6") // margin 
     .attr("dy", ".35em") // vertical-align 
     .attr("transform", function(d) { 
     // Locally transform the text within the containing group: 
     // Label should be flipped if group's rotation is greater than Math.PI (aka 180 degs) 
     var shouldBeFlipped = d.x + d.dx/2 - Math.PI/2 > Math.PI; 
     return "rotate(" + (shouldBeFlippled ? 180 : 0) + ")" 
     }) 
     .text(function(d) { return d.name;}); 
    });