Diagramme de réseau comme code

Au cours des deux dernières années, j'ai commencé à m'occuper davantage de la documentation. Écrivez un texte explicatif sur le fonctionnement de tel ou tel système - en général, c'est assez simple. Dessinez un diagramme sur lequel tous les objets clés seront affichés, la relation entre ces objets est également assez facile.

Mais le moment le plus problématique est de maintenir cette documentation à jour. Et bien, le texte, mais les diagrammes ... Parce que toute la documentation est en ligne, c'est-à-dire au format html, puis des images gif / jpeg / png sont attachées au texte, sur lequel les diagrammes sont réellement représentés. Et les schémas sont dessinés dans divers programmes tels que Visio ou des services en ligne à la draw.io. Ensuite, vous exportez le diagramme dans un format graphique et le joignez au html. Tout est simple.

Quel est le problème?

Les schémas sont généralement simples. Plus précisément, pas très compliqué. Oui, le nombre d'objets est de dix ou deux, le nombre de connexions est à peu près le même. Plus des signatures, quelques désignations. Des schémas simples peuvent être décrits avec des mots, mais trop complexes, hmm ... (s) "ils ne comprennent pas, monsieur." Il existe de nombreux systèmes, des changements doivent être apportés périodiquement, périodiquement, c'est-à-dire constamment, car ils suivent le développement de nos produits.

Vous pouvez intégrer le service html. L'as tu essayé?

Oui bien sûr. Par exemple, j'aime les graphiques gliffy.com. Mais pour les changements, vous devez vous rendre sur un service tiers, là pour le modifier. Et il est plus difficile de déléguer des amendements à un collègue.

Que faire?

Récemment, sur un github, je suis tombé sur le référentiel github.com/RaoulMeyer/diagram-as-code dans les recommandations. Graphique sous forme de code. Ceux. nous décrivons sur js le circuit dont nous avons besoin. Nous écrivons ce js directement dans le même html où se trouve l'autre texte de documentation.

Au fait, mais je n'écris pas du tout de documentation en html. En règle générale, la documentation est un ensemble de fichiers avec du texte de démarque, qui est ensuite converti en un site de documentation à part entière par un moteur, par exemple wintersmith. Ou un système wiki.

Cela s'avère très pratique: ici nous avons écrit le texte, puis la balise de script est ouverte et le code js du circuit y est décrit.

Qu'est-ce qui ne va pas?

