<!DOCTYPE html>
<html>

  <head>
    <base href="." />
    <link data-require="bootstrap@3.0.0" data-semver="3.0.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
    <script type="text/javascript" charset="utf-8">
      window.AngularVersionForThisPlunker = 'latest'
    </script>
    <title>angular playground</title>
    <link rel="stylesheet" href="style.css" />
    <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script>
    <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
    <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
    <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
    <script src="https://unpkg.com/gojs/release/go-debug.js"></script>
    <script src="config.js"></script>
    <script>
    System.import('app')
      .catch(console.error.bind(console));
  </script>
  </head>

  <body>
    <div class="container">
      <my-app>
      loading...
    </my-app>
  </div>
  </body>

</html>
/* Styles go here */

var angularVersion;
if(window.AngularVersionForThisPlunker === 'latest'){
  angularVersion = ''; //picks up latest
}
else {
  angularVersion = '@' + window.AngularVersionForThisPlunker;
}

System.config({
  //use typescript for compilation
  transpiler: 'typescript',
  //typescript compiler options
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  paths: {
    'npm:': 'https://unpkg.com/'
  },
  //map tells the System loader where to look for things
  map: {
    
    'app': './src',
    '@angular/core': 'npm:@angular/core'+ angularVersion + '/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common' + angularVersion + '/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler' + angularVersion  + '/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic' + angularVersion + '/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http' + angularVersion + '/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router' + angularVersion +'/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms' + angularVersion + '/bundles/forms.umd.js',
    '@angular/animations': 'npm:@angular/animations' + angularVersion + '/bundles/animations.umd.js',
    '@angular/platform-browser/animations': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser-animations.umd.js',
    '@angular/animations/browser': 'npm:@angular/animations' + angularVersion + '/bundles/animations-browser.umd.js',
    
    '@angular/core/testing': 'npm:@angular/core' + angularVersion + '/bundles/core-testing.umd.js',
    '@angular/common/testing': 'npm:@angular/common' + angularVersion + '/bundles/common-testing.umd.js',
    '@angular/compiler/testing': 'npm:@angular/compiler' + angularVersion + '/bundles/compiler-testing.umd.js',
    '@angular/platform-browser/testing': 'npm:@angular/platform-browser' + angularVersion + '/bundles/platform-browser-testing.umd.js',
    '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic' + angularVersion + '/bundles/platform-browser-dynamic-testing.umd.js',
    '@angular/http/testing': 'npm:@angular/http' + angularVersion + '/bundles/http-testing.umd.js',
    '@angular/router/testing': 'npm:@angular/router' + angularVersion + '/bundles/router-testing.umd.js',
    'tslib': 'npm:tslib@1.6.1',
    'rxjs': 'npm:rxjs',
    'gojs': 'npm:gojs/release/go-debug.js',
    'typescript': 'npm:typescript@2.2.1/lib/typescript.js'
  },
  //packages defines our app package
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    },
    rxjs: {
      defaultExtension: 'js'
    }
  }
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule)
import { NgModule } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { HttpModule } from '@angular/http'
import { AppComponent } from './app.component'
import { SearchComponent } from './search.component'
import { SearchService } from './search.service'
import { SearchDetailsComponent } from './search-details.component'
import { SearchFilterComponent } from './search-filter.component'
@NgModule({
  imports: [ BrowserModule, HttpModule ],
  declarations: [ AppComponent, SearchComponent, SearchDetailsComponent, SearchFilterComponent ],
  bootstrap: [ AppComponent ],
  providers: [SearchService]
})
export class AppModule {}
//our root app component
import { Component } from '@angular/core'


@Component({
  selector: 'my-app',
  template: `
    <div class="row">
      <h2>App with {{name}}</h2>
    </div>
    <div class="col-12">
        <search></search>
    </div>
  `,
})
export class AppComponent {
  name:string;
  constructor() {
    this.name = `GoJS`
  }
}
import { Component, OnInit } from '@angular/core'

import { SearchService } from './search.service'

@Component({
  selector: 'search',
  templateUrl: 'src/app/search.component.html',
  styles: [`
    ul {
      display: inline;
      list-style: none
    }`]
  providers: [SearchService]
})

export class SearchComponent implements OnInit {
  
