Skip to content

Instantly share code, notes, and snippets.

@patrickfav
Last active February 25, 2023 13:12
Show Gist options
  • Save patrickfav/cd20939b383b9c284511 to your computer and use it in GitHub Desktop.
Save patrickfav/cd20939b383b9c284511 to your computer and use it in GitHub Desktop.
Simple Sigma.js AngularJs Directive: Since I did not find any angularjs directive for angularjs I created a little simple of my own. This is by no means a ready-for-all solutions, but all the features I needed at the time; it is easily extended to your needs and maybe sometimes somebody will do a full-blown directive for sigma.js Tested: angular…
/*
* Copyright 2017 Patrick Favre-Bulle
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(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();
});
}
};
});
})();
function MyCtrl($scope) {
$scope.sigmaGraph = {
"nodes": [
{
"id": "n0",
"label": "A node",
"x": 0,
"y": 0,
"size": 3
},
{
"id": "n1",
"label": "Another node",
"x": 3,
"y": 1,
"size": 2
},
{
"id": "n2",
"label": "And a last one",
"x": 1,
"y": 3,
"size": 1
}
],
"edges": [
{
"id": "e0",
"source": "n0",
"target": "n1"
},
{
"id": "e1",
"source": "n1",
"target": "n2"
},
{
"id": "e2",
"source": "n2",
"target": "n0"
}
]
}
}
<script src="js/sigma.min.js"></script>
...
<sigmajs graph="sigmaGraph" width="100%" height="300px" releative-size-node="true"></sigmajs>
@sakovias
Copy link

Thanks for this gist. Could you give an advice on how to grab node data from within Angular? I'd like to be able to edit nodes' attributes after clicking on them, as well as be able to save the data to a model. How difficult this could be?

@patrickfav
Copy link
Author

Add something like this to the directive:

s.bind('clickNode', function(e) {
                var nodeId = e.data.node.id,
                    toKeep = s.graph.neighbors(nodeId);
                toKeep[nodeId] = e.data.node;

                s.graph.nodes().forEach(function(n) {
                    if (toKeep[n.id])
                        n.color = '#27ae60';
                    else
                        n.color = '#eee';
                });

                s.graph.edges().forEach(function(e) {
                    if (toKeep[e.source] && toKeep[e.target])
                        e.color = '#27ae60';
                    else
                        e.color = '#eee';
                });
                s.refresh();
            });

@sakovias
Copy link

Thanks @patrickfav. This puts me on the right track.

@jondea
Copy link

jondea commented Mar 9, 2017

Thanks for this gist, I found it really helpful.

On the related stack-exchange question, there were several comments criticising your use of $watch('graph'). Do you know why? Is it just a generic criticism of watching a variable which is two way bound? Does it not apply to the watch on width and height? I don't have the required reputation to comment directly unfortunately, but could you shed any light on why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment