Sigma.js in Angularjs
-
21-12-2019 - |
Question
I am having trouble using Sigma.js inside an Angular directive.
The steps I am taking are:
- I have built my app with yeoman.
- I have installed sigma as a bower_component and did run
npm run build
to obtained the minifiedsigma.min.js
- I have added it as a script in my
index.html
- I have added
sigma
as a dependency in myapp.js
. - I have imported it as a dependency in my directive as
sigma
The error that I am getting is: module 'sigma' is not available
Does anybody have an idea on what's going on?
This is the code: app.js
angular.module('uiApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'd3',
'directives',
'services',
'sigma'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
});
sigmagraph.js
'use strict';
angular.module('directives')
.directive('sigmagraph',['$log','sigma',function($log,sigma){
return {
scope:true,
restrict:'EA',
link: function (scope,el){
sigma.parsers.json('data.json', {
container: 'container',
settings: {
defaultNodeColor: '#ec5148'
}
});
}
};
}]);
Solution
Beware: although this should work, it is a very slow implementation (see comments)
For future reference, I made a simple Sigma.Js (v.1.0.3) Directive for AngularJs (1.2.25). It can be found in this gist: Simple Sigma.Js AngularJs Directive
It features only the basics (graph, width, height) but can easily be extended to your needs.
Here is the naked directive. See gist for full example.
(function() {
'use strict';
angular.module('sigmajs-ng', []).directive('sigmajs', function() {
//over-engineered random id, so that multiple instances can be put on a single page
var divId = 'sigmjs-dir-container-'+Math.floor((Math.random() * 999999999999))+'-'+Math.floor((Math.random() * 999999999999))+'-'+Math.floor((Math.random() * 999999999999));
return {
restrict: 'E',
template: '<div id="'+divId+'" style="width: 100%;height: 100%;"></div>',
scope: {
//@ reads the attribute value, = provides two-way binding, & works with functions
graph: '=',
width: '@',
height: '@',
releativeSizeNode: '='
},
link: function (scope, element, attrs) {
// Let's first initialize sigma:
var s = new sigma({
container: divId,
settings: {
defaultNodeColor: '#ec5148',
labelThreshold: 4
}
});
scope.$watch('graph', function(newVal,oldVal) {
s.graph.clear();
s.graph.read(scope.graph);
s.refresh();
if(scope.releativeSizeNode) {
//this feature needs the plugin to be added
sigma.plugins.relativeSize(s, 2);
}
});
scope.$watch('width', function(newVal,oldVal) {
console.log("graph width: "+scope.width);
element.children().css("width",scope.width);
s.refresh();
window.dispatchEvent(new Event('resize')); //hack so that it will be shown instantly
});
scope.$watch('height', function(newVal,oldVal) {
console.log("graph height: "+scope.height);
element.children().css("height",scope.height);
s.refresh();
window.dispatchEvent(new Event('resize'));//hack so that it will be shown instantly
});
element.on('$destroy', function() {
s.graph.clear();
});
}
};
});
})();
OTHER TIPS
I'm writing a guide to integrate Sigma and its plugins into Angular, see https://github.com/Linkurious/linkurious.js/wiki/How-to-integrate-with-Angular.js
This approach has been successfully implemented in Linkurious Enterprise and works with thousands of nodes and edges.
Sigma.js is not an angular module, so you cannot require it. It's a standlone Javascript library. If you just want to use Sigma.js in a directive, you only have to add it to your index.html