javascriptcytoscape.js

cytoscape.js only get targets from node.outgoers()


I am currently trying to use the node.outgoers() method to get all child nodes of a node. However, if I understand the documentation correctly, this method returns not just the child nodes, but also the edges that come with the nodes. I assume that I could use the optional selector mentioned in the documentation to filter, but since I am still relatively new to javascript I don't quiet understand how I can return only the nodes without the edges.

Essentially what my code is supposed to do is a HITS implementation, where each node gets stored in a map as a key and an array as value that contains the values as the following structure:

The function updateHub is then called to calculate the new value by summing the Authority values of all child nodes by accessing them from the map. However, this throws an Uncaught TypeError: Cannot read properties of undefined (reading '0') when trying to access the map of a child node. I believe that this is due to the afore mentioned issue that incomers() returns edges with targets and not just the targets.

 nodes.forEach((n)=>{
                var array = [];
                array.push(1.0);
                array.push(1.0);
                array.push(n.incomers());
                array.push(n.outgoers());
                map.set(n, array);
            })

            // calculate authority/hub for each node in the map
            // TODO - Not Working

            map.forEach(function(value, key) {
                updateAuthority(key, map, value);
                updateHub(key, map, value);
            });
function updateHub(n, map, array){

    array[3].forEach((c) =>{
        array[1] += map[c][0];
    });
}

I have tried using selectors but again, I am still quite new to JavaScript and cannot seem to figure this out.


Solution

  • in order to get the child nodes, you'll need to use node.outgoers().nodes(). I added a working example, the console output should contain all child nodes of a selected node, you can verify that in your browsers console(stackoverflow console doesn't work):

    var cy = window.cy = cytoscape({
      container: document.getElementById('cy'),
    
      boxSelectionEnabled: false,
      autounselectify: true,
    
      style: [{
          selector: 'node',
          css: {
            'content': 'data(id)',
            'text-valign': 'center',
            'text-halign': 'center',
            'height': '60px',
            'width': '60px',
            'border-color': 'black',
            'border-opacity': '1',
            'border-width': '10px'
          }
        },
        {
          selector: '$node > node',
          css: {
            'padding-top': '10px',
            'padding-left': '10px',
            'padding-bottom': '10px',
            'padding-right': '10px',
            'text-valign': 'top',
            'text-halign': 'center',
            'background-color': '#bbb'
          }
        },
        {
          selector: 'edge',
          css: {
            'target-arrow-shape': 'triangle'
          }
        },
        {
          selector: ':selected',
          css: {
            'background-color': 'black',
            'line-color': 'black',
            'target-arrow-color': 'black',
            'source-arrow-color': 'black'
          }
        }
      ],
    
      elements: {
        nodes: [{
            data: {
              id: 'n0'
            }
          },
          {
            data: {
              id: 'n1'
            }
          },
          {
            data: {
              id: 'n2'
            }
          },
          {
            data: {
              id: 'n3'
            }
          },
          {
            data: {
              id: 'n4'
            }
          },
          {
            data: {
              id: 'n5'
            }
          },
          {
            data: {
              id: 'n6'
            }
          },
          {
            data: {
              id: 'n7'
            }
          },
          {
            data: {
              id: 'n8'
            }
          },
          {
            data: {
              id: 'n9'
            }
          },
          {
            data: {
              id: 'n10'
            }
          },
          {
            data: {
              id: 'n11'
            }
          },
          {
            data: {
              id: 'n12'
            }
          },
          {
            data: {
              id: 'n13'
            }
          },
          {
            data: {
              id: 'n14'
            }
          },
          {
            data: {
              id: 'n15'
            }
          },
          {
            data: {
              id: 'n16'
            }
          }
        ],
        edges: [{
            data: {
              source: 'n0',
              target: 'n1'
            }
          },
          {
            data: {
              source: 'n1',
              target: 'n2'
            }
          },
          {
            data: {
              source: 'n1',
              target: 'n3'
            }
          },
          {
            data: {
              source: 'n2',
              target: 'n7'
            }
          },
          {
            data: {
              source: 'n2',
              target: 'n11'
            }
          },
          {
            data: {
              source: 'n2',
              target: 'n16'
            }
          },
          {
            data: {
              source: 'n3',
              target: 'n4'
            }
          },
          {
            data: {
              source: 'n3',
              target: 'n16'
            }
          },
          {
            data: {
              source: 'n4',
              target: 'n5'
            }
          },
          {
            data: {
              source: 'n4',
              target: 'n6'
            }
          },
          {
            data: {
              source: 'n6',
              target: 'n8'
            }
          },
          {
            data: {
              source: 'n8',
              target: 'n9'
            }
          },
          {
            data: {
              source: 'n8',
              target: 'n10'
            }
          },
          {
            data: {
              source: 'n11',
              target: 'n12'
            }
          },
          {
            data: {
              source: 'n12',
              target: 'n13'
            }
          },
          {
            data: {
              source: 'n13',
              target: 'n14'
            }
          },
          {
            data: {
              source: 'n13',
              target: 'n15'
            }
          },
        ]
      },
    
      layout: {
        name: 'dagre',
        padding: 5
      }
    });
    cy.off('click');
    cy.on('click', 'node', function(e) {
      console.log(e.target.outgoers().nodes());
    });
    body {
      font: 14px helvetica neue, helvetica, arial, sans-serif;
    }
    
    #cy {
      height: 100%;
      width: 75%;
      position: absolute;
      left: 0;
      top: 0;
      float: left;
    }
    <html>
    
    <head>
      <meta charset=utf-8 />
      <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
      <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.17/cytoscape.min.js"></script>
      <script src="https://unpkg.com/jquery@3.3.1/dist/jquery.js"></script>
      <script src="https://unpkg.com/dagre@0.7.4/dist/dagre.js"></script>
      <script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-dagre/1.5.0/cytoscape-dagre.js"></script>
    </head>
    
    <body>
      <div id="cy"></div>
    </body>
    
    </html>