  opt: any[] = [] // all outputs
  showMore: boolean[] = []
  visData : object
  constructor(private beService: SearchService) {}
  
  ngOnInit(): void {
    this.showMore = new Array(this.opt.length)
    this.showMore.fill(false)
  }
  
  onSearch(input: string) {
    if(!input) return;
    input = input.trim()
    this.beService.firstSearch(input)
    .then( res => this.opt.push(res) )
  }
  
  getQuery(input: string) {
    if(!input) return;
    input = input.trim()
    // create a JSON query for Backend service
    let qTemp = {'concept': encodeURIComponent(input), 'stepRange': 2, 'frozenConcept': 'ddd', 'language': 'en'}
    // console.log(JSON.stringify(qTemp))
    this.beService.querySearch(qTemp)
    .then( res=> this.visData = res)
  }
}
/**
 * Search BackEnd Service for the App
 **/
 
import { Injectable } from '@angular/core'
import { Http } from '@angular/http'

import 'rxjs/add/operator/toPromise'

@Injectable()

export class SearchService {
  // initial search Backend
  private searchEndpoint = 
  'http://hydra2.ikap.biba.uni-bremen.de:8090/detectMeaning/';
  private logicalEndpoint =
  'http://hydra2.ikap.biba.uni-bremen.de:8090/getLogicalView';
  
  constructor (private http: Http) { }
  
  firstSearch(term: string): Promise<any> {
    return this.http.get(`${this.searchEndpoint}?keyword=${term}`)
    .toPromise()
    .then(res => res.json());
  }
  
  querySearch(term: object): Promise<any> {
    return this.http.get(`${this.logicalEndpoint}?inputAsJson=${JSON.stringify(term)}`)
    .toPromise()
    .then( res => res.json());
  }
  
}
<div class="container">
  <div class="row input-group">
  <input type="text" class="form-control" 
    #searchVal placeholder="search.."/>
    
  <span class="input-group-btn">
  <button class="btn btn-default"
  (click)="onSearch(searchVal.value)">Search</button>
  </span>
  </div>
  <p>for test purpose: type <b>company</b>/ <b>contactperson</b>/
  <b>highchair</b> (w/o space) above and click the node.
  </p>
  <p>
    Error is visible in the Console Log. Mozilla Firefox <kbd>CTRL</kbd>+<kbd
>SHIFT</kbd>+<kbd>K</kbd>
  </p>
  <br/>
  <br/>
  <br/>
  
<div class="row">
  <ul>
   <li *ngFor="let eachOp of opt; let outerindex=index">
    <div class="btn-group" role="group"
     *ngFor="let each of eachOp.conceptOverview; let innerindex=index">
     <button class="btn btn-success" 
      (click)="getQuery(each.url)"
      *ngIf="innerindex===0 || showMore[outerIndex]">
       {{each['translatedURL']}}
     </button>
    </div>
    <div class="btn-group" style="list-style: none">
       <button class="btn btn-default" *ngIf="eachOp.conceptOverview.length > 1"
         (click)="showMore[outerIndex]=!showMore[outerIndex]">
         {{showMore[outerIndex] ? 'Hide': 'Show'}} Options
       </button>
     </div>
   </li>
  </ul>
 </div>
</div>
<search-details [config]="visData"></search-details>
import { Component, Input, onChanges,
  ViewChild, ElementRef, AfterViewInit } from '@angular/core'
import * as go from 'gojs'
import { RadialLayout } from './layout/RadialLayout'

@Component({
  selector: 'search-details',
  template: `
  <div class="container">
    <div class="displayArea" #myDiagramDiv></div>
    <div class="row">
    <search-filter *ngFor="let each of checkString" [eachFilter]="each"></search-filter>
    </div>
  </div>`,
  styles: [`
    .displayArea {
      width: 100%;
      height: 650px;
    }
  `]
})

export class SearchDetailsComponent implements onChanges, AfterViewInit {
  @Input()
  config: object; // visData from parent component
  
  @ViewChild('myDiagramDiv') element: ElementRef
  checkString: string[] = [];
  
  const $ = go.GraphObject.make
  const myDiagram: go.Diagram
  
  ngOnChanges() {
    if (!this.config || this.config.length === 0) return;
    
    // Generate the Radial Graph..
    let recApproach = new RecClass();
    recApproach.generateGraphRecApproach(this.config, this.myDiagram, this.$);
  } // ngOnChanges Ends..
  
