Which layout is best with cytoscape.js? [closed] - cytoscape.js

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
We are right now analysing cytoscape.js for our requirements and we wished to understand which layout extension out of http://js.cytoscape.org/#extensions/layout-extensions will be good for us. Can any one please help/guide us in choosing layouts?
We are thinking of having more than one layout depending on the use case however with each layout we would always like to have high performance with quick graph rendering.
Use Cases:-
1) We want to display 20,000 interactions(edges) and probably 40,000
interactors(nodes) at maximum level, we can reduce that down if it's
too much for any layout to handle.
Would "cise" and "fcose" be alright for this ?
2) Graph should spread out in the view port making use of any empty space
if small number of nodes/edges are displayed, I think we need to do
this by ourselves but just in case if it comes out of the box.
Would "spread" be alright for this ?
3) Non crossing edges.
Would "ngraph.forcelayout" be alright for this ?
4) We would need a functionality where there would be parent-child
relationship for edges so that when user clicks on parent edge,child
edges appear and vice versa.
Which layout would be best for this use case ?

Which layout extension would be the best highly depends on what kind of graph you are about to visualize. You would probably need to try a few and see what works best.
For a DAG the best (from my experience) layout is Dagre.
Dependencies:
<script src="lib/cyjs/cytoscape.min.js"></script>
<script src="lib/cyjs/dagre.js"></script>
<script src="lib/cyjs/cytoscape-dagre.js"></script>
Config:
layout: {
name: 'dagre',
rankDir: 'LR',
}
For auto-zooming you would use .fit() method on the cytoscape instance.
let cy = cytoscape(options);
...
cy.fit(cy.elements());
More generally, .elements(), .nodes(), .edges(), .$() can be used to get a collection of graph elements which can be used to show/hide, select/deselect, and fit-to. Collections also support all sorts of graph navigation functionality like fanin/fanout tree, which can be used to get a very pleasing graph exploration UI.
To give a taste of the collection API, a highlighting of a fanin + fanout tree of the selected node(s) would be something like
let n = cy.$('node:selected');
if (n != null) {
// find elements to be displayed
let ns = n
.predecessors()
.union(n)
.union(n.predecessors().union(n).successors());
// display them
ns.style("display", "element");
// hide the rest of the graph
cy
.elements()
.not(ns)
.style("display", "none");
// fit the view port to the displayed elements
cy
.fit(ns.union(ns.incomers())
.union(ns.outgoers()));
}

Related

Show or hide featues by zoom level and importance

Using arcgis for JS 4.24 MapView.
I have a feature layer with features of different importance to the user. The importance is defined in an attribute of the feature. What I want to achieve is, that less important features only show on a certain zoom level.
What I tried so far:
Clustering: is not what I want since it is grouping on occurrences not importance.
Unique Value Renderer: Does not seem to support visibility by zoom level but is otherwise exactly what I would use.
Setting the min-max visibility: This applies to all features and cannot be configured by attribute value.
What did I miss? Any other ways to apply custom styles to feature layers?
I guess a simple solution would be to create as many FeatureLayer instances as importances you have. In each of this instances you set,
definitionExpression to the importance level,
maxScale and minScale to constraint the visibility
This solution would work if the number of importance levels are "reasonable" (let say, less than 10 or so, you will have to test it).
Another solution would be to listen for scale changes in the map view (could be the updating event), and then apply a filter (could be definitionExpression again) with the correspondent importance. With this you do not need to have many instances of the same service.
EDIT
The reason for using updating, is to avoid doing stuff while the view is changing, something like this,
view.watch("updating", function (value) {
if (!value) {
// now is the moment to check view properties
// for example
if (view.scale < MIN_SCALE) {
doSomething();
};
}
});

How to do expensive operation in the app itself like searching in large list in react native? [duplicate]

