Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make vis.js lib to work with Angular2?

I'm trying to use a visjs lib but can't make their getting started example working it goes like this:

<script type="text/javascript">
    // DOM element where the Timeline will be attached
    var container = document.getElementById('visualization');

    // Create a DataSet (allows two way data-binding)
    var items = new vis.DataSet([
        {id: 1, content: 'item 1', start: '2013-04-20'},
        {id: 2, content: 'item 2', start: '2013-04-14'},
        {id: 3, content: 'item 3', start: '2013-04-18'},
        {id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19'},
        {id: 5, content: 'item 5', start: '2013-04-25'},
        {id: 6, content: 'item 6', start: '2013-04-27'}
    ]);

    // Configuration for the Timeline
    var options = {};

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);
</script>
like image 858
CommonSenseCode Avatar asked Oct 28 '16 01:10

CommonSenseCode


4 Answers

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

like image 84
Sairam Krish Avatar answered Nov 20 '22 11:11

Sairam Krish


Here is a simple plunker integrating the code you posted with Angular 2 https://plnkr.co/edit/TbPTfXFk4RSAuPn4BBxP?p=preview

In this example the integration is in OnInit

ngOnInit() {
    var container = document.getElementById('visualization');

    // Create a DataSet (allows two way data-binding)
    var items = new vis.DataSet([
        {id: 1, content: 'item 1', start: '2013-04-20'},
        {id: 2, content: 'item 2', start: '2013-04-14'},
        {id: 3, content: 'item 3', start: '2013-04-18'},
        {id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19'},
        {id: 5, content: 'item 5', start: '2013-04-25'},
        {id: 6, content: 'item 6', start: '2013-04-27'}
    ]);

    // Configuration for the Timeline
    var options = {};

    // Create a Timeline
    var timeline = new vis.Timeline(container, items, options);
  }
like image 31
TGH Avatar answered Nov 20 '22 09:11

TGH


Please find below code that using angular2 with vis and you just need to install vis and import it. In this example i have created a angular2 component for vis library.

import { Component , OnInit, OnDestroy } from '@angular/core';
import { Network, DataSet, Node, Edge, IdType } from 'vis';
@Component({
  selector: 'network-graph',
  templateUrl: './network-graph.component.html'
})
export class NetworkGraphComponent implements OnInit{
    public nodes: Node;
    public edges: Edge;
    public network : Network;

    public ngOnInit(): void {
          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},
              {from: 3, to: 3}
            ]);
           // create a network
          var container = document.getElementById('mynetwork');
          var data = {
            nodes: nodes,
            edges: edges
          };
          var options = {};
          var network = new Network(container, data, options);
    }
}
like image 23
meenu1meen Avatar answered Nov 20 '22 09:11

meenu1meen


Well, some modifications needed for the code proposed above which took me a while to by-pass ... so I share these :

1) you need to access the container by @ViewChild('netWords') netContainer: ElementRef; and #netWords in the html part.

2) you need to access fully the container element using the nativeElement property, so this would be this.network = new Vis.Network(this.netContainer.nativeElement, data, options);

It should work with these modifications.

like image 1
Marc Avatar answered Nov 20 '22 10:11

Marc