GUI programming in Clojure/Clojurescript - 'zoomable directed acyclic graphs' - javascript

I'm designing a GUI and want to find a library on the JVM or for javascript that I can use with Clojure or Clojurescript.
The problem:
I need to display 'zoomable' directed acyclic graphs (DAGs). A picture is worth 1000 words, so here is what the interface ought to look like, and how the screen changes under 'zooming':
Specifically, every node can have its own internal graph, with the restriction that each inner graph has the same number of inputs and outputs as the node itself.
My experience with graphics is limited in Javascript and nonexistent in Java, but...
My ideas:
Naively draw the whole graph with all 'inner graphs' already inside the nodes, and fade the inner graphs out for text when the zoom level is sufficiently far away. Use click events to change the zoom to and from this level. I don't think this will behave well when there are several nested inner graphs.
Draw the unzoomed graph and zoom into a node when clicked so that its background fills the screen, then overlay the inner graph. For nested inner graphs do the same trick, maintaining a 'background node' and 'inner graph'.
Is option 2 sensible? If so is there a library (ie graphviz) I can modify to achieve this behaviour? If there isn't a library, what framework (ie JavaFX) should I use?

If you don't care about struggling with Java interop syntax, I can highly recommend FXDiagram:
Selected features:
Modern graphics [based on JavaFX]
Suggestive metaphors
Optimized for usability
Multi-touch gestures
Smooth transitions/animations
Animated auto-layout (based on KIELER and Graphviz)
Animated undo/redo
JSON persistence
SVG export
Xtext/Eclipse integration
Graphical context menu
…and much more
It's open source (and active), written in Xtend and easily integrates models expressed in Xtext-based DSLs.

Related

Drawing shapes javascript

I have a web project that I have to create a virtual screen for example screen for mobile pc, in this screen I want to partition it into zones to subsequently assign displays on these areas, are they javascript libraries that facilitate drawing and recover the dimensions of these areas.
Thank you.
D3 is the best option for doing so, https://d3js.org/
You can learn more about D3 in https://benclinkinbeard.com/d3in5days/ (easy email starter course) since D3 can be used in really complex ways to display data and figures

Creating 2D scene in ReactVR

Can I create a 2D scene in ReactVR? I mean displaying elements on a screen like in normal React, for example, classical web menu which will be always displayed in the same place on screen. Or something like HUD in 3D games.
More context on what you are trying to achieve or what platforms you are targeting would help, but here are a few guidelines:
IN VR
You generally don't want to have permanent overlays or components that move along with the user. This tends to break immersion unless very carefully designed and properly implemented. You can still render 2D elements using the built-in Text, Image, and View components, but you have to be smart about interactions. A common alternative to this approach is fading in a menu/HUD whenever the user looks in a particular direction, e.g. when looking at the ground.
Either way, you will want to take a look at VrHeadModel and the APIs it exposes to query user's Yaw/Pitch/Roll or how to listen for head rotation events.
On WEB & Mobile
For these platforms, you can implement menus/HUDs using the DOM Overlay concept, which renders a traditional 2D surface on top of the 360 scene.
The linked sample shows how to implement what you need in 2D, using plain React, html, css, etc. In this case, it renders a simple overlay with text on it, but you can use it to implement persistent overlays, menus or whatever UI you believe is better consumed in 2D instead of within the 360 scene.

Drawing directed acyclic graphs in a web application - only strange approach available?

we're currently building a web application (AngularJS) which needs to draw directed acyclic graphs (up to 1000 nodes, up to 10000 edges) based on dynamically created data.
Since over a year I am looking for a library/tool which is calculating the required layout and drawing a graph which can be styled, is zoom and panable, interactive (e.g. highlight children on mouse over).
Graphviz is the tool which produces the best results but it's not really ready to be used on webservers (especially as I cannot guarantee the OS and don't want to).
I tried dagre and it's d3 rendering - and I like it very much, but it has two major drawbacks: 1) it doesn't really support ranking and clustering - which makes the output rather chaotic and 2) with the graphs getting bigger its performance is getting unacceptable.
Next thing which really looked convincing was cytoscape.js as the output looks very nice and it's rather fast in drawing even larger graphs (and allowing some performance tweaking). But its standard layouting (e.g. cose or breadthfirst) doesn't produce the output we're requireing.
From my current point of view a have two chances:
1) Create layout with dagre.js and drawing the result with cytoscape.js (layout: 'preset', using the calculated x and y for nodes from dagre layout). But 'compounds'/clusters are not supported that way.
2) Using [viz.js](https://github.com/mdaines/viz.js) (an emscripted Javascript version of Graphviz, again not really performing well in drawing the graphs) to calculate the result as output format plain and again using this result to draw it with cytoscape.js.
Now my question(s):
1) Do you have another idea how to achieve it?
2) Could you give me any hint on how to ideally link the chain if my ideas are correct?
(AngularJS -> REST Backend -> JSON to Frontend -> Restructure JSON for dagre or viz -> Calculate layout -> input result to cytoscape -> render in browser?!?) and is there a chance to do the layout calculation on my node.js frontend server and not the client itself (again due to performance)?
Any hint and idea is heaviley appreciated.
It sounds like you're dissatisfied with Dagre as a compound layout. That makes sense, because the author of Dagre did not implement compound support for it. Dagre is separate from Cytoscape.js but can be used by it. You'll note the author of Dagre has stated he will no longer update the library with new features from himself. Thus, your options are:
(1) Use another Cytoscape.js layout actually designed for compound nodes, like CoSE or Cola.
(2) Write your own layout for Cytoscape.js that meets your needs: http://js.cytoscape.org/#extensions/layouts
(3) Adapt Dagre to recognise compound nodes and make a pull request to the author: https://github.com/cpettitt/dagre Then the Cytoscape.js layout for Dagre can be updated to use the new Dagre APIs that you add.
Currently, compound graph layout is an open research area -- so you'll be hard pressed to find many layouts that support them at all in any library. Cytoscape.js has some compound supporting layouts, and you're free to fork them if you want different behaviour. Also note that the 2.5 branch has CoSE2 with an improved algorithm.
Cytoscape.js can use a dagre layout. You can look here in the cytoscape docs for more information, but you can just add your nodes and edges to the graph and then run the dagre layout. That way you don't have to position all of the nodes manually based on the position of nodes from the separate dagre.js.

