• laurent@lioncoding.com

Présentation de vis js

Vis.js est une bibliothèque permettant de concevoir des graphes sous forme de réseaux, de graphes 2D et 3D. Elle permet également une visualisation dynamique et interactive des graphes dans un navigateur web. Pour utiliser vis.js, télécharger l’archive de la bibliothèque ou utiliser le CDN JavaScript et CSS mais il est préférable d’utiliser l’archive pour benéficier de tous les composants de la bibliothèque.

Pour notre article, nous utiliserons vis.js pour construire un réseau simulant la supervision de systèmes informatiques.

Sujet

On suppose qu’on a une application dont le rôle est de superviser(faire du monitoring) d’un certain nombre de systèmes informatiques :

Notre rôle en tant que développeur est de mettre en place une appliction web permettant de visualiser tout le système infomatique en montrant les rapports de supervision.

Nous utiliserons Draw.io pour créer les images représentant chaque équipement informatique comme le montre l’image en début d’article mais vous aurez accès à ces images vers la fin.

Quelques concepts

Il est important d’appréhender quelques notions essentielles avant d’utiliser le réseau de vis.js à savoir les notions de nœuds(appelés nodes dans vis.js) de liens(appelés edges dans vis.js) et de réseau(Network).

Un nœud est un objet du réseau, donc un élément de notre imaginaire système informatique. un nœud est un objet JSON à ajouter à la liste des nœuds. Voici l’exemple de création d’un nœud:

// Nodes table
var nodes = [];
// Add nodes to the table
 nodes.push({id: 1, label: "Noeud1", title:"Noeud1", image: DIR + "image1.png", shape: "image"});
 nodes.push({id: 2, label: "Noeud2", title:"<span>Noeud2</span>", image: DIR + "image2.png", shape: "image"});

Un objet nœud a 4 proprités dont deux essentielles et obligatoires. Il s’agit de l’id et du label.

Un lien, comme son nom l’indique relie deux nœuds. Ce sont les liens qui donne la visibilité au réseau.

Voici, comment relier deux nœuds 1 et 2 avec une flêche.

// Edges table
var edges = [];
// Link two nodes with arrow
edges.push({from: 1, to: 2, arrows:"to"});

Le réseau est l’ensemble formé par les nœuds et les liens. Le code ci-dessous sert à créer un réseau en utilisant vis.js:

var network = null;
// Get HTML div element that should display the network
var container = document.getElementById("mynetwork");
// Our nodes and edges
var data = {
    nodes: nodes,
    edges: edges
};
// Options
var options = {  
    interaction:{
        zoomView: true
    } 
};
network = new vis.Network(container, data, options);

Pour plus de détails sur les options, faites un tour sur la documentation.

Mise en œuvre

La structure de notre projet se présente comme suit:

Project structure image

Le dossier dist est l’achive dézippée de vis.js. Le dossier js contient le fichier javascript qui dessinera le réseau et le dossier css pour le style.

Le code HTML de notre solution:

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="utf-8">
    <title>Newtwork monitoring</title>
    <script type="text/javascript" src="dist/vis.js"></script>
    <link href="dist/vis-network.min.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="js/main.js"></script>
    <link href="css/style.css" rel="stylesheet" type="text/css" />
</head>
<body onload="draw()">
    <div id="mynetwork"></div>
</body>
</html>

Le code CSS:

#mynetwork {
    width: 100%;
    height: 900px;
    margin-top: auto;
    padding: 0%;
}

@font-face {
    font-family: "Ubuntu";
    src: url(../fonts/Ubuntu-Regular.ttf);
}

* {
    font-family: "Ubuntu";
    font-weight: bold;
  }

Et enfin le code JavaScript:

var nodes = null;
var edges = null;
var network = null;

var DIR = "img/";

