How we implemented SVG Arrows in React: The Basics (1/3)
At Productboard we developed a tool that helps product managers prioritize functionality and work planning. One of the important parts of our app is the roadmap. A roadmap helps you visualize your future work plan, and you can share it with others. We can visualize this plan in many different modes — for example with dependency on time, product releases, or as a simple Kanban board.
A roadmap with dependency on time can look like this:
We can see four cards in this roadmap. They represent product features. Some of them may be related to each other, but they may not be obvious without additional context.
During the Product Discovery phase, we regularly interview our customers to understand their needs better and help them prioritize important features and issues. Seeing how features are dependent on each other directly from the roadmap is one of our customers’ top requirements.
To streamline this process, we decided to visualize roadmap dependencies between individual features using arrows:
How we implemented these arrows is what we are going to describe in this three-part series.
If you want to skip the nuts and bolts, you can go directly to our code on CodeSandbox or Github.
Use case
Before we jump into the implementation process, we first have to specify several characteristics of our arrow:
- It’s a Cubic Bezier curve with four points
- It’s rendered as an SVG element in React
- We have the start and end coordinates of the arrow
- We want to be able to detect mouse events like
onClick
,onMouseEnter
,onMouseLeave
Direction matters
The orientation of the arrow is always one direction. The arrow will start with the circle on the right side of the card and end with the arrowhead on the left side of the other card.
We distinguish two states:
Inspiration
Not wanting to reinvent the wheel, we looked at Github first to see if there was a solution we could use or be inspired by.
We went through the repositories, and we were interested in react-archer and react-xarrows. However, none of the solutions completely met our needs. Both were unnecessarily complicated and dealt with use cases that we do not have. For this reason, we decided to write our own component for drawing arrows, giving us full control over what is going on inside and allowing us to learn something new.
Naive implementation
Let’s go step by step through the implementation process in real-time. First, we’ll start off with a completely simple component that will show only a straight line between two different points (or “features” as we say at Productboard).
For this, we only need the X and Y coordinates of the two points and to determine how big the whole SVG element should be. We can also easily find out from these coordinates what width and height the SVG element should have.
This is the first step in the implementation of the arrow. The result in the roadmap might look like this:
Follow-up
In this first article, we described the basic specifics of the component we want to create, and we wrote a very naive implementation of an SVG line connecting two points.
It doesn’t look like an arrow yet. There are two more parts we have to finish:
- curving
- arrowhead
We will take a look at curving in the SECOND PART of this series.
The whole implementation of SVG arrows in React is available on CodeSandbox or Github.
Interested in joining our growing team? Well, we’re hiring across the board! Check out our careers page for the latest vacancies.