  ngAfterViewInit() {
    this.myDiagram = this.$(go.Diagram, this.element.nativeElement,
    {
      initialContentAlignment: go.Spot.Center,
      padding: 10,
      isReadOnly: true,
      'animationManager.isEnabled': false
    })
    
    let commonToolTip = this.$(go.Adornment, 'Auto',
            { 
              isShadowed: true 
              
            },
            this.$(go.Shape, { fill: '#FFFFCC' }),
            this.$(go.Panel, 'Vertical',
                { 
                  margin: 3 
                  
                },
                this.$(go.TextBlock,  // bound to node data
                  { 
                    margin: 4, font: 'bold 12pt sans-serif' 
                    
                  },
                  new go.Binding('text')),
                  this.$(go.TextBlock,  // bound to Adornment because of call to Binding.ofObject
                new go.Binding('text', '', 
                (ad) => {
                  return 'Connections: ' + ad.adornedPart.linksConnected.count; 
                }).ofObject())
            )  // end Vertical Panel
            )  // end Adornment
    this.myDiagram.nodeTemplate =
            this.$(go.Node, 'Spot',
            {
                locationSpot: go.Spot.Center,
                locationObjectName: 'SHAPE',  // Node.location is the center of the Shape
                selectionAdorned: true,
                click: (e: go.InputEvent, obj: go.GraphObject): void => { this.nodeClicked(e, obj); },
                toolTip: commonToolTip
            },
            this.$(go.Shape, 'Circle',
                {
                name: 'SHAPE',
                fill: 'lightgray',  // default value, but also data-bound
                stroke: 'transparent',
                strokeWidth: 2,
                desiredSize: new go.Size(20, 20),
                portId: ''  // so links will go to the shape, not the whole node
                },
                new go.Binding('fill', 'color')),
            this.$(go.TextBlock,
                {
                name: 'TEXTBLOCK',
                alignment: go.Spot.Right,
                alignmentFocus: go.Spot.Left
                },
                new go.Binding('text'))
            )

        // this is the root node, at the center of the circular layers
        this.myDiagram.nodeTemplateMap.add('Root',
            this.$(go.Node, 'Auto',
            {
                locationSpot: go.Spot.Center,
                selectionAdorned: true,
                toolTip: commonToolTip
            },
            this.$(go.Shape, 'Circle',
                { fill: 'white' }),
            this.$(go.TextBlock,
                { font: 'bold 12pt sans-serif', margin: 5 },
                new go.Binding('text'))
            ));

        // define the Link template
        this.myDiagram.linkTemplate =
            this.$(go.Link,
            {
                routing: go.Link.Normal,
                curve: go.Link.Bezier,
                selectionAdorned: true,
                layerName: 'Background'
            },
            this.$(go.Shape,
                {
                stroke: 'black',  // default value, but is data-bound
                strokeWidth: 1
                },
                new go.Binding('stroke', 'color')
                new go.Binding('strokeDashArray', 'dash'))
        )
  } // ngAfterViewInit Ends..
  
  nodeClicked(e, node): void {
    console.log(node.data.text)
    this.checkString.push(node.data.text)
  } // nodeClicked ends..
  

}

////////////////// Extreme Complexity below ///////////////////////////////////
////////////////// NO NEED TO LOOK HERE ///////////////////////////////////////

/**
 * class OntNode
 * A Node structure for Binary Tree of the complete Data obtained from server
 */
class OntNode {
    public id: number; // ID of the node
    public attr: any[] = []; // Array of all attributes connected to the node
    public children: OntNode[] = []; // Check for Nodes with Children
}

/**
 * Recursion Class for generating the Graph
 */
