gpt4 book ai didi

javascript - d3js 强制布局在节点上隐藏/取消隐藏单击扩展后错放节点

转载 作者:行者123 更新时间:2023-11-30 17:53:12 27 4
gpt4 key购买 nike

我正在尝试使用 d3 和强制布局创建图表。我使用了以下示例 http://bl.ocks.org/mbostock/1062288开始:

enter image description here

我还需要图像和标签,所以我看了这个例子 http://bl.ocks.org/mbostock/950642了解如何添加它们。

根据用户与节点的交互,我的图也会变大,因此如果用户单击没有子节点的节点,ajax 请求将转到后端服务以请求更多节点。该图旨在用作关系发现应用程序。我创建了以下 jsfiddle http://jsfiddle.net/R2JGa/7/了解我要实现的目标。

它工作得比较好,但我有一个恼人的问题:当向图中添加新节点时,旧节点不知何故会错位。例如,我从 3 个节点开始,根节点是“flare”。其他 2 个节点是“动画”和“分析”。在我的示例中,每当您单击当前没有子节点的节点时,子节点将始终为“x”、“y”、“z”、“t”。展开几个节点后,您会看到“animate”或“analytics”没有链接到根节点“flare”,而是链接到其他一些节点 (x,y,z,t)。或者有时,如果您展开 x 或 y 或 z 或 t,则子节点具有重复的 x 或 y 或 z 或 t。如果您单击“flare”隐藏整个图形,然后重新打开“flare”,您将看到节点已正确链接和命名。

我似乎不明白为什么会这样。有人可以在这里阐明一下吗?我还是 d3 的新手,发现它真的很有趣,但这些问题太烦人了......

代码如下:

var w = 960,
h = 800,
node,
link,
root;

var force = d3.layout.force()
.charge(-1000)
.size([w, h]);

var vis = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h);

d3.json("data.json", function (json) {
root = json;
update();
});

function update() {
var nodes = flatten(root);
nodes.reverse();
nodes = nodes.sort(function (a, b) {
return a.index - b.index;
});

var links = d3.layout.tree().links(nodes);

console.log(nodes);

// Restart the force layout.
force
.nodes(nodes)
.links(links)
.linkDistance(55)
.start();


var link = vis.selectAll(".link")
.data(links);

link.enter().append("line")
.attr("class", "link");

link.exit().remove();

var node = vis.selectAll("g.node")
.data(nodes)


var groups = node.enter().append("g")
.attr("class", "node")
.attr("id", function (d) {
return d.id
})
.on('click', click)
.call(force.drag);


groups.append("image")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", -8)
.attr("y", -8)
.attr("width", 16)
.attr("height", 16);


groups.append("text")
.attr("dx", 12)
.attr("dy", "0.35em")
.style("font-size", "10px")
.text(function (d) {
console.log(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 + ")";
});
});
}


// Color leaf nodes orange, and packages white or blue.
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}

// Toggle children on click.
function click(d) {
console.log(d);
if (d.children) {
d._children = d.children;
d.children = null;
update();
} else if (d._children) {
d.children = d._children;
d._children = null;
update();
}
else {
d3.json("expand.json", function (json) {
d.children = json.children;
update();
})
}
}

// Returns a list of all nodes under the root.
function flatten(root) {
var nodes = [], i = 0;

function recurse(node) {
if (node.children) node.children.forEach(recurse);
if (!node.id) node.id = ++i;
nodes.push(node);
}

recurse(root);
return nodes;
}

这是我请求的 2 个 json 文件:

数据.json

{
"name": "flare",
"id" : "flare",
"children": [
{
"name": "analytics",
"id": "analytics"

},
{
"name": "animate",
"id": "animate"
}
]
}

和展开.json

{"children": [
{
"name": "x",
"id": "x",
"size": 1983
},
{
"name": "y",
"id": "y",
"size": 2047
},
{
"name": "z",
"id": "z",
"size": 1375
},
{
"name": "t",
"id": "t",
"size": 1375
}
]}

PS:我必须对节点数组进行排序,否则图表会发生不好的事情,我不明白为什么。

最佳答案

这里是 fiddle到工作解决方案。我认为问题在于您声明 ID 并根据数组索引对它们进行排序的方式。您应该让扁平化代码声明 id,然后根据给定的 id 对它们进行排序。同样在递归函数中,您可能希望先声明父项,然后再声明子项。

function recurse(node) {
if(!node.id) node.id = ++i;
nodes.push(node);
if (node.children) node.children.forEach(recurse);
}

关于javascript - d3js 强制布局在节点上隐藏/取消隐藏单击扩展后错放节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18537905/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com