簡體   English   中英

D3 不正確的拖動行為

[英]D3 incorrect drag behaviour

這是我之前的問題d3 rect in one group in interfering with rect in another group的后續

兩個問題:

  1. 不正確的拖動行為。 單擊第二個矩形拖動它時,它會跳到第三個矩形所在的位置。

  2. 我添加了一個匿名函數,當 svg 在任何地方點擊時運行。 這應該添加一個新的矩形。 然而,這就是工作。

我知道每個問題我應該只有一個問題,但這些是相關的,我懷疑它們會一起解決。

 <!DOCTYPE html> <meta charset="utf-8"> <style> /*.active { stroke: #000; stroke-width: 2px; }*/ </style> <svg width="960" height="500"></svg> <script src="//d3js.org/d3.v4.min.js"></script> <script> var margin = { top: 20, right: 20, bottom: 20, left: 20 }, width = 600 - margin.left - margin.right, height = 600 - margin.top - margin.bottom; var svg = d3.select("svg"); var data = [{ x: 200 }, { x: 300 }, { x: 400 }]; var groove = svg.append("g") .attr("class", "groove_group"); groove.append("rect") .attr("x", 100) .attr("y", 150) .attr("rx", 2) .attr("ry", 2) .attr("height", 6) .attr("width", 800) .style("fill", "grey"); groove.append("rect") .attr("x", 102) .attr("y", 152) .attr("rx", 2) .attr("ry", 2) .attr("height", 2) .attr("width", 796) .style("fill", "black"); // create group var group = svg.selectAll(null) .data(data) .enter().append("g") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) .on("click", removeElement); group.append("rect") .attr("x", function(d) { return dx; }) .attr("y", 100) .attr("height", 100) .attr("width", 15) .style("fill", "lightblue") .attr('id', function(d, i) { return 'handle_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); group.append("text") .attr("x", function(d) { return dx }) .attr("y", 100) .attr("text-anchor", "start") .style("fill", "black") .text(function(d) { return "x:" + dx }); // create group var group = svg.selectAll("g") .data(data) .enter().append("g") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) .on("click", removeElement); group.append("rect") .attr("x", function(d) { return dx; }) .attr("y", 200) .attr("height", 100) .attr("width", 15) .style("fill", "lightblue") .attr('id', function(d, i) { return 'handle_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); group.append("text") .attr("x", function(d) { return dx }) .attr("y", 200) .attr("text-anchor", "start") .style("fill", "black") .text(function(d) { return "x:" + dx }); svg.on("click", function() { var coords = d3.mouse(this); var newData = { x: d3.event.x, } data.push(newData); group.selectAll("rect") .data(data) .enter() .append("rect") .attr("x", function(d) { return dx; }) .attr("y", 200) .attr("height", 100) .attr("width", 15) .style("fill", "steelblue") .attr('id', function(d, i) { return 'rect_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); }); function dragstarted(d) { d3.select(this).raise().classed("active", true); } function dragged(d) { d3.select(this).select("text") .attr("x", dx = d3.event.x); d3.select(this).select("rect") .attr("x", dx = d3.event.x); } function dragended(d) { d3.select(this) .classed("active", false); } function removeElement(d) { d3.event.stopPropagation(); data = data.filter(function(e) { return e != d; }); d3.select(this) .remove(); } </script>

為了正確的拖放行為,像這樣重寫你的代碼:

 var margin = { top: 20, right: 20, bottom: 20, left: 20 }, width = 600 - margin.left - margin.right, height = 600 - margin.top - margin.bottom; var svg = d3.select("svg"); var data = [{ x: 200 }, { x: 300 }, { x: 400 }]; var groove = svg.append("g") .attr("class", "groove_group"); groove.append("rect") .attr("x", 100) .attr("y", 150) .attr("rx", 2) .attr("ry", 2) .attr("height", 6) .attr("width", 800) .style("fill", "grey"); groove.append("rect") .attr("x", 102) .attr("y", 152) .attr("rx", 2) .attr("ry", 2) .attr("height", 2) .attr("width", 796) .style("fill", "black"); // create group var group = svg.selectAll(null) .data(data) .enter().append("g") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) .on("click", removeElement); group.append("rect") .attr("x", function(d) { return dx; }) .attr("y", 100) .attr("height", 100) .attr("width", 15) .style("fill", "lightblue") .attr('id', function(d, i) { return 'handle_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); group.append("text") .attr("x", function(d) { return dx }) .attr("y", 100) .attr("text-anchor", "start") .style("fill", "black") .text(function(d) { return "x:" + dx }); svg.on("click", function() { var coords = d3.mouse(this); var newData = { x: d3.event.x, } data.push(newData); group.selectAll("rect") .data(data) .exit() .enter() .append("rect") .attr("x", function(d) { return dx; }) .attr("y", 200) .attr("height", 100) .attr("width", 15) .style("fill", "steelblue") .attr('id', function(d, i) { return 'rect_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); }); function dragstarted(d) { d3.select(this).raise().classed("active", true); } function dragged(d) { d3.select(this).select("text") .attr("x", dx = d3.event.x); d3.select(this).select("rect") .attr("x", dx = d3.event.x); } function dragended(d) { d3.select(this) .classed("active", false); } function removeElement(d) { d3.event.stopPropagation(); data = data.filter(function(e) { return e != d; }); d3.select(this) .remove(); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script> <svg width="960" height="500"></svg>

