我有一个 SVG 容器,其中包含许多元素,每个元素包含一个矩形和一些水平数组中的文本元素。
我想单击一个元素并拖动到其他元素之一。第一个元素和拖过的元素应该突出显示 - 就像在普通文本编辑器选择中一样。
最后,我想知道选择的第一个和最后一个元素,以便我可以访问它们的数据。
我使用 d3 拖动行为进行了尝试,但是: 1. 无法突出显示中间元素 2. dragend 没有告诉我哪个元素是最后一个元素。
还尝试使用鼠标事件,但是: 1. 如果鼠标移回开头,我可以突出显示每个中间项目,但不容易删除突出显示。2. 如果鼠标移出容器,我可能会错过鼠标向上事件,留下突出显示的元素。3. 除非我收集所有鼠标悬停事件,否则我仍然不知道要完成哪个元素。
我实际上并不想移动选定的元素 - 只知道选择的第一个和最后一个。
我创建了这个小提琴来说明问题:http: //jsfiddle.net/avowkind/up54b/5/
HTML
<svg class='demosvg' version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<rect width="400" height="220"></rect>
<g id="container" transform="translate(10,10)"></g>
</svg>
Javascript
var mydata = [1, 2, 3, 4, 5];
/* each box is a group with a rect and text
positioned according to the data value
on drag/drop we want to know the dragged element, and the one it is dropped on.
we would like to highlight all the intervening elements too.
Ultimately we just want a result e.g. 2 was dragged to 5
*/
var boxg = d3.select('#container').selectAll('g').data(mydata).enter()
.append('svg:g')
.attr('id', function (d, i) {
return "b" + d;
})
.attr('transform', function (d, i) { return "translate(" + d * 50 + ",80)";})
.call(d3.behavior.drag()
.on("dragstart", function (d, i) {d3.select(this).classed("selected", true); })
.on("drag", function (d, i) {
// which element are we over here - to highlight it
var el = document.elementFromPoint(d3.event.x, d3.event.y);
console.log(el);
})
.on("dragend", function (d, i) {
console.log(d);
console.log(this);
console.log(d3.event);
// turn off all highlights
d3.selectAll('#container g').classed("selected", false);
// Which box got dropped on here ?
})
);
boxg.append('svg:rect')
.classed('box', true)
.attr('width', 40).attr('height', 40);
boxg.append('svg:text')
.text(function(d,i) { return d; })
.attr('dx', 15).attr('dy', 20);
CSS
.demosvg { fill:silver;}
.box { fill:lightblue;}
text { fill:black;}
.selected .box{ fill:gold;}
谢谢安德鲁