Directing the Forces on Artists
This month I cover the updates I made to the 3D data visualization library Force Directed Graph.
Last year I recounted how I had made developments to an ongoing creative inquiry I call “Shape of Art”.1 In the latest iteration of my now seven year inquiry into trying to grapple with how to give form to the pantheon of arts, I built two key improvements that make navigating the data more interesting. The improvements are to the underlying visualization library called Force Directed Graph.2 The first improvement is that you can easily control (and subsequently animate) which nodes in the graph are visible or hidden. Second, I wrote a text rendering path to include an optional label over each node. Let me walk you through it.
Refresher on Force Directed Graph
Force Directed Graph is a free and open source JavaScript library. It allows you to feed in a data set of “nodes”, essentially an arbitrary object with properties like color, size, position. You then also feed in “links” which are references to which node should be connected to another node with a line. Documented node properties are packed into formats that can be read on a device’s graphics card. Then a physics simulation that disperses the nodes and links on every frame while the application is running. Lastly, the nodes and links are drawn to the screen in an efficient way. There are many graph libraries that display and run this type of layout. However, this library is unique because the physics simulation and the rendering are primarily running on the graphics card. This allows for many calculations to happen in parallel. For example, calculating the position, velocity, and forces between thousands of nodes sixty times a second. The results are that the nodes can be in 2D or 3D space and the drawing of thousands of nodes and links can animate.

Animating Related Artists
This Force Directed Graph is really good at animating thousands of nodes efficiently. This feature is something that I felt was lacking in previous versions of my Shape of Art studies. I had spent a lot of time creating the dataset. I was proud that I had a list of about 100,000 artists and a way to link them. Plugging the data in, the graphs move. So, it was impressive that there was a lot of nodes on the screen. But, it was not materially different from what other libraries offered. I became focused on figuring out how to make the animation more dynamic. Partly because of the library I built. Partly due to the texts of Kandinsky that inspire this inquiry in the first place. His writing has a reverence for artists, the dissonance they create for their generation, and how future generations use that as a reference point for style. When I read his text, I get the sense that there is a push-and-pull between artists that are aware of each other. This latest feature attempts to address this by revealing nodes over time. At the bottom of the latest prototype, you can drag a slider left-and-right to reveal new artists. The artists date back all the way to 970. This gives historical context, but it also heightens the tug-of-way when a new node or artist is revealed in the graph.
Labeling Artists like a Point of Interest on a Map
The second aspect of previous studies I made was that visitors had to hover their mouse over a node in order to see the name of the artist that node represented. I imagine Edward Tufte would describe this as a poor visualization. In The Visual Display of Quantitative Information he said, “Above all else, show the data”.3 My studies had lots of nodes, but not a lot of data. You could tell the nodes are connected, but to who? And why? So, I went down a path to add labels to all nodes. The first attempt I made, it was all black. There are so many nodes that adding labels that were in a font size large enough to read made visual cacophony. One night driving I was looking for directions and zoomed out of my map. Eureka! This was how I should display the labels. In maps apps, labels are only rendered at specific zoom levels. You do not need the name of all streets if you can see an entire state. The logic that I imparted to Force Directed Graph was a priority system. It prioritizes labeling nodes that are in view. In the 3D environment we render to, this means a few things. First, there is a near and a far clip space. Basically, the camera does not need to worry about seeing anything that is too close or too far. Second, it prioritizes labeling nodes who have a lot of connections. Third, it discourages labeling nodes whose neighbors are already present. Fourth, the developer can always override this in a couple of ways: either force the priority on a specific node or alter a library level property called “obscurity”. The obscurity basically loosens or tightens these priorities as a zero-to-one slider. At an obscurity level of zero, you can see all the labels. The cacophony I started with. At an obscurity of one, you cannot see any labels. And at an obscurity of 0.5, 50% of labels can be visible. This four tiered system at an obscurity level of 0.9 is what you see in the current prototype (recorded in the video above). It is fairly simple compared to a Map application, but its behavior is reminiscent of the inspiration.
These two features have been months in the making. You can tell because the visual aesthetic of this prototype is pretty barebones. Personally, this version speaks to me more than the previous ones. It has more data. It is more alive. While not visible, I have also baked in color coding based on output formats defined in Artsy’s Art Genome Project.4 I am excited to add color to the next version. If you give this latest version a try, I would love to hear your thoughts.
–Jono
Force Directed Graph. 2026. https://jonobr1.com/force-directed-graph/
The Visual Display of Quantitative Information. Edward R. Tufte. 1983 and 2001. https://www.edwardtufte.com/book/the-visual-display-of-quantitative-information/
The Art Genome Project. Artsy. 2010s – Present. https://www.artsy.net/categories


