【问题标题】:How to add filled sections to SVG circles using d3.js如何使用 d3.js 将填充部分添加到 SVG 圆圈
【发布时间】:2019-06-29 05:35:44
【问题描述】:

我正在使用 d3.js 生成一些 SVG 圆圈。我能够生成它们,但我不知道如何将它们分成 4 个相等的部分并为每个部分填充颜色。我正在使用 d3.js 的第 4 版。

这是我的小提琴中我的 javascript 的 sn-p:

var nodes = [

  {"type":'family',"id":'f1',"name":'', "image":""},
  {"type":'person',"id":'p1',"name":'fred flintstone',"age": 39, "relationship": "father","sex":' '},
  {"type":'person',"id":'p2',"name":'wilma flintstone',"age": 36, "relationship": "mother","sex":'m'},
  {"type":'person',"id":'p3',"name":'pebbles flintstone',"age": 4 , "relationship": "daughter","sex":'mf'},
  {"type":'person',"id":'p4',"name":'dino',"age": 8 ,"relationship": "pet","sex":'m'},


  {"type":'family',"id":'f3',"name":'', "image":""},
  {"type":'person',"id":'p5',"name":'barney rubble',"age": 43, "relationship": "father","sex":'m'},
  {"type":'person',"id":'p6',"name":'betty rubble',"age": 41, "relationship": "mother","sex":'f'},
  {"type":'person',"id":'p7',"name":'bam bam rubble',"age": 4, "relationship": "son","sex":'m'},


]

//more code in my fiddle

  my.width = function(value) {
    if (!arguments.length) return width;
    width = value;
    return my;
  };

  my.nodes = function(value) {
    if (!arguments.length) return nodes;
    nodes = value;
    return my;
  };

  my.links = function(value) {
    if (!arguments.length) return links;
    links = value;
    return my;
  };

  my.height = function(value) {
    if (!arguments.length) return height;
    height = value;
    return my;
  };

  return my;
}

非常感谢。

https://jsfiddle.net/pqk8y3mb/

【问题讨论】:

    标签: javascript d3.js svg


    【解决方案1】:

    我建议使用 SVG 的 path 手动绘制弧线。

    首先,这是一个添加的工作示例:https://jsfiddle.net/mztafs0w/


    说明:

    SVG Path 有诸如 M 表示 Move、A 表示 Arc、L 表示绘制 Line to:

    • 大写字母是绝对像素移动
    • 小写字母是相对像素移动

    要使用 SVG 路径制作填充的饼图,您必须执行以下操作:

    image source


    假设您的半径为 40,并且您希望在右上角的象限中切片。整个命令是:

    • 移动 X(0) Y(-40) --移到顶部
    • 圆弧 X-Radius(40) Y-Radius(40) XRot(0) >180deg?(0) Sweep(1) X(40) Y(0) --向右弧
    • 直线 X(0) Y(0) --返回中心

    压缩成svg路径格式,显示为:

    M 0 -40 A 40 40 0 0 1 40 0 L 0 0(最少是M0,-40A40,40,0,0,1,40,0L0,0

    执行这 4 次以获得所有 4 个象限很简单,将半径替换为 ${r} 可以轻松调整大小。

    添加到您的 JS 小提琴中的最终代码:

    var slices=[];
      slices[0] = node.append("path")
      .attr("d", function(d) {
        let r = d.type == "family" ? family_radius + 5 : 40;
        return `M 0 -${r} A ${r} ${r} 0 0 1 ${r} 0 L 0 0`; } )
      .attr("fill", "coral");
    slices[1] = node.append("path")
        .attr("d", function(d) {
        let r = d.type == "family" ? family_radius + 5 : 40;
        return `M ${r} 0 A ${r} ${r} 0 0 1 0 ${r} L 0 0`; } )
      .attr("fill", "royalblue");
    slices[2] = node.append("path")
      .attr("d", function(d) {
        let r = d.type == "family" ? family_radius + 5 : 40;
        return `M 0 ${r} A ${r} ${r} 0 0 1 -${r} 0 L 0 0`; } )
      .attr("fill", "olivedrab");
    slices[3] = node.append("path")
      .attr("d", function(d) {
        let r = d.type == "family" ? family_radius + 5 : 40;
        return `M -${r} 0 A ${r} ${r} 0 0 1 0 -${r} L 0 0`; } )
      .attr("fill", "goldenrod");
    

    我建议您删除不工作的 describeArc 部分并使代码更DRY。您可以执行更多计算以使圆形切片在 0/90/180/270 以外的位置中断。如果您在这些方面需要帮助,请告诉我,或者您可以查看image source 以获取更多提示。

    我还将family_radius 更改为family_radius + 5,这样您就可以看到在这些小圆圈的白色填充下方绘制的弧线。如果不希望这样做,您可以删除这些圆圈上的白色填充(第 165 行 if(d.type == "family"){return "white"}),或者根本不为这些圆圈绘制这些切片。

    【讨论】:

    • 非常感谢!您不仅解决了我的问题,而且以一种非常容易理解和专业的方式解释了它。
    • 您的代码运行良好。我试图通过复制您所做的事情来了解它是如何工作的,方法是创建具有四个段而不是圆形的正方形。我没有为我的段使用弧线,而是尝试使用线生成器无济于事。我只成功地创建了没有段的正方形。我将如何做到这一点以及如何根据用户的性别创建一个正方形或圆形。
    • @user1647160 如果您在处理这个新问题时遇到问题,请创建一个新问题。您将对从 1 个角开始并移动到其他 3 个角的路径执行相同的操作,然后应用填充。
    • 感谢您的帮助。我试图自己弄清楚,几乎到了那里。这是我的新问题的链接:stackoverflow.com/questions/56942860/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    相关资源
    最近更新 更多