Using angular directives would be a clean approach to solve this problem. Let's start with installing vis.js
npm install vis
Component that displays the vis chart should have a container element for the chart., let's say
graph-visualization.component.html
<div [appGraphVis]="graphData" class="graph-container"></div>
graph-visualization.component.css
.graph-container {
height: 25em;
widows: 100%;
}
graph-visualization.component.ts
import { Component, OnInit } from '@angular/core';
import { DataSet } from 'vis';
@Component({
selector: 'app-graph-visualization',
templateUrl: './graph-visualization.component.html',
styleUrls: ['./graph-visualization.component.css']
})
export class GraphVisualizationComponent {
graphData = {};
constructor() { }
ngAfterContentInit(){
// create an array with nodes
var nodes = new DataSet([
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
// create an array with edges
var edges = new DataSet([
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
// provide the data in the vis format
this.graphData["nodes"] = nodes;
this.graphData["edges"] = edges;
}
}
Notice few things:
- this component only computes the data that need to be visualized and it doesn't do anything, like manupulating the DOM or use vis.js directly. Since vis.js is a DOM manulation, We could have a directive that handles it
- Used ngAfterContentInit rather than ngOnInit. This will delay the graph generation part and allow other DOM related tasks to complete
graphvis.directive.ts
import { Directive, TemplateRef, ViewContainerRef, Input, Renderer2, ElementRef } from '@angular/core';
import { Network } from 'vis';
@Directive({
selector: '[appGraphVis]'
})
export class GraphVisDirective {
network;
constructor(private el: ElementRef) {}
@Input() set appGraphVis(graphData){
console.log('graph data ', graphData);
var options = {};
if(!this.network){
this.network = new Network(this.el.nativeElement, graphData, options);
}
}
}
For simplicity, I have kept the options inside directive. In real world, options will be passed as another input from high level component.
Additional notes, we could add typescript's types for vis to help during development and debugging. It's available here:
yarn add @types/vis -D
If you are looking for a ready to use solution, check out this library - angular-vis. At the time of writing this, it doesn't support all features of vis.js
vis
? – Foible