DEV Community

Cover image for React-Archer: Drawing Arrows Between DOM Elements
Trevor Vardeman
Trevor Vardeman

Posted on

React-Archer: Drawing Arrows Between DOM Elements

For my latest project, I built a trip-tracking app called Trip Tracker. While coming up with the idea of the app, I used Miro to draw out concepts of what the UI would look like.

Since I'm allowing users to create trips, the trips themselves would naturally have many cities within them. I wanted a way to graphically show the user where their trip was starting, all the cities they're visiting in order, and where their trips ends. I drew this up with arrows in Miro to show the flow of the trip.

But how would I code this? Or would I have to insert images to show these arrows? It turns out, there was a nifty little package out there waiting to be installed called react-archer.

react-archer lets you easily create arrows between DOM elements. Perfect! Let's dive in to how I was able to make this work.

First, I installed the package.
npm install react-archer --save

Next, I needed to import ArcherContainer and ArcherElement:
import { ArcherContainer, ArcherElement } from "react-archer"

ArcherContainer is what it sounds like -- a container for all of the ArcherElements. ArcherElements are the DOM elements that the arrows will start from and point to. All of your actual DOM elements will be inside of an ArcherElement.

Let's add an ArcherContainer to our app:

    return (
      <ArcherContainer>
      </ArcherContainer>
    )
Enter fullscreen mode Exit fullscreen mode

Let's add two test elements as well. First, you'll need to open and close each ArcherElement, and then you need to give each ArcherElement some content. For the sake of simplicity, let's just use a <p> tag for each. Here's how it should look now:

    return (
      <ArcherContainer>
        <ArcherElement>
          <p>Test 1</p>
        </ArcherElement>
        <ArcherElement>
          <p>Test 2</p>
        </ArcherElement>
      </ArcherContainer>
    )
Enter fullscreen mode Exit fullscreen mode

Now it's time to add attributes that will create the lines and arrows for us.

First, each ArcherElement needs an ID. IDs are used as the destination for an arrow.

    return (
      <ArcherContainer>
        <ArcherElement id="test1">
          <p>Test 1</p>
        </ArcherElement>
        <ArcherElement id="test2">
          <p>Test 2</p>
        </ArcherElement>
      </ArcherContainer>
    )
Enter fullscreen mode Exit fullscreen mode

Next, let's add a "relations" attribute to the first ArcherElement. This is what will create our line and arrow. Here's what the code looks like:

  return (
    <ArcherContainer>
      <ArcherElement
        id="test1"
        relations={[
          {
            targetId: "test2",
            targetAnchor: "top",
            sourceAnchor: "bottom",
            style: { strokeColor: "black", strokeWidth: 1 }
          }
        ]}
      >
        <p>Test 1</p>
      </ArcherElement>
      <ArcherElement id="test2">
        <p>Test 2</p>
      </ArcherElement>
    </ArcherContainer>
  )
Enter fullscreen mode Exit fullscreen mode

Let's break down some of those attributes:

  • targetId: This is the ID of the ArcherElement that the arrow will point to
  • targetAnchor: This tells the arrow where on the target ArcherElement to point to
  • sourceAnchor: This is the side of the source ArcherElement the line will begin from
  • strokeColor: Controls the color of the arrow
  • strokeWidth: Controls how wide the arrow is

Those attributes are highly customizable, and there are many more that are not utilized in this example.

After centering the code with some CSS, it looks like this:

The Test 1 element has an arrow pointing to Test 2 element

Here's the full code from my example:

import Stack from 'react-bootstrap/Stack'
import { ArcherContainer, ArcherElement } from "react-archer"

function ArcherTest() {
  return (
    <Stack className="centered">
      <ArcherContainer>
        <ArcherElement
          id="test1"
          relations={[
            {
              targetId: "test2",
              targetAnchor: "top",
              sourceAnchor: "bottom",
              style: { strokeColor: "black", strokeWidth: 1 }
            }
          ]}
        >
          <p>Test 1</p>
        </ArcherElement>
        <ArcherElement id="test2">
          <p>Test 2</p>
        </ArcherElement>
      </ArcherContainer>
    </Stack>
  )
}

export default ArcherTest
Enter fullscreen mode Exit fullscreen mode

For my project, a user can create many cities, and I didn't limit them. They could have just 2, but they could also have 10. Not knowing how many ArcherElements to create, I had to create each ArcherElement by mapping an array of objects and setting each of their IDs/targetIDs dynamically. That result ended up looking like this:

Displaying 5 cities with react-archer arrows betweent hem

Please go check out the react-archer documentation on the GitHub page to see all of the possibilities and get some inspiration on how to use this spectacular package!

react-archer made my project look so much better and it was extremely easy to use, I'm so happy I found it.

Happy coding!

Top comments (0)