Stack Overflow ile ilgili ilk soru, bu yüzden bana katlanın! D3.js'de yeniyim, ancak sürekli olarak başkalarının onunla neler başardığına hayran kaldım ... ve kendimle ne kadar az ilerleme kaydedebildiğime neredeyse hayret ediyorum! Açıkçası ben bir şey söylemiyorum, bu yüzden umarım buradaki nazik ruhlar bana ışığı gösterebilir.
Niyetim, aşağıdakileri basitçe yapan yeniden kullanılabilir bir javascript işlevi yapmaktır:
- Belirtilen bir DOM öğesinde boş bir kuvvet yönelimli grafik oluşturur
- Aralarındaki bağlantıları belirleyerek bu grafiğe etiketli, görüntü taşıyan düğümleri eklemenizi ve silmenizi sağlar
Http://bl.ocks.org/950642'yi başlangıç noktası olarak aldım , çünkü bu esasen oluşturmak istediğim türden bir düzen:
Kodum şöyle görünüyor:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="underscore-min.js"></script>
<script type="text/javascript" src="d3.v2.min.js"></script>
<style type="text/css">
.link { stroke: #ccc; }
.nodetext { pointer-events: none; font: 10px sans-serif; }
body { width:100%; height:100%; margin:none; padding:none; }
#graph { width:500px;height:500px; border:3px solid black;border-radius:12px; margin:auto; }
</style>
</head>
<body>
<div id="graph"></div>
</body>
<script type="text/javascript">
function myGraph(el) {
// Initialise the graph object
var graph = this.graph = {
"nodes":[{"name":"Cause"},{"name":"Effect"}],
"links":[{"source":0,"target":1}]
};
// Add and remove elements on the graph object
this.addNode = function (name) {
graph["nodes"].push({"name":name});
update();
}
this.removeNode = function (name) {
graph["nodes"] = _.filter(graph["nodes"], function(node) {return (node["name"] != name)});
graph["links"] = _.filter(graph["links"], function(link) {return ((link["source"]["name"] != name)&&(link["target"]["name"] != name))});
update();
}
var findNode = function (name) {
for (var i in graph["nodes"]) if (graph["nodes"][i]["name"] === name) return graph["nodes"][i];
}
this.addLink = function (source, target) {
graph["links"].push({"source":findNode(source),"target":findNode(target)});
update();
}
// set up the D3 visualisation in the specified element
var w = $(el).innerWidth(),
h = $(el).innerHeight();
var vis = d3.select(el).append("svg:svg")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.nodes(graph.nodes)
.links(graph.links)
.gravity(.05)
.distance(100)
.charge(-100)
.size([w, h]);
var update = function () {
var link = vis.selectAll("line.link")
.data(graph.links);
link.enter().insert("line")
.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; });
link.exit().remove();
var node = vis.selectAll("g.node")
.data(graph.nodes);
node.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("image")
.attr("class", "circle")
.attr("xlink:href", "https://d3nwyuy0nl342s.cloudfront.net/images/icons/public.png")
.attr("x", "-8px")
.attr("y", "-8px")
.attr("width", "16px")
.attr("height", "16px");
node.append("text")
.attr("class", "nodetext")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) { return d.name });
node.exit().remove();
force.on("tick", function() {
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; });
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});
// Restart the force layout.
force
.nodes(graph.nodes)
.links(graph.links)
.start();
}
// Make it all go
update();
}
graph = new myGraph("#graph");
// These are the sort of commands I want to be able to give the object.
graph.addNode("A");
graph.addNode("B");
graph.addLink("A", "B");
</script>
</html>
Her yeni düğüm eklediğimde, mevcut tüm düğümleri yeniden etiketler; bunlar üst üste yığılır ve işler çirkinleşmeye başlar. Bunun nedenini anlıyorum: çünkü update()
yeni bir düğüm ekledikten sonra işlev işlevini çağırdığımda node.append(...)
, tüm veri kümesine a yapar. Bunu yalnızca eklediğim düğüm için nasıl yapacağımı çözemiyorum ... ve yalnızca görünüşe göre node.enter()
tek bir yeni öğe oluşturmak için kullanabiliyorum , bu nedenle bu, düğüme bağlanmam gereken ek öğeler için çalışmıyor . Bunu nasıl düzeltebilirim?
Bu konuda verebileceğiniz her türlü rehberlik için teşekkür ederiz!
Daha önce bahsedilen diğer birkaç hatanın kaynağını hızla düzelttiğim için düzenlendi
force.start()
bunun yerine kullanmakforce.resume()
kilit noktaydı. Çok teşekkürler!