class RecClass {
    names: string[] = []; // store the Strings from the JSON
    /**
     * generateGraphRecApproach : Rercusively generate graphs from the incoming JSON config
     * @param cnf : Incoming JSON config from Parent Component
     * @param myDiagram: Diagram parameter for GoJS
     * @param $: Make function for GoJS
     */
    public generateGraphRecApproach(cnf: any, myDiagram: any, $: any): void {
        // get a Tree structure of the incoming JSON
        let linkedOntTree = this.recursionParseJson(cnf);
        // console.log('Complete Tree:\n' + JSON.stringify(linkedOntTree)); --> DEBUG
        let nodeDataArray: any = []; // Create an Array of Nodes for GoJS.
        for (let i = 1; i < this.names.length + 1; i++ ) {
            nodeDataArray.push({key: i, text: this.names[i - 1], color: go.Brush.randomColor(128, 240) });
        }
        // Create The Links to Each node in the Tree with Recursion
        let linkDataArray: any = this.recursionLink(linkedOntTree);
        // console.log('LinkedDataList: ' + JSON.stringify(linkDataArray)); --> DEBUG
        // Diagram Layout..
        myDiagram.layout = $(RadialLayout, {
            maxLayers: 2,
            rotateNode: function(node: any, angle: any, sweep: any, radius: any) {
                // rotate the nodes and make sure the text is not upside-down
                node.angle = angle;
                let label = node.findObject('TEXTBLOCK');
                if (label !== null) {
                    label.angle = ((angle > 90 && angle < 270 || angle < -90) ? 180 : 0);
                }
            },
            commitLayers: function() {
                // optional: add circles in the background
                // need to remove any old ones first
                let diagram = this.diagram;
                let gridlayer = diagram.findLayer('Grid');
                let circles = new go.Set(go.Part);
                gridlayer.parts.each((circle: any) => {
                    if (circle.name === 'CIRCLE') { circles.add(circle); }
                });
                circles.each(function(circle) {
                    diagram.remove(circle);
                });
                // add circles centered at the root
                // let $ = go.GraphObject.make;  // for conciseness in defining templates
                for (let lay = 1; lay <= this.maxLayers; lay++) {
                    let radius = lay * this.layerThickness;
                    let circle =
                        $(go.Part,
                            { name: 'CIRCLE', layerName: 'Grid' },
                            { locationSpot: go.Spot.Center, location: this.root.location },
                            $(go.Shape, 'Circle',
                                { width: radius * 2, height: radius * 2 },
                                { fill: 'rgba(200,200,200,0.2)', stroke: null }));
                    diagram.add(circle);
                }
            }
        });

        // Use the Lists to Create the Radial Layout...
        myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
        // For Determining the Root of the Diagram
        let centerPoint = nodeDataArray[0];
        let rootNode = myDiagram.findNodeForData(centerPoint);
        let rootDiagram = rootNode.diagram;
        rootNode.category = 'Root';
        rootDiagram.layoutDiagram(true);
    }

    /**
     * recursionParseJson: returns a Tree of all the nodes from the JSON data
     * @param jsonNode JSON value from the Parent Component
     * @returns {OntNode}
     */

    private recursionParseJson(jsonNode: any): any {
        let node = new OntNode();

        // Adding node name
        this.names.push(jsonNode['concept']['translatedURL']);
        node.id = this.names.length;

        // Adding Attributes
        for (let eachDatProp of jsonNode.dataproperties) {
            this.names.push(eachDatProp.translatedURL);
            node.attr.push(this.names.length);
        }

        // Adding Children
        for (let childKey in jsonNode.objectproperties) {
            if (jsonNode.objectproperties.hasOwnProperty(childKey)) {
                // console.log(childKey); --> DEBUG
                node.children.push(this.recursionParseJson(jsonNode.objectproperties[childKey]));
            }
        }

        // console.log('Finished recFunc created node: ' + node.id); --> DEBUG
        return node;
    }

    /**
     * recursionLink: Create Links using Recursion for the Tree
     * @param linkedOntTree return value from recursionParseJson
     * @returns an Array of Link Information
     */
    private recursionLink(linkedOntTree: any): any {
        let linkedDataArray: any = [];

        for (let attr of linkedOntTree.attr) {
            linkedDataArray.push({from: linkedOntTree.id, to: attr});
        }

        for (let child of linkedOntTree.children) {
            linkedDataArray.push({from: linkedOntTree.id, to: child.id, dash: [4,4]});
            let childrenJson = this.recursionLink(child);
            childrenJson.forEach(element => {
                linkedDataArray.push(element);
            });
        }

        return linkedDataArray;
    }
}
'use strict';
/*
*  Copyright (C) 1998-2017 by Northwoods Software Corporation. All Rights Reserved.
*/

import * as go from 'gojs';

