2017-06-15 15 views
0

グラフを作成しましたが、今は有向リンクを追加したいと思います。d3.jsの力指向のレイアウトの矢頭の大きさを調整する

リンク上でマウスを動かすと大きくなり、ノードをクリックすると大きくなり、この2つの機能がリンク上の矢印で混乱するという機能が必要なので、問題があります。

私はここでstackoverflowで見つかった多くのソリューションをtryiedしたが、何も私のために働いた...誰かが私を助けることができますか?おかげ

ここに私のコード:

<!DOCTYPE html> 
     <meta charset="utf-8"> 
     <title>Modifying a force layout v4</title> 

     <style> 

     .link { 
      stroke: #3B3B3B; 
      /*stroke-width: 1px;*/ 
     } 

     .node { 
      stroke: #000; 
      stroke-width: 1.5px; 
     } 

     .svg { 
      border:3px solid black; 
      border-radius:12px; 
      margin:auto; 
     } 
     #arrow { 
      fill:green; 
     } 

     </style> 
     <body> 
     Node: 
     <div id="log"></div> 
     Link: 
     <div id="log2"></div> 
     <script src="//d3js.org/d3.v4.js"></script> 
     <script> 



      var width = 960, 
      height = 500; 
      radius = 17; 

      var expnsed = false; 

      var color = d3.scaleOrdinal(d3.schemeCategory20); 

      var nodes = [], 
      links = []; 


      var charge = d3.forceManyBody().strength(-150); 
      var simulation = d3.forceSimulation() 
      .force("link", d3.forceLink().distance(130).strength(.7)) 
      .force("charge", charge) 
      // use forceX and forceY instead to change the relative positioning 
      // .force("centering", d3.forceCenter(width/2, height/2)) 
      .force("x", d3.forceX(width/2)) 
      .force("y", d3.forceY(height/2)) 
      .on("tick", tick); 


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

      svg.append("defs").append("marker") 
       .attr("id", "arrow") 
       .attr("viewBox", "0 -5 10 10") 
       .attr("refX", 15) 
       .attr("refY", 0) 
       .attr("markerWidth", 6) 
       .attr("markerHeight", 6) 
       .attr("orient", "auto") 
       //.attr("fill","red") 
      .append("svg:path") 
       .attr("d", "M0,-5L10,0L0,5"); 
      var url = "https://api.myjson.com/bins/lj6ob"; 
      d3.json(url, function(error, graph) { 
      if (error) throw error; 
      nodes = graph.nodes; 
      links=graph.links; 
      console.log("graph.links.length: "+links.length) 

      for (var i = 0; i < links.length; i++){ 
       links[i].source = find(links[i].source); 
       links[i].target = find(links[i].target); 
      } 

      console.log("Link source: " + links[0].target) 


      start(); 
      }) 

     function find(name){ 
      for(var i = 0; i < nodes.length; i++){ 
      if (name == nodes[i].id){ 
       console.log("name: " + name) 
       console.log("id: " + nodes[i].id) 
       return i; 
      } 
      } 
     } 


     function start() { 
      var nodeElements = svg.selectAll(".node").data(nodes, function(d){return d.id}); 
      var linkElements = svg.selectAll(".line").data(links).attr("class","links"); 
      //console.log(nodes) 
      nodeElements.enter().append("circle").attr("class", function(d) {return "node " + d.index; }).attr("r", 17).attr("fill", function(d) { return color(d.group); }); 
      linkElements.enter().insert("line", ".node").attr("class", "link").attr("stroke-width", function(d) { return Math.sqrt(d.value)*2;}); 

      d3.selectAll("line").attr("marker-end", "url(#arrow)"); 

      nodeElements.exit().remove(); 
      linkElements.exit().remove(); 

      simulation.nodes(nodes) 
      simulation.force("link").links(links) 
    // NOTE: Very important to call both alphaTarget AND restart in conjunction 
     // Restart by itself will reset alpha (cooling of simulation) 
     // but won't reset the velocities of the nodes (inertia) 

     //remove alpha for slow incoming!! 
     //.alpha(1) 
      simulation.alpha(1).restart(); 
     } 

     function tick() { 
      var nodeElements = svg.selectAll(".node"); 
      var linkElements = svg.selectAll(".link"); 

      linkElements.append("title") 
      .text(function(d) { return "value link: " + d.value; }); 

      linkElements.on("mouseover", function(d) { 
        var g = d3.select(this); // The node 
        document.getElementById('log2').innerHTML = '<br> '+d.value; 
        g.attr("stroke-width", function(d) { return Math.sqrt(d.value)*4; }) 
       }); 

      linkElements.on("mouseout", function(d) { 
      var g = d3.select(this); // The node 
      g.attr("stroke-width", function(d) { return Math.sqrt(d.value)*2; }) 
      }); 


      nodeElements.append("title") 
      .text(function(d) { 
       return "node name: "+d.id + ", node group: "+d.group; 
      }); 

      nodeElements.on("mouseout", function(d) { 
        var g = d3.select(this); // The node 
        g.attr("fill", function(d) { return color(d.group); }) 
       }) 
       .on("mouseover", function(d) { 
        document.getElementById('log').innerHTML = '<br> '+d.id; 
        var g = d3.select(this); // The node 
        g.attr("fill", "red") 
       }); 
      nodeElements.on("click",click); 

      nodeElements.call(d3.drag() 
       .on("start", dragstarted) 
       .on("drag", dragged) 
       .on("end", dragended)); 

      /*nodeElements.attr("cx", function(d,i) {return d.x; }) 
      .attr("cy", function(d) { return d.y; })*/ 
      nodeElements.attr("cx", function(d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); }) 
      .attr("cy", function(d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); }); 

      linkElements 
      .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 click(d) { 
      d3.select(this).attr("r", 
       function(d){if (d3.select(this).attr("r")==17) {radius = 23;return "23"}else{radius = 17; return "17"}} 
      ); 
      //expand(); 
      var E = "E"; 
      if(d.id == E && expand){ 
      expand=false; 
      //expand_2(); 
      } 
     }; 

     function expand(){ 
      console.log("expand") 
      b = createNode("A") 
      nodes.push(b); 
      start(); 
     } 

     function expand_2(){ 
      d3.json("nodes_2.json", function(error, graph) { 
      for(var i = 0; i < graph.nodes.length; i++){ 
       var n = graph.nodes[i]; 
       nodes.push(n); 
      } 
      for(var i = 0; i < graph.links.length; i++){ 
       graph.links[i].source = find(graph.links[i].source) 
       graph.links[i].target = find(graph.links[i].target) 
       var l = graph.links[i]; 
       links.push(l); 
      } 
      start(); 
      }) 
     } 

     function zoomed() { 
      g.attr("transform", d3.event.transform); 
     } 

     function dragstarted(d) { 
      if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
      d.fx = d.x; 
      d.fy = d.y; 
     } 

     function dragged(d) { 
      d.fx = d3.event.x; 
      d.fy = d3.event.y; 
     } 

     function dragended(d) { 
      if (!d3.event.active) simulation.alphaTarget(0); 
      d.fx = null; 
      d.fy = null; 
     } 
     function createNode(id) { 
      return {id: id, x: width/2, y:height/2} 
     } 

     </script> 

