据我看到update(),输入(),exit()用于从数据更新视图。还有另一种方法,从GUI更新数据吗?
e.g。点击B-circle,点击删除 - >将从GUI中删除,但仍然存在于数据中..通过单击刷新,它会再次出现:
http://jsfiddle.net/stefanf/6Qm2z/33/
'var nodesToRemove = pack.nodes(data);
var sel = vis.selectAll("circle").data(nodesToRemove, function(d){
return d.id;
});
sel.remove();'
P.S。我现在可以通过首先使用javascript更新数据来实现,但我的问题是,是否有适当的d3方式..
答案 0 :(得分:1)
我做过这个工作小提琴http://jsfiddle.net/6Qm2z/36/
var dataGlobal = {
"name": "Area",
"id": 1,
"size": 1,
"children": [
{
"name": "F",
"id": 2,
"size": 1,
"children": [
{ "name": "C",
"id": "3",
"size": 1
},
{
"name": "D",
"id": 4,
"size": 1,
"children": [
{ "name": "A",
"id": 5,
"size": 0.5
},
{ "name": "B",
"id": 6,
"size": 1
}
]
},
{
"name": "H",
"id": 7,
"size": 1
}
]
}
]
};
var w = 680,
h = 600,
r = 420,
x = d3.scale.linear().range([0, r]),
y = d3.scale.linear().range([0, r]),
node,
root;
var pack = d3.layout.pack()
.size([r, r])
.value(function(d) { return d.size; })
var vis = d3.select("body").insert("svg:svg", "h2")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + (w - r) / 2 + "," + (h - r) / 2 + ")");
node = root = dataGlobal;
var refreshGraph = function(newArray) {
var nodes;
if(newArray != null){
nodes=newArray;
}
else{
nodes = pack.nodes(root);
}
var sel = vis.selectAll("circle")
.data(nodes, function(d) { return d.id; });
sel
.enter().append("svg:circle");
sel
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.r; })
.on("dblclick", function(d) { return zoom(node == d ? root : d); })
.on("click", function () {
d3.select(".selected").classed("selected", false);
d3.select(this).classed("selected", true);
});
sel.exit().remove();
sel = vis.selectAll("text")
.data(nodes, function(d) { return d.name; });
sel
.enter().append("svg:text");
sel
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.style("opacity", function(d) { return d.r > 20 ? 1 : 0; })
.text(function(d) { return d.name; });
sel.exit().remove();
d3.select(window).on("click", function() { zoom(root); });
}
function zoom(d, i) {
var k = r / d.r / 2;
x.domain([d.x - d.r, d.x + d.r]);
y.domain([d.y - d.r, d.y + d.r]);
var t = vis.transition()
.duration(d3.event.altKey ? 7500 : 750);
t.selectAll("circle")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", function(d) { return k * d.r; });
t.selectAll("text")
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return y(d.y); })
.style("opacity", function(d) { return k * d.r > 20 ? 1 : 0; });
node = d;
d3.event.stopPropagation();
}
d3.select('#refreshBtn').on("click", function(d) {
updatedRefresh(dataGlobal);
});
d3.select('#addBtn').on("click", function(d) {
obj = {
"name": document.getElementById('textBtn').value,
"id": document.getElementById('idBtn').value,
"size": 1
}
d3.select(".selected").datum().children.push(obj)
refreshGraph()
});
d3.select("#deleteBtn").on("click", function() {
d3.select(".selected").each(function(data){
var nodesToRemove = pack.nodes(data);
var sel = vis.selectAll("circle").data(nodesToRemove, function(d){
return d.id;
});
sel.remove();
vis.selectAll("text").data(nodesToRemove, function(d){
return d.name;
})
.remove();
dataGlobal.children = prune(dataGlobal.children, data.id);
});
});
refreshGraph();
function prune(array, label) {
for (var i = 0; i < array.length; ++i) {
var obj = array[i];
if (obj.id === label) {
// splice out 1 element starting at position i
array.splice(i, 1);
return array;
}
if (obj.children) {
if (prune(obj.children, label)) {
if (obj.children.length === 0) {
// delete children property when empty
delete obj.children;
// or, to delete this parent altogether
// as a result of it having no more children
// do this instead
array.splice(i, 1);
}
return array;
}
}
}
}
function updatedRefresh(newArray) {
debugger;
var nodes;
if(newArray != null){
nodes=pack.nodes(newArray);
}
else{
nodes = pack.nodes(root);
}
var sel = vis.selectAll("circle")
.data(nodes, function(d) { return d.id; });
sel
.enter().append("svg:circle");
sel
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", function(d) { return d.r; })
.on("dblclick", function(d) { return zoom(node == d ? root : d); })
.on("click", function () {
d3.select(".selected").classed("selected", false);
d3.select(this).classed("selected", true);
});
sel.exit().remove();
sel = vis.selectAll("text")
.data(nodes, function(d) { return d.name; });
sel
.enter().append("svg:text");
sel
.attr("class", function(d) { return d.children ? "parent" : "child"; })
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.style("opacity", function(d) { return d.r > 20 ? 1 : 0; })
.text(function(d) { return d.name; });
sel.exit().remove();
d3.select(window).on("click", function() { zoom(root); });
}
每次删除一项时,我都会使用dataGlobal
函数更新prune
数组。
查看要使用数组输入更新的updatedRefresh
函数