Avoiding overlapping edges with minimal physics in vis.js
Asked Answered
R

2

8

I'm using vis.js to build a story visualization tool, and a key feature is to allow authors to manually position nodes via dragging. There's also often several edges with the same origin and destination nodes. Without physics, these edges overlap.

Currently to avoid edge overlap, I enable physics for a small interval whenever a new edge is created to repel any overlapping edges from each other. Ideally I would have physics always disabled and edges would not overlap, but I don't think that is possible.

Are there any recommendations for how to apply vis physics so that it's disabled on node drag, stabilizes quickly also prevents edge overlap?

Restrictive answered 8/6, 2018 at 18:8 Comment(0)
R
5

If anyone comes across this issue, the solution is to calculate the roundness for each edge, based on how many edges have the same origin and destination node.

example: http://jsbin.com/wojanuboxi/edit?html,js,output

 var nodes = new vis.DataSet([
 {id: 1, label: '1'},
 {id: 2, label: '2'},
 {id: 3, label: '3'}
]);
var edges = new vis.DataSet([
  {id: 1, from: 1, to: 2, smooth: {type: 'curvedCW', roundness: 0.2}},
  {id: 2, from: 1, to: 2, smooth: {type: 'curvedCW', roundness: -2.2}},
  {id: 5, from: 1, to: 2, label: 5,  smooth: {type: 'curvedCW', roundness: 0.4}},
  {id: 6, from: 1, to: 2, label: 6, smooth: {type: 'curvedCW', roundness: -2.4}},

  {id: 3, from: 1, to: 3, smooth: {type: 'curvedCW', roundness: -2.1}},
  {id: 4, from: 1, to: 3, smooth: {type: 'curvedCW', roundness: 0.1}}
]);
var data = {
  nodes: nodes,
  edges: edges
};
var options = {
  physics: false,
  layout: {
    hierarchical: {
      direction: 'UD'
    }
  }
};

var networkContainer = document.getElementById('networkContainer');
var network = new vis.Network(networkContainer, data, options);
Restrictive answered 18/6, 2018 at 17:9 Comment(1)
But how can we force Visnetwork to do it automatically?Jamieson
E
0

After disabling the physics variable, I couldn't find a useful solution for the overlap problem. for the edge. I have created a temporary solution for this.this can solve the overlap problem for a small number of edges. but for too many edges there will be overlap problem again. The roundness value sets the roundness of the edge. If we give it random values ​​in a negative and positive range, we may be out of luck. :)

getConnectedEdgesCountAndCreateRandomRoundness(toRouterId: number, fromRouterId: number): number {
            var randomRoundness: number = 0;
            var connectedEdgesCount = this.network.getConnectedEdges(toRouterId).filter(value => this.network.getConnectedEdges(fromRouterId).includes(value)).length;
            if(connectedEdgesCount === 0){
                randomRoundness = 0;
            } 
            else if (connectedEdgesCount === 1){
                randomRoundness = this.generateRandomNumber(-0.25,0.25);
            }
            else if (connectedEdgesCount === 2){
                randomRoundness = this.generateRandomNumber(-0.5,0.5);
            }
            else {
                randomRoundness = this.generateRandomNumber(-1.25,1.25);
            }

            return randomRoundness;
        }
      
                    var randomRoundness = this.getConnectedEdgesCountAndCreateRandomRoundness(this.toRouterId,this.fromRouterId);

                    this.edges.add({
                        id: this.circuitEdge.id,
                        from: this.fromRouterNode.id,
                        to: this.toRouterNode.id,
                        label: this.circuitEdge.name,
                        type: this.circuitEdge.type,
                        color: visEdgeColor,
                        smooth: { enabled: true, type: "curvedCW", roundness: randomRoundness}
                    });
        
Eyecup answered 30/10, 2021 at 21:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.