/**
* Given a root Node this arranges connected nodes in concentric rings,
* layered by the minimum link distance from the root.
*/
export class RadialLayout extends go.Layout {
  private _root: go.Node = null;
  private _layerThickness: number = 100;  // how thick each ring should be
  private _maxLayers: number = Infinity;

  /**
  * Copies properties to a cloned Layout.
  */
  protected cloneProtected(copy: any) {
    super.cloneProtected(copy);
    // don't copy .root
    copy._layerThickness = this._layerThickness;
    copy._maxLayers = this._maxLayers;
  }

  /*
  * The Node to act as the root or central node of the radial layout.
  */
  get root(): go.Node { return this._root; }
  set root(value: go.Node) {
    if (this._root !== value) {
      this._root = value;
      this.invalidateLayout();
    }
  }

  /*
  * The thickness of each ring representing a layer.
  */
  get layerThickness(): number { return this._layerThickness; }
  set layerThickness(value: number) {
    if (this._layerThickness !== value) {
      this._layerThickness = value;
      this.invalidateLayout();
    }
  }

  /*
  * The maximum number of layers to be shown, in addition to the root node at layer zero.
  * The default value is Infinity.
  */
  get maxLayers(): number { return this._maxLayers; }
  set maxLayers(value: number) {
    if (this._maxLayers !== value) {
      this._maxLayers = value;
      this.invalidateLayout();
    }
  }

  /**
  * Use a LayoutNetwork that always creates RadialVertexes.
  */
  public createNetwork () {
    let net = new go.LayoutNetwork();
    net.createVertex = () => new RadialVertex();
    return net;
  }

  /**
  */
  public doLayout(coll: go.Diagram|go.Group|go.Iterable<go.Part>) {
    if (this.network === null) {
      this.network = this.makeNetwork(coll);
    }

    if (this.root === null) {
      // If no root supplied, choose one without any incoming edges
      let it = this.network.vertexes.iterator;
      while (it.next()) {
        let v = it.value;
        if (v.node !== null && v.sourceEdges.count === 0) {
          this.root = v.node;
          break;
        }
      }
    }
    if (this.root === null) {
      // If could not find any default root, choose a random one
      this.root = this.network.vertexes.first().node;
    }
    if (this.root === null) {return; }  // nothing to do

    let rootvert = this.network.findVertex(this.root) as RadialVertex;
    if (rootvert === null) {
        throw new Error('RadialLayout.root must be a Node in the LayoutNetwork that the RadialLayout is operating on');
    }

    this.arrangementOrigin = this.initialOrigin(this.arrangementOrigin);
    this.findDistances(rootvert);

    // sort all results into Arrays of RadialVertexes with the same distance
    let verts: any[] = [];
    let maxlayer = 0;
    let it = this.network.vertexes.iterator;
    while (it.next()) {
      let vv = it.value as RadialVertex;
      vv.laid = false;
      let layer = vv.distance;
      if (layer === Infinity) {continue; } // Infinity used as init value (set in findDistances())
      if (layer > maxlayer) { maxlayer = layer; }
      let layerverts: any = verts[layer];
      if (layerverts === undefined) {
        layerverts = [];
        verts[layer] = layerverts;
      }
      layerverts.push(vv);
    }

    // now recursively position nodes (using radlay1()), starting with the root
    rootvert.centerX = this.arrangementOrigin.x;
    rootvert.centerY = this.arrangementOrigin.y;
    this.radlay1(rootvert, 1, 0, 360);

    // Update the "physical" positions of the nodes and links.
    this.updateParts();
    this.network = null;
  }

  /**
  * recursively position vertexes in a radial layout
  */
  private radlay1(vert: RadialVertex, layer: number, angle: number, sweep: number) {
    if (layer > this.maxLayers) {return; } // no need to position nodes outside of maxLayers
    let verts: any[] = []; // array of all RadialVertexes connected to 'vert' in layer 'layer'
    vert.vertexes.each(function(v: RadialVertex) {
      if (v.laid) {return; }
      if (v.distance === layer) {verts.push(v); }
    });
    let found = verts.length;
    if (found === 0) {return; }

    let radius = layer * this.layerThickness;
    let separator = sweep / found; // distance between nodes in their sweep portion
    let start = angle - sweep / 2 + separator / 2;
    // for each vertex in this layer, place it in its correct layer and position
    for (let i = 0; i < found; i++) {
      let v = verts[i];
      let a = start + i * separator; // the angle to rotate the node to
      if (a < 0) {a += 360; } else if (a > 360) {a -= 360; }
      // the point to place the node at -- this corresponds with the layer the node is in
      // all nodes in the same layer are placed at a constant point, then rotated accordingly
      let p = new go.Point(radius, 0);
      p.rotate(a);
      v.centerX = p.x + this.arrangementOrigin.x;
      v.centerY = p.y + this.arrangementOrigin.y;
      v.laid = true;
      v.angle = a;
      v.sweep = separator;
      v.radius = radius;
      // keep going for all layers
      this.radlay1(v, layer + 1, a, sweep / found);
    }
  }

