Как заставить vis.js lib работать с Angular2?

Я пытаюсь использовать библиотеку visjs, но не могу заставить их работать с примером, это выглядит так:

<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>

4 ответа

Решение

Вот простой плункер, интегрирующий код, который вы опубликовали с Angular 2 https://plnkr.co/edit/TbPTfXFk4RSAuPn4BBxP?p=preview

В этом примере интеграция в 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);
  }

Пожалуйста, найдите ниже код, который использует angular2 с vis и вам просто нужно установить vis и импортировать это. В этом примере я создал компонент angular2 для библиотеки vis.

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);
    }
}

Использование угловых директив было бы чистым подходом для решения этой проблемы. Начнем с установки vis.js

npm install vis

Компонент, который отображает диаграмму vis, должен иметь контейнерный элемент для диаграммы. Скажем,

граф-visualization.component.html

<div [appGraphVis]="graphData" class="graph-container"></div>

граф-visualization.component.css

.graph-container {
    height: 25em;
    widows: 100%;
}

граф-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;
  }

}

Обратите внимание на несколько вещей:

  • этот компонент только вычисляет данные, которые необходимо визуализировать, и ничего не делает, например, манипулирует DOM или напрямую использует vis.js. Поскольку vis.js является DOM-манипуляцией, у нас может быть директива, которая его обрабатывает
  • Использовал ngAfterContentInit вместо ngOnInit. Это задержит этап генерации графа и позволит завершить выполнение других задач, связанных с DOM.

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);
    }

  }

}

Для простоты я оставил параметры внутри директивы. В реальном мире опции будут переданы как еще один вход от компонента высокого уровня.

Дополнительные примечания, мы могли бы добавить типы машинописи для vis, чтобы помочь во время разработки и отладки. Это доступно здесь:

yarn add @types/vis -D

Если вы ищете готовое решение, проверьте эту библиотеку - angular-vis. На момент написания этого он не поддерживает все функции vis.js

Ну, некоторые модификации, необходимые для кода, предложенного выше, что заняло у меня некоторое время, чтобы обойти... поэтому я делюсь этим:

1) вам нужно получить доступ к контейнеру с помощью @ViewChild('netWords') netContainer: ElementRef; и #netWords в части HTML.

2) вам необходимо получить полный доступ к элементу контейнера, используя свойство nativeElement, поэтому это будет this.network = new Vis.Network(this.netContainer.nativeElement, data, options);

Должно работать с этими модификациями.

Другие вопросы по тегам