2017-01-16 14 views
1

私が管理している境界線内にドラッグ可能なノードを保持しようとしています。 私は境界に達するとノードが停止し、マウスのどこにでもパスが伝わるのかどうかはわかりません。d3.jsリンクノードの境界線がリンクされていないパス

はここd3.jsを使用してJSFiddle

var width = 400, 
     height = 400; 

    var force = d3.layout.force() 
     .size([width, height]) 
     .on("tick", tick); 

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

    var link = svg.selectAll(".link"), 
     node = svg.selectAll(".node"); 

    function tick() { 
     text.attr("transform", transform); 
     link.attr("d", linkArc); 

     var radius = 15; 
     var dx = function(d) { 
     return Math.max(radius, Math.min(width - radius, d.x)) 
     } 
     var dy = function(d) { 
     return Math.max(radius, Math.min(height - radius, d.y)) 
     } 

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

     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; 
     }); 




    } 

    function explicitlyPosition() { 
     node.each(function(d) { 
     d.x = 0; 
     d.y = 0; 
     d.fixed = false; 
     }); 
     tick(); 
     node.each(function(d) { 
     d.fixed = true; 
     }); 
     force.resume(); 
    } 

    var graph = { 
     "nodes": [{ 
     "id": "aa", 
     "x": 100, 
     "y": 250, 
     "fixed": true 
     }, { 
     "id": "bb", 
     "x": 200, 
     "y": 200, 
     "fixed": true 
     }, { 
     "id": "cc", 
     "x": 200, 
     "y": 300, 
     "fixed": true 
     }, { 
     "id": "dd", 
     "x": 300, 
     "y": 250, 
     "fixed": true 
     }, { 
     "id": "ee", 
     "x": 350, 
     "y": 300, 
     "fixed": true 
     }, { 
     "id": "ff", 
     "x": 250, 
     "y": 250, 
     "fixed": true 
     }], 
     "links": [{ 
     "source": "aa", 
     "target": "bb", 
     "type": "type1" 
     }, { 
     "source": "bb", 
     "target": "cc", 
     "type": "type1" 
     }, { 
     "source": "cc", 
     "target": "dd", 
     "type": "type3" 
     }, { 
     "source": "bb", 
     "target": "dd", 
     "type": "type1" 
     }, { 
     "source": "bb", 
     "target": "dd", 
     "type": "type2" 
     }] 
    }; 

    var edges = []; 
    graph.links.forEach(function(e) { 
     var sourceNode = graph.nodes.filter(function(n) { 
      return n.id === e.source; 
     })[0], 
     targetNode = graph.nodes.filter(function(n) { 
      return n.id === e.target; 
     })[0]; 

     edges.push({ 
     source: sourceNode, 
     target: targetNode, 
     type: e.type 
     }); 
    }); 
    console.log(edges); 
    //any links with duplicate source and target get an incremented 'linknum' 
    for (var i = 0; i < edges.length; i++) { 
     if (i != 0 && 
     edges[i].source == edges[i - 1].source && 
     edges[i].target == edges[i - 1].target) { 
     edges[i].linknum = edges[i - 1].linknum + 1; 
     } else { 
     edges[i].linknum = 1; 
     }; 
    }; 

    force 
     .nodes(graph.nodes) 
     .links(edges) 
     .start(); 

    link = link.data(edges) 
     .enter().append("path") 
     .attr("class", function(d) { 
     return "link " + d.type; 
     }) 
     .attr("marker-end", function(d) { 
     return "url(#" + d.type + ")"; 
     }) 
     .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; 
     }) 
     .attr("d", linkArc); 

    var node_drag = self.force = d3.behavior.drag() 
     .on("dragstart", dragstart) 
     .on("drag", dragmove) 
     .on("dragend", dragend); 

    node = node.data(graph.nodes) 
     .enter().append("circle") 
     .attr("class", "node") 
     .attr("r", 8) 
     .call(node_drag); 


    function linkArc(d) { 
     var curve = 2; 
     var homogeneous = 3.2; 
     var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = Math.sqrt(dx * dx + dy * dy) * (d.linknum + homogeneous)/(curve * homogeneous); //linknum is defined above 
     return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
    } 

    function transform(d) { 

     return "translate(" + d.x + "," + d.y + ")"; 
    } 

    function dragstart(d, i) { 
     force.stop(); // stops the force auto positioning before you start dragging 
    } 

    function dragmove(d, i) { 
     d.px += d3.event.dx; 
     d.py += d3.event.dy; 
     d.x += d3.event.dx; 
     d.y += d3.event.dy; 
     tick(); 
    } 

    function dragend(d, i) { 
     d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff 
     tick(); 
     force.resume(); 
    } 

    var text = svg.append("g").selectAll("text") 
     .data(graph.nodes) 
     .enter().append("text") 
     .attr("x", 8) 
     .attr("y", ".31em") 
     .text(function(d) { 
     return d.id; 
     }); 

    // Per-type markers, as they don't inherit styles. 
    svg.append("svg:defs").selectAll("marker") 
     .data(["type1", "type2", "type3"]) 
     .enter().append("svg:marker") 
     .attr("id", String) 
     .attr("viewBox", "0 -5 10 10") 
     .attr("refX", 15) 
     .attr("refY", -1.5) 
     .attr("markerWidth", 6) 
     .attr("markerHeight", 6) 
     .attr("orient", "auto") 
     .append("svg:path") 
     .attr("d", "M0,-5L10,0L0,5"); 

新品ですが起こっていただきました!の例だと、私は本当にこの問題を解決するために見ているかわからない、任意のヘルプは素晴らしいだろう!

おかげ

答えて

1

あなたは代わりに内部tickで、dragmove内の境界を設定することができます

function dragmove(d, i) { 
    d.x = d.x > width ? width : d.x < 0 ? 0 : d.x + d3.event.dx; 
    d.y = d.y > height ? height : d.y < 0 ? 0 : d.y + d3.event.dy; 
    tick(); 
} 

ここにあなたのフィドルです:https://jsfiddle.net/0v21Lhk3/

+0

すごいです!どうもありがとう。 – MattStudios

+1

私はちょうどd.y行 "幅"は "高さ"を変更する必要があります気づいた。 – MattStudios

+0

ありがとうございます。 –

関連する問題