繁体   English   中英

D3圆圈包布局中的圆圈文字

[英]Text along circles in a D3 circle pack layout

我试图在circle pack layout标记一些圆圈,文本沿着圆圈本身流动。

这是一个实验性的jsfiddle

在此输入图像描述

如您所见,可以沿着圆圈渲染文本,以其顶部为中心。 虽然浏览器的曲线SVG文本渲染很糟糕。 但是,让我们说我们不关心它。

这是另一个jsfiddle

在此输入图像描述

在这些情况下,我想在此图表上放置弯曲标签:

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

您可以在代码本身中看到我的一些尝试。 我已经尝试了几个小时。 我的主要问题是圆圈中的圆圈现在位于XY空间中的某个位置,而在第一个jsfiddle中,所有圆圈都具有坐标系原点的中心。

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

基础数据基于此表:

在此输入图像描述

(注意:这与我前几天询问的'圆形包作为D3力布局的节点'的问题有些相关,但这是一个独立的实验。)

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

在此输入图像描述

注意(因为我正在回答我的问题):如果你们中的一些人已经花时间解决这个问题并找到了另一个解决方案,请发布它,我会接受你的回答。 感谢@FernOfTheAndes参与找到这个解决方案的过程,因为它充满了与svg弧一起工作的痛苦和痛苦。

这是解决方案的jsfiddle

在此输入图像描述

正如评论中所提到的,关键部分是产生弧形作为普通的香草svg弧,而不是通过d3.svg.arc()。

用于定义弧的SVG规则很明确,但有点难以管理。 这是一个用于弧的svg语法的交互式资源管理器

此外,这两个函数在定义正确弧线的过程中帮助了我:

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();})

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

只是更新一些VividD的代码。

对于小于180度的弧,describeArc函数无法正常工作,并且在函数和调用时都会触发start和end变量。

这是一个更新的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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM