tldr;
Certain applications require a visual cue that two items are related. There are many ways to accomplish this effect, but one simple way is to use the leader-line NPM package. The package allows you to draw a line between two elements by just passing the elements to a constructor function. The library then takes over, allowing you to pass options for customization as well. In this article, I’ll show you how to use the library in your Angular application to draw lines between two Angular elements.
Setup(#setup)
To get started, you need to first install the npm package:
$ npm install leader-line
After that, you need to include the JavaScript file from the package in the scripts
array for the project in the angular.json
file:
...
"scripts": ["node_modules/leader-line/leader-line.min.js"],
...
This will load the script for your project so the library can be used in the application.
Drawing a Line Between Two Elements
To draw a line between two elements with the leader-line
package, two HTML elements should be passed in to the LeaderLine
constructor. The starting element is the first argument, the ending element is the second argument. A third optional argument can be passed in which customizes the look of the line. The package makes it very easy to draw the line.
The only hard part about this is making sure we get access to the Angular element in the correct way. The “Angular way” of accessing DOM elements does not include using the document
like you would in normal JavaScript applications:
const startingElement = document.querySelector('#starting-element');
const endingElement = document.querySelector('#ending-element');
const line = new LeaderLine(startingElement, endingElement);
That’s how we would access the DOM in a normal JavaScript application, but Angular discourages directly accessing the DOM in this manner. To access the elements in Angular, we should use ElementRef
s and ViewChild
or ViewChildren
. You can read more about these topics here or here for example. We won’t go in depth here on the topic, but in a nutshell ViewChild
gives you access to DOM elements in a component’s class file. Here’s an example of the class file and the component template:
// app.component.ts
declare var LeaderLine: any;
export class AppComponent() implements AfterViewInit {
@ViewChild('startingElement', { read: ElementRef }) startingElement: ElementRef;
@ViewChild('endingElement', { read: ElementRef }) endingElement: ElementRef;
ngAfterViewInit() {
const line = new LeaderLine(startingElement.nativeElement, endingElement.nativeElement);
}
}
<app-box #startingElement>Starting Element</app-box>
<app-box #endingElement>Ending Element</app-box>
The reason for creating the line in the ngAfterViewInit
method is because the elements may not be available in the template when the component first initializes, but will be available in the ngAfterViewInit
method. In that method, we can create the line, and it will be drawn on the screen.
Removing the Lines
Once the line is drawn on the screen with LeaderLine, it will stay until manually removed. If the component layout changes, the line may need to be re-drawn. You can remove the line as long as you’ve kept access to the line in a local variable by calling the remove
method on the line:
line.remove();
Line Options
LeaderLine provides a lot of options to customize the output of the line. I won’t go over them all here because the documentation is very good, but you can change the color of the line, the style of the line, where exactly it starts and ends in relation to the respective HTML elements, path labels, and much more. Check out the documentation here for all the options that you can pass to the constructor. You can also call the setOptions
method and pass in an object to set the options for the line.
Conclusion
The LeaderLine package has been really helpful on my most recent project at work. We are building a workflow builder (do this, then this, etc) and lines need to be drawn from one element to the next to visually display the workflow. I was worried about how best to draw those lines on the screen, but this package was easy to install and easy to work with. In a matter of a few minutes I was able to be up and running, where rolling my own solution would have taken several days.
Top comments (0)