2017-04-20 45 views
0

シナリオ:d3js複数ネットワークの問題

私は複数のネットワークをレンダリングしています。

単一ノード、複数の接続されたノードネットワークで構成されています。

ドラッグされたときにノードが重ならないように、ネットワーク全体が相対位置を維持するように、d3-force(シミュレーション)をアタッチしようとしています。

多人数の力を使っていますか?

問題:シミュレーションの負荷は(simulation.restart())、ネットワーク全体が離れて

  1. を広げ続けています。すべてのノード/ネットワークは無期限に移動し続けます。
  2. あるネットワークのノードをドラッグしても、他のすべてのネットワークが移動します。

誰かが私に適切な解決策を教えていただければ幸いです。

相続人の小さなフィドル

https://jsfiddle.net/pdubey84/or0tn49k/2/

Network

var nodes = [ 
    { id: "mammal", group: 0, label: "Mammals", level: 1 }, 
    { id: "dog" , group: 0, label: "Dogs" , level: 2 }, 
    { id: "cat" , group: 0, label: "Cats" , level: 2 }, 
    { id: "fox" , group: 0, label: "Foxes" , level: 2 }, 
    { id: "elk" , group: 0, label: "Elk" , level: 2 }, 
    { id: "insect", group: 1, label: "Insects", level: 1 }, 
    { id: "ant" , group: 1, label: "Ants" , level: 2 }, 
    { id: "bee" , group: 1, label: "Bees" , level: 2 }, 
    { id: "fish" , group: 2, label: "Fish" , level: 1 }, 
    { id: "carp" , group: 2, label: "Carp" , level: 2 }, 
    { id: "pike" , group: 2, label: "Pikes" , level: 2 }, 
    { id: "pike" , group: 3, label: "Pikes" , level: 1 }, 
    { id: "pike" , group: 4, label: "Pikes" , level: 1 }, 
    { id: "pike" , group: 4, label: "Pikes" , level: 1 }, 
    { id: "foo" , group: 4, label: "foo" , level: 1 }, 
    { id: "bar" , group: 4, label: "bar" , level: 1 } 
] 

var links = [ 
    { target: "mammal", source: "dog" , strength: 0.7 }, 
    { target: "mammal", source: "cat" , strength: 0.7 }, 
    { target: "mammal", source: "fox" , strength: 0.7 }, 
    { target: "mammal", source: "elk" , strength: 0.7 }, 
    { target: "insect", source: "ant" , strength: 0.7 }, 
    { target: "insect", source: "bee" , strength: 0.7 }, 
    { target: "fish" , source: "carp", strength: 0.7 }, 
    { target: "fish" , source: "pike", strength: 0.7 }, 
    { target: "cat" , source: "elk" , strength: 0.1 }, 
    { target: "carp" , source: "ant" , strength: 0.1 }, 
    { target: "elk" , source: "bee" , strength: 0.1 }, 
    { target: "dog" , source: "cat" , strength: 0.1 }, 
    { target: "fox" , source: "ant" , strength: 0.1 }, 
    { target: "pike" , source: "cat" , strength: 0.1 }, 
    { target: "foo" , source: "bar" , strength: 0.1 } 
] 



function getNodeColor(node, neighbors) { 
    return 'red' 
} 


function getLinkColor(node, link) { 
    return '000' 
} 

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

var svg = d3.select('svg') 
svg.attr('width', width).attr('height', height) 

// simulation setup with all forces 
var linkForce = d3 
    .forceLink() 
    .id(function (link) { return link.id }) 
    .strength(function (link) { return link.strength }) 

var simulation = d3 
    .forceSimulation() 
    .force('link', linkForce) 
    .force('charge', d3.forceManyBody().strength(-500).distanceMax(50)) 
    .force('center', d3.forceCenter(width/2, height/2)) 


var dragDrop = d3.drag().on('start', function (node) { 
    node.fx = node.x 
    node.fy = node.y 
}).on('drag', function (node) { 
    simulation.alphaTarget(0.7).restart() 
    node.fx = d3.event.x 
    node.fy = d3.event.y 
}).on('end', function (node) { 
    if (!d3.event.active) { 
    simulation.alphaTarget(0) 
    } 
    node.fx = null 
    node.fy = null 
}) 

var linkElements = svg.append("g") 
    .attr("class", "links") 
    .selectAll("line") 
    .data(links) 
    .enter().append("line") 
    .attr("stroke-width", 1) 
     .attr("stroke", "rgba(50, 50, 50, 0.2)") 

var nodeElements = svg.append("g") 
    .attr("class", "nodes") 
    .selectAll("circle") 
    .data(nodes) 
    .enter().append("circle") 
    .attr("r", 10) 
    .attr("fill", getNodeColor) 
    .call(dragDrop) 


simulation.nodes(nodes).on('tick',() => { 
    nodeElements 
    .attr('cx', function (node) { return node.x }) 
    .attr('cy', function (node) { return node.y }) 
    linkElements 
    .attr('x1', function (link) { return link.source.x }) 
    .attr('y1', function (link) { return link.source.y }) 
    .attr('x2', function (link) { return link.target.x }) 
    .attr('y2', function (link) { return link.target.y }) 
}) 

simulation.force("link").links(links) 

答えて

0

どちらの行動が期待されています。離れて拡散

  1. ネットワーク::これは、あなたがこれらの問題のために何ができるかである私は、あなたがシミュレーションのみの300ティックを実行したときにロードされているので、ドラッグ機能の話をしているとします。その場合はsimulation.alphaTargetの代わりにsimulation.alphaを使用してください。あなたがd3.forceCenter()を使用しているので起こります:あなたは一つのネットワーク、すべてのネットワークの動きをドラッグすると

    simulation.alpha(0.7).restart(); 
    
  2. simulation.alphaはエントロピーを制御するための正しい方法です。 APIによれば:すべてのノードの平均位置(重心すべてのノードが同じ重みを持っている場合)が所定の位置になるように

    センタリング力が均一にノードを変換します。あなたが最初にドラッグしたとき(強調鉱山)あなたが何ができるか

は、この力をキャンセルされます。https://jsfiddle.net/yjkgdgad/

+0

ありがとう:ここ

simulation.force("center", null) 

は、これら二つの変更であなたのフィドルです@Gerardo ...私はあなたのソリューションを試しましたが、問題はまだ同じです....コンポーネントをドラッグしようとするたびに、他の接続されているコンポーネントがすべて動き始めます....その種類の問題私が大規模なネットワークをたくさん持っているとき、私は何らかの形で各コンポーネントを識別してから、それらのコンポーネントにのみ強制して、他のものを動かすことができないかどうか疑問に思っています。思考? – prgrmr

+0

さて、それは* 3番目の問題です。それはあなたの質問にはありません。それは、あなたがシミュレーションを再加熱しているために起こります。 –

+0

こんにちは@gerardo ...私はそれをバグして申し訳ありませんが、私はたくさんのことを試しましたが、私が言及した第3の問題は依然として残っています。お互いに干渉しないように、複数のコンポーネントに異なる力を持たせる方法を知っていますか? – prgrmr