Yeni düğümler yönelik Kuvvet düzeni ekleme
Yığın Taşması ilk soru, sabırlı ol! D3.js ama sürekli başkaları ile gerçekleştirmek mümkün ne hayran olmuş yeni duyuyorum... ve ne kadar az kendim ile yapmak mümkün oldum neredeyse gibi hayret! Açıkça tür ruhlar burada bana ışığı göster umuyorum öyle bir şey grokking, ben değilim.
Benim niyetim şudur: yapan yeniden kullanılabilir bir javascript işlevi yapmaktır
- Zorla yönettiği bir boş belirtilen bir DOM öğesi grafik oluşturur
- Sen eklemek ve silmek etiketli görüntü taşıyan bu grafik için, onların arasında bağlantı belirtme düğümler
Bir başlangıç noktası olarak http://bl.ocks.org/950642 aldım, aslında düzen bir yana oluşturmak mümkün olmak istiyorum
Benim kod şöyle görünür:
<!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 zaman yeni bir düğüm eklemek, yeniden etiketleri mevcut tüm düğümleri; üst üste bu kazık ve işler çirkin bir hal almaya başlar. Yeni bir düğüm ekleme üzerine update()
İşlev işlevi aradığımda, tüm veri kümesi için node.append(...)
. çünkü bu yüzden anlıyorum: Bunu nasıl yapacağımı çözemedimekliyorum tek düğüm... ve sadece görünüşte node.enter()
tek bir yeni öğe oluşturmak için kullanabilirsiniz, bu düğüme bağlı gereken ek unsurlar için çalışmıyor. Bu durumu nasıl düzeltebilirim?
Bu konuda herhangi verebilecek olduğun herhangi bir yardım için teşekkür ederiz!
Ben hızlı bir şekilde daha önce sözü birkaç diğer hata kaynağı sabit çünkü düzenlenmiştir
CEVAP
Bu çalışma elde edememesi çok uzun saatler sonra, nihayet belgelere herhangi bir bağlantı olduğunu sanmıyorum bu bir demo tökezledi arasında: http://bl.ocks.org/1095795:
Bu demo sonunda bana sorunu çözmek yardımcı anahtarları içeriyordu.
enter()
birden çok nesne ekleme bir değişken için enter()
atama, ve sonra bunun için ekleme yapılabilir. Bu mantıklı. İkinci önemli kısmı, düğüm ve Bağlantı diziler grafik ve model düğümleri silinmiş ve eklendikçe uyumu gidecek force()
-- aksi dayalı olmalıdır.
Bu ise yeni bir dizi yerine inşa edilirse, aşağıdaki attributes eksikliği meydana gelir:
- dizin düğümler içinde dizi düğüm sıfır tabanlı dizini.
- x - x-koordinatı geçerli düğüm pozisyon.
- y - y-koordinatı geçerli düğüm pozisyon.
- px - x-koordinat önceki düğüm yerleştirin.
- py - y-koordinat önceki düğüm pozisyon.
- sabit bir boolean olup olmadığını düğüm konumunu gösteren kilitlendi.
- kilo - düğüm ağırlığı; ilgili bağlantıları sayısı.
Bu nitelikler kesinlikle force.nodes()
ama eğer bu mevcut değilse, o zaman onlar için arama için gerekli değildirrastgeleilk çağrı üzerine force.start()
tarafından başlatıldığını.
Eğer herkes merak ediyor, çalışma kodu bu gibi görünüyor:
<script type="text/javascript">
function myGraph(el) {
// Add and remove elements on the graph object
this.addNode = function (id) {
nodes.push({"id":id});
update();
}
this.removeNode = function (id) {
var i = 0;
var n = findNode(id);
while (i < links.length) {
if ((links[i]['source'] === n)||(links[i]['target'] == n)) links.splice(i,1);
else i ;
}
var index = findNodeIndex(id);
if(index !== undefined) {
nodes.splice(index, 1);
update();
}
}
this.addLink = function (sourceId, targetId) {
var sourceNode = findNode(sourceId);
var targetNode = findNode(targetId);
if((sourceNode !== undefined) && (targetNode !== undefined)) {
links.push({"source": sourceNode, "target": targetNode});
update();
}
}
var findNode = function (id) {
for (var i=0; i < nodes.length; i ) {
if (nodes[i].id === id)
return nodes[i]
};
}
var findNodeIndex = function (id) {
for (var i=0; i < nodes.length; i ) {
if (nodes[i].id === id)
return i
};
}
// set up the D3 visualisation in the specified element
var w = $(el).innerWidth(),
h = $(el).innerHeight();
var vis = this.vis = d3.select(el).append("svg:svg")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.gravity(.05)
.distance(100)
.charge(-100)
.size([w, h]);
var nodes = force.nodes(),
links = force.links();
var update = function () {
var link = vis.selectAll("line.link")
.data(links, function(d) { return d.source.id "-" d.target.id; });
link.enter().insert("line")
.attr("class", "link");
link.exit().remove();
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id;});
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.call(force.drag);
nodeEnter.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");
nodeEnter.append("text")
.attr("class", "nodetext")
.attr("dx", 12)
.attr("dy", ".35em")
.text(function(d) {return d.id});
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.start();
}
// Make it all go
update();
}
graph = new myGraph("#graph");
// You can do this from the console as much as you like...
graph.addNode("Cause");
graph.addNode("Effect");
graph.addLink("Cause", "Effect");
graph.addNode("A");
graph.addNode("B");
graph.addLink("A", "B");
</script>
C bir dize içine bir yeni satır ekleme...
Elinize sağlık, varolan bir çözümü içi...
Varsayılan değer ile yeni bir SQL sütu...
Yeni bir ağ taşıyıcısı Android ekleme...
Nasıl Eclipse her dosyanın sonunda yen...