JavaScript packages for graphics

From ImpVis Wiki
Revision as of 15:29, 28 September 2021 by Cclewley (talk | contribs) (→‎Simulations)
(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.

Example of plotly, d3, SVG and Canvas

The Lattice Vibration Collection has both data plots and simulations. The one on the website has been created with the 2020 vue.js template. However, there are two other versions, particularly created to showcase the implementation of the different graphics packages. The first version is purely plotly.js and the second in d3.js with a mixture of SVG and Canvas. Below we compare the two versions to illustrate the pros and cons.

Here are the relevant links to the two versions: plotly version and d3 version. You can find the full source code in this GitHub repo.

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 d3 version 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 visualisation 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 simulations 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.