Andrew Fredette
Andrew Fredette

Reputation: 221

Avoiding overlapping edges with minimal physics in vis.js

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?

Upvotes: 8

Views: 4910

Answers (2)

miraç turanli
miraç turanli

Reputation: 1

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}
                    });
        

Upvotes: 0

Andrew Fredette
Andrew Fredette

Reputation: 221

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);

Upvotes: 5

Related Questions