已绘制元素上的拖动事件
Drag Event on element already drawn
我对已经绘制的元素的拖动事件有问题,如果我需要移动它们我必须单击 "Circle" Link 然后工作,事件在 select 后消失另一种选择。
重要的是事件保持绑定,尽管另一个选项是 selected。
我尝试添加这一行,但没有用。
d3.select(this).call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended));
代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>FAM</title>
<script type="text/javascript" src="jquery-min.js"></script>
<script type="text/javascript" src="d3.v4.min.js"></script>
<script type="text/javascript">
$(function () {
var svg = d3.select('#svf');//.on("mousedown", mousedown).on("mouseup", mouseup);
var container = svg.append('g');
var pxy = new Array(), line, i = 0, j = 0;
for (i = 0; i < 500; i = i + 10) {
container.append('line').attr('x1', i).attr('y1', 0).attr('x2', i).attr('y2', 500).attr('stroke', '#CFCECE').attr('stroke-width', 1).attr('fill', 'none');
}
for (j = 0; j < 500; j = j + 10) {
container.append('line').attr('x1', 1).attr('y1', j).attr('x2', 500).attr('y2', j).attr('stroke', '#CFCECE').attr('stroke-width', 1).attr('fill', 'none');
}
function main() {
pxy = new Array();
var coords = d3.mouse(this), x = coords[0], y = coords[1];
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 1) {
pxy = new Array();
container.append('circle').attr('cx', x).attr('cy', y).attr('r', 30).attr('stroke-width', 2).attr('stroke', '#000').attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
}
if (conv == 2) {
pxy = new Array();
container.append('rect').attr('x', x).attr('y', y).attr('width', 60).attr('height', 60).attr('stroke-width', 2).attr('stroke', '#000').attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
}
if (conv == 3) {
}
if (conv == 4) {
pxy[pxy.length] = x;
pxy[pxy.length] = y;
pxy[pxy.length] = x;
pxy[pxy.length] = y + 30;
pxy[pxy.length] = x + 160;
pxy[pxy.length] = y + 30;
pxy[pxy.length] = x + 160;
pxy[pxy.length] = y;
container.append('polyline').attr("stroke", '#000').attr('stroke-width', 1).attr('fill', 'transparent').on('click', clicked).attr('points', pxy).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
pxy = new Array();
}
}
svg.on('click', main);
function mousedown() {
var m = d3.mouse(this);
line = container.append("line")
.attr("x1", m[0])
.attr("y1", m[1])
.attr("x2", m[0])
.attr("y2", m[1]).attr('stroke', '#000').attr('stroke-width', 2).attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
svg.on('mousemove', mousemove);
}
function mousemove() {
var m = d3.mouse(this);
line.attr('x2', m[0]).attr('y2', m[1]);
}
function mouseup() {
svg.on('mousemove', null);
svg.on('click', null);
console.log('...');
}
function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}
function dragged(d) {
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 1) {
d3.select(this).attr('cx', +d3.select(this).attr('cx') + d3.event.dx);
d3.select(this).attr('cy', +d3.select(this).attr('cy') + d3.event.dy);
}
if (conv == 2) {
d3.select(this).attr('x', +d3.select(this).attr('x') + d3.event.dx);
d3.select(this).attr('y', +d3.select(this).attr('y') + d3.event.dy);
}
if (conv == 3 || conv == 4) {
this.x = this.x || 0;
this.y = this.y || 0;
this.x += d3.event.dx;
this.y += d3.event.dy;
d3.select(this).attr('transform', 'translate(' + this.x + ',' + this.y + ')');
}
}
function dragended(d) {
d3.select(this).classed('active', false);
}
d3.select('body').on('keydown', function () {
if (d3.event.keyCode === 27) {
pxy = new Array();
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
svg.on('mousemove', null);
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 3) {
svg.on('click', mousedown);
}
}
});
function clicked(d, i) {
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 20) {
d3.select(this).remove();
} else {
/*This line doesn´t work*/
var element = $(this).prop('tagName');
if (element == 'circle' || element == 'rect') {
d3.select(this).call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended));
}
}
}
$('#lnk_circle').click(function () {
svg.on('click', main);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_rectangle').click(function () {
svg.on('click', main);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_polyline').click(function () {
svg.on('click', main);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_line').click(function () {
svg.on('click', mousedown).on("dblclick", mouseup);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_erase').click(function () {
svg.on('click', null);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
//$('#svg').find('g').find('circle,rect,line').on("dblclick", clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
});
</script>
<style>
line,circle,rect,polyline{ shape-rendering:crispEdges;}
</style>
</head>
<body>
<div id="dv_conv" style="float: left;width:200px;border:1px solid #000;margin-right: 1px">
<a href="#" id="lnk_circle" data-pressed="0" data-conv="1">Circle</a><br/>
<a href="#" id="lnk_rectangle" data-pressed="0" data-conv="2">Rectangle</a><br/>
<a href="#" id="lnk_line" data-pressed="0" data-conv="3">Line</a><br/>
<a href="#" id="lnk_polyline" data-pressed="0" data-conv="4">PolyLine</a><br/>
<a href="#" id="lnk_erase" data-pressed="0" data-conv="20">Erase</a><br/>
</div>
<div id="dv_familiogram" style="float: left;width:500px;height: 500px;border:1px solid #000;overflow: hidden">
<svg id="svf" style="width:500px;height:500px"></svg>
</div>
</body>
</html>
问题是您在 dragged
中的 select 操作基于 Link 被点击的功能,而不是基于您拖动的形状类型。
您可以将 dragged
函数替换为多个函数(每个函数用于特定形状类型):
function dragged_conv1(d) {
d3.select(this).attr('cx', +d3.select(this).attr('cx') + d3.event.dx);
d3.select(this).attr('cy', +d3.select(this).attr('cy') + d3.event.dy);
}
function dragged_conv2(d) {
d3.select(this).attr('x', +d3.select(this).attr('x') + d3.event.dx);
d3.select(this).attr('y', +d3.select(this).attr('y') + d3.event.dy);
}
function dragged_conv34(d) {
this.x = this.x || 0;
this.y = this.y || 0;
this.x += d3.event.dx;
this.y += d3.event.dy;
d3.select(this).attr('transform', 'translate(' + this.x + ',' + this.y + ')');
}
并将每个函数绑定到 main
函数中的每个形状:
if (conv == 1) {
pxy = new Array();
container.append('circle') ... .on("drag", dragged_conv1)...;
}
if (conv == 2) {
pxy = new Array();
container.append('rect') ... .on("drag", dragged_conv2)...;
}
if (conv == 4) {
// ... some code here ...
container.append('polyline') ... .on("drag", dragged_conv34)...;
pxy = new Array();
}
我对已经绘制的元素的拖动事件有问题,如果我需要移动它们我必须单击 "Circle" Link 然后工作,事件在 select 后消失另一种选择。
重要的是事件保持绑定,尽管另一个选项是 selected。
我尝试添加这一行,但没有用。
d3.select(this).call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended));
代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>FAM</title>
<script type="text/javascript" src="jquery-min.js"></script>
<script type="text/javascript" src="d3.v4.min.js"></script>
<script type="text/javascript">
$(function () {
var svg = d3.select('#svf');//.on("mousedown", mousedown).on("mouseup", mouseup);
var container = svg.append('g');
var pxy = new Array(), line, i = 0, j = 0;
for (i = 0; i < 500; i = i + 10) {
container.append('line').attr('x1', i).attr('y1', 0).attr('x2', i).attr('y2', 500).attr('stroke', '#CFCECE').attr('stroke-width', 1).attr('fill', 'none');
}
for (j = 0; j < 500; j = j + 10) {
container.append('line').attr('x1', 1).attr('y1', j).attr('x2', 500).attr('y2', j).attr('stroke', '#CFCECE').attr('stroke-width', 1).attr('fill', 'none');
}
function main() {
pxy = new Array();
var coords = d3.mouse(this), x = coords[0], y = coords[1];
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 1) {
pxy = new Array();
container.append('circle').attr('cx', x).attr('cy', y).attr('r', 30).attr('stroke-width', 2).attr('stroke', '#000').attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
}
if (conv == 2) {
pxy = new Array();
container.append('rect').attr('x', x).attr('y', y).attr('width', 60).attr('height', 60).attr('stroke-width', 2).attr('stroke', '#000').attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
}
if (conv == 3) {
}
if (conv == 4) {
pxy[pxy.length] = x;
pxy[pxy.length] = y;
pxy[pxy.length] = x;
pxy[pxy.length] = y + 30;
pxy[pxy.length] = x + 160;
pxy[pxy.length] = y + 30;
pxy[pxy.length] = x + 160;
pxy[pxy.length] = y;
container.append('polyline').attr("stroke", '#000').attr('stroke-width', 1).attr('fill', 'transparent').on('click', clicked).attr('points', pxy).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
pxy = new Array();
}
}
svg.on('click', main);
function mousedown() {
var m = d3.mouse(this);
line = container.append("line")
.attr("x1", m[0])
.attr("y1", m[1])
.attr("x2", m[0])
.attr("y2", m[1]).attr('stroke', '#000').attr('stroke-width', 2).attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
svg.on('mousemove', mousemove);
}
function mousemove() {
var m = d3.mouse(this);
line.attr('x2', m[0]).attr('y2', m[1]);
}
function mouseup() {
svg.on('mousemove', null);
svg.on('click', null);
console.log('...');
}
function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}
function dragged(d) {
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 1) {
d3.select(this).attr('cx', +d3.select(this).attr('cx') + d3.event.dx);
d3.select(this).attr('cy', +d3.select(this).attr('cy') + d3.event.dy);
}
if (conv == 2) {
d3.select(this).attr('x', +d3.select(this).attr('x') + d3.event.dx);
d3.select(this).attr('y', +d3.select(this).attr('y') + d3.event.dy);
}
if (conv == 3 || conv == 4) {
this.x = this.x || 0;
this.y = this.y || 0;
this.x += d3.event.dx;
this.y += d3.event.dy;
d3.select(this).attr('transform', 'translate(' + this.x + ',' + this.y + ')');
}
}
function dragended(d) {
d3.select(this).classed('active', false);
}
d3.select('body').on('keydown', function () {
if (d3.event.keyCode === 27) {
pxy = new Array();
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
svg.on('mousemove', null);
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 3) {
svg.on('click', mousedown);
}
}
});
function clicked(d, i) {
var lnk = $('#dv_conv').find('a[data-pressed="1"]');
var conv = lnk.attr('data-conv');
if (conv == 20) {
d3.select(this).remove();
} else {
/*This line doesn´t work*/
var element = $(this).prop('tagName');
if (element == 'circle' || element == 'rect') {
d3.select(this).call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended));
}
}
}
$('#lnk_circle').click(function () {
svg.on('click', main);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_rectangle').click(function () {
svg.on('click', main);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_polyline').click(function () {
svg.on('click', main);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_line').click(function () {
svg.on('click', mousedown).on("dblclick", mouseup);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
$('#lnk_erase').click(function () {
svg.on('click', null);
$('#lnk_circle').attr('data-pressed', 0);
$('#lnk_rectangle').attr('data-pressed', 0);
$('#lnk_polyline').attr('data-pressed', 0);
$('#lnk_line').attr('data-pressed', 0);
$(this).attr('data-pressed', 1);
return false;
});
//$('#svg').find('g').find('circle,rect,line').on("dblclick", clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
});
</script>
<style>
line,circle,rect,polyline{ shape-rendering:crispEdges;}
</style>
</head>
<body>
<div id="dv_conv" style="float: left;width:200px;border:1px solid #000;margin-right: 1px">
<a href="#" id="lnk_circle" data-pressed="0" data-conv="1">Circle</a><br/>
<a href="#" id="lnk_rectangle" data-pressed="0" data-conv="2">Rectangle</a><br/>
<a href="#" id="lnk_line" data-pressed="0" data-conv="3">Line</a><br/>
<a href="#" id="lnk_polyline" data-pressed="0" data-conv="4">PolyLine</a><br/>
<a href="#" id="lnk_erase" data-pressed="0" data-conv="20">Erase</a><br/>
</div>
<div id="dv_familiogram" style="float: left;width:500px;height: 500px;border:1px solid #000;overflow: hidden">
<svg id="svf" style="width:500px;height:500px"></svg>
</div>
</body>
</html>
问题是您在 dragged
中的 select 操作基于 Link 被点击的功能,而不是基于您拖动的形状类型。
您可以将 dragged
函数替换为多个函数(每个函数用于特定形状类型):
function dragged_conv1(d) {
d3.select(this).attr('cx', +d3.select(this).attr('cx') + d3.event.dx);
d3.select(this).attr('cy', +d3.select(this).attr('cy') + d3.event.dy);
}
function dragged_conv2(d) {
d3.select(this).attr('x', +d3.select(this).attr('x') + d3.event.dx);
d3.select(this).attr('y', +d3.select(this).attr('y') + d3.event.dy);
}
function dragged_conv34(d) {
this.x = this.x || 0;
this.y = this.y || 0;
this.x += d3.event.dx;
this.y += d3.event.dy;
d3.select(this).attr('transform', 'translate(' + this.x + ',' + this.y + ')');
}
并将每个函数绑定到 main
函数中的每个形状:
if (conv == 1) {
pxy = new Array();
container.append('circle') ... .on("drag", dragged_conv1)...;
}
if (conv == 2) {
pxy = new Array();
container.append('rect') ... .on("drag", dragged_conv2)...;
}
if (conv == 4) {
// ... some code here ...
container.append('polyline') ... .on("drag", dragged_conv34)...;
pxy = new Array();
}