Javascript 如何使用JS拖动几个圆?
我用d3画了一组圆。我可以轻松地拖动其中一个圆圈,并跟踪其cx和cy位置Javascript 如何使用JS拖动几个圆?,javascript,d3.js,Javascript,D3.js,我用d3画了一组圆。我可以轻松地拖动其中一个圆圈,并跟踪其cx和cy位置 var width= 800; var height=600; svg= d3.select("body").select(".div1").append("svg") .attr("width", width) .attr("height",height); transformed_data = [
var width= 800;
var height=600;
svg= d3.select("body").select(".div1").append("svg")
.attr("width", width)
.attr("height",height);
transformed_data = [
[5, 20], [480, 90], [250, 50], [100, 33], [330, 95],
[410, 12], [475, 44], [25, 67], [85, 21], [220, 88]
];
X = [0,800];
Y = [0,600];
xScale =d3.scale.linear().domain(X).range([70, width-70]);
yScale =d3.scale.linear().domain(Y).range([70, height-70]);
drag = d3.behavior.drag()
.on("drag", function(d,i) {
d3.select(this).attr("cx", d3.event.x);
d3.select(this).attr("cy", d3.event.y);
})
.on("dragend",function(d,i){
});
svg.selectAll('circle')
.data(transformed_data)
.enter()
.append("circle")
.attr("id", function(d,i){return "id_" + i.toString();})
.attr("cx", function(d,i){return xScale(transformed_data[i][0]);})
.attr("cy", function(d,i){return yScale(transformed_data[i][1]);})
.attr("r",10)
.call(drag);
但是,我不知道如何使用鼠标选择几个圆并将它们拖到一起。有什么想法吗,比如说 有一个实现,允许您拖动多个元素,该链接由@Lars提供,效果很好,但交互不自然,我个人不喜欢。代码如下: 搜索了一会儿之后。我最终得到了以下代码,它工作得非常完美,我相信交互是非常自然的
<html>
<head>
<title>jQuery UI Selectable - Serialize</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/theme/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
rect.selection {
stroke: black;
stroke-dasharray: 4px;
stroke-opacity : 0.9;
fill: transparent;
}
.state circle {
stroke : gray;
cursor : pointer;
}
.state {
fill : black;
}
.selected{
fill : red;
}
</style>
<body>
<div class="div1"></div>
</body>
<script type="text/javascript">
var width = 800,
radius=10,
height = 600;
svg= d3.select("body").select(".div1").append("svg")
.attr("width", width)
.attr("height",height);
var transformed_data= d3.range(10).map(function(d) {
return {
x: parseInt(Math.random() * width),
y: parseInt(Math.random() * height),
}
});
// Drag Evenet
drag = d3.behavior.drag()
.on("drag", function( d, i) {
var selection = d3.selectAll('.selected');
console.log(selection[0] + "---"+selection[1]);
svg.selectAll( "rect.selection").remove();
if(selection[0].indexOf(this)==-1) {
selection = d3.select(this);
selection.classed("selected", true);
}
selection.attr("cx", function(d){ d.x += d3.event.dx; return d.x;})
selection.attr("cy", function(d,i){d.y += d3.event.dy; return d.y;})
});
gStates = svg.selectAll('circle')
.data(transformed_data)
.enter()
.append("circle")
.attr("class","state")
.attr("id", function(d,i){return "id_" + i.toString();})
.attr("cx", function(d,i){return d.x;})
.attr("cy", function(d,i){return d.y;})
.attr("r",10)
.call(drag);
svg.on( "mousedown", function() {
if(!d3.event.ctrlKey) {
d3.selectAll(".selected").classed( "selected", false);
}
var p = d3.mouse(this);
svg.append( "rect")
.attr({
class : "selection",
x : p[0],
y : p[1],
width : 0,
height : 0
})
})
.on( "mousemove", function() {
var s = svg.select( "rect.selection");
if( !s.empty()) {
var p = d3.mouse( this),
d = {
x : parseInt( s.attr( "x"), 10),
y : parseInt( s.attr( "y"), 10),
width : parseInt( s.attr( "width"), 10),
height : parseInt( s.attr( "height"), 10)
},
move = {
x : p[0] - d.x,
y : p[1] - d.y
};
if( move.x < 1 || (move.x*2<d.width)) {
d.x = p[0];
d.width -= move.x;
} else {
d.width = move.x;
}
if( move.y < 1 || (move.y*2<d.height)) {
d.y = p[1];
d.height -= move.y;
} else {
d.height = move.y;
}
s.attr( d);
d3.selectAll( ".state").each( function( state_data, i) {
if(
!d3.select(this).classed("selected") &&
// inner circle inside selection frame
state_data.x-radius>=d.x && state_data.x+radius<=d.x+d.width &&
state_data.y-radius>=d.y && state_data.y+radius<=d.y+d.height
) {
d3.select(this)
.classed( "selection", true)
.classed( "selected", true);
}
});
}
})
.on( "mouseup", function() {
// remove selection frame
svg.selectAll( "rect.selection").remove();
// remove temporary selection marker class
d3.selectAll( '.state.selection').classed( "selection", false);
})
.on( "mouseout", function() {
if( d3.event.relatedTarget.tagName=='HTML') {
// remove selection frame
svg.selectAll( "rect.selection").remove();
// remove temporary selection marker class
d3.selectAll( '.state.selection').classed( "selection", false);
}
});
</script>
</head>
jQuery UI可选-序列化
矩形选择{
笔画:黑色;
笔划阵列:4px;
笔划不透明度:0.9;
填充:透明;
}
.州议会{
笔画:灰色;
光标:指针;
}
.州{
填充:黑色;
}
.选定{
填充物:红色;
}
可变宽度=800,
半径=10,
高度=600;
svg=d3。选择(“正文”)。选择(“div1”)。追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
变量转换_数据=d3.范围(10).映射(函数(d){
返回{
x:parseInt(Math.random()*宽度),
y:parseInt(Math.random()*高度),
}
});
//拖网
drag=d3.behavior.drag()
.开启(“拖动”,功能(d,i){
var selection=d3.selectAll('.selected');
console.log(选择[0]+“--”+选择[1]);
selectAll(“rect.selection”).remove();
if(选择[0]。indexOf(此)==-1){
选择=d3。选择(本);
selection.classed(“selected”,true);
}
selection.attr(“cx”,函数(d){d.x+=d3.event.dx;返回d.x;})
attr(“cy”,函数(d,i){d.y+=d3.event.dy;返回d.y;})
});
gStates=svg.selectAll('circle')
.数据(转换的_数据)
.输入()
.附加(“圆圈”)
.attr(“类别”、“状态”)
.attr(“id”,函数(d,i){return“id_”+i.toString();})
.attr(“cx”,函数(d,i){返回d.x;})
.attr(“cy”,函数(d,i){返回d.y;})
.attr(“r”,10)
.呼叫(拖动);
on(“mousedown”,function()){
如果(!d3.event.ctrlKey){
d3.选择全部(“.selected”).classed(“selected”,false);
}
var p=d3.小鼠(此);
svg.append(“rect”)
艾特先生({
类:“选择”,
x:p[0],,
y:p[1],,
宽度:0,
身高:0
})
})
.on(“mousemove”,function(){
var s=svg.select(“rect.selection”);
如果(!s.empty()){
var p=d3.鼠标(此),
d={
x:parseInt(s.attr(“x”),10),
y:parseInt(s.attr(“y”),10),
宽度:parseInt(s.attr(“宽度”),10),
高度:parseInt(s.attr(“高度”),10)
},
移动={
x:p[0]-d.x,
y:p[1]-d.y
};
如果(move.x<1 | | |(move.x*2),则有一个实现允许您拖动多个元素,该链接由@Lars提供,效果非常好,但交互不自然,我个人不喜欢。下面是代码:
在搜索了一段时间后,我最终得到了以下代码,它工作得非常完美,我相信交互是非常自然的
<html>
<head>
<title>jQuery UI Selectable - Serialize</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/theme/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
rect.selection {
stroke: black;
stroke-dasharray: 4px;
stroke-opacity : 0.9;
fill: transparent;
}
.state circle {
stroke : gray;
cursor : pointer;
}
.state {
fill : black;
}
.selected{
fill : red;
}
</style>
<body>
<div class="div1"></div>
</body>
<script type="text/javascript">
var width = 800,
radius=10,
height = 600;
svg= d3.select("body").select(".div1").append("svg")
.attr("width", width)
.attr("height",height);
var transformed_data= d3.range(10).map(function(d) {
return {
x: parseInt(Math.random() * width),
y: parseInt(Math.random() * height),
}
});
// Drag Evenet
drag = d3.behavior.drag()
.on("drag", function( d, i) {
var selection = d3.selectAll('.selected');
console.log(selection[0] + "---"+selection[1]);
svg.selectAll( "rect.selection").remove();
if(selection[0].indexOf(this)==-1) {
selection = d3.select(this);
selection.classed("selected", true);
}
selection.attr("cx", function(d){ d.x += d3.event.dx; return d.x;})
selection.attr("cy", function(d,i){d.y += d3.event.dy; return d.y;})
});
gStates = svg.selectAll('circle')
.data(transformed_data)
.enter()
.append("circle")
.attr("class","state")
.attr("id", function(d,i){return "id_" + i.toString();})
.attr("cx", function(d,i){return d.x;})
.attr("cy", function(d,i){return d.y;})
.attr("r",10)
.call(drag);
svg.on( "mousedown", function() {
if(!d3.event.ctrlKey) {
d3.selectAll(".selected").classed( "selected", false);
}
var p = d3.mouse(this);
svg.append( "rect")
.attr({
class : "selection",
x : p[0],
y : p[1],
width : 0,
height : 0
})
})
.on( "mousemove", function() {
var s = svg.select( "rect.selection");
if( !s.empty()) {
var p = d3.mouse( this),
d = {
x : parseInt( s.attr( "x"), 10),
y : parseInt( s.attr( "y"), 10),
width : parseInt( s.attr( "width"), 10),
height : parseInt( s.attr( "height"), 10)
},
move = {
x : p[0] - d.x,
y : p[1] - d.y
};
if( move.x < 1 || (move.x*2<d.width)) {
d.x = p[0];
d.width -= move.x;
} else {
d.width = move.x;
}
if( move.y < 1 || (move.y*2<d.height)) {
d.y = p[1];
d.height -= move.y;
} else {
d.height = move.y;
}
s.attr( d);
d3.selectAll( ".state").each( function( state_data, i) {
if(
!d3.select(this).classed("selected") &&
// inner circle inside selection frame
state_data.x-radius>=d.x && state_data.x+radius<=d.x+d.width &&
state_data.y-radius>=d.y && state_data.y+radius<=d.y+d.height
) {
d3.select(this)
.classed( "selection", true)
.classed( "selected", true);
}
});
}
})
.on( "mouseup", function() {
// remove selection frame
svg.selectAll( "rect.selection").remove();
// remove temporary selection marker class
d3.selectAll( '.state.selection').classed( "selection", false);
})
.on( "mouseout", function() {
if( d3.event.relatedTarget.tagName=='HTML') {
// remove selection frame
svg.selectAll( "rect.selection").remove();
// remove temporary selection marker class
d3.selectAll( '.state.selection').classed( "selection", false);
}
});
</script>
</head>
jQuery UI可选-序列化
矩形选择{
笔画:黑色;
笔划阵列:4px;
笔划不透明度:0.9;
填充:透明;
}
.州议会{
笔画:灰色;
光标:指针;
}
.州{
填充:黑色;
}
.选定{
填充物:红色;
}
可变宽度=800,
半径=10,
高度=600;
svg=d3。选择(“正文”)。选择(“div1”)。追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度);
变量转换_数据=d3.范围(10).映射(函数(d){
返回{
x:parseInt(Math.random()*宽度),
y:parseInt(Math.random()*高度),
}
});
//拖网
drag=d3.behavior.drag()
.开启(“拖动”,功能(d,i){
var selection=d3.selectAll('.selected');
console.log(选择[0]+“--”+选择[1]);
selectAll(“rect.selection”).remove();
if(选择[0]。indexOf(此)==-1){
选择=d3。选择(本);
selection.classed(“selected”,true);
}
selection.attr(“cx”,函数(d){d.x+=d3.event.dx;返回d.x;})
attr(“cy”,函数(d,i){d.y+=d3.event.dy;返回d.y;})
});
gStates=svg.selectAll('circle')
.数据(转换的_数据)
.输入()
.附加(“圆圈”)
.attr(“类别”、“状态”)
.attr(“id”,函数(d,i){return“id_”+i.toString();})
.attr(“cx”,函数(d,i){返回d.x;})
.attr(“cy”,函数(d,i){返回d.y;})
.attr(“r”,10)
.呼叫(拖动);
sv