How to use eles.components() to filter direct neighbours of one node? - cytoscape.js

I want to filter all nodes not further away then one edge of a given node. I dont have a compound graph. I tried
var children = cy.$('#1').components()
But this only returns the node #1. I also tried
var allEles = cy.elements()
var myChildren = allEles.componentsOf(cy.$('#1'))
But this seems to return all nodes again. The docs also state a selector syntax "> (child selector) Matches direct children of the parent node (e.g. node > node)." But I cant figure that one out either. I tried
var myChildren = cy.elements('node#1 > node')
getting an empty array.
So, how can filter for direct children (depth=1) of a given node?

Did you try use:
// outgoers return all elements (edges as well) comming out from $('#1')
// nodes() > select only nodes
var children = cy.$('#1').outgoers().nodes();
doc: https://js.cytoscape.org/#nodes.outgoers

Related

Cytoscape.js Getting IDs For All Nodes Selected

I'm using Cytoscape.js to represent a network diagram. I can highlight more than one node at a time by selecting the first node followed by the second node while holding the shift key.
How can I have all the node ids that I have selected available in Javascript? For example and this would be ideal, if all the node ids that have simultaneously selected where organized into a Javascript list.
I looked in the cytoscape.js docs and could not find the location where this is described.
To receive ids of all selected:
elements
var typeIds = cy.elements(':selected');
nodes
var typeIds = cy.elements('node:selected');
edges
var ConnIds = cy.elements('edge:selected');
In order to get Ids of all selected nodes you could try this:
cy = window.cy = cytoscape ({
container : document.getElementBy('cy'),
// define a style for selected node
style : cytoscape.stylesheet()
.selector('node')
.css ({..............})
.selector('edge')
.css({...............})
.selector('node:selected')
.css({ 'border-color' : 'red'})
}),
elements : eles,
layout : {.............}
});

How to create an empty collection in cytoscape.js?

I want users to hide nodes in a cytoscape.js graph but also have a reset function. How should I initialize hiddenNodes in the following code? I looked at http://js.cytoscape.org/#collection/building--filtering which tells me how to add and remove nodes from a collection but not how to create an empty one.
var hiddenNodes = ?
function hide(nodes)
{
nodes.hide();
hiddenNodes = hiddenNodes.union(nodes);
}
function reset()
{
hiddenNodes.show();
}
P.S.: The hidden nodes are just a MWE, I know I could do this with selectors also.
P.P.S.: Are there alternative functions for union and difference that change the collection directly or are there only those who return new objects?
From the documentation for collection:
cy.collection() - Get an empty collection

How to use selector :removed in cytoscape.js?

How can I get removed eles from the graph?
cy.filter(":removed") doesn't work and cy.elements() doesn't have removed eles.
Thanks!
Cytoscape.js does not keep removed elements in the graph. That would contradict that they're removed. So, of course if you ask the graph for all removed elements, it will return to you an empty collection -- i.e. there are no removed elements in the graph.
The :removed selector exists for completeness and so you can use it on your own collections. If you have a collection for which you've held onto a reference, some elements may be removed later on but they'll still be in the referenced collection.
You need to remember which nodes you removed and then call restore on them:
var removed = [];
function remove(elements)
{
removed.push(elements);
selected.remove();
}
function restore()
{
cy.startBatch();
for (var i = 0; i < removed.length; i++)
{
removed[i].restore();
}
removed = [];
cy.endBatch();
}
For some reason, removing takes a long time on a large graph. And if you only remove and restore nodes, their connected edges are gone.

Sencha Touch 2: Load a List from a store.queryBy result

