分层布局中的节点是否可以通过某些功能进行排序?

问题描述

给定一个有向图,其中每个节点都关联了一个值,我们如何使用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>