【问题标题】:How to use linkRadial to draw a link between two points?如何使用 linkRadial 在两点之间绘制链接?
【发布时间】:2017-07-06 21:03:08
【问题描述】:

我需要在圆上的点和聚集在所述圆的中心的点之间手动绘制一些链接。我有源点和目标点的 x,y 对,但我不希望它们之间有一条简单的直线;我想要一条曲线(类似于树形图中的链接)。我可以使用linkHorizontal 或linkVertical,但它们的切线是恒定的;我想使用linkRadial 并让切线成为该特定弧点处的径向线(我也有度数)。

虽然我不理解linkRadial API;它需要一个角度和一个半径,而不是 x 或 y 点。如何将我的两个 x,y 对(和径向线角度)转换为预期的角度和半径?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    由于您有一个包含 x 和 y 位置的数据数组(“我有源点和目标点的 x,y 对”),您必须转换他们到angle 和radius。让我们看看如何做到这一点。

    首先,让我们看一个固定坐标的例子。例如,假设您有这个数据数组,具有x 和y 位置:

    var data = [{
        source: {y: 150,x: 75
        },
        target: {y: 300,x: 0
        }
    }, {
        source: {y: 150,x: 75
        },
        target: {y: 0,x: 0
        }
    }, {
        source: {y: 150,x: 75
        },
        target: {y: 150,x: 150
        }
    }, ];
    

    使用此链接生成器...

    var link = d3.linkHorizontal()
        .x(function(d) {
            return d.y;
        })
        .y(function(d) {
            return d.x;
        });
    

    ...你会有这样的图表:

    var data = [{
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 300,
        x: 0
      }
    }, {
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 0,
        x: 0
      }
    }, {
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 150,
        x: 150
      }
    }, ];
    
    var svg = d3.select("svg");
    
    var link = d3.linkHorizontal()
      .x(function(d) {
        return d.y;
      })
      .y(function(d) {
        return d.x;
      });
    
    svg.selectAll(null)
      .data(data)
      .enter()
      .append("path")
      .attr("fill", "none")
      .attr("stroke", "blue")
      .attr("d", link);
    <script src="https://d3js.org/d3.v4.js"></script>
    <svg></svg>

    我们如何将其转换为可与d3.linkRadial() 一起使用的数据集?

    一个选项是迭代每个对象,使用基本三角函数来填充angle 和radius 属性:

    var radialData = data.map(function(d) {
        return {
            source: {
                x: 0,
                y: 0
            },
            target: {
                x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
                y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
            }
        };
    });
    

    然后,使用这个链接生成器:

    var linkRadial = d3.linkRadial()
        .angle(function(d) {
            console.log(d)
            return d.x;
        })
        .radius(function(d) {
            return d.y;
        });
    

    我们会有这个:

    var data = [{
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 300,
        x: 0
      }
    }, {
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 0,
        x: 0
      }
    }, {
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 150,
        x: 150
      }
    }, ];
    
    var svg = d3.select("svg");
    
    var radialData = data.map(function(d) {
      return {
        source: {
          x: 0,
          y: 0
        },
        target: {
          x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
          y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
        }
      };
    });
    
    var g = svg.append("g")
      .attr("transform", "translate(150,75)")
    
    var linkRadial = d3.linkRadial()
      .angle(function(d) {
        return d.x;
      })
      .radius(function(d) {
        return d.y;
      });
    
    g.selectAll(null)
      .data(radialData)
      .enter()
      .append("path")
      .attr("fill", "none")
      .attr("stroke", "red")
      .attr("d", linkRadial);
    <script src="https://d3js.org/d3.v4.js"></script>
    <svg></svg>

    现在将两个生成器放在一起,以进行比较:

    var data = [{
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 300,
        x: 0
      }
    }, {
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 0,
        x: 0
      }
    }, {
      source: {
        y: 150,
        x: 75
      },
      target: {
        y: 150,
        x: 150
      }
    }, ];
    
    var svg = d3.select("svg");
    
    var link = d3.linkHorizontal()
      .x(function(d) {
        return d.y;
      })
      .y(function(d) {
        return d.x;
      });
    
    svg.selectAll(null)
      .data(data)
      .enter()
      .append("path")
      .attr("fill", "none")
      .attr("stroke", "blue")
      .attr("d", link);
    
    var radialData = data.map(function(d) {
      return {
        source: {
          x: 0,
          y: 0
        },
        target: {
          x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
          y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
        }
      };
    });
    
    var g = svg.append("g")
      .attr("transform", "translate(150,75)")
    
    var linkRadial = d3.linkRadial()
      .angle(function(d) {
        return d.x;
      })
      .radius(function(d) {
        return d.y;
      });
    
    g.selectAll(null)
      .data(radialData)
      .enter()
      .append("path")
      .attr("fill", "none")
      .attr("stroke", "red")
      .attr("d", linkRadial);
    <script src="https://d3js.org/d3.v4.js"></script>
    <svg></svg>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-22
      • 2018-10-06
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 2016-09-21
      • 1970-01-01
      • 2014-03-20
      相关资源
      最近更新 更多