13 August 2025

GraphViz as a WebAssembly module

A long-awaited feature in the bibref project is to visualize statement graphs inside the WebAssembly Qt application. This was not possible due to the missing port of GraphViz library for the WebAssembly platform. In fact, some work has already been done by, for example, in the hpcc-js-wasm project. Recently, I had a look at it, but finally I started to work on my own build to keep everything under control.

I faced several issues. The first challenge was to find the best settings to compile GraphViz via Emscripten. This is the final method that lead to a success on the source code of GraphViz 13.1.2:

emconfigure ./configure CFLAGS="-sUSE_ZLIB -pthread" \
 LDFLAGS="-sUSE_ZLIB -pthread" \
 --disable-shared --enable-static --with-qt=no \
 --prefix=$EMSDK/upstream/emscripten/cache/sysroot

Here we force using Emscripten's bundled implementation of the zlib library and enable POSIX threads. Also, we don't want to build the shared library (in fact, we would get errors on code duplication), only the static version. It is important to disable Qt support because the build system wants to include the native version of Qt in the other case. Using the correct prefix makes sure that the install step (below) copies the library to its right final folder.

Now make -i will compile GraphViz and ignore some possible problems (for example, the utilities dot_static, gvpack and gvpack_static) will not compile, but it is safe to ignore these errors because they do not play a role when using the library. The library must be installed by entering make -i install.

To check these steps, we should find the cdt, cgraph, pathplan, xdot, gvc and gvpr libraries installed (as .a and .la files) with their pkgconfig descriptions (as .pc files) and the plugins gvplugin_core, gvplugin_dot_layout, gvplugin_kitty, gvplugin_neato_layout and gvplugin_vt.

Using the library

As an application, here is how this has been integrated in the latest version of bibref.

First, to avoid problems with duplication of zlib, I had to remove the zlib folder from another library, SWORD, by deleting the folder src/utilfuns/zlib (this folder may be missing in some versions in the library, in that case this step can be skipped). This seems to be a strange issue in Emscripten: sometimes it complains about duplications, but not always.

It was quite annoying to list all required parts of GraphViz in the CMakeLists.txt file. Maybe there is a better way, but for now I find this solution to load the library during the build process correctly:

find_library(gvc_LIB NAMES libgvc.a)
find_library(gvpr_LIB NAMES libgvpr.a)
find_library(gvplugin_dot_layout_LIB NAMES libgvplugin_dot_layout.a
 PATHS "$ENV{EMSDK}/upstream/emscripten/cache/sysroot/lib/graphviz")
find_library(gvplugin_core_LIB NAMES libgvplugin_core.a
 PATHS "$ENV{EMSDK}/upstream/emscripten/cache/sysroot/lib/graphviz")
find_library(cdt_LIB NAMES libcdt.a)
find_library(cgraph_LIB NAMES libcgraph.a)
find_library(xdot_LIB NAMES libxdot.a)
find_library(pathplan_LIB NAMES libpathplan.a)

in the detection part and

target_link_libraries(bibref-qt PRIVATE ...
${gvc_LIB} ${gvpr_LIB} ${cdt_LIB} ${cgraph_LIB} ${xdot_LIB} ${pathplan_LIB}
${gvplugin_dot_layout_LIB} ${gvplugin_core_LIB})

in the linking part (I use additional libraries, that is why ... is present).

The result

Here is an example how this looks like in the browser. The screenshot is a demo of the latest build of bibref, located at matek.hu/zoltan/bibref-qt-2025-08-13:

The GraphViz library draws the graph presented in the bottom-right subwindow Visualize of the figure. In fact, the image is a Scalable Vector Graphics (SVG) object (rendered by the QSvgWidget class from Qt), thus it can be scaled arbitrarily when the subwindow is rescaled, exactly the same way how it works in the native desktop application:
Of course, there is still room for improving the look. Unfortunately, the font used in both graphs seems to be displayed in a bit inaccurate positions. But for the moment, this is acceptable.


Entries on topic technical developments

  1. Embedding realgeom in GeoGebra (9 July 2021)
  2. Web version of Tarski (1 October 2021)
  3. Developing Giac with Qt Creator on Windows (24 January 2022)
  4. Compiling Giac via MSYS2/CLANG32 (2 April 2022)
  5. Terminals on the web (28 June 2022)
  6. Torus puzzle (15 April 2023)
  7. Tube amoeba (16 April 2023)
  8. XaoS in WebAssembly (30 August 2023)
  9. Debut of GNU Aris in WebAssembly (11 November 2023)
  10. JGEX 0.81 (in Hungarian) (10 December 2023)
  11. xaos.app (2 January 2024)
  12. Compiling and running bibref-qt on Wine (22 August 2024)
  13. Treasure of Count Goldenwald (6 January 2025)
  14. Developing C++ code for desktop and web with cmake (7 March 2025)
  15. Statement analysis in bibref (8 March 2025)
  16. An online Qt GUI version of bibref (20 April 2025)
  17. JGEX via CheerpJ (5 July 2025)
  18. Connecting ISBTF's LXX-NT database with bibref (10 July 2025)
  19. GraphViz as a WebAssembly module (13 August 2025)

Zoltán Kovács
Linz School of Education
Johannes Kepler University
Altenberger Strasse 69
A-4040 Linz