Διάγραμμα δικτύου ως κωδικός / Διάγραμμα δικτύου ως κωδικός

Τα τελευταία δύο χρόνια έχω ασχοληθεί περισσότερο με την τεκμηρίωση. Η σύνταξη ενός επεξηγηματικού κειμένου σχετικά με το πώς λειτουργεί αυτό ή εκείνο το σύστημα είναι γενικά αρκετά απλή. Η σχεδίαση ενός διαγράμματος που θα εμφανίζει όλα τα βασικά αντικείμενα και τις συνδέσεις μεταξύ αυτών των αντικειμένων είναι επίσης αρκετά εύκολη.

Αλλά η πιο προβληματική πτυχή είναι η ενημέρωση αυτής της τεκμηρίωσης. Και το κείμενο θα ήταν μια χαρά, αλλά τα διαγράμματα... Γιατί... όλη η τεκμηρίωση είναι online, π.χ. σε μορφή html, τότε το κείμενο συνοδεύεται από εικόνες gif/jpeg/png, οι οποίες στην πραγματικότητα δείχνουν τα διαγράμματα. Και τα διαγράμματα σχεδιάζονται σε διάφορα προγράμματα όπως το Visio ή οι διαδικτυακές υπηρεσίες a la draw.io. Στη συνέχεια εξάγετε το διάγραμμα σε μορφή γραφικού και το επισυνάπτετε σε html. Είναι απλό.

Ποιο είναι το πρόβλημα;

Τα σχήματα είναι συνήθως απλά. Πιο συγκεκριμένα, όχι πολύ περίπλοκο. Ναι, ο αριθμός των αντικειμένων είναι μια ντουζίνα ή δύο, ο αριθμός των συνδέσεων είναι περίπου ο ίδιος. Συν υπογραφές, κάποιοι χαρακτηρισμοί. Τα απλά σχήματα μπορούν να περιγραφούν με λέξεις, αλλά πολύ σύνθετα, αχ... (γ) «δεν θα καταλάβουν, κύριε». Υπάρχουν πολλά σχήματα, πρέπει να γίνονται αλλαγές σε αυτά περιοδικά, επεισοδιακά, δηλ. συνεχώς, γιατί παρακολουθούν την ανάπτυξη των προϊόντων μας.

Μπορείτε να ενσωματώσετε το html της υπηρεσίας. Το έχεις δοκιμάσει?

Ναι σίγουρα. Για παράδειγμα, μου αρέσουν τα γραφικά από το gliffy.com. Αλλά για να κάνετε αλλαγές, πρέπει να μεταβείτε σε μια υπηρεσία τρίτου μέρους και να επεξεργαστείτε εκεί. Και είναι πιο δύσκολο να αναθέσετε διορθώσεις σε έναν συνάδελφο.

Τι να κάνω;

Πρόσφατα βρήκα ένα αποθετήριο στο Github στις συστάσεις github.com/RaoulMeyer/diagram-as-code. Διάγραμμα ως κωδικός. Εκείνοι. περιγράφουμε το κύκλωμα που χρειαζόμαστε σε js. Γράφουμε αυτό το js απευθείας στο ίδιο html όπου βρίσκεται το άλλο κείμενο τεκμηρίωσης.

Παρεμπιπτόντως, γράφω τεκμηρίωση όχι εξ ολοκλήρου σε html. Συνήθως, η τεκμηρίωση είναι ένα σύνολο αρχείων με κείμενο σήμανσης, το οποίο στη συνέχεια μετατρέπεται σε μια πλήρη τοποθεσία τεκμηρίωσης από κάποια μηχανή, για παράδειγμα χειμωνιάτικο. Ή ένα σύστημα wiki.

Αποδεικνύεται πολύ βολικό: έχουμε γράψει το κείμενο, στη συνέχεια ανοίγει η ετικέτα σεναρίου και περιγράφεται σε αυτό ο κώδικας JS του σχήματος.

Τι συμβαίνει πάλι;

Μου άρεσε αυτό το αποθετήριο, αλλά αυτό δεν είναι το μόνο παράδειγμα όπου σχεδιάζεται ένα διάγραμμα χρησιμοποιώντας κώδικα ή μια αναπαράσταση κειμένου. (Στο τέλος του άρθρου θα υπάρχουν σύνδεσμοι για έργα και άρθρα που έψαξα στο Google στο διάγραμμα θέματος ως κώδικας.)

Και δεν είμαι ο μόνος που επεξεργάζεται την τεκμηρίωση. Μερικές φορές συνεισφέρουν και οι συνάδελφοι - διορθώστε μια λέξη, αλλάξτε μια περιγραφή, εισαγάγετε νέες εικόνες. 

