JavaScript packages for graphics

From ImpVis Wiki
Revision as of 14:00, 28 September 2021 by Cclewley (talk | contribs) (Created page with "The main categories of visualisation are simulations and data plots - we describe possible JS packages for each below. == Simulations == In simulations, we often think about...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The main categories of visualisation are simulations and data plots - we describe possible JS packages for each below.

Simulations

In simulations, we often think about elements moving around, like two-body collisions, electromagnetic waves in plasma, or an oscillating spring. It can be cursor-reactive or button/slider-reactive, or a combination of both. An example is the Gauss’ Law visualisation. The user can use their cursor to drag and drop charges or draw an integral loop and control the charges' magnitude and polarity using a slider.

2D simulations

Scalable Vector Graphics (SVGs) are a good starting point for mechanics simulations with just a few elements. (Guide: https://www.w3schools.com/graphics/svg_intro.asp) It also has the perk of using your own ready-made images on the graphics (see SVG Drag And Drop example).

SVG's performances are poor when there are many (this number depends on the complexity) elements. In this case, Canvas is a better option. The performance of any library will indeed be affected by the number of calculations involved, but SVG's way of handling the graphics does make it worse.

Canvas is suitable for 2D simulations with many elements, as it is much more efficient than using SVGs. However, the downside is that it is harder to use since there are fewer preset shapes and functions. Canvas also does not support event handlers natively, so it is harder to get mouse interactivity and other similar things working. Additionally, Canvas does not natively support text rendering, so it will be hard to put good looking text on the canvas. Finally, Canvas is resolution-dependent unlike SVGs.

On the up side, Canvas is not too hard to use, and you can expect to get a smooth performance with up to around 1000 animated objects. A useful video guide to help you get started with canvas can be found at the following link: HTML5 Canvas Tutorials for Beginners | Become a Canvas Pro.

SVG vs. Canvas The key difference is the way data is used. Datum can be assigned to individual SVG elements, and so we can select and update individual SVG elements. In Canvas, the canvas comprises pixels, so we cannot bind data to individual shapes. We redraw the entire canvas each time the data is refreshed.

3D simulations

Three.js will likely be our go-to library for 3D content, both interactive and otherwise. The library is based on WebGL and is highly performant, so well suited to physics simulations with multiple bodies. There is a steep learning curve involved, but the library’s main strength is the breadth of what can be achieved with it. Primitive geometries (spheres, cuboids, etc.) are easy enough to add. Custom shapes can be programmed in with a little more effort by defining the vertex positions. Even more sophisticated volumes may be modelled in third-party software (such as Blender) and loaded into three.js through the .gltf format.

Here is a handy resource that can walk you through the library to make the basics a little more intuitive:  https://threejsfundamentals.org/threejs/lessons/threejs-fundamentals.html.

Three.js can also be used to plot 3D graphs, although the library does not have any specific functions or classes to aid in this. The benefit of using three.js for graphs is the interface's customizability and the fact that graphs may still be panned or rotated through while they are animated - a useful feature for 3D content - unlike with plotly.js.

Data plots

There are many different data plots, ranging from line plots, charts, maps, and networks. Here is a website that may help you decide the best way to visualise your data: https://www.data-to-viz.com/. Data plots are usually button/slider-reactive, but cursor-reactive is possible and useful in the case of input graphs, e.g., cursor adjustable graphs.

Plotly.js is an intuitive library for beginners as it has convenient built-in functions, for example, Plotly.newPlot(); however, it is tough to make plotly plots cursor reactive. If you want cursor reactive plots, then a different library should be used. Another feature of plotly is that it can easily be used to make 3D plots.

d3.js is a more robust library in the sense that it gives you more control on customisations but has a steeper learning curve. D3.js is used in conjunction with either SVG or Canvas, so one should be familiar with these when using D3.

To illustrate the point, we now compare the codes for making a basic line plot.

plotly.js – https://plotly.com/javascript/line-charts/

d3.js – https://www.d3-graph-gallery.com/graph/line_basic.html

More examples of plotly.js and d3.js at

https://plotly.com/javascript/

https://www.d3-graph-gallery.com/index.html


Why use d3.js on top of SVG/Canvas instead of raw SVG/Canvas?

d3.js allows easier data manipulation and binding, especially large datasets, through JS.


An example suite

The Lattice Vibration suite has both data plots and mechanics simulations. It has been made in two versions, the first is purely plotly.js and the second in d3.js with a mixture of SVG and Canvas. Now we compare the two versions to illustrate the pros and cons.


Comparing the user interface

In the plotly suite, you might find the built-in functions useful. For instance, showing the closest data on hover, zooming in with the cursor, and panning. This cursor reactivity does not naturally occur in d3. As you scroll down the suite, you may find loading time getting longer on the plotly suite, but the d3 suite remains relatively smooth. On page 3 (2 Dimensional), you can find the drag-and-drop SVG (the two black arrows) working well with the sliders and the main vis. At this point, the plotly version suffers a significant performance deterioration even without drag-and-drop capabilities. Moving on to the last page, you should find that the d3 version has a shorter loading time, and the animation remains smooth. On the plotly version, you may find it tricky using the camera (changing the viewing angle of the 3D vis).


Comparing the code

On the Mie potential plotly JS file, you should find that when the animated orange ball is not required, plotting the static graph is simply putting the data into the Plotly.newPlot() function. You don't need to specify functions to draw axes or care about where to place the overall graph as you do in the d3 files. However, d3 allows for much more customisation. Plotly does make animation easy with Plotly.animatePlot(), but the animation in d3 is smoother. Focusing on the d3version of the 2D lattice vibration JS file, you should be able to compare the difference between the way data-binding works in SVG and Canvas.


Summary of the types of Vis and JS Graphics Libraries

For straightforward plots where all you require is the capability to plot static data, plotly.js may be the best choice. However, although it is possible to create animations and 3D plots, we do not recommend it for anything other than basic animations and 3D plots. The performance of plotly is quite bad, and animations quickly become very slow.


For mechanics visualisations or less traditional plots in 2D, you should consider SVGs or Canvas. For animations with many objects or other simulations that may struggle with performance, Canvas is probably best. However, SVGs are easier to use and still perform much better than plotly.js. If your animation is relatively straightforward, then you may be able to use SVGs or Canvas on their own, although you should learn about d3.js as well as it might be helpful

.

Pro tips

Before writing anything, make sure you’re familiar with the content that already exists on the Imperial Visualisations website. If a pre-existing visualisation in a suite looks somewhat like what you want one of your visualisations to be, then having a look at the code for the pre-existing one will give you good help. Don’t be afraid to start by copying the content of pre-existing files into your currently empty files and playing around with how the old code works. This is actually how a lot of visualisations start off!

Once you’ve had a look at someone else’s code, copy over some interaction structure. It’s useful to understand how the JS and HTML files talk to one another, but if you’re stuck, taking other people’s files and just understanding how their files work is a big help. If you’ve done this, make sure that the names of the files referenced in the “brains” of the HTML (down the bottom) are the ones you want them to be (they need to be referencing the files locally to your computer), so copying and pasting the content of their files won’t usually work, as the HTML will be unable to find the files that have (incorrectly) been asked for. Now that the interactions between files have correctly been set up, you should be able to get going.

When working out the maths, be careful with special cases that arise when dividing any two things. For example, suppose you wanted arctan(y1/x1) to find an angle. In that case, you’d need to create the special case for if x1=0, as JavaScript would have a problem with dividing by zero, even though you might not always consider this a problem. Algebraically we’d expect pi/2, so for this, you’d have to create the special case to return pi/2 for when x1 = 0.