问题描述
给定一个有向图,其中每个节点都关联了一个值,我们如何使用vis.js来显示根据这个值排序的节点?例如,相同深度的所有节点从“最有价值”到“最不有价值”从左到右显示
解决方法
在下面的示例中,节点 5 到 8 是节点 4 的子节点,并按从左到右的顺序添加,这是由于索引 edges
而不是相对于 value
每个节点。
因此我们可以重新排列 edges
以对 from
中的 value
节点的 nodes
进行降序排序:
function rank(edges) {
// get a copy of edges
let edges2 = edges.map(function(edge) {return Object.assign({},edge);});
// sort edges by node value
edges2.sort(function(a,b) {
let nodeA = nodes.find(function(n) {return n.id == a.from});
let nodeB = nodes.find(function(n) {return n.id == b.from});
return nodeB.value - nodeA.value;
});
return edges2;
}
未排名的工作示例,以及每个此函数的排名:
const nodes = [
{id: 1,level: 0,value: 1,label: "1"},{id: 2,level: 1,label: "2"},{id: 3,value: 2,label: "3"},{id: 4,level: 2,label: "4"},{id: 5,level: 3,label: "5"},{id: 6,label: "6"},{id: 7,value: 3,label: "7"},{id: 8,value: 4,label: "8"}
];
const edges = [
{from: 2,to: 1},{from: 3,{from: 4,to: 3},{from: 5,to: 4},{from: 6,{from: 7,{from: 8,to: 4}
];
const options = {
nodes: {
shape: "dot"
},edges: {
smooth: {
type: "cubicBezier",forceDirection: "vertical",roundness: 0.4
}
},layout: {
hierarchical: {
direction: "UD",},physics: false
}
// unranked
const data1 = {
nodes: nodes,edges: edges
}
const container1 = document.getElementById("network1");
const network1 = new vis.Network(container1,data1,options);
// ranked
const data2 = {
nodes: nodes,edges: rank(edges)
}
function rank(edges) {
// get a copy of edges
let edges2 = edges.map(function(edge) {return Object.assign({},b) {
let nodeA = nodes.find(function(n) {return n.id == a.from});
let nodeB = nodes.find(function(n) {return n.id == b.from});
return nodeB.value - nodeA.value;
});
return edges2;
}
const container2 = document.getElementById("network2");
const network2 = new vis.Network(container2,data2,options);
#wrapper {
display: flex;
}
#network1 {
flex: 0 0 50%;
height: 180px;
border: 1px solid #000;
}
#network2 {
flex: 1;
height: 180px;
border: 1px solid #000;
}
<script type="text/javascript" src="https://unpkg.com/vis-network@9.0.4/dist/vis-network.min.js"></script>
<div id="wrapper">
<div id="network1"></div>
<div id="network2"></div>
</div>