This question already has answers here:
How to run time expensive code in React Native
(2 answers)
Closed 1 year ago.
I have a json of 10000 records which I need to show in a Flatlist.I am using a virtualized list which is working fine.Now I have certain filters which on click should filter out the json and re render the list with the new data.I am simply filtering out the data.
const filters = foo1;
const largeList = [{ id:1, foo:'foo1',bar:10 },{id:2, foo:'foo1',bar:20} ...]
const filteredList = largeList.filter(l=>l.foo === filters && l.bar > 10);
The filters are dynamic and this lags my application since it puts pressure in the UI thread.I have used InteractionManager.runafterinteractions() but that is not working in this situation. How do I do such expensive operations in the app without blocking the UI thread ?
If you can't delegate the filter to your backend, the best way to achieve better performance is replacing .filter with a for loop.
There are a lot of pages online demonstrating that the for loop is much faster than array functions. (https://javascript.plainenglish.io/are-for-loops-better-than-arrays-filter-or-foreach-methods-f54b6880d201)
Moreover, you need to evaluate a better configuration of your Flatlist:
removeClippedSubviews:
If true, views that are outside of the viewport are detached from the native view hierarchy.
maxToRenderPerBatch:
It is a VirtualizedList prop that can be passed through FlatList. This controls the amount of items rendered per batch, which is the next chunk of items rendered on every scroll.
updateCellsBatchingPeriod:
While maxToRenderPerBatch tells the amount of items rendered per batch, setting updateCellsBatchingPeriod tells your VirtualizedList the delay in milliseconds between batch renders (how frequently your component will be rendering the windowed items).
pure component:
Implement update verification to your components. React's PureComponent implement a shouldComponentUpdate with shallow comparison. This is expensive here because it needs to check all your props. If you want a good bit-level performance, create the strictest rules for your list item components, checking only props that could potentially change. If your list is basic enough, you could even use. (React.memo could be a good solution)
source: https://reactnative.dev/docs/optimizing-flatlist-configuration

cytoscape.js layout that allows child positioning within compound (e.g. like dot's rank)

I am trying to use cytoscape to replace my dot output and make it interactive (move nodes and compounds, expand/collapse compounds, etc.)
When a graph is first loaded, the user should be presented with a default layout though. However, I am struggling to find a layout/config that supports what dot calls rank.
In my graph I have compound nodes that represent components.
Components contain other components and/or states, transitions, variables.
Each component can specify inputs and outputs.
In dot I tried to add some form of flow within the system (rankdir=LR;) by positioning the inputs on the left (rank=source;) and the outputs on the right (rank=sink;).
Other elements have no rank and are hence freely positioned.
I then specified cluster subgraphs containing all recursive components.
Now, here is what I have in dot. I hope it explains what I would like to end up with.
First, I already saw this question, but as far as I understood it's for manual positioning, rather than layouts.
I haven't found a layout that fully supports positioning nodes within the compound.
I looked into using the cytoscape.js-cola layout with the following options:
layout: {
name: 'cola',
flow: { axis: 'y', minSeparation: 40 },
avoidOverlap: true
}
I ended up with this
As you can see, there is some flow, but not as nicely as in dot.
I tried adding some function for the alignment parameter, but as far as I understood I can only specify the absolute coordinates (e.g. return {'x': 0};). This basically allows me to align ALL inputs, rather than all inputs of a compound.
Here is a CodePen of my example to play around with: https://codepen.io/anon/pen/GEaOQQ
In the Javascript you can see the comments of
You could try Klay: https://github.com/cytoscape/cytoscape.js-klay
If any of the existing layouts don't meet your requirements, you can use any algorithm you'd like by writing a layout extension. You could port the exact layout you're using with dot/graphviz, if you like.

Declarative coding or programmatic coding in Dojo Projects? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
In my own experience, I like programmatic coding. To name a few benefits at here:
Better performance: no need to parse.
No switch between html and javascript: no html, everything in code(use css to control layout.)
Easy to dynamically change the content.
Easy to be read and be maintained.
But, it seams a lot of users at here using declarative coding. my question is : what's the benefit to use declarative coding? Which one is dojo gurus' favorite?
Like fransisco said, you can seperate your code easier. I mean, if you instantiate all your widgets in your JavaScript code, your JavaScript will become pretty large and your HTML will usually be small (only contains "container" nodes which you use to place widgets in).
Better performance: I have to agree with you that it indeed lowers the performance since you have to parse your entire page, but you can optimize that by disabling parseOnLoad and by only parsing the DOM nodes you actually need. At the company I work for we did that by placing all Dojo widget markup inside a <div> with a certain classname. Then in our JavaScript code we do something like:
query(".containsDojo").forEach(node) {
parser.parse(node);
});
No switch between HTML and JS: The switch between HTML and JS makes it easier to understand your code and to have a context. For example, if you need to modify widget A by widget B that's placed on a page called C.html. Then it's easy to look for your widget A since you know on what page it is and where it's located (top, bottom, ...). If you put everything in your JavaScript file, you will have a hard time managing your code since you don't know in what context the widget is initialized. You will have to look through your entire JavaScript code because the widget can be initialized at any point in your code.
Easy to dynamically change the content: If you need dynamic content I usually create some kind of widget myself and put the JavaScript logic there so my "main" JavaScript and HTML code still look clean. You can always use the dijit/registry module to change certain things in your content.
Easy to read and be maintained: I totally disagree with that, similar to what I said in my previous paragraph about the switch between HTML and JavaScript. I mean, what's the difference between a dijit/form/TextBox and a normal HTML input-field? Not much, they're both UI items. Yet, if I follow your thoughts I would put the TextBox somewhere in the JavaScript code and the normal HTML input field inside your HTML. The HTML not only provides you a context, but also centralizes all UI elements.

Who is the parent?

I have a qml app which is created via two separate ways.
1) via a c++ code during startup
2) via my main.qml as one of the tabs.
Inside the qml app I want to know who is my parent so that I can decide if I should stay on my current page or load some other qml. How to know who is the parent to take such decision?
This question is difficult to answer for a few reasons. Notably, it's not especially clear what you want. The simple answer to your question is that a QML element always has access to it's parent via the exposed parent property that exists on all objects. If your question is more complicated as it appears then you need to rephrase the question to better clarify what you actually want.