// Called when the Visualization API is loaded.
function draw() {
    // Create a data table with nodes.
    nodes = [];

    // Create a data table with links.
    edges = [];

    // Central nodes
    nodes.push({id: 1, label: "Monitor", title:"<strong>Main I</strong>", image: DIR + "storage_sync_camera.png", shape: "image"});
    nodes.push({id: 2, label: "Storage", title:"<strong>Storage server Node</strong>", image: DIR + "pont.png", shape: "image"});
    nodes.push({id: 3, label: "Jobs Server", title:"<strong>Jobs Server Node</strong>", image: DIR + "pont.png", shape: "image"});
    nodes.push({id: 4, label: "FTP Directory", title:"<strong>FTP Directory Node</strong>", image: DIR + "pont.png", shape: "image"});
    nodes.push({id: 5, label: "Monitor 2", title:"<strong>Main II</strong>", image: DIR + "main_2.png", shape: "image"});

    // Central Edges
    edges.push({from: 1, to: 2, arrows:"to"});
    edges.push({from: 1, to: 3, arrows:"to"});
    edges.push({from: 1, to: 4, arrows:"to"});
    edges.push({from: 1, to: 5, arrows:"to"});


    // Monitor II
    nodes.push({id: 6, label: "Backup001", title:"<strong>Backup001</strong>", image: DIR + "backup.png", shape: "image"});
    nodes.push({id: 7, label: "Primary001", title:"<strong>Primary001</strong>", image: DIR + "primary_site.png", shape: "image"});
    nodes.push({id: 8, label: "Backup002", title:"<strong>Backup002</strong>", image: DIR + "backup.png", shape: "image"});
    edges.push({from: 5, to: 6, arrows:"to"});
    edges.push({from: 5, to: 7, arrows:"to"});
    edges.push({from: 5, to: 8, arrows:"to"});


    // Storage servers
    nodes.push({id: 9, label: "HP-DATA-01", title:"<strong>HP-DATA-01</strong>", image: DIR + "storage_server_alert.png", shape: "image",
    title:"Disk C:<strong style="color:green"> 600 Go / 1 To</strong></br>Disk D:<strong style="color:red"> 490 Go / 500 Go</strong>"});
    nodes.push({id: 10, label: "DESKTOP-DATA-01", title:"<strong>DESKTOP-DATA-01</strong>", image: DIR + "storage_server.png", shape: "image"});
    nodes.push({id: 11, label: "SLQAzure001", title:"<strong>SLQAzure001</strong>", image: DIR + "sql_azure.png", shape: "image"});
    nodes.push({id: 12, label: "MySQLServer001", title:"<strong>MySQLServer001</strong>", image: DIR + "mysql_server.png", shape: "image"});
    nodes.push({id: 13, label: "Cloud", title:"<strong>Cloud</strong>", image: DIR + "pont.png", shape: "image"});
    nodes.push({id: 14, label: "Cloud001", title:"<strong>Cloud001</strong>", image: DIR + "cloud.png", shape: "image"});
    nodes.push({id: 15, label: "Cloud002", title:"<strong>Cloud002</strong>", image: DIR + "cloud.png", shape: "image"});
    nodes.push({id: 16, label: "Cloud003", title:"<strong>Cloud003</strong>", image: DIR + "cloud.png", shape: "image"});
    edges.push({from: 2, to: 9, arrows:"to"});
    edges.push({from: 2, to: 10, arrows:"to"});
    edges.push({from: 2, to: 11, arrows:"to"}); 
    edges.push({from: 2, to: 12, arrows:"to"});
    edges.push({from: 2, to: 13, arrows:"to"});
    edges.push({from: 13, to: 14, arrows:"to"});
    edges.push({from: 13, to: 15, arrows:"to"});
    edges.push({from: 13, to: 16, arrows:"to"});



    // Jobs server
    nodes.push({id: 17, label: "HP-JOB-02", title:"<strong>HP-JOB-02</strong>", image: DIR + "job_server.png", shape: "image"});
    nodes.push({id: 18, label: "DESKTOP-JOB-02", title:"<strong style="color:red"> Intrusion detect !</strong>", image: DIR + "job_server_intruision_alert.png", shape: "image"});
    edges.push({from: 3, to: 17, arrows:"to"});
    edges.push({from: 3, to: 18, arrows:"to"});


    // FTP directories
    nodes.push({id: 19, label: "Music", title:"<strong>Music directory</strong>", image: DIR + "data_type.png", shape: "image"});
    nodes.push({id: 20, label: "Videos", title:"<strong style="color:red"> Videos directory corrupted !</strong>", image: DIR + "data_type_alert.png", shape: "image"});
    nodes.push({id: 21, label: "Mooc", title:"<strong style="color:red"> Mooc directory corrupted !</strong>", image: DIR + "data_type_alert.png", shape: "image"});
    nodes.push({id: 22, label: "Documents", title:"<strong>Document directory</strong>", image: DIR + "data_type.png", shape: "image"});
    edges.push({from: 4, to: 19, arrows:"to"});
    edges.push({from: 4, to: 20, arrows:"to"});
    edges.push({from: 4, to: 21, arrows:"to"});
    edges.push({from: 4, to: 22, arrows:"to"});



    // create a network
    var container = document.getElementById("mynetwork");
    var data = {
        nodes: nodes,
        edges: edges
      };
        var options = {  
            interaction:{
                dragNodes:true,
                dragView: true,
                hideEdgesOnDrag: false,
                hideNodesOnDrag: false,
                hover: true,
                hoverConnectedEdges: true,
                keyboard: {
                enabled: false,
                speed: {x: 10, y: 10, zoom: 0.1},
                bindToWindow: true
                },
                multiselect: false,
                navigationButtons: true,
                selectable: true,
                selectConnectedEdges: true,
                tooltipDelay: 200,
                zoomView: true
            } 
    };
    network = new vis.Network(container, data, options);

};

Voici la Démo et le Code source. Toutes les images utilisées se trouvent dans l’archive du code source.