Qerubin
Qerubin

Reputation: 212

select nodes whose attribute (array-type) contains a certain value with cytoscape.js

I am currently visualizing a network where the nodes have an attribute of type list, example:

{"data": {"name": "b", "go": ["c", "d", "f"], "id": "n0"}, "group": "nodes"},
{"data": {"name": "a", "go": ["a", "b", "c"], "id": "n1"}, "group": "nodes"},
{"data": {"target": "n0", "source": "n1", "id": "e1"}, "group": "edges"}

Is it possible, using cytoscape.js, to select all the nodes whose list-attribute ('go' in the example) contains a certain value?

Something like:

cy.elements('node[go.contains("b")]')

which would select node n1...

Many thanks in advance

Upvotes: 8

Views: 2295

Answers (1)

maxkfranz
maxkfranz

Reputation: 12242

Alternative: If you don't need to use selectors, you can instead use a filter function and keep the attribute as an array: cy.elements().filter(function(){ return this.data('go').indexOf('foo') >= 0; })

An array contains check can be expensive to do in a selector, as they are most often used in stylesheets -- which need to be applied whenever there's a state change. Currently, there is no way to do what you're suggesting with the existing selectors and your current data structure.

You may find it easier to work with an object rather than an array. The object can be simple name:true pairs like go: { foo: true, bar: true }. Since undefined is falsey, you only need to define the positive cases like in your array.

This way, you can use a simple selector like node[go\\.foo] (or node[?go\\.foo] if you want to be a bit more explicit). It's also simpler and cheaper to do checks in your own code (e.g. node.data('go.foo') ? 'has it' : 'does not').

Upvotes: 4

Related Questions