cy.on calling for each node selected (cytoscape js)

4,007 views
Skip to first unread message

dms

unread,
May 21, 2013, 1:34:32 PM5/21/13
to cytoscap...@googlegroups.com

I am trying to get all information from selected node in my graph (using cytoscape js) to build an information table (as I used to do with cytoscape web - flash version) but I don't find a way for doing it using the js version. (I am super new to jquery / javascript ).


Trying to use this example:

cy.on('select', 'node', function(event){
     // cyTarget holds a reference to the originator
     // of the event (core or element)
     var evtTarget = event.cyTarget;
     window.evtTarget = evtTarget;
     createTable(evtTarget);
     if( evtTarget === cy ){
          //console.log('click on background');
     } else {

        //console.log('click on some element');
        //console.log("clicked on " + evtTarget.data("id"));
     }})

I call my createTable() function with the evtTarget (node data) as parameters, but as one might know it calls my createTable() function for every node selected. 
What I need is to get all selected node data, and then call my function (I tried to use a collection, but not working so far).

Could someone please help me finding a way to obtain all selected / clicked nodes and then calling a function with this data ?

I DO appreciate any help.


dms

unread,
May 21, 2013, 1:43:43 PM5/21/13
to cytoscap...@googlegroups.com
I know this would be a solution, but it's not beautiful:

window["mynode"] = new Array();
   cy.on('select', 'node', function(event){
   //debugger;
     // cyTarget holds a reference to the originator
     // of the event (core or element)
     var evtTarget = event.cyTarget;
     window.evtTarget = evtTarget;
     createTable(evtTarget);
     if( evtTarget === cy ){
         console.log('click on background');
     } else {
     mynode.push(evtTarget.data());
       console.log('click on some element');
       console.log("clicked on " + evtTarget.data("id"));
     }}) //end-of click


Any insights ?

dms

unread,
May 21, 2013, 1:46:55 PM5/21/13
to cytoscap...@googlegroups.com
Even having all information I need inside an array, I still cannot call a function only once.

Max

unread,
May 21, 2013, 2:01:49 PM5/21/13
to cytoscap...@googlegroups.com
Use your selectors:

// inside the select callback…
var selectedNodes = cy.$('node:selected'); // query the graph for selected nodes

// now iterate over the collection
for( var i = 0; i < selectedNodes.length; i++ ){
  var node = selectedNodes[i];

  callSomeFunctionOn( node );
--
You received this message because you are subscribed to the Google Groups "cytoscape-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cytoscape-disc...@googlegroups.com.
To post to this group, send email to cytoscap...@googlegroups.com.
Visit this group at http://groups.google.com/group/cytoscape-discuss?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

dms

unread,
May 21, 2013, 2:22:55 PM5/21/13
to cytoscap...@googlegroups.com
Thank you for your time Max, (I do appreciate your help).

That's what I am doing now, but once I have all elements selected, how can I call a function passing my new array/object only once ?

I have a function createTable(arrayOfNodes) that I am supposed to call only once to draw my selected nodes table.


example:

          cy.on('select', 'node', function(event){
   window["selectedNodes"] = cy.$('node:selected');
});

OK, now I have all elements node:selected and I can iterate here and get all data I need, but how to call my function createTable only once ?


Please, I do appreciate your help.

Bumbu Alex

unread,
May 21, 2013, 4:07:27 PM5/21/13
to cytoscape-discuss
Dirty but simple solution:

cy.on('select', 'node', function(event){
  clearTimeout(cy.nodesSelectionTimeout);
  cy.nodesSelectionTimeout = setTimeout(function () {
    console.log(cy.$('node:selected'));
  }, 300)
})

I use a timeout to wait until all select events will pass. And as clearTimeout will clear previous timeouts, only the last one will fire (if there will be no blocking long-lasting executions).

You may decrease timeout time (e.g. 20), but keep in mind that this is not a universal solution.

A much better solution will be to take in account mouseup/touchend events. Or maybe there is some built-in solution.

dms

unread,
May 21, 2013, 4:21:40 PM5/21/13
to cytoscap...@googlegroups.com
Hi Alex,

thank you for your time and solution :)

by now "it solves" the problem, but I am pretty sure it must be a better way to do it, don't you think ?


Cheers.,

Bumbu Alex

unread,
May 21, 2013, 4:39:19 PM5/21/13
to cytoscape-discuss
yes, there shold be something better, but as I see select event is available only for one element.
Also select event added to a collection fires for each element (the same as in my example).

So by now I don't see any other solution. Maybe when I'll work more with it I'll be able to propose a better solution.

The only optimization that I see by now is to put function outside of event scope:
function doSomething() {
  console.log(cy.$('node:selected'));
}
cy.on('select', 'node', function(event){
  clearTimeout(cy.nodesSelectionTimeout);
  cy.nodesSelectionTimeout = setTimeout(doSomething, 300)
})


Reply all
Reply to author
Forward
0 new messages