Dans cette partie nous allons parler du paramétrage des évènements et des interactions avec le graphe. L’avantage d’avoir un graphe dynamique en javascript est bien de pouvoir interagir avec lui, afin d’afficher des informations supplémentaires, de rediriger l’utilisateur vers une autre page et plein d’autre choses
La capture des évènements
Il est très simple d’écouter les évènements de VisNetwork, pour cela il suffit d’ajouter des écouteurs à notre réseau comme ceci :
network.on("nomEvenement", mafunction);
Il existe un large choix d’évènements pour visnetwork, voici une petite liste de ceux que j’estime intéressants, vous pouvez retrouver les autres dans la doc :
click
: Clic gauche de la souris sur la zone d’affichage du graphedoubleClick
: Double clic sur la zone d’affichage du graphe.oncontext
: Clic droit de la souris sur la zone d’affichage du graphe.dragStart
: Évènement déclenché lors du déclenchement du déplacement d’un noeud.dragging
: Évènement déclenché lors du déplacement d’un noeud.dragEnd
: Évènement déclenché lors de l’arrêt du déplacement d’un noeud.zoom
: Déclenché lors de l’action de zoom et de dezoom (molette de la souris).selectNode
: Déclenché lors de la sélection d’un noeud.selectEdge
: Déclenché lors de la sélection d’un lien.deselectNode
: Déclenché lors de la dé-sélection d’un noeud.deselectEdge
: Déclenché lors de la dé-sélection d’un lien.
Clic et double-clic
Avant de commencer la présentation des exemples, je vous fournis le code JavaScript utilisé afin que vous puissiez reproduire les exemples chez vous.
let nodes = new vis.DataSet([]);
let edges = new vis.DataSet([]);
let container = document.getElementById('graphe');
let data = {
nodes: nodes,
edges: edges
};
let options = {
interaction:{hover:true}
};
// Initialisation de l'instance de VisNetwork
let network = new vis.Network(container, data, options);
// Ajout de nos deux noeuds
nodes.add(
[
{
id: 1,
label: "N1"
},
{
id: 2,
label: "N2"
}
]
);
// Ajout du lien entre nos deux noeuds
edges.add(
[
{
from: 1,
to: 2,
label: "E1",
}
]
);
Nous allons écouter l’action de clic du notre graphe, elle se déclenche lorsque l’utilisateur clique sur la zone d’affichage du graphe.
network.on("click", function(data)
{
if(data.nodes.length > 0)
{
alert(data.nodes[0]);
}
});
Le paramètre data
contient un tableau de tout les identifiants des noeuds et un tableau de tout les identifiants des liens dans la zone du clic. Dans notre exemple on vérifie qu’il y a bien un noeud dans la zone du clic et l’on affiche l’identifiant de ce noeud dans un pop-up.
Voici un second exemple pour vous montrer comment récupérer les labels des noeuds et des liens sélectionnés.
network.on("doubleClick", function(data)
{
if(data.nodes.length > 0)
{
var selectedNode = nodes.get(data.nodes[0]);
var label = selectedNode.label;
alert(label);
}
else if(data.edges.length > 0)
{
var selectedEdges = edges.get(data.edges[0]);
var label = selectedEdges.label;
alert(label);
}
});
La méthode nodes.get(id)
nous permet de récupérer toutes les informations du noeud sur lequel on a cliqué, on récupère ensuite le label du noeud ou du lien, puis on l’affiche.
Zoom/Dézoom
Dans cet exemple on va afficher le niveau de zoom actuel dans une zone de texte.
Les paramètres de l’action de zoom ne sont pas les mêmes que les autres actions, ces paramètres sont :
direction
: égale à+
ou-
.scale
: échelle actuelle du zoom (Nombre).pointer
: {x
: position de la souris en x,y
: position de la souris en y}.
Voici un exemple d’affichage du zoom actuel à chaque action de zoom ou de dézoom.
// Code Javascript
function zoom(data)
{
document.getElementById("infos").innerHTML = data.scale;
}
network.on("zoom", zoom);
Il faut également ajouter une balise HTML qui contiendra nos informations : <div id="infos"></div>
Exercice
Je vous propose un petit exercice pour mettre en pratique les évènements, à partir du drag and drop (déplacement d’un noeud).
Le but est lors du déplacement d’un noeud de mesurer et d’afficher la valeur de son déplacement, pour cela on va utiliser les évènements dragStart
, dragging
et dragEnd
.
Petite Astuce :
Pour récupérer la position d’un noeud il faut utiliser la méthode network.getPositions(idNoeud)[idNoeud]
Procédure à suivre :
- Lors de l’action
dragStart
, stocker la position du noeud. - Lors de l’action
dragging
, afficher la valeur actuelle du déplacement par rapport à la position initiale du noeud. - Lors de l’action
dragEnd
, afficher la valeur du déplacement qui vient de se terminer (ex:Dernier déplacement : X : 215 || Y : 17
).
Bon courage
Si vous n’y arrivez pas, vous pouvez retrouver la solution ci dessous :
Code HTML :
<!doctype html>
<html>
<head>
<title>Tuto VisNetwork</title>
<style>
#graphe
{
display: inline-block;
width: 800px;
height: 600px;
background-color: #f0f0f0;
}
</style>
<script type="text/javascript" src="vis.min.js"></script>
</head>
<body>
<div id="graphe"></div>
<div id="infos"></div>
<script type="text/javascript" src="graph.js"></script>
</body>
</html>
Code Javascript :
let nodes = new vis.DataSet([]);
let edges = new vis.DataSet([]);
let container = document.getElementById('graphe');
let data = {
nodes: nodes,
edges: edges
};
let options = {
interaction:{hover:true}
};
// Initialisation de l'instance de VisNetwork
let network = new vis.Network(container, data, options);
// Ajout de nos deux noeuds
nodes.add(
[
{
id: 1,
label: "N1"
},
{
id: 2,
label: "N2"
}
]
);
// Ajout du lien entre nos deux noeuds
edges.add(
[
{
from: 1,
to: 2,
label: "E1",
}
]
);
// Stockage de la position de départ
let startPos = {};
// Fonction appelé lors du lancement du déplacement
function dragStart(data)
{
if(data.nodes.length > 0)
{
// Récupération des informations du noeud en cours de déplacement
let selectedNode = nodes.get(data.nodes[0]);
// Mise à jour de la variable stockant la position de départ
startPos = network.getPositions(data.nodes[0])[data.nodes[0]];
}
}
// Fonction s'exécutant en continu au cours du déplacement
function dragging(data)
{
let text = "";
if(data.nodes.length > 0)
{
// Récupération des informations du noeud en cours de déplacement
let selectedNode = nodes.get(data.nodes[0]);
// Récupération de la position du noeud
let pos = network.getPositions(data.nodes[0])[data.nodes[0]];
// Calcul de la différence de position entre la position actuel du noeud et sa position au debut de déplacement
let posDiffX = pos.x - startPos.x;
let posDiffY = pos.y - startPos.y;
// Affichage du différenciel de position
text += "X:" + posDiffX + " || Y:" + posDiffY;
}
document.getElementById("infos").innerHTML = text;
}
// Fonction s’exécutant à la fin de l'action de déplacement (au relâchement de la souris)
function dragEnd(data)
{
let text = "";
if(data.nodes.length > 0)
{
// Récupération des informations du noeud
let selectedNode = nodes.get(data.nodes[0]);
// Récupération de la position du noeud
let endPos = network.getPositions(data.nodes[0])[data.nodes[0]];
// Calcul de la différence de position entre la position actuel du noeud et sa position au début de déplacement
let posDiffX = endPos.x - startPos.x;
let posDiffY = endPos.y - startPos.y;
// Affichage du différentiel de position
text += "Dernier déplacement : X:" + posDiffX + " || Y:" + posDiffY;
}
document.getElementById("infos").innerHTML = text;
}
// Déclenchement des évènements
network.on("dragStart", dragStart);
network.on("dragging", dragging);
network.on("dragEnd", dragEnd);
Ce chapitre sur les évènements est maintenant terminé, si vous voulez connaître d’autres évènements rendez vous sur la doc où vous retrouverez une description en anglais de chaque évènements.
Dans la prochaine partie, je vous ferait découvrir les hierarchicals layouts permettant d’ordonnancer les noeuds et le clustering permettant de regrouper les noeuds.