javascript - Avoiding overlapping edges with minimal physics in vis.js - Stack Overflow

I'm using vis.js to build a story visualization tool, and a key feature is to allow authors to man

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 remendations for how to apply vis physics so that it's disabled on node drag, stabilizes quickly also prevents edge overlap?

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 remendations for how to apply vis physics so that it's disabled on node drag, stabilizes quickly also prevents edge overlap?

Share Improve this question edited Jul 1, 2018 at 11:35 YakovL 8,40513 gold badges73 silver badges113 bronze badges asked Jun 8, 2018 at 18:08 Andrew FredetteAndrew Fredette 2213 silver badges9 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

If anyone es 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./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);

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 = thiswork.getConnectedEdges(toRouterId).filter(value => thiswork.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}
                    });
        

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744197866a4562741.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信