但是,添加新元素有什么問題,我不知道。

以下是對您的問題的解釋:

  1. 您正在重新分配var groups ,也就是說,您的代碼中有兩個var groups ,最后一個覆蓋了第一個。 只需刪除最后一個變量。
  2. 在追加新矩形的函數中,您使用的是選擇矩形的更新選擇。 但是,您的輸入選擇會附加組 ( <g> ) 元素,而不是矩形。

看看重構的函數,它將數據綁定到一個新創建的組並將矩形附加到該組:

var newGroup = svg.selectAll(".group")
    .data(data, function(d) {
        return d.x
    })
    .enter()
    .append("g")
    //etc...

newGroup.append("rect")
    //etc...

此外,在數據綁定中使用鍵選擇,這樣您就可以確切地知道正在拖動的矩形:

.data(data, function(d){return d.x})

這是帶有這些更改的代碼:

 <!DOCTYPE html> <meta charset="utf-8"> <style> /*.active { stroke: #000; stroke-width: 2px; }*/ </style> <svg width="960" height="500"></svg> <script src="//d3js.org/d3.v4.min.js"></script> <script> var margin = { top: 20, right: 20, bottom: 20, left: 20 }, width = 600 - margin.left - margin.right, height = 600 - margin.top - margin.bottom; var svg = d3.select("svg"); var data = [{ x: 200 }, { x: 300 }, { x: 400 }]; var groove = svg.append("g") .attr("class", "groove_group"); groove.append("rect") .attr("x", 100) .attr("y", 150) .attr("rx", 2) .attr("ry", 2) .attr("height", 6) .attr("width", 800) .style("fill", "grey"); groove.append("rect") .attr("x", 102) .attr("y", 152) .attr("rx", 2) .attr("ry", 2) .attr("height", 2) .attr("width", 796) .style("fill", "black"); // create group var group = svg.selectAll(null) .data(data, function(d){return dx}) .enter().append("g") .attr("class", "group") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) .on("click", removeElement); group.append("rect") .attr("x", function(d) { return dx; }) .attr("y", 100) .attr("height", 100) .attr("width", 15) .style("fill", "lightblue") .attr('id', function(d, i) { return 'handle_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); group.append("text") .attr("x", function(d) { return dx }) .attr("y", 100) .attr("text-anchor", "start") .style("fill", "black") .text(function(d) { return "x:" + dx }); svg.on("click", function() { var coords = d3.mouse(this); var newData = { x: coords[0], } data.push(newData); var newGroup = svg.selectAll(".group") .data(data, function(d){return dx}) .enter() .append("g") .attr("class", "group") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) .on("click", removeElement); newGroup.append("rect") .attr("x", function(d) { return dx; }) .attr("y", 200) .attr("height", 100) .attr("width", 15) .style("fill", "steelblue") .attr('id', function(d, i) { return 'rect_' + i; }) .attr("rx", 6) .attr("ry", 6) .attr("stroke-width", 2) .attr("stroke", "black"); }); function dragstarted(d) { d3.select(this).raise().classed("active", true); } function dragged(d) { d3.select(this).select("text") .attr("x", dx = d3.event.x); d3.select(this).select("rect") .attr("x", dx = d3.event.x); } function dragended(d) { d3.select(this) .classed("active", false); } function removeElement(d) { d3.event.stopPropagation(); data = data.filter(function(e) { return e != d; }); d3.select(this) .remove(); } </script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM