gpt4 book ai didi

javascript - D3 图形布局 - 具有多个父级的树结构

转载 作者:行者123 更新时间:2023-11-30 15:47:40 25 4
gpt4 key购买 nike

首先让我声明我是 D3 和 Javascript 的新手。通过一些试验,我试图开发一个类似树的结构,问题是节点可以有多个父节点。

输入:

带有节点链接 信息的 Json,例如,

 var graph = {
"nodes": [ { "id" : 0},
{ "id" : 1},
{ "id" : 2},
{ "id" : 3},
{ "id" : 4},
{ "id" : 5}
],
"links": [ { "target": 5, "source": 1 },
{ "target": 2, "source": 0 },
{ "target": 3, "source": 4 },
{ "target": 1, "source": 2},
{ "target": 1, "source": 0 },

]
};

注意:这只是为了引用,因为我有数据,它可能有数千个节点。

输出:

我想要像树结构一样的输出,有点像this ,也就是说,必须将节点绘制在类似深度/级别的结构中,其中根位于顶部,并且以最小化链接重叠的方式排列相同级别的节点。

编辑:上面提供的输入的输出是 this假设零是根。

我面临的问题:

  1. 因为我只得到节点及其源和目标,而不是它们的坐标,所以我必须解析整个列表计算级别,然后根据该级别划分高度,然后绘制节点。处理此类问题最有效的方法是什么?我应该深入研究算法解决方案吗?

或者

  1. D3 中是否有一些图形绘制函数将此 JSON 作为输入并完成其余工作?

请注意,节点可以有多个父节点,我在这里的主要重点是以适当/分层顺序绘制这些节点,所以我面临的主要问题是计算所有节点的 X/Y 坐标如上所述输入。

请帮助我更好地理解这个主题,谢谢。

最佳答案

一整天都在想这个问题。使用内置的 d3 构造,我认为 this与您将要达到的差不多。我已获取您的数据并将其转换为版本 4 示例:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.links line {
stroke: #aaa;
stroke-width: 5px;
}

.nodes circle {
pointer-events: all;
stroke: none;
}
</style>
<svg width="600" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");

var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.force("y", d3.forceY())

var graph = {
"nodes": [{
"id": 0
}, {
"id": 1
}, {
"id": 2
}, {
"id": 3
}, {
"id": 4
}, {
"id": 5
}],
"links": [{
"target": 5,
"source": 1
}, {
"target": 2,
"source": 0
}, {
"target": 3,
"source": 4
}, {
"target": 1,
"source": 2
}, {
"target": 1,
"source": 0
},

]
};

var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line");

var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 10);

node.append("title")
.text(function(d) {
return d.id;
});

simulation
.nodes(graph.nodes)
.on("tick", ticked);

simulation.force("link")
.links(graph.links);

function ticked() {

var k = 6 * simulation.alpha();

// Push sources up and targets down to form a weak tree.
link
.each(function(d) {
d.source.y -= k, d.target.y += k;
})
.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("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});

}
</script>

如果不想要移动和沉降效果,可以预先计算布局来制作static .


我还尝试将您的数据转换为分层格式,以便与 d3.tree 一起使用但没有太多运气复制你的形象:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node circle {
fill: #999;
}

.node text {
font: 10px sans-serif;
}

.node--internal circle {
fill: #555;
}

.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}

.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
</style>
<svg width="300" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var graph = {
"nodes": [{
"id": 0
}, {
"id": 1
}, {
"id": 2
}, {
"id": 3
}, {
"id": 4
}, {
"id": 5
}],
"links": [{
"target": 5,
"source": 1
},{
"target": 2,
"source": 0
}, {
"target": 3,
"source": 4
}, {
"target": 1,
"source": 2
}, {
"target": 1,
"source": 0
}]
};

var root = {
id: 0,
data: graph.nodes[0],
children: []
}

function recurChild(obj) {
graph.links.forEach(function(d) {
if (d.source === obj.id) {
var c = {
id: d.target,
data: graph.nodes[d.target],
children: []
};
obj.children.push(c);
recurChild(c);
}
});
}
recurChild(root);

root = d3.hierarchy(root);

var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(40,0)");

var tree = d3.tree()
.size([height, width - 160]);

tree(root);

console.log(root.descendants())

var link = g.selectAll(".link")
.data(root.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", function(d) {
return "M" + d.y + "," + d.x + "C" + (d.y + d.parent.y) / 2 + "," + d.x + " " + (d.y + d.parent.y) / 2 + "," + d.parent.x + " " + d.parent.y + "," + d.parent.x;
});

var node = g.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", function(d) {
return "node" + (d.children ? " node--internal" : " node--leaf");
})
.attr("transform", function(d) {
return "translate(" + d.y + "," + d.x + ")";
})

node.append("circle")
.attr("r", 2.5);

node.append("text")
.attr("dy", 3)
.attr("x", function(d) {
return d.children ? -8 : 8;
})
.style("text-anchor", function(d) {
return d.children ? "end" : "start";
})
.text(function(d) {
return d.data.id;
});
</script>

d3.hierarchy 确实暗示了这一点,没有多个父结构的直接层次结构。

关于javascript - D3 图形布局 - 具有多个父级的树结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39818279/

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