2017-02-27 9 views
0

各ノードのドラッグ領域を円/矩形で制限する必要があるd3.jsのアプリケーションがあります。このドラッグ領域は、各ノードについて静的であってもよく、そのjsonデータに含まれてもよい。 ここにhttp://jsfiddle.net/InferOn/5wssqqdw/1/例が見つかりましたが、私の要件を満たしていません。私はこのようにしたい何各ノードのドラッグ領域を制限するd3.js

:ここ

enter image description here

は、私はこのようなものを行う必要があります私の例です。

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 

 
<body> 
 
<script 
 
    src="https://code.jquery.com/jquery-3.1.1.min.js" 
 
    integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" 
 
    crossorigin="anonymous"></script> 
 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
 
    <style> 
 
    body{ 
 
\t background:url(images/bg.jpg) repeat; 
 
} 
 
\t svg{ 
 
\t margin: 0 auto; 
 
\t display: block; 
 
} 
 
.link{ 
 
\t stroke: #51565b; 
 
\t stroke-width:20; \t 
 
\t stroke-opacity: 1; 
 
\t 
 
} 
 
    </style> 
 
    <script> 
 
    var width = 800, 
 
    height = 600 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 

 
var force = d3.layout.force() 
 
    .gravity(1) 
 
    .linkDistance(function (d) { 
 
    return d.distance; 
 
\t }) 
 
.charge(-40000) 
 
.size([width, height]); 
 

 
var datajson = { 
 
    "nodes": [{ 
 
    "name": "a", 
 
    "node_id": "10", 
 
    "group": 2, 
 
\t "node_img" : "http://loremflickr.com/320/240/dog" 
 
    }, { 
 
    "name": "b", 
 
    "group": 1, 
 
\t "node_id": "11", 
 
\t "node_img" : "http://loremflickr.com/320/240/dog" 
 
    }, { 
 
    "name": "c", 
 
    "group": 1, 
 
\t "node_id": "12", 
 
\t "node_img" : "http://loremflickr.com/320/240/dog" 
 
    } 
 
    ], 
 
    "links": [{ 
 
    "source": 0, 
 
    "target": 1, 
 
    "value": 1, 
 
    "distance": 400 
 
    }, { 
 
    "source": 1, 
 
    "target": 2, 
 
    "value": 2, 
 
    "distance": 300 
 
    }, { 
 
    "source": 2, 
 
    "target": 0, 
 
    "value": 3, 
 
    "distance": 300 
 
    }] 
 
} 
 

 
var numNodes = datajson.nodes.length 
 
var r = 20; 
 
datajson.nodes.forEach(function(node, i) { 
 
    node.x = width/2 + r * Math.sin(2 * Math.PI * i/numNodes) 
 
    node.y = height/2 + r * Math.cos(2 * Math.PI * i/numNodes) 
 
}) 
 

 
force 
 
    .nodes(datajson.nodes) 
 
    .links(datajson.links) 
 
    .start(); 
 

 
var drag = force.drag() 
 
    .on("drag", dblclick); 
 

 
var link = svg.selectAll(".link") 
 
    .data(datajson.links) 
 
    .enter().append("line") 
 
    .attr("class", "link"); 
 

 
var node = svg.selectAll(".node") 
 
    .data(datajson.nodes) 
 
    .enter().append("g") 
 
    .attr("class", function(d) { return "node "+"class_"+d.node_id}) 
 
    .call(force.drag); 
 

 
\t 
 
    \t //circle 
 
\t var circle = node.append("circle") 
 
\t .attr("r", 55) 
 
\t .attr("id", function(d) { return d.node_id }) 
 
\t .style("fill", function (d) { return 'rgba(81,86,91,1)'; }) 
 
\t .attr("class", function(d) { return "circle circle_"+d.node_id }); 
 
\t 
 
\t //image 
 
node.append("image") 
 
    .attr("x", -37) 
 
    .attr("y", -37) 
 
    .attr("width", 75) 
 
    .attr("height", 75) 
 
    .attr("xlink:href", function(d) { 
 
    return d.node_img; 
 
    }); 
 
    
 
force.on("tick", function() { 
 
    link.attr("x1", function(d) { 
 
     return d.source.x; 
 
    }) 
 
    .attr("y1", function(d) { 
 
     return d.source.y; 
 
    }) 
 
    .attr("x2", function(d) { 
 
     return d.target.x; 
 
    }) 
 
    .attr("y2", function(d) { 
 
     return d.target.y; 
 
    }); 
 

 
    node.attr("transform", function(d) { 
 
    return "translate(" + d.x + "," + d.y + ")"; 
 
    }); 
 
}); 
 

 

 
function dblclick(d) { 
 

 
} 
 
    
 
    </script> 
 
</body>

答えて

1

