2016-05-29 4 views
0

私はd3 JSの初心者です。私は任意のノード(マウスオーバーイベント)上でマウスを移動するたびに、すべてのターゲットノードと対応するリンクをハイライト表示する必要があります。これを行うにはどうすればよいですか? 私の現在のコードは次のとおりです。d3階層エッジバンドルでソースノードとそのすべてのターゲットノードと対応するリンクをハイライトする方法

<html> 
    <head> 

     <style> 
      .node { 
       font: 11px "Helvetica Neue", Helvetica, Arial, sans-serif; 
      } 
      .link { 
       stroke: steelblue; 
       stroke-opacity: .4; 
       fill: none; 
      } 
     </style> 

    </head> 
    <body> 
      <script src="http://d3js.org/d3.v3.min.js"></script> 
      <script> 
      var classes=[ 
{"name":"a","size":3938,"imports":["b","f"]}, 
{"name":"b","size":3938,"imports":[]}, 
{"name":"c","size":3938,"imports":["a"]}, 
{"name":"d","size":3938,"imports":[]}, 
{"name":"e","size":3938,"imports":[]}, 
{"name":"f","size":3938,"imports":[]} 


]; 
        var diameter = 960, 
         radius = diameter/2, 
         innerRadius = radius - 120; 
        var cluster = d3.layout.cluster() 
         .size([360, innerRadius]); 

        var bundle = d3.layout.bundle(); 

        var line = d3.svg.line.radial() 
         .interpolate("bundle") 
         .tension(.85) 
         .radius(function(d) { return d.y; }) 
         .angle(function(d) { return d.x/180 * Math.PI; }); 

        var svg = d3.select("body").append("svg") 
         .attr("width", diameter) 
         .attr("height", diameter) 
         .append("g") 
         .attr("transform", "translate(" + radius + "," + radius + ")"); 



         var nodes = cluster.nodes(packageHierarchy(classes)), 
          links = packageImports(nodes); 

         svg.selectAll(".link") 
          .data(bundle(links)) 
         .enter().append("path") 
          .attr("class", "link") 
          .attr("d", line); 

         svg.selectAll(".node") 
          .data(nodes.filter(function(n) { return !n.children; })) 
         .enter().append("g") 
          .attr("class", "node") 
          .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; }) 
         .append("text") 
          .attr("dx", function(d) { return d.x < 180 ? 8 : -8; }) 
          .attr("dy", ".31em") 
          .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; }) 
          .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; }) 
          .text(function(d) { return d.key; }); 


        // Lazily construct the package hierarchy from class names. 

        function packageHierarchy(classes) { 
         var map = {}; 
         function find(name, data) { 
         var node = map[name], i; 
         if (!node) { 
          node = map[name] = data || {name: name, children: []}; 
          if (name.length) { 
          node.parent = find(name.substring(0, i = name.lastIndexOf("."))); 
          node.parent.children.push(node); 
          node.key = name.substring(i + 1); 
          } 
         } 
         return node; 
         } 
         classes.forEach(function(d) { 
         find(d.name, d); 
         }); 
         return map[""]; 
        } 


        // Return a list of imports for the given array of nodes. 
        function packageImports(nodes) { 
         var map = {}, 
          imports = []; 
         // Compute a map from name to node. 
         nodes.forEach(function(d) { 
         map[d.name] = d; 
         }); 
         // For each import, construct a link from the source to target node. 
         nodes.forEach(function(d) { 
         if (d.imports) d.imports.forEach(function(i) { 
          imports.push({source: map[d.name], target: map[i]}); 
         }); 
         }); 
         return imports; 
        } 
        </script> 



    </body> 
</html> 

答えて

2

まずあなたが機能colorNodeを作ります。

目的は、すべてのDOMを繰り返し、フィルタを使用してデータ名が同じかどうかを確認することです。それらのフィルタリングされたノードのために、そのスタイルを赤く塗りつぶします

  function colorNode(name){ 
       //iterate through all the dom and get the DOM which has the data 
       var node = d3.selectAll(".node")[0].filter(function(d){ 
       return d3.select(d).data()[0].name == name; 
       }); 
       //for the matching node DOM set the fill to be red 
       d3.selectAll(node).style("fill", "red"); 
      } 
のリンクを表示するための同じ

  function colorLink(src,tgt){ 
       //iterate through all the links for src and target. 
       var link = d3.selectAll(".link")[0].filter(function(d){ 
       return (d3.select(d).data()[0][0].name == src && d3.select(d).data()[0][2].name == tgt); 
       }); 
       //for the filtered link make the stroke red. 
       d3.selectAll(link).style("stroke", "red"); 
      } 

次ノードのconfigure mouseoverイベントに。

.on("mouseover", function(d){ 
          //first make all the nodes/links black(reset). 
          d3.selectAll(".node").style("fill", "black"); 
          d3.selectAll(".link").style("stroke", "steelblue"); 
          //color the node which is hovered. 
          colorNode(d.name); 
          //iterate over the imports which is the targets of the node(on which it is hovered) and color them. 
          d.imports.forEach(function(name){ 
          colorNode(name); 
          //color the link for a given source and target name. 
          colorLink(d.name, name); 
          }); 
         }) 

作業コードhere

+0

@Cyril ....ありがとう...しかし、私がしたかったのは、それに接続されたすべてのリンクの色です。着信リンクと発信リンクの両方...。発信リンク... ....私たちは発信元ノードのインポート内のすべてのノードをチェックしますが、着信リンクをどのように取得しますか?私はd3.selectAll( '。link')を試みました。forEach(関数(a){if(a.target === d d)} ...しかし、リンクの代わりにパスの配列を返していました。 – Jason

+0

これはhttp://plnkr.co/edit/DLqarh1r7cZRjCXI8QwG?p=preview – Cyril

+1

ありがとうございました。あなたの第1の解決策の助けを借りて私自身でそれをしました... – Jason

関連する問題