力指向グラフを作成するために D3JS を使用しています。プレバージョンでは、たとえば 1200 ノードと 3717 リンクのグラフをパフォーマンスの問題なしに作成できます。しかし、スクリプトのクリーン バージョンでは、580 ノードと 649 リンクのグラフは非常に低速です。
最初のバージョンでは、グラフの作成とノードとリンクのスタイルが同時に作成されます。2 番目のバージョンでは、ノードのスタイルを動的に変更する必要があります。たとえば、ズームアウトしたときやボタンをクリックしたときに小さなノードを非表示にします。これを行うために、スクリプトを 4 つの関数に分けます。
- 力システムで使用するノードとリンクの選択
- フォースシステムの開始
- 表示するノードの選択
- 表示するノードのスタイル
ノードを追加または削除してすべての関数を呼び出すか、ズームインまたはズームアウトして最後の 2 つを呼び出して、ユーザーに表示されるものだけを変更します。
この分離がパフォーマンス不足の原因である可能性はありますか? これらの関数がすべて終了したとき、ティック関数が実行されているときに問題が発生するため、そうは思いません。しかし、それは 2 つのバージョン間の唯一の変更点です。
助けてくれてありがとう、下手な英語でごめんなさい!
編集1:コード
力システムで使用するノードとリンクの選択
function choiceNodesToUseForForce(){
//First we clean previous selection
for(itCN1=0;itCN1<nodesUnDisplayed.length;itCN1++){
nodesUnDisplayed[itCN1].isUsed = false;
}
for(itCN1=0;itCN1<linksUnDisplayed.length;itCN1++){
linksUnDisplayed[itCN1].isUsed = false;
}
usedLinks = new Array();
usedNodes = new Array();
for(itCNAU1=0;itCNAU1<linksUnDisplayed.length;itCNAU1++){
lien = linksUnDisplayed[itCNAU1];
//We used a link if one of his nodes is open (=focused)
if((lien.source.isFocused || lien.target.isFocused) && lien.time <= time[1] && lien.time >= time[0] && !lien.isUsed){
usedLinks.push(lien);
lien.isUsed = true;
if(!lien.source.isUsed){
usedNodes.push(lien.source);
lien.source.isUsed = true;
}
if(!lien.target.isUsed){
usedNodes.push(lien.target);
lien.target.isUsed = true;
}
}
}
}
力システムの開始
function startingForce(){
force.stop();
force.nodes(usedNodes).links(usedLinks);
force.start();
}
表示するノードの選択
function choiceNodesToShow(){
//First we clean the previous selection
for(itCN1=0;itCN1<nodesUnDisplayed.length;itCN1++){
nodesUnDisplayed[itCN1].isDisplayed = false;
}
for(itCN1=0;itCN1<linksUnDisplayed.length;itCN1++){
linksUnDisplayed[itCN1].isDisplayed = false;
}
showedNodes = new Array();
showedLinks = new Array();
for(itCN1=0;itCN1<usedLinks.length;itCN1++){
lien = liensUtilises[itCN1];
//We show a link if : his two nodes are displayed
if(lien.source.size > sizeLimite && lien.target.size > sizeLimite && !lien.isDisplayed){
liensAAfficher.push(lien);
//Add of nodes
if(!lien.source.isDisplayed){
showedNodes.push(lien.source);
lien.source.isDisplayed = true;
}
if(!lien.target.isDisplayed){
showedNodes.push(lien.target);
lien.target.isDisplayed = true;
}
}
}
}
表示するノードのスタイル
function styleNoeudsAAfficher(){
d3.selectAll('.node').remove();
d3.selectAll('.link').remove();
link = svg.selectAll('.link');
node = svg.selectAll('.node');
node = node.data(showedNodes, function(d){ return d.name;});
if(mode == "normal"){
user.enter().append("circle") //Idem lien
.attr("class", function(d) {return "node "+d.id+d.name;})
.attr("r", function(d){ return d.size;})
.attr("cx", function(d) {return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("x", function(d) { return d.x-d.size/2; })
.attr("y", function(d) { return d.y-d.size/2; })
.attr("fill", function(d){return color(d.community);})
.style("stroke-width", 1)
.style("stroke", "black")
.style("cursor", "pointer")
.on("click", function(d){ clicNode(d);})
.call(force.drag)
.append("title")
.text(function(d){return d.name;});
user.exit().remove();
link = link.data(showedLinks, function(d) { return d.sourceId + "-" + d.targetId; });
link.enter().insert("line", ".node")
.attr("class", "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; })
.style("stroke-width", 1)
.style("stroke", "#848484")
.append("title")
.text(function(d){return d.source.name+" - "+d.target.name;})
link.exit().remove(); //On supprime les liens qui ont disparus
}