下面是生成的html:
<g title="some" cx="308" cy="98">
<circle class="node" cx="308" cy="98" r="20" style="stroke: gray; fill: white;">
<text dx="298" dy="103">some</text>
</g>
当我拖动此元素时,只有外部g元素的cx和cy发生变化。圆圈和文字保持在同一位置。
我希望在拖动时将圆和文本与g元素一起拖动。
这是我的生成节点代码:
node = container.append("g").selectAll("svg.node")
.data(json.nodes)
.enter().append("g").call(drag);
node.append("svg:circle")
.attr("cx",function(nodeObj) { return (nodeObj.x);})
.attr("cy",function(nodeObj) { return (nodeObj.y);})
.attr("r", 20)
.style("stroke", "gray")
.style("fill", "white");
node.append("text")
.attr("dx",function(nodeObj) { return (nodeObj.x - 10);})
.attr("dy",function(nodeObj) { return (nodeObj.y + 5);})
.text(function(nodeObj) {return nodeObj.name;});
node.attr("title",function(nodeObj) {return nodeObj.name;});
拖动行为:
drag = d3.behavior.drag()
.on("dragstart", dragstarted)
.on("drag", dragmove)
.on("dragend", dragended);
dragmove = function (nodeObj) {
nodeObj.x += d3.event.dx;
nodeObj.y += d3.event.dy;
tick(); // this is the key to make it work together with updating both px,py,x,y on d !
};
dragstarted = function () {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
};
dragended = function (nodeObj) {
if (d3.event.sourceEvent.which == 1){
d3.select(this).classed("dragging", false);
tick();
}
};
tick = function () {
link.attr("x1", function(nodeObj) { return nodeObj.source.x; })
.attr("y1", function(nodeObj) { return nodeObj.source.y; })
.attr("x2", function(nodeObj) { return nodeObj.target.x; })
.attr("y2", function(nodeObj) { return nodeObj.target.y; });
node.attr("cx",function(nodeObj) { return (nodeObj.x);})
node.attr("cy",function(nodeObj) { return (nodeObj.y);})
force.stop();
};
答案 0 :(得分:1)
在SVG中,g
元素没有cx
和cy
属性 - 设置它们不会产生任何影响。您需要设置的是transform
属性,例如到translate(<x>,<y>)
。因此,更新节点位置的代码将是
node.attr("transform", function(nodeObj) {
return "translate(" + nodeObj.x + "," + nodeObj.y + ")";
});
另请注意,力布局已经提供了拖动节点的工具,此外无需使用拖动行为:
container.call(force.drag);
参见例如this example