Search code examples
javascriptcytoscape.js

Circle Layout node angles cytoscape


How can i get the angle of each node with the center of the circumference in cytoscape using circle layout? Visual example: enter image description here


Solution

  • First step to get the angle of the node, get the center of the circumference
    So i get 3 points of the 3rd first nodes to get it:

    AX= cy.nodes()[0]._private.position.x   
    AY= cy.nodes()[0]._private.position.y   
    BX= cy.nodes()[1]._private.position.x   
    BY= cy.nodes()[1]._private.position.y   
    CX= cy.nodes()[2]._private.position.x   
    CY= cy.nodes()[2]._private.position.y   
    
    var yDelta_a = BY - AY 
    var xDelta_a = BX - AX; 
    var yDelta_b = CY - BY; 
    var xDelta_b = CX - BX;
    var aSlope = yDelta_a / xDelta_a; 
    var bSlope = yDelta_b / xDelta_b;
    
    //Get center circumference
    coordCentroCircunferenciaX = (aSlope*bSlope*(AY - CY) + bSlope*(AX + BX) - aSlope*(BX+CX) )/(2* (bSlope-aSlope) );
    coordCentroCircunferenciaY = -1*(coordCentroCircunferenciaX- (AX+BX)/2)/aSlope +  (AY+BY)/2;     
    

    Then iterate through the nodes getting the angles:

    for (i = 1;i< cy.nodes().length; i=i+1) { //starts nodes loop
        let nodo=cy.nodes()[i];
        array.push(nodo._private.data.name);
    
        //get the node position(x,y)
        nodox=nodo._private.position.x
        nodoy=nodo._private.position.y
    

    Now with 3 points: center circumference , node position and another point in the x axis

    C = { x: coordCentroCircunferenciaX, y: coordCentroCircunferenciaY };
    A = { x: nodox, y: 0 };
    B = { x: nodox,y:nodoy  };
    

    Then i get the angle with this function:

    function find_angle(A,B,C) {
        var AB = Math.sqrt(Math.pow(B.x-A.x,2)+ Math.pow(B.y-A.y,2));    
        var BC = Math.sqrt(Math.pow(B.x-C.x,2)+ Math.pow(B.y-C.y,2)); 
        var AC = Math.sqrt(Math.pow(C.x-A.x,2)+ Math.pow(C.y-A.y,2));
        return Math.acos((BC*BC+AB*AB-AC*AC)/(2*BC*AB))*(180/Math.PI);   
    }
    

    Finally this is the angle with the center of the circumference:

    let angulo=Math.round(find_angle(A,B,C))
    

    So with this angle i can get this effect to rotate node labels: