首页 > 解决方案 > 如何在不知道它们在 x 和 y 中的位置的 2 个元素之间建立动态线?

问题描述

我有两个元素, acircle和 a rectangle,它们分别包含在不同的g元素中,它们的位置相对于它们的父元素,即g元素。在这种情况下,mycircle和 myrectangle没有定义xy立场。这就是我问这个问题的原因,我想知道如何在我完全不知道它们在 svg 中的绝对位置的情况下制作第一到第二行元素。

var svg=d3.select("svg");
var g1=svg.append("g").attr("transform","translate(50,100)");
var g2=svg.append("g").attr("transform","translate(500,250)");

var rect=g1.append("rect").attr("id","myrect").attr("width",100).attr("height",100).attr("x",0).style("fill","blue");
var circle=g2.append("circle").attr("id","mycircle").attr("r",30).style("fill","red");

let origin= d3.select("#myrect");
let destiny= d3.select("#mycircle");
/*svg.append("line") 
  .style("stroke", "black") // colour the line
  .attr("x1", origin.x) // x position of the first end of the line
  .attr("y1", origin.y) // y position of the first end of the line
  .attr("x2", destiny.x) // x position of the second end of the line
  .attr("y2", destiny.y); // y position of the second end of the line
}*/
//.getBoundingClientRect()
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg style="width:1000px;height:500px; border:1px solid red;"></svg>

标签: d3.js

解决方案


对于每个形状,使用数据绑定getClientBoundingRect()获取每个元素的位置、高度和宽度。我们绑定到一个属性。

source.datum(source.node().getBoundingClientRect())
.attr('nodeX', d=>d.x + d.width/2)
.attr('nodeY', d=>d.y + d.height/2)

target.datum(target.node().getBoundingClientRect())
.attr('nodeX', d=>d.x + d.width/2)
.attr('nodeY', d=>d.y + d.height/2)

var svg=d3.select("svg");
var g1=svg.append("g").attr("transform","translate(50,100)");
var g2=svg.append("g").attr("transform","translate(500,250)");

var rect=g1.append("rect").attr("id","myrect").attr("width",100).attr("height",100).attr("x",0).style("fill","blue");
var circle=g2.append("circle").attr("id","mycircle").attr("r",30).style("fill","red");

let source = d3.select("#myrect");
let target = d3.select("#mycircle");

source.datum(source.node().getBoundingClientRect())
.attr('nodeX', d=>d.x + d.width/2)
.attr('nodeY', d=>d.y + d.height/2)

target.datum(target.node().getBoundingClientRect())
.attr('nodeX', d=>d.x + d.width/2)
.attr('nodeY', d=>d.y + d.height/2)

svg.append("line") 
  .style("stroke", "black") // colour the line
  .attr("x1", source.attr('nodeX')) // x position of the first end of the line
  .attr("y1", source.attr('nodeY')) // y position of the first end of the line
  .attr("x2", target.attr('nodeX')) // x position of the second end of the line
  .attr("y2", target.attr('nodeY')); // y position of the second end of the line
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg style="width:1000px;height:500px; border:1px solid red;"></svg>


推荐阅读