2014-01-25 28 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  
    }