Επομένως, θα ήθελα να δω το διάγραμμα σε μια ευανάγνωστη, κατανοητή μορφή κειμένου που δεν θα απαιτούσε μεγάλη καμπύλη εκμάθησης. Και σε ορισμένα σημεία μπορείτε ακόμη και απλώς να κάνετε copy-paste για να επιταχύνετε την προσθήκη ενός νέου κυκλώματος. 

Και ένας άλλος συνάδελφος σημείωσε ότι ο κώδικας είναι, φυσικά, καλός, αλλά αν χρησιμοποιείτε δομή, όλα μπορεί να είναι πολύ αυστηρά και εκφραστικά.

Επομένως, προσπάθησα να φανταστώ το διάγραμμα ως ένα σύνολο πολλών μικρών συστοιχιών που περιγράφουν κόμβους, συνδέσεις, ομάδες κόμβων, καθώς και τη θέση των κόμβων. Αποδείχθηκε, κατά την ταπεινή μου γνώμη, αρκετά βολικό, αν και, φυσικά, η γεύση και το χρώμα...

Πώς είναι αυτό ένα γράφημα σε έναν πίνακα;

  • Κάθε κόμβος περιγράφεται από ένα αναγνωριστικό που προσδιορίζει μοναδικά τον κόμβο.
  • Μπορείτε επίσης να προσθέσετε ένα εικονίδιο στον κόμβο και να προσθέσετε μια επιγραφή.
  • Μπορείτε να καθορίσετε μια σχέση μεταξύ δύο κόμβων.
  • Για επικοινωνία στο διάγραμμα, μπορείτε να ορίσετε το χρώμα και την επιγραφή.
  • Η κατεύθυνση της επικοινωνίας ορίζεται από την πηγή στον στόχο. Και η πηγή και ο στόχος υποδεικνύονται με αναγνωριστικά κόμβων.
  • Ένας ή περισσότεροι κόμβοι μπορούν να προστεθούν σε μια ομάδα.
  • Η σχέση μπορεί επίσης να καθοριστεί τόσο από την ομάδα όσο και προς την ομάδα.

Χρησιμοποιώντας αυτούς τους απλούς κανόνες, έχουμε το ακόλουθο διάγραμμα. Μόλις? Αρκετά.

Διάγραμμα δικτύου ως κωδικός / Διάγραμμα δικτύου ως κωδικός

Και περιγράφεται από τον παρακάτω κώδικα js. Το κύριο πράγμα εδώ είναι το αντικείμενο των στοιχείων. Σε ποιους κόμβους υποδεικνύονται - κόμβοι, ακμές - συνδέσεις.
 

  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);

Φυσικά, δεν κατέληξα στο σχέδιο του κυκλώματος ο ίδιος, αλλά χρησιμοποίησα τη βιβλιοθήκη cytoscape.js είναι ένα πολύ ισχυρό εργαλείο οπτικοποίησης. Χρησιμοποιώ μόνο ένα κλάσμα των δυνατοτήτων στη λύση μου. 

Εντάξει, αυτό είναι ένα απλό παράδειγμα. Μπορεί να είναι πιο περίπλοκο;

Ναι παρακαλώ. Για να υποδείξουμε θέσεις, χρησιμοποιούμε θέσεις, για να υποδείξουμε ομάδες, υποδεικνύουμε μια λίστα ομάδων σε ομάδες και τα ίδια τα στοιχεία έχουν ένα χαρακτηριστικό ομάδας.

Διάγραμμα δικτύου ως κωδικός / Διάγραμμα δικτύου ως κωδικός

Και αυτός είναι ο κωδικός:

<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>

Από τη μία πλευρά, ένα τέτοιο σχήμα είναι σχεδόν μερικές οθόνες κώδικα σε φορητό υπολογιστή, από την άλλη πλευρά, η δομή a la json σάς επιτρέπει να συμπληρώνετε όλα τα δεδομένα κατ' αναλογία, γρήγορα και μπορείτε να κάνετε αντιγραφή-επικόλληση.

Γιατί οι θέσεις τοποθετούνται χωριστά από τους κόμβους;

Είναι πιο άνετο. Πρώτα καθορίζουμε τους κόμβους. Στη συνέχεια, μπορούμε να καθορίσουμε μερικές ομάδες και να τις υποδείξουμε σε κόμβους. Στη συνέχεια ορίζουμε τις συνδέσεις. Και μόνο τότε, όταν υπάρχουν τα κύρια αντικείμενα και οι συνδέσεις μεταξύ τους, παίρνουμε τη θέση αυτών των αντικειμένων στο διάγραμμα. Ή αντιστρόφως.

