2014-01-25 31 views
3

我正在試圖用可縮放的旭日圖來形象化大型數據庫。在我的json的較低層次上,我的孩子太多了,因此文本標籤在外邊緣非常混亂且不可讀。在D3可縮放的旭日形狀中,如何根據縮放級別製作標籤?

我可以根據它們的絕對深度級別打開或關閉標籤,但這意味着即使在縮放時也不會顯示這些標籤。

我的問題是,我如何計算特定縮放級別的「相對」深度,然後根據該深度顯示標籤?

據我所知,d.depth只表示絕對水平。

+0

你是什麼意思「相對深度」? –

+0

假設有5個級別。在基本視圖中,顯示所有5個級別。在這個視圖中,我只想要1,2,3級顯示全文,4,5級顯示縮略或不顯示文本。然後,在放大一級時,我們顯示2,3,4,5級。這一次,我想要2,3,4等級被完全標記,而等級5被縮寫。所以在任何縮放時,我都希望最低的3個顯示的級別具有全文,其餘的縮寫。 – user2991908

+0

如果標籤有足夠的空間可能會更好 - 請參閱http://stackoverflow.com/questions/19792552/d3-put-arc-labels-in-a-pie-chart-if-there-是 - 足夠的空間 –

回答

4

我假設你從Jason Davies的example工作。

從他的劇本的相關代碼

function click(d) { 
    path.transition() 
     .duration(duration) 
     .attrTween("d", arcTween(d)); 

    // Somewhat of a hack as we rely on arcTween updating the scales. 
    text.style("visibility", function(e) { 
      return isParentOf(d, e) ? null : d3.select(this).style("visibility"); 
     }) 
     .transition() 
     .duration(duration) 
     .attrTween("text-anchor", function(d) { 
      return function() { 
      return x(d.x + d.dx/2) > Math.PI ? "end" : "start"; 
      }; 
     }) 
     .attrTween("transform", function(d) { 
      var multiline = (d.name || "").split(" ").length > 1; 
      return function() { 
      var angle = x(d.x + d.dx/2) * 180/Math.PI - 90, 
       rotate = angle + (multiline ? -.5 : 0); 
      return "rotate(" + rotate + ")translate(" 
        + (y(d.y) + padding) + ")rotate(" 
        + (angle > 90 ? -180 : 0) + ")"; 
      }; 
     }) 
     .style("fill-opacity", function(e) { 
       return isParentOf(d, e) ? 1 : 1e-6; 
     }) 
     .each("end", function(e) { 
      d3.select(this).style("visibility", 
        isParentOf(d, e) ? null : "hidden"); 
     }); 
    } 

注意其中的一些功能如何引用兩個不同的數據對象,d VS e。這是因爲,除非它被內部函數掩蓋,否則點擊函數內的d是單擊元素的數據對象 - 即成爲圓圈中心的數據對象。

如果他爲數據對象(function(e){})指定了內部函數的不同名稱,那麼這是與具有屬性更改的單個元素關聯的數據對象。因此,他可以調用比較兩個數據對象的函數,以確定給定元素是否應該隱藏或不在該縮放級別。

你想要做同樣的事情,除了你不僅隱藏文字,如果它是中心輪的父母,如果它是一個後代太深,你也隱藏它。所以,你想是這樣的:

  if (e.depth > d.depth + 3) return "hidden"; 

如果您添加的代碼取決於款式選擇,賈森 - 戴維斯實際上是改變文本的不透明度或能見度三點:可見性設置之前和過渡之後(「結束時「事件),不透明度在兩者之間消失。您是否希望您的標籤能夠點擊進出,還是希望它們能夠淡入淡出?

+0

此解決方案工作。謝謝! – user2991908

+0

很高興聽到它。請將其標記爲「已接受」,以免再次顯示在「未回答的問題」列表中。 – AmeliaBR

+0

我有一個後續問題 - 如果基於相同的條件,我想改變文本本身,而不僅僅是可見性,我仍然可以這樣做嗎?例如,如果我想最初只在外部輪輻上顯示一個單詞,但是一旦我們放大,我想要顯示更多.. – user2991908

1

我還不能評論,所以如果你在他的身邊尋找戴維斯的代碼並找到對此答案毫無幫助的縮小版本,可能會發現這裏有幫助 - 完整版本移到此處:https://code.google.com/p/testprogramming/source/browse/trunk/javascript/svg/d3/test/wheel.js?r=394&spec=svn394

所有重要的功能isParentOf從上面的答案中缺少,必須從完整版本中收集。

- 附加信息: 如果您希望基於「縮放」級別顯示標籤,則需要注意的是,sunburst不使用.zoom()函數,您必須找到手動路徑。就我而言,我想將所有標籤隱藏在最高縮放級別,但是如果選擇了其他級別,則會顯示它們。爲了達到這個目的,我在開頭隱藏文字,然後每次點擊我使用以下測試

var text = g.append("text") 
    .attr("class","mylabel") 
    .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; }) 
    .attr("x", function(d) { return y(d.y); }) 
    .attr("dx", "4") // left - margin for text 
    .attr("dy", ".25em") // vertical-align of text in cell 
    .text(function(d) { return (d.name == 'root') ? ('') : d.name; }) 
    .attr("font-size", function(d) { return d.ci_type === 'type' ? 12 : 10}) //font-size of text 
    //.attr("visibility",function(d) { return d.dx < 0.009? "hidden" : "visible"}) // hide text of labels of partitions less than 2% 
    .attr("visibility", "hidden") // hide labels at root level - starting level 


    function click(d) { 
    // fade out all text elements 
    text.transition().attr("opacity", 0); 
    path.transition() 
    .duration(750) 
    .attrTween("d", arcTween(d)) 
    .each("end", function(e, i) { 
     // check if the animated element's data e lies within the visible angle span given in d 
     if (e.x >= d.x && e.x < (d.x + d.dx)) { 
     // get a selection of the associated text element 
     var arcText = d3.select(this.parentNode).select("text"); 
     // fade in the text element and recalculate positions 
     arcText.transition().duration(750) 
      .attr("opacity", 1) 
      .attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" }) 
      .attr("x", function(d) { return y(d.y); }) 

     } 
    }); 


    // if the vis is at the 'root' level hide text, otherwise show <! here is the test! 
    var str = d.name; 
    var patt = 'root'; 
    var atRoot = (str === patt) ? true : false ; 

    //console.log(atRoot); 

    //console.log(d.name) ; 

    text.attr("visibility",function(d) { return atRoot ? "hidden" : "visible"}) 


    // end of click  
    }