A bug in Vis.js drawing library and source code correction

Source: Internet
Author: User

1. BUG1.1 Bug Trigger condition

When using the Vis.js drawing, there is an edge between two nodes A and b that has a point from a to B, and a side that points from B to a, and the drawing library crashes.

1.2 Bug resolution

Vis.js is the dynamic calculation of the position between two nodes, and then display it on the page, and in the case described above, in the calculation of the distance between A and B, the code will appear in addition to the 0 bug, causing the program to crash.

2. Solution

The source has more than 30,000 lines, in order to find this bug took a week to determine the final function of the problem.

In the Vis.js source code line 12,258th (after the version update location may be different), there is a _calculatenodeforces () function, the source code is as follows:

  

/** * Calculate the forces the nodes apply on eachother based on a repulsion field.   * This field is linearly approximated. * * @private*/_calculatenodeforces:function () {    vardx, dy, angle, distance, FX, FY, combinedclustersize, Repulsingforce, Node1, Node2, I, J; varnodes = This. Calculationnodes; varNodeindices = This. calculationnodeindices; //Approximation Constants    varA_base = -2/3; varb = 4/3; //repulsing forces between nodes    varNodedistance = This. constants.physics.repulsion.nodeDistance; varMinimumdistance =nodedistance; //we loop from I through all and the last entree in the array    //J Loops from I+1 to the last. This is the We do not double count any of the indices, nor i = = J     for(i = 0; i < nodeindices.length-1; i++) {Node1=Nodes[nodeindices[i]];  for(j = i + 1; j < Nodeindices.length; J + +) {Node2=Nodes[nodeindices[j]]; Combinedclustersize= Node1.clustersize + node2.clustersize-2; DX= node2.x-node1.x; Dy= Node2.y-node1.y; Distance = math.sqrt (DX * dx + dy *dy); Minimumdistance= (Combinedclustersize = = 0)? Nodedistance: (Nodedistance * (1 + combinedclustersize * This. constants.clustering.distanceAmplification)); varA = a_base/minimumdistance; if(Distance < 2 *minimumdistance) {          if(Distance < 0.5 *minimumdistance) {Repulsingforce= 1.0; }          Else{Repulsingforce= A * distance + B;//linear approx of 1/(1 + math.exp ((distance/minimumdistance-1) * steepness))          }          //amplify the repulsion for clusters.Repulsingforce *= (Combinedclustersize = = 0)? 1:1 + combinedclustersize * This. constants.clustering.forceAmplification; Repulsingforce = Repulsingforce/ distance; FX= DX *Repulsingforce; FY= Dy *Repulsingforce; Node1.fx-=FX; Node1.fy-=fy; Node2.fx+=FX; Node2.fy+=fy; }      }    }  }};

There is a distance variable, marked red, that is, this variable in the case we introduced will be 0, and then it as a divisor, so the program crashes.

The modified code is as follows:

  

/** * Calculate the forces the nodes apply on eachother based on a repulsion field.   * This field is linearly approximated. * * @private*/_calculatenodeforces:function () {    vardx, dy, angle, distance, FX, FY, combinedclustersize, Repulsingforce, Node1, Node2, I, J; varnodes = This. Calculationnodes; varNodeindices = This. calculationnodeindices; //Approximation Constants    varA_base = -2/3; varb = 4/3; //repulsing forces between nodes    varNodedistance = This. constants.physics.repulsion.nodeDistance; varMinimumdistance =nodedistance; //we loop from I through all and the last entree in the array    //J Loops from I+1 to the last. This is the We do not double count any of the indices, nor i = = J     for(i = 0; i < nodeindices.length-1; i++) {Node1=Nodes[nodeindices[i]];  for(j = i + 1; j < Nodeindices.length; J + +) {Node2=Nodes[nodeindices[j]]; Combinedclustersize= Node1.clustersize + node2.clustersize-2; DX= node2.x-node1.x; Dy= Node2.y-node1.y; Distance= math.sqrt (DX * dx + dy *dy); if (distance = = 0) {distance = 0.001; } minimumdistance= (Combinedclustersize = = 0)? Nodedistance: (Nodedistance * (1 + combinedclustersize * This. constants.clustering.distanceAmplification)); varA = a_base/minimumdistance; if(Distance < 2 *minimumdistance) {          if(Distance < 0.5 *minimumdistance) {Repulsingforce= 1.0; }          Else{Repulsingforce= A * distance + B;//linear approx of 1/(1 + math.exp ((distance/minimumdistance-1) * steepness))          }          //amplify the repulsion for clusters.Repulsingforce *= (Combinedclustersize = = 0)? 1:1 + combinedclustersize * This. constants.clustering.forceAmplification; Repulsingforce= Repulsingforce/distance; FX= DX *Repulsingforce; FY= Dy *Repulsingforce; Node1.fx-=FX; Node1.fy-=fy; Node2.fx+=FX; Node2.fy+=fy; }      }    }  }};

Add a judgment and let it not be 0.

A bug in the Vis.js drawing library and source code correction

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.