答えて

2

あなたがmarkerUnits="userSpaceOnUse"を定義する場合は、矢印に固定サイズを与えることができます。あなたの現在の大きさを再作成するには:

 svg.append("defs").append("marker") 
      .attr("id", "arrow") 
      .attr("viewBox", "0 -5 10 10") 
      .attr("refX", 15) 
      .attr("refY", 0) 
      .attr("markerUnits", "userSpaceOnUse") 
      .attr("markerWidth", 30) 
      .attr("markerHeight", 30) 
      .attr("orient", "auto") 

を使用すると、ホバー上のマーカーのサイズを変更したい場合は、最善の解決策は、第2のマーカー要素arrow-hoverを持っているかもしれません大きく、あなたは一時的にCSSを経由して交換すること:

line { 
    marker-end: url(#arrow); 
} 
line:hover { 
    marker-end: url(#arrow-hover); 
} 
+0

ありがとうございます、あなたのソリューションは問題ありませんが、私は右矢印を選択することができます私はラインをホバリングでサイズを変更する? –

+0

私はこの機能を使用ホバー上のリンクをサイズ変更するための意味: \t linkElements.on( "マウスオーバー" 機能(D){ \t \tするvar G = d3.select(この); \t g.attr(「ストローク-width」、関数(D){Math.sqrt(d.value)* 4を返す。 \t \t}) \t g.attr( "markerWidth"、20) \t \t .ATTR( "markerHeight"、20) ; \t}); しかし、私はラインの右のマーカーを選択することはできません... g.selectAll( "マーカー")も試しましたが、うまくいきませんでした... –

+0

マーカのIDが異なる必要があります。それらを、またはどれも、rezised得る。編集を参照してください。 – ccprog

関連する問題