2014-01-21 137 views
4

我想用沿着圆圈本身流动的文本在circle pack layout中标记一些圆圈。沿D3圆圈包装布局中的圆圈的文本

这是一个实验jsfiddle

enter image description here

正如你所看到的,有可能呈现沿圆,在其顶部居中的文本。虽然浏览器渲染弯曲的SVG文本是可怕的。但是,让我们说我们不关心它。

这里是另一个jsfiddle

enter image description here

我想放置在该曲线图中弯曲的标签,在这些条件下:

  • 的圆圈代表一个省(仅深度== 1) (不列颠哥伦比亚省,艾伯塔省,等等)
  • 该省所有儿童(换句话说,分配的议会席位数)的总和大于5
  • 该省的名称应该全部为大写。

你可以在代码本身看到我的一些尝试。我一直在努力几个小时。我的主要问题是圆中的圆现在是X Y空间中的某个位置,而在第一个jsfiddle中,所有圆都有坐标系原点中的中心。

也许你可以通过重新审视一下来帮助我。

基础数据是基于该表:

enter image description here

(注:这是有点关系的问题'Circle packs as nodes of a D3 force layout'我问了一天,然而,这是一个独立的实验)

我决定使用常规SVG弧代替d3.svg.arc()。我仍然认为这是一个正确的决定。然而,这里是我现在有::) jsfiddle

enter image description here

+0

一个快速提示:由于将cx和cy属性分配给var arc,所以抛出异常。如果你评论这两个标签,那么标签会显示在左上角(你提到的协调问题)。这可能是显而易见的,而且你已经从实验中知道了一些,但是想要指出它是一个理智检查。 – FernOfTheAndes

+0

是的,这是一种“发展”的例子,所以这是正常的。 :)我知道所有捆绑在那个角落的文字。这实际上是我的问题 - 如何把它放在正确的地方。感谢您引起我的注意,现在其他人也会知道发生了什么...... :) – VividD

+0

关于attr'startOffset =“”',[docs](http://www.w3.org/) TR/SVG11/text.html#TextPathElement)说:如果给出了除百分比之外的(这是您给出的百分比),那么'startOffset'表示沿当前用户坐标系中测量的路径的距离。在文档之后,然后在[沿着路径的距离](http://www.w3.org/TR/SVG11/paths.html#DistanceAlongAPath)上着陆。目前,这看起来像是textPath元素和指定x,y坐标的可能性之间的唯一连接。这里希望这不是一些兔子线索 – FernOfTheAndes

回答

1

只是更新一些VividD的代码。

对于小于180度的弧线,describeArc函数无法正常工作,并且在函数和调用它时将起始和结束变量翻转过来。

这里是一个更新describeArc函数处理圆弧的所有备选方案,包括小弧和倒弧:

function describeArc(x, y, radius, startAngle, endAngle) { 
    var start = polarToCartesian(x, y, radius, startAngle); 
    var end = polarToCartesian(x, y, radius, endAngle); 
    var arcLength = endAngle - startAngle; 
    if (arcLength < 0) arcLength += 360; 
    var longArc = arcLength >= 180 ? 1 : 0; 
    var d = [ 
    "M", start.x, start.y, 
    "A", radius, radius, 0, longArc, 1, end.x, end.y 
    ].join(" "); 
    return d; 
} 

随着这一变化的功能应该颠倒开始和结束值被称为是更有意义:

describeArc(d.x, d.y, d.r, -160, 160); 
6

注(因为我回答我的问题):如果你们当中有些人已经花了在这个问题上的时间,发现另一种解决办法,请张贴,我会接受你的回答。感谢@FernOfTheAndes参与寻找此解决方案的过程,因为它充满了使用svg弧的痛苦和苦恼。

下面是解的jsfiddle

enter image description here

正如注释提到的,关键部分是产生的电弧作为纯香草SVG圆弧,不经由d3.svg.arc()。

定义弧的SVG规则很清晰,但有点难以管理。这里是an interactive explorer of svg syntax for arcs

function polarToCartesian(centerX, centerY, radius, angleInDegrees) { 
    var angleInRadians = (angleInDegrees-90) * Math.PI/180.0; 
    return { 
     x: centerX + (radius * Math.cos(angleInRadians)), 
     y: centerY + (radius * Math.sin(angleInRadians)) 
    }; 
} 

function describeArc(x, y, radius, startAngle, endAngle){ 
    var start = polarToCartesian(x, y, radius, endAngle); 
    var end = polarToCartesian(x, y, radius, startAngle); 
    var arcSweep = endAngle - startAngle <= 180 ? "0" : "1"; 
    var d = [ 
     "M", start.x, start.y, 
     "A", radius, radius, 0, 1, 1, end.x, end.y 
    ].join(" "); 
    return d;  
} 

这是实际直接生成曲面的标签代码:

而且,这两个功能在确定正确的弧线这个过程让我

var arcPaths = vis.append("g") 
    .style("fill","navy"); 
var labels = arcPaths.append("text") 
    .style("opacity", function(d) { 
     if (d.depth == 0) { 
      return 0.0; 
     } 
     if (!d.children) { 
      return 0.0; 
     } 
     var sumOfChildrenSizes = 0; 
     d.children.forEach(function(child){sumOfChildrenSizes += child.size;}); 
     //alert(sumOfChildrenSizes); 
     if (sumOfChildrenSizes <= 5) { 
      return 0.0; 
     } 
     return 0.8; 
    }) 
    .attr("font-size",10) 
    .style("text-anchor","middle") 
    .append("textPath") 
    .attr("xlink:href",function(d,i){return "#s"+i;}) 
    .attr("startOffset",function(d,i){return "50%";}) 
    .text(function(d){return d.name.toUpperCase();}) 

幸运的是,在中心文本弧线只是设置正确属性的问题。

+0

我会在这里发布。和你的一样,各种其他的摆弄。为了让文字*在圆内,同时仍然是正确的方式,我使路径半径比圆半径小一点。我试图使用“textLength”属性来压缩文本以适应,但它似乎不适用于''元素。 http://jsfiddle.net/2hM3s/4/ – AmeliaBR

+0

@AmeliaBR我刚将.style(“font-size”,12)改为.attr(“font-size”,12),结果是:(http: //的jsfiddle。net/VividD/vCG6w /)(这个错误总是出现在我的例子中) – VividD

+0

@AmeliaBR我认为你应该发布这个答案,它对未来的读者能够看到两种方法是有好处的。 – VividD