2016-05-25 8 views
0

私はサンキーチャートを実装しました。チャートを通してノードパスをトレースする機能があります。しかしながら、機能が立っているので、ユーザは、ノードのパスのハイライトを強調表示および除去するノードをmouseenterに持たなければならない。マウスセンターでノードのパスを強調表示し、そのハイライトを削除するには、どのような方法が良いですか(不透明度の変更によって)mouseout? Btw私はちょうどmouseentermouseoutの組み合わせを使用するための関数を呼び出そうとしましたが、それは問題を解決するように見えませんでした。ここに私のコードは次のとおりです。Mouseeventをより効率的に処理する方法

function highlightNodeLinks(node, i) { 

    var remainingNodes = [], 
     nextNodes = [], 
     strokeOpacity = 0, 
     traverse; 

    if (d3.select(this).attr('data-hover') === '1') { 
     d3.select(this).attr('data-hover', '0'); 
     strokeOpacity = 0.2; 
    } else { 
     d3.select(this).attr('data-hover', '1'); 
     strokeOpacity = 0.5; 
    } 

    traverse = [{ 
     linkType : 'sourceLinks', 
     nodeType : 'target' 
    }, { 
     linkType : 'targetLinks', 
     nodeType : 'source' 
    }]; 

    traverse.forEach(function (step) { 
     node[step.linkType].forEach(function (link) { 
     remainingNodes.push(link[step.nodeType]); 
     highlightLink(link.id, strokeOpacity); 
     }); 

     while (remainingNodes.length) { 
     nextNodes = []; 
     remainingNodes.forEach(function (node) { 
      node[step.linkType].forEach(function (link) { 
      nextNodes.push(link[step.nodeType]); 
      highlightLink(link.id, strokeOpacity); 
      }); 
     }); 
     remainingNodes = nextNodes; 
     } 
    }); 
    } 

    function highlightLink(id, opacity) { 
    d3.select('#link-' + id).style('stroke-opacity', opacity); 
    } 

、ここでは、それが呼ばれる方法です:任意の配慮やアドバイスを事前に

.on('mouseover', highlightNodeLinks) 

いつものように感謝します。

+0

パス内のすべてのリンクのリストを事前計算してから、このリストを「ちょうど」反復してハイライトそれらをオンまたはオフにする?私はそれがあなたのために適している場合はいくつかのコードを与えることができます(むしろ重いメモリの負荷が、より速い) – tarulen

+0

@ tarulenあなたが気にしないなら、私はあなたの提案を見たいと思います –

+0

あなたはノードクラスを与えることができます:ホバー擬似適切なクラスで。 –

答えて

2

2つのステップでは、まず各ノードがマウスオーバーで強調表示する必要のあるリンクを知るように前処理を行います。これは、(それは非常に大規模なグラフのスケールはありません)メモリのために重いですが、その後ずっと

//call this once after loading the data and first drawing of the links 
node.forEach(function(n) { 

linkIds= []; //add this field to each node 

traverse.forEach(function (step) { 
    node[step.linkType].forEach(function (link) { 
    remainingNodes.push(link[step.nodeType]); 
    linkIds.push(link.id); 
    }); 

    while (remainingNodes.length) { 
    nextNodes = []; 
    remainingNodes.forEach(function (node) { 
     node[step.linkType].forEach(function (link) { 
     nextNodes.push(link[step.nodeType]); 
     linkIds(link.id); 
     }); 
    }); 
    remainingNodes = nextNodes; 
    } 

    //add the list of links to a new field in the node 
    //& transform already ids into d3 selections 
    n.linksToHighlight = linkIds.map(function(id) {return d3.select("link-"+id)}) 
}); 

応答する必要があり、その後、コードの強調表示:

function highlighter(ratio) { 
    return function(node) { 
    node.linksToHighlight.forEach(function (s) {s.style("stroke-opacity",ratio}) 
    } 
} 


[select nodes] 
.on('mouseenter', highlighter(0.5))  
.on('mouseout', highlighter(1)) 
関連する問題