Creating own dynamic layer type in OL3

I am currently migrating a special dynamic layer type I created for OpenLayers from OL2 to OL3. The layer displays markers (a lot of them, usually around 1000) that are moving on predefined trajectories. Trajectories are loaded in a special JSON format from a server.
My current approach for OL2 is very performant, heavily optimized and uses the Raphael library (http://raphaeljs.com/). The general application layout looks like this:
OpenLayers2 is loaded, the map is created
A special layer "DynLayer" is created which is modelled after OL2's own VectorLayer. This layer handles communication with OL2 (zooming, panning, dragging etc) and provides a very sophisticated asynchronous mechanism to redraw to map (that is, move the markers) based on the current interaction (for example, the refresh rate goes down if the user is currently panning to map to prevent a stuttering effect). During construction, the DynLayer creates a Raphael SVG-layer and attaches it into the DOM. If the map is panned or zoomed, the Raphael layer is synchronized by the DynLayer.
Markers are then created on the SVG-layer and their position is periodically updated
This approach works extremely well and because Raphael supports older IE versions, it also runs in IE8 and IE7. It also enables me to provide animations based on Raphaels built-in animate method.
I am now trying to migrate this application to OL3 and I am not 100% sure what the best approach would be. Is it possible in OL3 to add custom-built layers after OL3 is loaded? If so, is there any documentation? I tried implementing my own version of a VectorLayer, but OL3 threw a ton of errors related to the goog object provided by the Closure API.
More generally speaking: would it be better to recreate my old approach and draw a Raphael layer on top of OL3? This method would allow me to reuse most of my previous code. Or should I use methods provided by OL3 to draw directly on a HTML5 canvas? If so, how can I obtain control of the refresh rate of the canvas?
I had I a look at the example at http://ol3js.org/en/vector-api/examples/dynamic-data.html?q=dynamic but it does not really fullfil my needs. The markers are animated in an endless loop, and I need specific control over the refresh rate. More generally, how do I prevent my markers from being deleted on one of OL3's own canvas refreshes (for example, if new tiles are loaded).
My general impression of OL3 is that it is more difficult to add own extensions than with OL2, which appeared more 'open' to me than OL3.
Thanks for any help!
Note that OL3 is not meant to work well with IE7 or other 'old' browsers.
As far as I understand OL3 was build for performance and has fast vector rendering.
It also integrates with d3, so it can probably integrate with other technologies.

Pie, bar, line: SVG/VML better than Canvas

I need to choose a library for "standard" charting: pies, lines and bars.
From what I've read, it seems to me that the best format is SVG/VML, like Highcharts for example. SVG is becoming standard across all major browsers, now that IE 9 accepts it. It seems easier to rescale and export than Canvas.
Still, I see that several charting libraries rely on Canvas. Am I missing something? Is there any reason for considering Canvas over SVG for such applications?
You can generally achieve the same results with either. Both end up drawing pixels to the screen for the user. The major differentiators are that HTML5 Canvas gives you pixel-level control over the results (both reading and writing), while SVG is a retained-mode graphics API that makes it very easy to handle events or manipulate the artwork with JavaScript or SMIL Animation and have all redrawing taken care of for you.
In general, I'd suggest using HTML5 Canvas if you:
need pixel-level control over effects (e.g. blurring or blending)
have a very large number of data points that will be presented once (and perhaps panned), but are otherwise static
Use SVG if you:
want complex objects drawn on the screen to be associated with events (e.g. move over a data point to see a tooltip)
want the result to print well at high resolution
need to animate the shapes of various graph parts independently
will be including text in your output that you want to be indexed by search engines
want to use XML and/or XSLT to produce the output
Canvas isn't needed unless you want heavy manipulation/animation or are going to have 10,000+ charts. More on performance analysis here.
It is also important to make the distinction: Charting and diagramming are two different things. Displaying a few bar charts is very different from (for instance) making diagramming flowcharts with 10,000+ movable, link-able, potentially-animated objects.
Every SVG element is a DOM element, and adding 10,000 or 100,000 nodes to the DOM causes incredible slowdown. But adding that many elements to Canvas is entirely doable, and can be quite fast.
In case it may have confused you: RaphaelJS (in my opinion the best charting SVG Library) makes use of the word canvas, but that is no way related to the HTML <canvas> element.
In the past two years, my preference has been to use svg, as I mainly deal with relatively small datasets to build pies, column charts or maps.
However one advantage I have found with canvas is the ability to save the chart as an image thanks to the toDataURL method. I haven't found an equivalent for svg, and it seems that the best way to save an svg chart client side is to convert it to canvas first (using for example canvg).

Categories

Resources