  /**
  * Update RadialVertex.distance for every vertex.
  */
  private findDistances(source: RadialVertex) {
    let diagram = this.diagram;
    // keep track of distances from the source node
    this.network.vertexes.each(function(v: RadialVertex) { v.distance = Infinity; });
    // the source node starts with distance 0
    source.distance = 0;
    // keep track of nodes for we have set a non-Infinity distance,
    // but which we have not yet finished examining
    let seen = new go.Set(RadialVertex);
    seen.add(source);

    // local function for finding a vertex with the smallest distance in a given collection
    function leastVertex(coll: any) {
      let bestdist = Infinity;
      let bestvert: any = null;
      let it = coll.iterator;
      while (it.next()) {
        let v = it.value;
        let dist = v.distance;
        if (dist < bestdist) {
          bestdist = dist;
          bestvert = v;
        }
      }
      return bestvert;
    }

    // keep track of vertexes we have finished examining;
    // this avoids unnecessary traversals and helps keep the SEEN collection small
    let finished = new go.Set(RadialVertex);
    while (seen.count > 0) {
      // look at the unfinished vertex with the shortest distance so far
      let least = leastVertex(seen);
      let leastdist = least.distance;
      // by the end of this loop we will have finished examining this LEAST vertex
      seen.remove(least);
      finished.add(least);
      // look at all edges connected with this vertex
      least.edges.each(function(e: any) {
        let neighbor = e.getOtherVertex(least);
        // skip vertexes that we have finished
        if (finished.contains(neighbor)) {return; }
        let neighbordist = neighbor.distance;
        // assume "distance" along a link is unitary, but could be any non-negative number.
        let dist = leastdist + 1;
        if (dist < neighbordist) {
          // if haven't seen that vertex before, add it to the SEEN collection
          if (neighbordist === Infinity) {
            seen.add(neighbor);
          }
          // record the new best distance so far to that node
          neighbor.distance = dist;
        }
      });
    }
  }

  /**
  * This override positions each Node and also calls {@link #rotateNode}.
  */
  commitLayout() {
    super.commitLayout();

    let it = this.network.vertexes.iterator;
    while (it.next()) {
      let v = it.value as RadialVertex;
      let n = v.node;
      if (n !== null) {
        n.visible = (v.distance <= this.maxLayers);
        this.rotateNode(n, v.angle, v.sweep, v.radius);
      }
    }

    this.commitLayers();
  }

  /**
  * Override this method in order to modify each node as it is laid out.
  * By default this method does nothing.
  */
  rotateNode(node: go.Node, angle: number, sweep: number, radius: number) {
  }

  /**
  * Override this method in order to create background circles indicating the layers of the radial layout.
  * By default this method does nothing.
  */
  commitLayers() {
  }
} // end RadialLayout


/**
* @ignore
* @constructor
* @extends LayoutVertex
* @class
*/
class RadialVertex extends go.LayoutVertex {
  distance: number = Infinity;  // number of layers from the root, non-negative integers
  laid: boolean = false;  // used internally to keep track
  angle: number = 0;  // the direction at which the node is placed relative to the root node
  sweep: number = 0;  // the angle subtended by the vertex
  radius: number = 0;  // the inner radius of the layer containing this vertex
}
import { Component, Input } from '@angular/core';

@Component({
  selector: 'search-filter',
  template: `<div class="container" style="padding: 25px; margin: 25px; width: 50%;">
    <div class="row">{{eachFilter}}</div>
    </div>`
})

export class SearchFilterComponent {
  @Input() eachFilter: string = 'testfilter'
}