Γίνεται χωρίς θέσεις;

Γίνεται χωρίς θέσεις. Αλλά θα είναι λίγο τσαλακωμένο· μπορείτε να δείτε αυτήν την επιλογή στα παραδείγματα. Αυτό οφείλεται στο γεγονός ότι υπάρχει ένας αλγόριθμος για τη θέση των κόμβων για το cytoscape fcose, το οποίο λαμβάνει υπόψη και την παρουσία ομάδων. Ο καθορισμός θέσεων καθιστά το διάγραμμα πιο ελεγχόμενο, αλλά στο στάδιο του πρώτου σχεδίου του διαγράμματος είναι δυνατό χωρίς θέσεις.

Οι θέσεις μπορούν επίσης να καθοριστούν στο στυλ Θωρηκτού. Εκείνοι. ο ένας κόμβος βρίσκεται στο a1 και ο άλλος στο d5. Βοηθά ιδιαίτερα ότι το cytoscape κάνει τα αντικείμενα στον καμβά να κινούνται, π.χ. μπορούμε να τα μετακινήσουμε, να δούμε διαφορετικές επιλογές διάταξης και μετά να διορθώσουμε τη διάταξη των στοιχείων που μας αρέσουν στον κώδικα.

Σε γενικές γραμμές, είναι κατανοητό. Μπορείτε επίσης να δοκιμάσετε;
 
Φυσικά, για να δημιουργήσω γρήγορα κυκλώματα, έκανα τον εαυτό μου μικρό ο συντάκτης, το οποίο ενημερώνει το ίδιο το σχήμα και αποθηκεύει την πιο πρόσφατη έκδοση στο πρόγραμμα περιήγησης (στο localStorage).

Το έχεις δοκιμάσει? Τώρα μπορείτε να το προσθέσετε στη σελίδα σας.

Μετά πάλι:

1. Σύνδεση του σεναρίου

<script src="https://unpkg.com/@antirek/[email protected]/dist/code-full.min.js"></script>

2. Προσθήκη κώδικα σε 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. επεξεργαζόμαστε τον κώδικα στο διάγραμμα που χρειαζόμαστε (νομίζω ότι είναι πιο εύκολο από το να σχεδιάσουμε μια κουκουβάγια :)

Περισσότερες λεπτομέρειες στο σελίδα του έργου στο github.

Το αποτέλεσμα;

Πέτυχα τους στόχους μου - για να προσθέσω ενσωματωμένα διαγράμματα στην τεκμηρίωση, η μορφή είναι αρκετά απλή και κατανοητή. Δεν είναι κατάλληλο για σούπερ κυκλώματα, αλλά για μικρά κυκλώματα που εξηγούν τη δομή των συνδέσεων, είναι απολύτως εντάξει. Μπορείτε πάντα να τροποποιήσετε γρήγορα και να αλλάξετε κάτι με την πάροδο του χρόνου. Ναι, και οι συνάδελφοι μπορούν να διορθώσουν κάτι στην αποβάθρα οι ίδιοι, τουλάχιστον λεζάντες για αντικείμενα, χωρίς ειδική εκπαίδευση))

Τι μπορεί να βελτιωθεί;

Υπάρχουν, φυσικά, πολλές επιλογές εδώ. Προσθέστε επιπλέον εικονίδια (όλα τα υπάρχοντα προστίθενται ενσωματωμένα στο σενάριο). Επιλέξτε ένα πιο εκφραστικό σύνολο εικονιδίων. Δώστε τη δυνατότητα να καθορίσετε το στυλ της γραμμής σύνδεσης. Προσθέστε μια εικόνα φόντου.

Τι νομίζετε;
 
Έχω ήδη αρκετές ιδέες για εφαρμογή σε θέματα, μπορείτε να προσθέσετε και τις δικές σας στα σχόλια.

Η λύση μου είναι σίγουρα εφαρμόσιμη σε ένα στενό εύρος προβλημάτων και ίσως βρείτε ένα πιο βολικό εργαλείο για τη σχεδίαση διαγραμμάτων απλώς κωδικοποιώντας τα - όπως λένε "δείξε μου το διάγραμμά σου ως κώδικα"

  1. καλή επιλογή
  2. Εξαιρετική εξυπηρέτηση (9 τύποι διαδικτυακού επεξεργαστή γραφημάτων)
  3. Φυσικά, mermaid.js
  4. Και αν σας αρέσουν τα εξαιρετικά λεπτομερή και πολύπλοκα διαγράμματα, τότε σίγουρα θα θαυμάσετε αυτό το έργο: go.drawthe.net

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο