A fresh new version of sigma.js

Sigma.js is a JavaScript library for graph rendering. It was created by Alexis (from our team) over 12 years ago, and we extensively use it at OuestWare. It’s an integral part of our history and identity: Paul (from our team) hired Alexis at the Sciences Po médialab in 2013 to develop sigma version 1.0, and Benoît (from our team) began using it before meeting Alexis and Paul. And now, we integrate it in about every other project we produce.

A screenshot showing that the first commit of sigma.js dates back to January 2012
The first commit of sigma.js! !

Sigma.js v2.0

After an initial trial version developed in 2012, sigma version 1.0 was developed by Alexis and Guillaume Plique at the médialab, and was released in 2014.

Guillaume and Alexis at FOSDEM 2019
Guillaume and Alexis at FOSDEM 2019

At this stage, we could develop very interactive web applications for exploration and/or visualization of networks, but we lacked tools. It would be preferable to separate the rendering tools from the “processing” tools of graphs. That’s why Guillaume created Graphology in 2016. He then started developing a new version of sigma, which only does rendering, using graphology as the graph model, and for all algorithms.

After creating OuestWare, we also started using this “unofficial” version of sigma, until we decided, together with the médialab, to finalize a version 2.0. In September 2021, we all met in Nantes, and finally released this new version, with a brand-new showcase page designed by Robin de Mourat.

A Sizable Issue

In 2022, we started working on Gephi Lite, and began encountering certain limitations of sigma, especially in managing the sizes of nodes and edges. In essence:

  • The size of nodes is interpolated between pixel values that do not depend on the size of the scene, unlike their positions;
  • Nodes and edges grow “less than the zoom”: when zooming by a ratio R, they grow by a ratio sqrt(R).

An animation showing that the variation in node size is sometimes unexpected
Nodes are tighter when the scene is smaller

For Gephi Lite, we needed better control of element sizes, so they would be in the same reference frame as the node positions, and they would grow linearly with the zoom. And we were not the only ones. Unfortunately, the design of the APIs in sigma (that is, the code indicating how to draw the nodes and edges) did not allow for this, and to properly implement these features, it was first necessary to break the existing code.

That’s why, at the end of 2022, with the help of Benjamin Ooghe-Tabanou, Alexis began to restructure this code as well as the translations of coordinates between the different reference frames, and Guillaume wrote a layer that would greatly simplify the writing of programs.

But we limited our efforts: we did not want to rush out a new major version of sigma, and we all had plenty of feature ideas that we would like to add in the process. And unfortunately, both at OuestWare and the médialab, sigma was never our current priority.

A Welcome Sponsor

A screenshot of G.V()
A screenshot of G.V()

In early 2023, Arthur Bigeard, who has a very advanced use of sigma in his application G.V(), contacted us to help him improve his use of sigma. He was already using the latest version, and had discovered some “hidden” features of sigma that we thought we were the only ones using (like Guillaume’s experiments, for example). After detailing to him the feature ideas we had in mind for a new version of sigma, Arthur decided to hire us to advance on sigma. We made regular updates with him, and he validated the priority features on which we needed to put the most effort, but we remained very free on how to proceed.

A Busy Roadmap

We took advantage of the major overhaul that involved breaking the programs to think about what we could/wanted to add in the process:

  • Instanced rendering could significantly reduce the memory footprint of the programs. Essentially, it would allow sending only once the attributes that change for each element and not for each vertex (color, size, etc.);
  • Picking would allow for collision detection with all programs, without having to calculate it ourselves. Plus, it would eliminate the need for managing the quadtree;
  • More refined data indexing would make sigma much more efficient in many cases, by precisely using the payloads of graphology events.

Also, we decided to include other features that we’ve been wanting for a long time:

  • We finally got the @sigma organization on NPM, so we want to start publishing “official” packages for sigma extensions. Thus, we would restructure the project into a monorepo;
  • We also wanted to improve the website, with a Storybook (rather than examples in CodeSandbox which break too regularly since the release of v2), and with proper documentation.

Sigma.js v3.0

We’ve made significant progress in the past few months. To summarize:

  • Alexis implemented picking and instanced rendering in the program utilities, as well as on all existing programs;
  • Benoit heavily optimized the update management. Now, in many cases, only the affected indexes are modified, which should increase sigma’s performance;
  • Benoit also implemented support for TypeScript generics in sigma, to clarify the type of the graph;
  • Alexis released the node-image renderer and integrated various features from Guillaume’s version, and it’s now published under @sigma/node-image
  • Finally, Alexis was able to take Guillaume’s code from his experiments for drawing curved edges (a long-requested feature), added label drawing for curved edges, and published all this under @sigma/edge-curve

Regarding the modernization of tasks:

  • We refactored the repository into a monorepo, with Lerna to manage publishing;
  • We replaced Mocha with Vitest (to be able to run unit tests in a browser environment);
  • We replaced Benoit’s ad-hoc code with Playwright for end-to-end tests;
  • We replaced the outdated Webpack configurations of the project with Preconstruct (used for sigma, but also the other existing and upcoming packages), and Vite for the minified version of sigma for CDNs;
  • We migrated the demo from Create React App to Vite;
  • We wrote the new documentation, based on Docusaurus;
  • We migrated the ad-hoc benchmarking code to vitest bench, but it does not yet work properly with the browser mode (we are closely monitoring the ticket).

The homepage of the new sigma documentation

Again, a huge thank you to Arthur from G.V(). Without his support, we wouldn’t have been able to release version 3.0, at least not as quickly.

Sigma v3 is still in the testing phase before releasing a non-beta version, but we are already using it in several projects, and we’ve become more responsive than before in maintenance, as the code is fresher (and so are we). This new sigma should be less memory-intensive, probably more efficient - we’re looking forward to being able to measure that reliably. And finally, we have curved edges, which have been requested for so long \o/

A graph displayed with sigma featuring curved edges
The long-awaited curved edges