Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zoomable network graph in AngularJS

Tags:

I would like to visualize a network graph in an AngularJS application. The nodes and edges are stored as a JSON object, and nodes will be added and modified later on (say once every 30 seconds). I want to use Angular data binding to automatically update the graph when the JSON object changes. The graph will have 10-1000 nodes. The nodes will be rectangular text nodes containing about a sentence each. I would like the graph to be zoom- and pan-able.

I know about the following options so far:

  • ArborJS

    It is easy to make dynamic updating work with Angular (using ParticleSystem.merge). However, Arbor does not seem to support zoomable behavior, and it does not seem to be well-supported. For example, the single-node bug is still unresolved.

  • D3

    There is a zoomable force layout demo, and various places have information on using d3 with Angular. D3 is well-supported, but it seems lower-level than the options below. For example, creating a network graph with good-looking rectangular node labels seems nontrivial.

  • VisJS

    VisJS supports zoomable network graphs, and there is a work-in-progress Angular library, but I don't know how reliable both VisJS and its Angular library are.

  • SigmaJS

    SigmaJS also supports zoomable network graphs, but I don't know whether it plays nicely with Angular.

  • CytoscapeJS

  • kmap

Are there other relevant libraries? What is the best library to use for this project, and how can I implement such a zoomable dynamic network graph given the library?

like image 856
Andreas Avatar asked Jun 24 '14 21:06

Andreas


Video Answer


1 Answers

I've been experimenting in VisJs in angular, and I'm really liking it so far. Their network is both pannable and zoomable, and you can select nodes. The documentation has been easy to follow and there are a lot of examples on their site. Since vis's networks can dynamically update, I found it easy to integrate it in my angular app. For example, I created this directive:

app.directive('visNetwork', function() {     return {         restrict: 'E',         require: '^ngModel',         scope: {             ngModel: '=',             onSelect: '&',             options: '='         },         link: function($scope, $element, $attrs, ngModel) {             var network = new vis.Network($element[0], $scope.ngModel, $scope.options || {});              var onSelect = $scope.onSelect() || function(prop) {};             network.on('select', function(properties) {                 onSelect(properties);             });          }      } }); 

Which I use in my html like so:

<vis-network ng-model="network_data" options="network_options" on-select="onNodeSelect" id="previewNetwork"> </vis-network> 

Then in my controller I have the following:

    $scope.nodes = new vis.DataSet();     $scope.edges = new vis.DataSet();     $scope.network_data = {         nodes: $scope.nodes,         edges: $scope.edges     };     $scope.network_options = {         hierarchicalLayout: {             direction: "UD"         }      };     $scope.onNodeSelect = function(properties) {         var selected = $scope.task_nodes.get(properties.nodes[0]);         console.log(selected);     };      $scope.nodes.add([         {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'}]);      $scope.edges.add([         {id: 1, from: 1, to: 2},         {id: 2, from: 3, to: 2}     ]); 
like image 157
efeder Avatar answered Oct 12 '22 22:10

efeder