ここでこれを行うための一つの方法です:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 

 
<body> 
 
    <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> 
 
    <script src="http://d3js.org/d3.v3.min.js"></script> 
 
    <style> 
 
    body { 
 
     background: url(images/bg.jpg) repeat; 
 
    } 
 
    
 
    svg { 
 
     margin: 0 auto; 
 
     display: block; 
 
    } 
 
    
 
    .link { 
 
     stroke: #51565b; 
 
     stroke-width: 20; 
 
     stroke-opacity: 1; 
 
    } 
 
    </style> 
 
    <script> 
 
    var width = 800, 
 
     height = 600 
 

 
    var svg = d3.select("body").append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    var force = d3.layout.force() 
 
     .gravity(1) 
 
     .linkDistance(function(d) { 
 
     return d.distance; 
 
     }) 
 
     .charge(-40000) 
 
     .size([width, height]); 
 

 
    var datajson = { 
 
     "nodes": [{ 
 
     "name": "a", 
 
     "node_id": "10", 
 
     "group": 2, 
 
     "node_img": "http://loremflickr.com/320/240/dog", 
 
     "drag_radius": 150 
 
     }, { 
 
     "name": "b", 
 
     "group": 1, 
 
     "node_id": "11", 
 
     "node_img": "http://loremflickr.com/320/240/dog", 
 
     "drag_radius": 200 
 
     }, { 
 
     "name": "c", 
 
     "group": 1, 
 
     "node_id": "12", 
 
     "node_img": "http://loremflickr.com/320/240/dog", 
 
     "drag_radius": 100 
 
     }], 
 
     "links": [{ 
 
     "source": 0, 
 
     "target": 1, 
 
     "value": 1, 
 
     "distance": 400 
 
     }, { 
 
     "source": 1, 
 
     "target": 2, 
 
     "value": 2, 
 
     "distance": 300 
 
     }, { 
 
     "source": 2, 
 
     "target": 0, 
 
     "value": 3, 
 
     "distance": 300 
 
     }] 
 
    } 
 

 
    var numNodes = datajson.nodes.length 
 
    var r = 20; 
 
    datajson.nodes.forEach(function(node, i) { 
 
     node.x = width/2 + r * Math.sin(2 * Math.PI * i/numNodes) 
 
     node.y = height/2 + r * Math.cos(2 * Math.PI * i/numNodes) 
 
    }) 
 

 
    force 
 
     .nodes(datajson.nodes) 
 
     .links(datajson.links) 
 
     .start(); 
 

 
    var drag = force.drag() 
 
     .on("drag", drag) 
 
     .on("dragstart", dragstart) 
 
     .on("dragend", dragend); 
 

 
    var link = svg.selectAll(".link") 
 
     .data(datajson.links) 
 
     .enter().append("line") 
 
     .attr("class", "link"); 
 

 
    var node = svg.selectAll(".node") 
 
     .data(datajson.nodes) 
 
     .enter().append("g") 
 
     .attr("class", function(d) { 
 
     return "node " + "class_" + d.node_id 
 
     }) 
 
     .call(force.drag); 
 

 

 
    //circle 
 
    var circle = node.append("circle") 
 
     .attr("r", 55) 
 
     .attr("id", function(d) { 
 
     return d.node_id 
 
     }) 
 
     .style("fill", function(d) { 
 
     return 'rgba(81,86,91,1)'; 
 
     }) 
 
     .attr("class", function(d) { 
 
     return "circle circle_" + d.node_id 
 
     }); 
 

 
    //image 
 
    node.append("image") 
 
     .attr("x", -37) 
 
     .attr("y", -37) 
 
     .attr("width", 75) 
 
     .attr("height", 75) 
 
     .attr("xlink:href", function(d) { 
 
     return d.node_img; 
 
     }); 
 

 
    force.on("tick", function() { 
 
     link.attr("x1", function(d) { 
 
      return d.source.x; 
 
     }) 
 
     .attr("y1", function(d) { 
 
      return d.source.y; 
 
     }) 
 
     .attr("x2", function(d) { 
 
      return d.target.x; 
 
     }) 
 
     .attr("y2", function(d) { 
 
      return d.target.y; 
 
     }); 
 

 
     node.attr("transform", function(d) { 
 
     return "translate(" + d.x + "," + d.y + ")"; 
 
     }); 
 
    }); 
 

 
    function drag(d) { 
 
     var dx = d.orig_x - d.px 
 
      dy = d.orig_y - d.py, 
 
      dd = Math.sqrt((dx * dx) + (dy * dy)); 
 
     // am I out of bounds 
 
     if (dd >= d.drag_radius - 55){ 
 
     // set to previous values 
 
     d.px = d.last_x; 
 
     d.py = d.last_y; 
 
     } 
 
     // remember previous values 
 
     d.last_x = d.px; 
 
     d.last_y = d.py; 
 
    } 
 
    
 
    function dragstart(d) { 
 
     // original position 
 
     if (!d.orig_x) d.orig_x = d.x; 
 
     if (!d.orig_y) d.orig_y = d.y; 
 
    
 
     // draw bounds circle 
 
     d.bounds_obj = svg.append('circle') 
 
     .attr("transform", "translate(" + d.orig_x + "," + d.orig_y + ")") 
 
     .attr("r", d.drag_radius) 
 
     .style("fill", "none") 
 
     .style("stroke", "steelblue") 
 
     .style("stroke-width", "2px"); 
 
    } 
 
    function dragend(d) { 
 
     // remove circle and clean-up 
 
     d.bounds_obj.remove(); 
 
     d.bounds_obj = undefined; 
 
    } 
 
    </script> 
 
</body>

+0

こんにちは、それは一つの例外を除いて、予想通り、制限領域の円が一緒に動いている作品各ノードは、ドレーン中にノードの位置を変更できないように(外側の円)を固定することができます。あなたのおかげで助けてくれてありがとうございます。 – Subrata

+0

@Subrata、各ドラッグの後に境界円がノードの新しい位置を囲むように移動することを意味しますか? – Mark

+0

はい@マーク、境界円。 – Subrata

関連する問題