I had a List that used to work when it was bound directly to a store but now I want that list to get it's data from a queryBy on the original store.
Looking at the documentation is seems like setItems should do what I want.
var myStore = Ext.getStore('myStoreData');
var myData = myStore.queryBy(function(item) {
return item.get('status') !== null;
});
// At this point myData looks valid and has the data I want.
// Ext.apply.create.Class {all: Array[5], items: Array[5], keys: Array[5], indices: Object, map: Object…}
Ext.getCmp('myListComponent').setItems(myData.items);
I keep getting the error "Object [object Object] has no method 'getItemId'". I tried various other incantations but without success. I also took a look at setData and add but without success.
========================
After getting Thiem's answer I just ended up creating a function that would create a filtered copy of an existing store and then just setting the List store to that. Code below for others edification...
storeCopy: function(store, filterBy) {
var records = [];
var allRecords = null;
if(filterBy)
allRecords= store.queryBy(filterBy);
else
allRecords= store.queryBy(function(){return true;});
allRecords.each(function(r){
var rec = r.copy();
rec.setId(r.getId());
records.push(rec);
});
var store2 = new Ext.data.Store({
recordType: store.recordType
});
store2.add(records);
return store2;
},
Thanks all.
setItems method does a totally different thing. For example, says you have an Ext.Container which consists of a form, some fields, and some interaction buttons. These things are call child components, or items of the container. They are oftenly declared in the items config of the parent container and setItems is designed to programmatically set the value of that config. So it has nothing to do with the store logic.
In your situation, here is one of the solutions:
Create a store instance which contains filtered data.
Use this command: yourList.setStore('yourFilteredStore')
And it should reload... hope this helps

dynatree selectmode=3 is not honoured when using lazy loading

I was trying to use dynatree with lazy loading on in my project.
When I tried to combine the select functionality with the checkboxes and select mode 3 I was disappointed to see that the select rule for mode 3 which is select everything including children children .... children when the parent is selected.
This is because the children havent yet been loaded.
Does anyone have a workaround to get this working ? I would very much appreciate any suggestions.
Zank ya!!
When adding the children of the parent you selected, check if the parent has children. If TRUE, add each child and set each of those children to selected.
Here is some code below. The onLazyRead will go up top. Every time you click on a lazy node, this function will trigger. Inside this function should be a call to your function that fetches child data for the node you just selected.
The code below that is the way I solved this problem. Pretty much all it is doing is checking if the parent of the node you are adding is selected. If TRUE, you add the node, then .select() it.
This is much simpler when deselecting a node because all the nodes are already loaded. When deselecting, just go down the hierarchy of the tree from the node that is being deselected and simply un-check each node.
I know this is a lot of code to just throw at you, but hopefully you can grasp the idea out of it. If you cannot, I will try to check back to this thread during work. Maybe you can even post what you have so far?
onLazyRead: function(node){
jQuery("#tree2").dynatree("getTree").disable();
var pParentID = node.data.key;
//Select the Node
doChildReport(pParentID); //Get Children for this node's ID
},
///....
//Methods to grab data from a "XMLHttpRequest GET" go here
//....
//When you finally want to add the children that you fetched using the ID of the node you selected...
//treeArray is an array of node data that has been parsed out of a
//string returned by a "XMLHttpRequest GET"
//Contents of array in order, repeating: treeArray[0] = ParentID, [1] = nodeID [2] = nodeName
//Example, the array would return [111], [222], ["Child Node"]
if(){ //IF Next fetched node is on the last level, ie. no children
//add normally
}
else{ //If NOT, add lazy.
if(treeArray[1] != "nill" && treeArray[1] != undefined){
//IF THE PARENT NODE IS SELECTED
if(jQuery("#tree2").dynatree("getTree").getNodeByKey(treeArray[0]).isSelected() == true){
//AND IF the child node does not exist
if(jQuery("#tree2").dynatree("getTree").getNodeByKey(treeArray[1]) == null){
//Add the child node and then mark it selected
addChildNodeLazy(treeArray[1], treeArray[2], treeArray[0]);
jQuery("#tree2").dynatree("getTree").getNodeByKey(treeArray[1]).select();
}
}else{
if( jQuery("#tree2").dynatree("getTree").getNodeByKey(treeArray[1]) == null){
addChildNodeLazy(treeArray[1], treeArray[2], treeArray[0]);
}
}
}
}
Lazy load function...
function addChildNodeLazy(NodeID, NodeName, ParentID){
jQuery("#tree2").dynatree("getTree").getNodeByKey(ParentID).addChild({title: NodeName, key: NodeID, icon: false, isFolder: true, isLazy: true});
}
Admittedly, the following is a bit of a hack...but it solves this problem:
onSelect: function (flag, node) {
if (flag && node.childList == undefined) {
node.reloadChildren(function() {
node.select(false);
node.select(true);
});
}
If node is being selected (flag == true) AND the node has not been loaded yet (childList == undefined) then call reloadChildren with a callback function. The callback runs after the data is loaded and simply toggles the checkbox off/on. This causes all the child nodes (which now exist) to be selected.