Leverage on D3.js v4 to build a Network Graph for Tableau
By: Charmaine Chui
Tags: Tableau, D3js, Data Processing, Network Analysis, Data Visualization

Leverage on D3.js v4 to build a Network Graph for Tableau

Using D3.js to auto-calculate the (x, y) coordinates of each node and adjust the layout to your liking

So recently countries around the world are feverishly contact-tracing to control the Covid-19 infection rates. As a fellow data analyst I have been exposed to my fair share of network diagrams lately. It was intriguing to see a graph made up primarily of nodes and links to be not only aesthetically appealing but also represent connectivity between different entities effectively.

Image by Author | An example of a network graph rendered by d3.js to visualise frequency occurrences of #tags on stackoverflow

Majority of network graph visualisations are mostly deployed on web applications. The harsh truth is web development time far exceeds that of dashboarding. Moreover teams I have worked with are often only interested in snapshots of the network diagram so the ability to plot network diagrams on dashboarding tools such as Tableau would offer greater convenience in highlighting significant findings where interactivity with the graph is less crucial. Hence, I proceeded to explore and implement ways to plot the exact same graph on Tableau with minimal effort. This led me to create a pet project comprising of 2 parts —

Part I: A web application to output data directly for Tableau (functionalities include flexibility to manually adjust the graph’s layout + export of the final Tableau-ready data output)

Part II: Using the data generator created in Part I, include a network diagram in my next Tableau dashboard accordingly.

Part I: Creation of Web Application Tool

With regards to this part of the project, I had based my web app’s layout and functionalities on Tristan Guillevin’s https://observablehq.com/@ladataviz/network-data-generator

Image by Author | Showcasing functionalities on https://observablehq.com/@ladataviz/network-data-generator including: Enabling users to input their own JSON file to render the network diagram and export the 2 CSV files for Tableau. Additionally, configurations for node size and force parameters can be adjusted to vary the overall layout.

Don’t get me wrong while I felt it was wonderful and I was thoroughly impressed in the ingenuity of leveraging on the d3 graphing library, there were 2 main constraints when I attempted to use the outputs in Tableau —

Constraint 1: The tool does not allow the flexibility of dragging nodes directly to other positions to enable a more custom layout. While strength and collision parameters can be toggled, the node movements are unpredictable and hard to manipulate.

Constraint 2: The output generated ultimately does render the exact layout previewed in the tool. However, when I attempted to filter the displays of some nodes or links, there was no particular field in the data outputs — nodes.csv and links.csv which allowed this to happen in Tableau easily.

Before resolving the above 2 issues, I went ahead to develop the web interface in a similar format as the one by Tristan Guillevin:

Image by Author | Preview of my web application deployed at https://tableau-data-utility.herokuapp.com/. Similarly, users are able to input in their own JSON files which follow the specified format. Configurations are also enabled for the graph layout. In addition, the button with the Tableau icon illustrates how subsequent data joins occur between the 2 output files — nodes.csv and links.csv

Basically, it’s a single page application with all instructions and required information along the way. Now, here comes arguable one of the most user-friendly features — Enabling users to manually alter and drag the nodes to conform the graph to their desired layout:

Image by Author | Demonstration of a simple adjustment to a graph’s original layout on the web app at https://tableau-data-utility.herokuapp.com/

Here’s a clear comparison that the tool has successfully altered the nodes’ coordinates after being shifted:

Image by Author | (Left) Pre-Adjustment Layout of Network Graph rendered by d3.js. | (Right) Visualisation of graph on Tableau by csv files exported

Image by Author | (Left) Post-Adjustment Layout of Network Graph rendered by d3.js. | (Right) Visualisation of graph on Tableau by csv files exported

Hence, (1/2) of the constraints is resolved — the other outstanding issue being that the original output generated do not allow filtering of specific nodes or links when plotted in Tableau (which shall be addressed and elaborated on in the Part II).

Part II: Including a Network Graph in Tableau Dashboard for Data Profiling/Analysis

Eventually, I decided on identifying Singapore’s Dengue Clusters in 2020-Q3. The raw data sources are stated in the final dashboard itself but after geocoding and some data transforming, the required JSON input to generate the Tableau graphs are churned out: https://github.com/incubated-geek-cc/tableau-data-utility/blob/master/public/data/sg_dengue_clusters.json

After plotting the network graph and adding the maps onto the dashboard, I faced the 2nd constraint of being unable to filter by specific nodes/links:

[Id] (nodes.csv): Identifier of each node

[Id] (links.csv): The [Id] of the node i.e. the source/target

[Key] (links.csv): a numerical value auto-generated to identify the source node and target node

[Type] (links.csv): source/target

Realistically only the [Id] field can be used to identify which nodes/links to filter. However due to the output format when a single node is filtered the links of the nodes are not filtered by default, this leaves many suspending links in the diagram:

Image by Author | Demonstration on Tableau to show nodes c0 to c7 filtered. Note that links of filtered nodes are still present.

The solution I came up with was to generate an extra field known as [Link Id], which basically concatenates the [Id] of the source node and the [Id] of the target node. This serves the same purpose as the [Key] field, which is used to distinguish the links but both nodes and links are now identifiable by the [Link Id].

Thereafter, a field known as [Filter by Link Id] is created with the following formula:

IF [Parameters].[Cluster Id]=’All’ THEN TRUE

ELSE

RIGHT(link_id,LEN([Parameters].[Cluster Id]))=[Parameters].[Cluster Id]

END

Hence, the dashboard can finally be cross-filtered across the network diagram and other visualisations simultaneously:

Image by Author | Node [Id] c10 is selected, filtering across all visualisations on the dashboard deployed at https://public.tableau.com/views/SingaporesDengueClusters2020/sg_dengue_clusters_2020?:language=en&:display_count=y&:origin=viz_share_link

Thank you for taking the time to read and here ends my exploration of plotting network graphs on Tableau dashboards!

Feel free to use the tool deployed over at https://tableau-data-utility.herokuapp.com/ to generate your Tableau network datasets.