分层布局中的节点可以使用某些功能进行排序吗?

Can nodes in a hierarchichal layout be ordered with some function?

给定一个有向图,其中一个值与每个节点相关联,我们如何使用 vis.js 来显示根据该值排序的节点?例如,相同深度的所有节点从左到右从“最有价值”到“最不有价值”显示

在下面的示例中,节点 5 到 8 是节点 4 的子节点,并且按照 edges 的索引而不是 [=15= 的索引顺序从左到右添加] 每个节点。

所以我们可以重新排列 edges 以在 nodes:

中对 from 节点的 value 进行降序排序
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, value: 1, label: "2"},
  {id: 3, level: 1, value: 2, label: "3"},
  {id: 4, level: 2, value: 1, label: "4"},
  {id: 5, level: 3, value: 1, label: "5"},
  {id: 6, level: 3, value: 2, label: "6"},
  {id: 7, level: 3, value: 3, label: "7"},
  {id: 8, level: 3, value: 4, label: "8"}
];

const edges = [
  {from: 2, to: 1},
  {from: 3, to: 1},
  {from: 4, to: 3},
  {from: 5, to: 4},
  {from: 6, to: 4},
  {from: 7, to: 4},
  {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({}, 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 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>