Adding a Context Menu to D3 Force Graph
Tags: contextmenus, d3js, javascript, react
Published: 2020-05-20 08:56:50

---
title: Adding a Context Menu to D3 Force Graph
published: true
date: 2020-05-20 08:53:00 UTC
tags: context-menus,d3js,javascript,react
canonical_url: https://medium.com/@gilfink/adding-a-context-menu-to-d3-force-graph-def5f197f343
---

A few weeks ago I published a post called “[Creating a Force Graph using React and D3](https://dev.to/gilfink/creating-a-force-graph-using-react-and-d3-jpg-temp-slug-2341904)” that explained how to create a force graph using **D3** which is wrapped in **React** container. In this post I’ll add a new feature to the graph — a context menu. Make sure to read the previous post before you continue reading this post.

#### The Context Menu Event

The browser regular behavior when you press the right mouse button is to open the browser context menu. In some scenarios you might want to control what is going to happen when your user is pressing the right mouse button. For that purpose you can use the **contextmenu** event. The **contextmenu** event enables you to wire a custom handler and you can also prevent from the browser context menu to open. The following code shows how to wire the event to some element to prevent the browser context menu:

{% gist https://gist.github.com/gilf/8e299e88c37aaff5709cba17b7bac6b2 %}

#### D3 and Context Menus

The **contextmenu** event can be used on any DOM element and therefore can also be wired to **SVG** elements as well. The easiest way to add the event to a **D3** created element is using the **on** function like any other event wiring. The following code shows how to wire the **contextmenu** event to **D3** selected element and to prevent the browser context menu:

{% gist https://gist.github.com/gilf/6a9d039dd4d847b9b0fe54e94c889c4c %}

In this example, we use the **d3.event** in order to prevent the default browser behavior.

#### Creating a D3 Context Menu

Now that we know how to wire the **contextmenu** event, we can start generating our own context menu. We will start with a function that will be responsible to create the menu:

{% gist https://gist.github.com/gilf/f04c9861a03a1070e687dbd42da307ad %}

The **createContextMenu** function will receive the node data, an array of menu items, the width and height of the **SVG** and the **SVG** id. The function will calculate the the position of the pressed node, which can be a little tricky, and also will prevent the browser regular behavior. The position of the menu can be affected by many things (view port, location of the **SVG** in the page and more) and therefore its calculation is separated from the menu creation. In my example the location is easily calculated using the **d3.event ** point.

Now let’s create the **menuFactory** function which will be responsible to generate the menu:

{% gist https://gist.github.com/gilf/e7487d7bbf07bad0f0814df239e192be %}

Most of the code in the function is straight forward. We add menu entries according to the menu items we got. Each entry is a rectangle with text, which is taken from a **title** property on the menu item. We also wire handler to **click** event which will run the **action** function in the menu items. Last but not least, we handle the closing of the menu if the user click outside of it.

#### Wiring The Menu to the Force Graph

In order to wire the context menu to the force graph we first will need to create the **menuItems** array:

{% gist https://gist.github.com/gilf/68908a5b5286fb03a954e556ad5897ab %}

Once the array is available all we have to do is to run the **createContextMenu** function with all the relevant data once the **contextmenu** event occurs. Here is the complete graph code including the context menu:

{% gist https://gist.github.com/gilf/a9154baf4739ec1ed5d513742f43b7f5 %}

In the CSS module you can add the following rules to make the menu visibility more appealing:

{% gist https://gist.github.com/gilf/eb11b5fef74e455fa56b963600896d17 %}

Here is how the graph will look like with an open context menu:

![](https://cdn-images-1.medium.com/max/1024/1*vUrGRVe-Ch_808qb2MlQ5g.png)<figcaption>Force Graph with Context Menu</figcaption>

#### Summary

In the post I explained how you can add a **D3** generated context menu to a force graph. Context menus can be very useful to add actions to your graph so I hope that you will find this post valuable. You can find the graph code [here](https://1drv.ms/u/s!AvRpQcwPfoDMgqFYvvmmF3wrQNAOCw?e=fhciaT).