2017-10-08 16 views
0

私はd3jsを使ってsvgをドラッグアンドドロップしています。 2つの問題があり、私はそれらがお互いに関連していると思います。D3jsはオブジェクトをドラッグアンドドロップし、ドロップされた場所を検出します。

  1. 円をドロップすると、四角形にドロップされたことを検出する必要があります。私が見てきたいくつかの例では、マウスのx座標とy座標を使用していますが、完全に理解していません。

  2. もう1つの問題は、四角形の後ろに円が表示されることです。円と矩形が作成された順番を変えずに円が周りを移動しているときに、それを前面に移動する方法はありますか(円を最初に作成し、次に矩形を作成する)。

var width = window.innerWidth, 
 
    height = window.innerHeight; 
 

 
var drag = d3.behavior.drag() 
 
    .on("dragstart", dragstarted) 
 
    .on("drag", dragged) 
 
    .on("dragend", dragended); 
 

 
//create circle and space evenly 
 
var svg = d3.select("body") 
 
    .append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 
var circle = d3.select("svg") 
 
    .append("circle") 
 
    .attr("cx", 50) 
 
    .attr("cy", 30) 
 
    .attr("r", 15) 
 
    .attr("transform", "translate(0,0)") 
 
    .style("stroke", "black") 
 
    .call(drag); 
 

 

 
function dragstarted(d) { 
 
    d3.event.sourceEvent.stopPropagation(); 
 
} 
 

 
function dragged(d) { 
 
    d3.select(this).attr("transform", "translate(" + [d3.event.x, d3.event.y] + ")"); 
 
} 
 

 
function dragended(d) { 
 
    d3.event.sourceEvent.stopPropagation(); 
 

 
    // here would be some way to detect if the circle is dropped inside the rect. 
 
    
 
} 
 

 
var ellipse = svg.append("rect") 
 
     .attr("x", 150) 
 
     .attr("y", 50) 
 
     .attr("width", 50) 
 
     .attr("height", 140) 
 
     .attr("fill", "green");
<script src="https://d3js.org/d3.v3.min.js"></script>

すべてのヘルプは高く評価されます。

答えて

0

バウンディングクライアントの四角形が含まれるように更新されますが、存在する任意の数の四角形を反復処理します。 New Fiddle here.

これは私の解決方法です。小さな "moveToBack"ヘルパー関数seen hereを使用して、表示される順序を変更せずに矩形を背面に移動しました。

円と矩形の位置を取得するために、私はvanilla js getBoundingClientRect()メソッドを大量に使用しました。これらはすべてthis JS Fiddleで一緒に見ることができます。

var width = window.innerWidth, 
    height = window.innerHeight; 

var drag = d3.behavior.drag() 
    .on("dragstart", dragstarted) 
    .on("drag", dragged) 
    .on("dragend", dragended); 

//create circle and space evenly 
var svg = d3.select("body") 
    .append("svg") 
    .attr("width", width) 
    .attr("height", height); 

var circle = d3.select("svg") 
    .append("circle") 
    .attr("r", 15) 
    .attr("transform", "translate(50,30)") 
    .style("stroke", "black") 
    .attr("id", "circle") 
    .call(drag); 


d3.selection.prototype.moveToBack = function() { 
    return this.each(function() { 
    var firstChild = this.parentNode.firstChild; 
    if (firstChild) { 
     this.parentNode.insertBefore(this, firstChild); 
    } 
    }); 
}; 

var rect = svg.append("rect") 
     .attr("x", 150) 
     .attr("y", 50) 
     .attr("width", 50) 
     .attr("height", 140) 
     .attr("fill", "green") 
     .attr("id", "rect") 
     .moveToBack(); 

var rect2 = svg.append("rect") 
     .attr("x", 350) 
     .attr("y", 50) 
     .attr("width", 50) 
     .attr("height", 140) 
     .attr("fill", "green") 
     .attr("id", "rect") 
     .moveToBack(); 

function dragstarted(d) { 
    d3.event.sourceEvent.stopPropagation(); 
} 

function dragged(d) { 
    d3.select(this).attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")"); 
} 

function dragended(d) { 
    // Define boundary 
    var rects = document.querySelectorAll("rect"); 
    for (var i = 0; i < rects.length; i++) { 
    var rectDimensions = rects[i].getBoundingClientRect(); 
    var xmin = rectDimensions.x; 
    var ymin = rectDimensions.y; 
    var xmax = rectDimensions.x + rectDimensions.width; 
    var ymax = rectDimensions.y + rectDimensions.height; 
    // Get circle position 
    var circlePos = document.getElementById("circle").getBoundingClientRect(); 
    var x1 = circlePos.x; 
    var y1 = circlePos.y; 
    var x2 = circlePos.x + circlePos.width; 
    var y2 = circlePos.y + circlePos.height; 
    if(x2 >= xmin && x1 <= xmax && y2 >= ymin && y1 <= ymax) { 
     rects[i].setAttribute("fill", "red"); 
    } else { 
     rects[i].setAttribute("fill", "green"); 
    } 
    } 
    d3.event.sourceEvent.stopPropagation(); 
} 
+0

ありがとうございました。私はバウンディングボックスを含まないソリューションを探していました。なぜなら、ただ1つの長方形があり、アイテムが長方形にドロップされているからです。 [リンク](http://bl.ocks.org/jmuyskens/8993967)。ボックスの上に要素があるかどうかに基づいてボックスがドラッグされると、これは赤く変わります。 – ben

+0

@benコードと[JS Fiddle](https://jsfiddle.net/heybignick/a0447ah2/7/)を更新して、任意の数の矩形を繰り返し処理しました。 – Nick

関連する問題