d3.js を使用して動的な力指向のネットワーク マップを作成しました。マップは最初にすべてのネットワーク ノードを取得し、ノードを結合する線として表示されるネットワーク インターフェイスで正しく表示します。これはすべてうまくいきます。
ユーザーが特定のプロジェクトに属するネットワーク インターフェイスをフィルタリングすることを決定した場合、ここで問題が発生します。同じ d3.layout.force インスタンスを再利用し、最初にマップを作成する同じ関数を実行しますが、新しいデータを使用します。物事を単純にするために、質問に関係のないものをすべて削除して、ソースをかなり圧縮しました。
var _this = {
graphLayout : d3.layout.force(),
node : null,
link : null,
selectedProject : null,
/*****************************************************
Initialize engine
*****************************************************/
render : function() {
// Creates the SVG container, sets up markers and gradients and whatnots
// unnecessary for me to include here I think.
// Start simulation
_this.update();
// Apply event handling and set up onTick
},
/*****************************************************
Perform a data update. This will read data from an
external url, and redraw all graphics.
*****************************************************/
update : function(project) {
if (project !== undefined) {
_this.selectedProject = project;
}
url = 'someService'+(!project ? '/GetNodes' : '/GetNodesByProjectId?projectId='+project.ProjectNumber);
d3.json(url, function(json) {
// Update nodes based on data
// Apply data to graph layout
_this.graphLayout
.nodes(json.nodes)
.links(json.links)
// Even more parameters which are unnecessary for this question
.start();
// Join lines config
_this.link = d3.select(" svg > .lineContainer").selectAll("g.link").data(_this.graphLayout.links());
var group = _this.link.enter().append("svg:g")
// More attributes and click event handling for the lines
.attr('id', function(d) { return d.InterfaceNumber; });
group.append("svg:line");
_this.link.exit().remove();
// Node rendering config
_this.node = d3.select(" svg > .nodeContainer").selectAll("g.node").data(_this.graphLayout.nodes());
group = _this.node.enter().append("svg:g")
// More attributes and click event handling for the nodes
.attr('id', function(d) { return d.Id; });
group.append("svg:path")
.attr("d", _this.nodeSVGPath)
.attr("fill", function(d) { return "url(#blackGradient)"; });
そして、ここで私の問題に遭遇します:
// Add label to node
group.append('svg:text').attr('class', 'label').attr('transform', 'translate(25, 30)').text(function(d,i) { return d.Name; });
_this.node.exit().remove();
});
},
ここで .text に配置された function(d,i) は、update が 2 回目に呼び出されたときに実行されないようです。ここでd3に何かがキャッシュされていますか、それとも何か不足していますか?
ここでの問題は、ノード (または行) に正しいデータオブジェクトが含まれているが、ノードに表示されるテキストが一致しないことです。これにより、d3js は svg オブジェクトを完全に再利用したものの、新しく更新されたオブジェクトとデータを交換したと思われます。 .