Reputation: 3051
I have 2 elements, a circle
and a rectangle
. both are inside a different g
element. As I am learning about d3.js
I want that using the id
selectors of each element, I can create a line
that joins both elements. I don't know how to do it, I have read that with the property, getBoundingClientRect
I can get the real properties of each element within the svg
but i get errors when using it.
how can I do it?
var svg=d3.select("svg");
var g1=svg.append("g");
var g2=svg.append("g");
var rect=g1.append("rect").attr("id","myrect").attr("width",100).attr("height",100).attr("x",0).style("fill","blue");
var circle=g1.append("circle").attr("id","mycircle").attr("r",30).attr("cx",500).attr("cy",100).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>
Upvotes: 3
Views: 66
Reputation: 102194
There are better ways to do this, but here in this answer I'll just follow your approach.
In D3, methods such as attr()
with just one argument are getters:
+origin.attr("x")
This will get the x
attribute of the rectangle. The unary plus is important here because the getter returns a string, not a number. So, just get the rectangle's position, add half width/height, and get the circle's position:
var svg=d3.select("svg");
var g1=svg.append("g");
var g2=svg.append("g");
var rect=g1.append("rect").attr("id","myrect").attr("width",100).attr("height",100).attr("x",0).style("fill","blue");
var circle=g1.append("circle").attr("id","mycircle").attr("r",30).attr("cx",500).attr("cy",100).style("fill","red");
let origin= d3.select("#myrect");
let destiny= d3.select("#mycircle");
svg.append("line")
.style("stroke", "black")
.attr("x1", +origin.attr("x") + +origin.attr("width")/2)
.attr("y1", +origin.attr("y") + +origin.attr("height")/2)
.attr("x2", +destiny.attr("cx"))
.attr("y2", +destiny.attr("cy"));
<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>
Upvotes: 2