Cytoscape simple directive – angularJs

Cytoscape sample

I needed a mind-map chart for Angular and found the amazing Cytoscape.js project.
Check Cytoscape’s project site you’ll find lots of information about customizing the charts object.

Note: In this article I’ll show a simple directive sample that wraps it and connects it to a controller. I have used here a simple $broadcast method and just kept the data in a controller. It is not the recommended way and just used to simplify the sample without adding a service and more complex ways to interact with the directive.

Check out the sample @ directivemaker.info/cytoscape

Download source files @ https://github.com/zivpug/Cytoscape-simple-directive/


HTML part of the directive





cytoscape – the directive’s element
cy-data – object name that contains the Nodes data
cy-edges – object name that contains the Edges data
cy-click – function to be called in the Controller, when clicking on a Node.


Basic element’s CSS

This CSS shapes the Cytoscape element in display.

#cy {
    height: 400px;
    width: 80%;
    border: 2px solid #662244;
    position: relative;
    clear: both;
}

The controller

Holding two objects – one for the nodes and one for the edges (the connecting lines between nodes) . It can use just one, more complex, object for both, but I wrote it like that to be easier to read and understand.

The controller also holds functions to add nodes and edges from the sample form.

The $scope.objTypes object just holds types of grouping data. I used the available shapes of Cytoscape as types for the sample.

angular.module('cytoscapeSample').controller('CytoscapeCtrl',function($scope, $rootScope){
    // container objects
    $scope.mapData = [];
    $scope.edgeData = [];
    // data types/groups object - used Cytoscape's shapes just to make it more clear
    $scope.objTypes = ['ellipse','triangle','rectangle','roundrectangle','pentagon','octagon','hexagon','heptagon','star'];

    // add object from the form then broadcast event which triggers the directive redrawing of the chart
    // you can pass values and add them without redrawing the entire chart, but this is the simplest way
    $scope.addObj = function(){
        // collecting data from the form
        var newObj = $scope.form.obj.name;
        var newObjType = $scope.form.obj.objTypes;
        // building the new Node object
        // using the array length to generate an id for the sample (you can do it any other way)
        var newNode = {id:'n'+($scope.mapData.length), name:newObj, type:newObjType};
        // adding the new Node to the nodes array
        $scope.mapData.push(newNode);
        // broadcasting the event
        $rootScope.$broadcast('appChanged');
        // resetting the form
        $scope.form.obj = '';
    };

    // add Edges to the edges object, then broadcast the change event
    $scope.addEdge = function(){
        // collecting the data from the form
        var edge1 = $scope.formEdges.fromName.id;
        var edge2 = $scope.formEdges.toName.id;
        // building the new Edge object from the data
        // using the array length to generate an id for the sample (you can do it any other way)
        var newEdge = {id:'e'+($scope.edgeData.length), source: edge1, target: edge2};
        // adding the new edge object to the adges array
        $scope.edgeData.push(newEdge);
        // broadcasting the event
        $rootScope.$broadcast('appChanged');
        // resetting the form
        $scope.formEdges = '';
    };

    // sample function to be called when clicking on an object in the chart
    $scope.doClick = function(value)
    {
        // sample just passes the object's ID then output it to the console and to an alert
        console.debug(value);
        alert(value);
    };
});

The directive

This is a simple sample directive.

angular.module('cytoscapeSample').directive('cytoscape', function($rootScope) {
    // graph visualisation by - https://github.com/cytoscape/cytoscape.js
    return {
        restrict: 'E',
        template :'
', replace: true, scope: { // data objects to be passed as an attributes - for nodes and edges cyData: '=', cyEdges: '=', // controller function to be triggered when clicking on a node cyClick:'&' }, link: function(scope, element, attrs, fn) { // dictionary of colors by types. Just to show some design options scope.typeColors = { 'ellipse':'#992222', 'triangle':'#222299', 'rectangle':'#661199', 'roundrectangle':'#772244', 'pentagon':'#990088', 'hexagon':'#229988', 'heptagon':'#118844', 'octagon':'#335577', 'star':'#113355' }; // graph build scope.doCy = function(){ // will be triggered on an event broadcast // initialize data object scope.elements = {}; scope.elements.nodes = []; scope.elements.edges = []; // parse edges // you can build a complete object in the controller and pass it without rebuilding it in the directive. // doing it like that allows you to add options, design or what needed to the objects // doing it like that is also good if your data object/s has a different structure for (i=0; i
Check out the sample @
directivemaker.info/cytoscape

Download source files @
https://github.com/zivpug/Cytoscape-simple-directive/

Leave a Reply

Your email address will not be published. Required fields are marked *