J'ai aimé ce référentiel, mais ce n'est pas le seul exemple quand un diagramme est dessiné en utilisant du code ou une vue texte. (À la fin de l'article, il y aura des liens vers des projets et des articles qui ont été répertoriés sur le diagramme du sujet sous forme de code.)

Et je ne suis pas le seul à corriger la documentation. Parfois, des collègues apportent également leur contribution - corrigez le mot, changez la description, insérez de nouvelles images. 

Par conséquent, je voudrais voir le diagramme dans un format de texte lisible et compréhensible, qui ne devrait pas être étudié pendant longtemps. Et par endroits, il est même facile de faire du copier-coller pour accélérer l'ajout d'un nouveau schéma. 

Et un autre collègue a noté que le code est, bien sûr, bon, mais si vous utilisez la structure, tout peut être très strict et expressif.

Par conséquent, j'ai essayé de présenter le schéma comme un ensemble de plusieurs petits tableaux qui décrivent les nœuds, les connexions, les groupes de nœuds, ainsi que l'emplacement des nœuds. Il s'est avéré, à mon humble avis, assez pratique, bien que, bien sûr, le goût et la couleur ...

Comment est le graphique dans le tableau?

  • Chaque nœud est décrit par un identifiant qui identifie de manière unique le nœud.
  • Vous pouvez également ajouter une icône au nœud, ajouter une inscription.
  • Vous pouvez spécifier une relation entre deux nœuds.
  • Pour la communication sur le schéma, vous pouvez définir la couleur, l'inscription.
  • La direction de la communication est définie de la source à la cible. Et la source et la cible sont indiquées par les identifiants du nœud.
  • Un ou plusieurs nœuds peuvent être ajoutés au groupe.
  • Un lien peut également être spécifié d'un groupe à un groupe.

En utilisant ces règles simples, nous obtenons un tel schéma. Simplement? Assez.



Et il est décrit par le code js suivant. La chose principale ici est l'objet éléments. Dans quels nœuds - nœuds, arêtes - connexions sont indiqués.
 
  const elements = {
    nodes: [       //  
      { id: 'client', type: 'smartphone', label: 'Mobile App'},
      { id: 'server', type: 'server', label: 'Main Server'},
      { id: 'db1', type: 'database', label: 'DB 1'},
      { id: 'db2', type: 'database', label: 'DB 2'},
    ],
    edges: [       //  
      { source: 'client', target: 'server', label: 'request' },
      { source: 'server', target: 'db1', label: 'request' },
      { source: 'server', target: 'db2', label: 'request' },
    ],
  };
  Diagram('scheme1', elements);

Bien sûr, je ne pensais pas à dessiner le circuit moi-même, mais j'ai utilisé la bibliothèque cytoscape.js , un outil de visualisation très puissant. Opportunités Toliku que dans ma décision j'utilise seulement. 

Il s'agit clairement d'un exemple simple. Cela peut-il être plus compliqué?

Oui s'il vous plaît. Pour indiquer des positions - nous utilisons des positions, pour indiquer des groupes - nous spécifions une liste de groupes dans des groupes, et les éléments eux-mêmes ont un attribut de groupe.



Et voici le code:

<div id="scheme5" style="height:500px;width:800px;"></div>
<script>
  const elements5 = {
    groups: [
      { id: 'g1', label: '  1'},
      { id: 'g2', label: '  2'},
    ],
    nodes: [
      { id: 'man1', type: 'person', label: ''},
      { id: 'client', type: 'smartphone', label: ''},
      { id: 'agent-backend', type: 'server', group: 'g1', label: 'agent-backend'},
      { id: 'web', type: 'server', group: 'g1', label: ' admin'},
      { id: 'www', type: 'server', group: 'g1', label: ' '},
      { id: 'mongodb1', type: 'database', group: 'g1', label: 'Mongo DB 1'},
      { id: 'mongodb2', type: 'database', group: 'g1', label: 'Mongo DB 2'},
      { id: 'runner-integration1', type: 'worker', group: 'g1', label: ''},
      { id: 'runner-integration2', type: 'worker', group: 'g1', label: ''},
      { id: 'api', type: 'server', group: 'g1', label: 'API'},
      { id: 'server2', type: 'server', group:'g2', label: ''},
      { id: 'otherServer', type: 'server', group:'g2', label: ''},
      { id: 'firebase', type: 'cloud', label: 'Google Firebase'},
    ],
    edges: [
      { source: 'client', target: 'agent-backend', label: 'json', color: 'red' },
      { source: 'agent-backend', target: 'mongodb1', color: 'red' },
      { source: 'agent-backend', target: 'mongodb2',  color: 'red' },
      { source: 'mongodb1', target: 'runner-integration1', label: '' },
      { source: 'mongodb2', target: 'runner-integration2', label: '' },
      { source: 'mongodb1', target: 'web', label: '  ' },
      { source: 'runner-integration1', target: 'server2', label: '' },
      { source: 'runner-integration2', target: 'otherServer', label: '' },
      { source: 'api', target: 'firebase', label: '', color: 'blue', },
      { source: 'firebase', target: 'client', label: 'push', color: 'blue'},
      { source: 'server2', target: 'api', label: '', color: 'blue'},
      { source: 'man1', target: 'client', },
    ],
    positions: [
      { id: 'client', row: 2, col: 1,},
      { id: 'agent-backend', row: 2, col: 3,},
      { id: 'web', row: 6, col: 3,},
      { id: 'www', row: 1, col: 3,},
      { id: 'mongodb1', row: 1, col: 4,},
      { id: 'mongodb2', row: 2, col: 5,},
      { id: 'runner-integration1', row: 3, col: 3,},
      { id: 'runner-integration2', row: 4, col: 3,},
      { id: 'api', row: 5, col: 3,},
      { id: 'server2', row: 6, col: 7,},
      { id: 'otherServer', row: 4, col: 7,},
      { id: 'firebase', row: 5, col: 1,},
      { id: 'logger', row: 2, col: 7,},
      { id: 'crm', row: 5, col: 8,},
    ],
};
  Diagram('scheme5', elements5, {layout: 'grid'});
</script>

Un tel schéma, d'une part, est presque deux écrans de code sur l'ordinateur portable, d'autre part, une structure la json vous permet de remplir toutes les données par analogie, rapidement et vous pouvez copier-coller.

Et pourquoi les positions sont-elles prises séparément des nœuds?

C'est plus confortable. Nous spécifions d'abord les nœuds. Ensuite, nous pouvons indiquer quelques groupes et les indiquer dans les nœuds. Ensuite, nous désignons la connexion. Et puis, lorsque les objets principaux et les connexions entre eux le sont, nous reprenons l'emplacement de ces objets sur le diagramme. Ou vice versa.

Est-ce possible sans positions?

C'est possible sans positions. Mais ce sera un peu froissé, dans les exemples vous pouvez voir cette option. Cela est dû au fait que pour le cytoscape, il existe un algorithme pour la localisation des nœuds fcose, qui prend également en compte la présence de groupes. La spécification des positions rend le schéma plus contrôlable, mais au stade de la première ébauche du schéma, il est possible sans positions.

De plus, les positions peuvent être spécifiées dans le style de bataille navale. Ceux. un nœud est situé en a1 et l'autre en d5. Il est particulièrement utile que le cytoscape forme des objets sur une toile mobile, c'est-à-dire nous pouvons les déplacer, regarder différentes options de mise en page, puis fixer dans le code votre arrangement préféré d'éléments.

En général, je vois. Vous pouvez aussi essayer?
 
Bien sûr, pour créer rapidement des schémas, je me suis fait un petit éditeur , qui met à jour le schéma lui-même et stocke la dernière option dans le navigateur (dans localStorage).

L'as tu essayé? Vous pouvez maintenant ajouter à votre page.

Là encore:

1. Nous connectons un script

<script src="https://unpkg.com/@antirek/network-diagram@0.1.4/dist/code-full.min.js"></script>

2. Ajoutez au code html

<div id="scheme1" style="height:300px;width:800px;"></div>
<script>      
  const elements = {    
    nodes: [
      { id: 'client', type: 'smartphone', label: 'Mobile App'},
      { id: 'server', type: 'server', label: 'Main Server'},
      { id: 'db1', type: 'database', label: 'DB 1'},
      { id: 'db2', type: 'database', label: 'DB 2'},
    ],
    edges: [
      { source: 'client', target: 'server', label: 'request' },
      { source: 'server', target: 'db1', label: 'request' },
      { source: 'server', target: 'db2', label: 'request' },
    ],
  };
  Diagram('scheme1', elements);
</script>

3. éditez le code selon le schéma dont nous avons besoin (je pense que c'est plus facile que de dessiner un hibou :)

Plus de détails sur la page du projet sur le github.

Quel est le résultat?

J'ai atteint mes objectifs - pour ajouter des schémas en ligne à la documentation, le format est assez simple et direct. Ce n'est pas adapté aux superschemes, mais aux petits circuits qui expliquent la structure des connexions, ce n'est même rien. Vous pouvez toujours le réparer rapidement et changer quelque chose au fil du temps. Oui, et les collègues peuvent corriger eux-mêmes quelque chose dans le dock, au moins les signatures des objets sans formation spéciale))

Qu'est-ce qui peut être amélioré?

Il y a bien sûr de nombreuses options. Faites l'ajout d'icônes supplémentaires (toutes disponibles sont ajoutées en ligne au script). Choisissez un ensemble d'icônes plus expressif. Permet de spécifier un style de ligne de lien. Ajoutez une image d'arrière-plan.

Qu'est-ce que tu penses?
 
J'ai déjà quelques idées pour la mise en œuvre dans les problèmes, vous ajoutez également la vôtre dans les commentaires.


Ma solution est certainement applicable dans une gamme étroite de tâches, et vous trouverez peut-être un outil plus pratique pour dessiner des diagrammes en les encodant simplement - comme ils disent `` montrez-moi votre diagramme en tant que code ''

  1. Bon choix
  2. Service chic  (9 types d'éditeur de cartes en ligne)
  3. Bien sûr mermaid.js
  4. Et si vous aimez les schémas super détaillés et complexes, ce projet vous ravira certainement: go.drawthe.net

All Articles