我正在尝试创建一个双树结构,而不是svg节点,我想在这些点上附加div
。如何找到每个的终点坐标以在特定点上放置div。
这就是我到目前为止 -
var nodePosition = [];
$(document).ready(function() {
$(".static-doubletree-container").makeStaticDoubleTree();
});
jQuery.fn.makeStaticDoubleTree = function() {
var margin = {
top: 30,
right: 10,
bottom: 10,
left: 10
},
width = 960 - margin.left - margin.right,
halfWidth = width / 2,
height = 500 - margin.top - margin.bottom,
i = 0,
duration = 500,
root;
var getChildren = function(d) {
var a = [];
if (d.winners)
for (var i = 0; i < d.winners.length; i++) {
d.winners[i].isRight = false;
d.winners[i].parent = d;
a.push(d.winners[i]);
}
if (d.challengers)
for (var i = 0; i < d.challengers.length; i++) {
d.challengers[i].isRight = true;
d.challengers[i].parent = d;
a.push(d.challengers[i]);
}
return a.length ? a : null;
};
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
});
var connector = diagonal;
var calcLeft = function(d) {
var l = d.y;
if (!d.isRight) {
l = d.y - halfWidth;
l = halfWidth - l;
}
return {
x: d.x,
y: l
};
};
var vis = d3.select(".static-doubletree-container").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
setTimeout(function() {
var json = {
"name": "Overall Winner",
"winners": [{
"name": "Winner Left 1",
"winners": [{
"name": "Winner Left 3"
}, {
"name": "Winner Left 4"
}]
}, {
"name": "Winner Left 2"
}],
"challengers": [{
"name": "Challenger Right 1",
"challengers": [{
"name": "Challenger Right 3"
}, {
"name": "Challenger Right 4"
}]
}, {
"name": "Challenger Right 2",
"challengers": [{
"name": "Challenger Right 5"
}, {
"name": "Challenger Right 6"
}]
}]
};
root = json;
root.x0 = height / 2;
root.y0 = width / 2;
var t1 = d3.layout.tree().size([height, halfWidth]).children(function(d) {
return d.winners;
}),
t2 = d3.layout.tree().size([height, halfWidth]).children(function(d) {
return d.challengers;
});
t1.nodes(root);
t2.nodes(root);
var rebuildChildren = function(node) {
node.children = getChildren(node);
if (node.children) node.children.forEach(rebuildChildren);
}
rebuildChildren(root);
root.isRight = false;
update(root);
});
var toArray = function(item, arr, d) {
arr = arr || [];
var dr = d || 1;
var i = 0,
l = item.children ? item.children.length : 0;
arr.push(item);
if (item.position && item.position === 'left') {
dr = -1;
}
item.y = dr * item.y;
for (; i < l; i++) {
toArray(item.children[i], arr, dr);
}
return arr;
};
function update(source) {
// Compute the new tree layout.
var nodes = toArray(source);
// Normalize for fixed-depth.
nodes.forEach(function(d) {
if (d.isRight) {
d.y = d.depth * 180 + halfWidth;
} else {
d.y = width - (d.depth * 180 + halfWidth);
}
});
// Update the nodes…
var node = vis.selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", click);
// nodeEnter.append("circle")
// .attr("r", 1e-6)
// .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
p = calcLeft(d);
return "translate(" + p.y + "," + p.x + ")";
});
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
p = calcLeft(d.parent || source);
return "translate(" + p.y + "," + p.x + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links...
var link = vis.selectAll("path.link")
.data(tree.links(nodes), function(d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {
x: source.x0,
y: source.y0
};
return connector({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", connector);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = calcLeft(d.source || source);
if (d.source.isRight) o.y -= halfWidth - (d.target.y - d.source.y);
else o.y += halfWidth - (d.target.y - d.source.y);
return connector({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
var p = calcLeft(d);
d.x0 = p.x;
d.y0 = p.y;
});
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(source);
}
}
};
.node circle {
cursor: pointer;
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font-size: 11px;
}
path.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
.node.selected circle {
fill: green;
}
.static-doubletree-container {
position: relative;
}
.node-container-div {
width: 120px;
height: 50px;
border-radius: 25px;
background: #ccc;
position: absolute;
}
.root {
top: 230px;
left: 400px;
}
.overlay-divs {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="static-doubletree-container">
<div class="overlay-divs">
<div class="node-container-div root">
</div>
</div>
</div>
答案 0 :(得分:2)
在这种情况下,链接的最后一点是:
d3.selectAll(".link")[0].forEach(function(path){
var j = path.getBBox();
console.log(j)//returns the tightest bounding rectange from which co-ordinates can be found
})
修改强>
因为在你发布的小提琴中,链接有转换,所以你必须在转换完成后运行代码。
window.setTimeout(function(){
d3.selectAll(".link")[0].forEach(function(path){
var j = path.pathSegList
x = j[j.length-1].x
y = j[j.length-1].y
console.log(x,y)//last position of link
})
}, duration);
工作代码here
希望这有帮助!
答案 1 :(得分:1)
您可以尝试使用rectObject = object.getBoundingClientRect();
这也有效。这里有更多文档 - https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect