我有一个d3布局,其中10个节点的结构如下......
<body>
<svg id="mainSvg" style="position: relative" width="1200" height = "1200">
<g>
<svg width = "800" height="800>
<g class="nodeGroupSVG" transform=translate(someXValue,someYValue) scale(someScaleValue)
<g class="node" transform=translate(someXValue,someYValue)>
<circle>
<text>
</g>
//9 more of these individual node groupings
</g>
</svg>
</g>
<g class="gToMoveTo">
//starts off empty
</g>
<svg>
</body>
我想将节点移动到一个新容器,这可以通过使用...
在jquery中轻松实现$('.gToMoveTo').append($('.node'));
但是当涉及到向新DOM位置的过渡动画时,我在解决这个问题时遇到了麻烦:JQuery - animate moving DOM element to new parent?
使用该函数对我来说与简单的jquery行具有完全相同的效果(加上我假设的更小的延迟是由于调用了动画函数 - 即使没有逐渐过渡到新位置)
所有这些都是很长的问题,是否有人知道为什么我列出的函数不适合动画SVG组元素的转换?如果是这样,是否有任何想法可以使其适应SVG。
答案 0 :(得分:2)
这是一种常见的算法:
以下是代码:
<html>
<head>
<script src="d3.v3.min.js"></script>
<script src="jquery-2.1.0.min.js"></script>
<style>
.svg_contariner {
background-color:#CCCCCC;
}
#origin {
width:200px;
height:200px;
margin:5px;
}
#target {
width:200px;
height:200px;
margin:5px;
}
circle {
fill:#e72;
}
text {
font-family:Tahoma, Geneva, sans-serif;
font-size:10px;
}
.clone {
margin:0;
padding:0;
width:20px;
height:20px;
position:absolute;
}
</style>
</head>
<body>
<div id="data"></div>
<script>
var data_text = "", data = [], r = 10;
/* --- add some random data --- */
for (i = 0; i < 10; i++) {
data.push( {
"x": Math.round(Math.random() * 180)+10,
"y": Math.round(Math.random() * 180)+10,
"text": i
});
data_text += "x:" + data[i].x + " y:" + data[i].y + " text:" + data[i].text + "<br>";
}
/* --- create 2 containers --- */
var svgContainerTar = d3.select("body").append("svg")
.attr("id","target")
.attr("class","svg_contariner");
var svgContainerOrg = d3.select("body").append("svg")
.attr("id","origin")
.attr("class","svg_contariner");
/* --- add g node to origin --- */
var ele = svgContainerOrg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("class", "node")
.on("click", function (d) { /* --- bind onClick to every g --- */
d3.select(this).remove(); /* --- remove origin element --- */
moveCircle(d); /* --- create, animate ghost --- */
});
/* --- add circle to g --- */
var circles = ele.append("circle")
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; })
.attr("r", r+"px");
/* --- add text to g --- */
var labels = ele.append("text")
.attr("dx", function(d) {return d.x - 2})
.attr("dy", function(d) {return d.y + 3})
.text(function (d) {return d.text});
function moveCircle(d) {
ori_x = d.x;
ori_y = d.y;
ori_tex = d.text;
ori_pos = $("#origin").position();
tar_pos = $("#target").position();
/* --- create ghost using jQuery --- */
$("body").append("<div id='ghost' class='clone' style='left:"+(ori_x - r/2+ori_pos.left)+";top:"+(ori_y - r/2+ori_pos.top)+"';>"+
"<svg width='20px' height='20px'>"+
"<circle cx='"+r+"' cy='"+r+"' r='"+r+"px'></circle>"+
"<text x='"+(r - 2)+"' y='"+(r+3)+"'>"+ori_tex+"</text>"+
"</svg></div>");
/* --- animate ghost --- */
$("#ghost").animate({
"left" : tar_pos.left + ori_x,
"top" : tar_pos.top + ori_y
},100,"swing",
function () {
time = setTimeout(function () { /* --- when animation ends create target element --- */
var new_node = d3.select("#target")
.append ("g")
.attr("class", "node");
new_node.append("circle")
.attr("cx", ori_x+r/2+"px")
.attr("cy", ori_y+r/2+"px")
.attr("r", r+"px")
new_node.append("text")
.attr("dx", ori_x+r/2-2)
.attr("dy", ori_y+r/2+3)
.text(ori_tex);
$("#ghost").remove(); /* --- remove ghost --- */
},100)
});
}
</script>
</body></html>
希望这个帮助