0
我是新來的d3和svg,我已經組合了來自各種示例的力向圖。重置d3的所有變量力量有向圖,javascript,svg
當我第一次調用d3Graph()函數時,它會正確繪製(第一幅圖像)。當我第二次打電話時,它不會(第二張圖片)。如果我刷新頁面並再次調用它,它可以正常工作。我已經明確地取消了所有的變量,所以我不明白爲什麼它不能正確繪製 - 也就是說我希望它和頁面重新加載一樣,因此每次調用都是全新的運行,重新讀取JSON並繪製從頭開始。
任何幫助將是巨大的
第一個呼叫不正確的平局:
無需刷新頁面問題,第二個呼叫:
D3代碼:
function d3Graph() {
var linkDistance = 100;
var colors = d3.scale.category10();
var w = 1000;
var h = 600;
var links= null;
var nodes= null;
var force= null;
var edges= null;
var nodelabels= null;
var edgepaths= null;
var edgelabels= null;
var svg= null;
d3.select("svg").selectAll("*").remove();
$("#svg_container").empty();
svg = d3.select("#svg_container").append("svg").attr({
"width" : w,
"height" : h
});
d3.json("/workflows/graph.json?id=1", function(error, dataset) {
if (error)
throw error;
links = [];
dataset.edges.forEach(function(e) {
var sourceNode = dataset.nodes.filter(function(n) {
return n.id === e.source;
})[0], targetNode = dataset.nodes.filter(function(n) {
return n.id === e.target;
})[0];
links.push({
id : e.id,
edge_type : e.edge_type,
source : sourceNode,
target : targetNode
});
});
force = d3.layout.force().nodes(dataset.nodes).links(links).size([w, h]).linkDistance([linkDistance]).charge([-2000]).theta(0.1).gravity(0.05).start();
edges = svg.selectAll("line").data(links).enter().append("line").attr("id", function(d, i) {
return 'edge' + i
})
.attr('marker-end', function(d) {
if (d.edge_type == 'prerequisite') {
return 'url(#arrowhead)';
}
})
.attr('stroke', function(d) {
if (d.edge_type == 'prerequisite') {
return '#000';
} else {
return '#F00';
}
})
nodes = svg.selectAll("circle").data(dataset.nodes).enter().append("circle").attr({
"r" : 15
}).style("fill", function(d, i) {
return colors(i);
}).call(force.drag).on("click", function(d) {
$('#workflow_stage_id').val(d.id);
$('#workflow_stage_name').val(d.name);
});
nodelabels = svg.selectAll(".nodelabel").data(dataset.nodes).enter().append("text").attr({
"x" : function(d) {
return d.x;
},
"y" : function(d) {
return d.y;
},
"class" : "nodelabel",
"stroke" : "black"
}).text(function(d) {
return d.name + ' [ID:' + d.id + ']';
});
edgepaths = svg.selectAll(".edgepath").data(links).enter().append('path').attr({
'd' : function(d) {
return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y
},
'class' : 'edgepath',
'fill-opacity' : 0,
'stroke-opacity' : 0,
'fill' : 'blue',
'stroke' : 'red',
'id' : function(d, i) {
return 'edgepath' + i
}
})
edgelabels = svg.selectAll(".edgelabel").data(links).enter().append('text').on("click", function(d) {
$('#workflow_stage_edge_id').val(d.id);
})
.attr({
'class' : 'edgelabel',
'id' : function(d, i) {
return 'edgelabel' + i
},
'dx' : 50,
'dy' : 0,
'font-size' : 14,
'fill' : '#000'
});
edgelabels.append('textPath').attr('xlink:href', function(d, i) {
return '#edgepath' + i
})
.text(function(d, i) {
return 'ID:' + d.id
});
svg.append('defs').append('marker').attr({
'id' : 'arrowhead',
'viewBox' : '-0 -5 10 10',
'refX' : 25,
'refY' : 0,
'orient' : 'auto',
'markerWidth' : 10,
'markerHeight' : 10,
'xoverflow' : 'visible'
}).append('svg:path').attr('d', 'M0 ,-5 L 10 ,0 L 0,5').attr('fill', '#000').attr('stroke', '#000');
force.on("tick", function() {
edges.attr({
"x1" : function(d) {
return d.source.x;
},
"y1" : function(d) {
return d.source.y;
},
"x2" : function(d) {
return d.target.x;
},
"y2" : function(d) {
return d.target.y;
}
});
nodes.attr({
"cx" : function(d) {
return d.x;
},
"cy" : function(d) {
return d.y;
}
});
nodelabels.attr("x", function(d) {
return d.x;
}).attr("y", function(d) {
return d.y;
});
edgepaths.attr('d', function(d) {
var path = 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
return path
});
edgelabels.attr('transform', function(d, i) {
if (d.target.x < d.source.x) {
bbox = this.getBBox();
rx = bbox.x + bbox.width/2;
ry = bbox.y + bbox.height/2;
return 'rotate(180 ' + rx + ' ' + ry + ')';
} else {
return 'rotate(0)';
}
});
});
});
}
查看d3的輸入,退出和更新模式,有很多關於該主題的好博客文章 – StackOverMySoul
感謝@Davidlrnt,但據我瞭解,輸入/退出是用於動態添加和刪除數據?我更喜歡重新讀取json並刷新/重繪圖表,因爲json數據可能會在後端更改。我可以看到enter()調用,但我認爲取消節點對象例如會擺脫所有引用 – Simon