How to create an empty collection in cytoscape.js? - 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

Related

Why does data in list1 changed automatically when I change the data in the other list2 which is cloned from the list1? Using Vue.Draggable

I am using Vue.Draggable in my Vue project and trying to drag(clone) a button from sider into a draggable component.
I want to modify the data when I clone the button into the component. But I find that when I modify the data in the list which is binded with the component, the original list that sider used got changed automatically.
Is there some kind of synchronization mechanism in Vue.Draggable or something? I want to change the object data in the component only.
I tried to modify the object in the list2 manually by using a vue extension in Chrome browser. And it still happens. So I think maybe it's not bug in my code.
addEntity (conditionID, entity) {
if (!entity.forChoose) {
}
else {
let variable = 0;
for (let i = 0, len = this.whens.length; i < len; i++) {
if (this.whens[i].entity[0].id == entity.id) {
variable++;
}
}
this.whens[conditionID].entity[0].forChoose = false;
this.whens[conditionID].entity[0].variable = variable;
this.whens[conditionID].entity[0].name = entity.name + '-fake';
}
},
The code above is the event when I drag the data into the component, and changed some variable.
Although I did nothing to the original data in the Sider where I cloned the data from, it still got changed as well.
Is there a way to change the dragged data but do not affect the original data?
Please help me, thank you!
I think this is happening because of the immutability.
so can you try using spread operator to create new shallow copy of your list before you change it.
how to use spread operator (triple dot)
let newArrayOfWhens = [...this.whens]
then use the "newArrayOfWhens" array in your code
You can create a deep clone as well if you want, but try to avoid it if it is not necessary.
you can use a library call "lodash" to do it very easily
deepClone

bind dynamically to this vuejs

Hey guys I have the following function its working ok but I think it could be better.
methods: {
onFileChange(e, filedName) {
console.log(e.target.files);
console.log(filedName);
const file = e.target.files[0];
const fileToCheck=document.getElementById(filedName);
console.log(fileToCheck);
if(filedName=='thumbnail1'){
if(fileToCheck.value!=''){
this.thumbnail1 = fileToCheck;
this.thumbnail1Url= URL.createObjectURL(file);
} else {
this.thumbnail1=null;
this.thumbnail1Url=null;
}
}
if(filedName=='thumbnail2'){
if(fileToCheck.value!=''){
console.log(fileToCheck);
this.thumbnail2=fileToCheck;
this.thumbnail2Url = URL.createObjectURL(file);
} else {this.thumbnail2=fileToCheck; this.thumbnail2Url=null;}
}
},
Instead of checking the value for
if(fieldName == "something"){
this.something = URL.createObjectURL(file)
}
I would simply pass in a string of the fieldName and bind to it dynamically by just typing this.fieldName (filedName could equal thumbnail1 or thumbnail2 or chicken for all I care I just want to be able to pass in the name of the data atrribute and bind to it that way) but when ever I do this it doesn't work. Any help here would be great.
It's not completely clear to me what you want to accomplish, but I think you're asking about creating a dynamic data property for a view component. If that's the case, there are a couple of things to consider.
First, the example you cite, this.fieldName is not correct JavaScript syntax if fieldName is a string that contains a property name. The correct version is this[fieldName].
Note, though, that you can't simply define a new data property for a Vue component by setting it to a value. That's a limitation of JavaScript that's described in the Vue documentation. If data[fieldName] is an existing property that's defined in the component's data object, then you'll be okay. Even if you don't know the value of the property, you can initialize it, for example, with a value of null and then update the value in your method. Otherwise, you'll need to add the property to an existing non-root-level property as the documentation explains.

Can't initialize custom form objects on second datatables pages

You can add static form object's like selects & inputs to datatable columns as shown here:
https://datatables.net/examples/api/form.html
But I'm trying to add custom bootstrap widgets. Like TouchSpin found here:
http://www.virtuosoft.eu/code/bootstrap-touchspin/
When I initialize TouchSpin it only initializes the objects on the first datatables page shown, the objects on the second/third pages are not initialized.
Anyone have an idea how to fix this? Its probably because the second/third pages are not part of the DOM yet?
What you need to hook into is the "drawCallback" function. You can specify it in the options when creating the DataTable. It would look something like this:
var table = $('#example').DataTable({
//... Your other options ... //
drawCallback: function(settings) {
// This callback is called when the draw is complete which happens on:
// paging, sorting, and of course when you call ".draw()". The current
// DataTable page is in the DOM with all the HTML.
// You can get the jquery element for the table like this.
var dataTableJqueryObj = $(this);
// You can get the API object like this.
var apiDataTableObj = this.api();
// Initialize your controls ...
}
});
Let me know if you have any other questions.

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