最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin4浏览0评论

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}
                    });
        
发布评论

评论列表(0)

  1. 暂无评论