Javascript 如何在数据未更改的情况下刷新D3树?
我在D3树上遇到了一个问题(仅在Safari中),当在一棵树的顶部,在模式窗口中打开一棵新树,然后关闭时,所有节点都变黑(它们最初是图像) 作为一种解决方法,我曾想过在模式窗口关闭后立即完全重画树。但我不能让D3认为数据(实际上并没有改变)是新的,我已经尝试克隆数据对象以使其退出先前的数据。但它不起作用,它只是在现有节点之上绘制相同的节点 更新-正如评论中所建议的那样-我已尝试在一份报告中重现我遇到的问题。尝试在Safari中打开模式窗口几次-节点中的初始树图片将变为黑色Javascript 如何在数据未更改的情况下刷新D3树?,javascript,angularjs,d3.js,Javascript,Angularjs,D3.js,我在D3树上遇到了一个问题(仅在Safari中),当在一棵树的顶部,在模式窗口中打开一棵新树,然后关闭时,所有节点都变黑(它们最初是图像) 作为一种解决方法,我曾想过在模式窗口关闭后立即完全重画树。但我不能让D3认为数据(实际上并没有改变)是新的,我已经尝试克隆数据对象以使其退出先前的数据。但它不起作用,它只是在现有节点之上绘制相同的节点 更新-正如评论中所建议的那样-我已尝试在一份报告中重现我遇到的问题。尝试在Safari中打开模式窗口几次-节点中的初始树图片将变为黑色 var app = a
var app = angular.module('plunker', ['mgcrea.ngStrap']);
app.controller('MainCtrl', function ($scope, $modal) {
});
app.directive('tree', tree);
function tree() {
return {
restrict: 'E',
scope: true,
replace: false,
link: function (scope, element, attrs) {
var treeData = [{
"name": "Top Level",
"parent": "null",
"value": 10,
"type": "black",
"level": "red",
"icon": "http://placekitten.com/g/48/48",
"children": [{
"name": "Level 2: A",
"parent": "Top Level",
"value": 5,
"type": "grey",
"level": "red",
"icon": "http://placekitten.com/g/48/48",
"children": [{
"name": "Son of A",
"parent": "Level 2: A",
"value": 5,
"type": "steelblue",
"icon": "http://placekitten.com/g/48/48",
"level": "orange"
}, {
"name": "Daughter of A",
"parent": "Level 2: A",
"value": 18,
"type": "steelblue",
"icon": "http://placekitten.com/g/48/48",
"level": "red"
}]
}, {
"name": "Level 2: B",
"parent": "Top Level",
"value": 10,
"type": "grey",
"icon": "http://placekitten.com/g/48/48",
"level": "green"
}]
}];
// ************** Generate the tree diagram *****************
var margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var i = 0;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function (d) {
return [d.y, d.x];
});
var svg = d3.select(element[0]).append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
root = treeData[0];
update(root);
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function (d) {
d.y = d.depth * 180;
});
// Declare the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
});
var defs = node.append('defs').attr('id', 'imgdefs');
var roundedCircle = defs.append("pattern")
.attr("id", "grump_avatar")
// .append("svg:image")
// .attr("xlink:href", 'http://placekitten.com/g/48/48')
.attr("width", 48)
.attr("height", 48)
// .attr("x", 0)
// .attr("y", 0);
roundedCircle.append("image")
.attr("xlink:href", function (d) {
return d.icon;
})
// .attr("x", "-12px")
// .attr("y", "-12px")
.attr("width", "48px")
.attr("height", "48px");
nodeEnter.append("circle")
.attr("cx", 48 / 2)
.attr("cy", (48 - 40) / 2)
.attr("r", 48 / 2)
.style('fill-opacity', 1)
.attr("fill", "url(#grump_avatar)");
// Declare the links…
var link = svg.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
});
// Enter the links.
link.enter().insert("path", "g")
.attr("class", "link")
.style("stroke", function (d) {
return d.target.level;
})
.attr("d", diagonal);
}
}
}
}
现在我已经用这样的解决方案结束了——每次打开模式时,我都会删除整个svg(
d3.select(“svg”).remove();
)元素,然后调用另一个函数从一开始就绘制树。现在我用这样的解决方案结束了——每次打开模式时,我都会删除整个svg(d3.select(“svg”).remove();
)元素,然后调用另一个函数从一开始就绘制树。除非您提供更多上下文并共享一些代码,否则您的问题和自我回答都不会提供任何可供学习的内容。请看一看,以及如何提供。遵守这些规则会给你更多的关注,能够理解你的问题的读者也更有可能提供帮助。@altocumulus很公平,我补充说,除非你提供更多的上下文和共享一些代码,否则你的问题和自我回答都会提供任何可供学习的东西。请看一看,以及如何提供。坚持这些规则会给你更多的关注,能够理解你的问题的读者更有可能提供帮助。@altocumulus够公平的,我添加了Plunker