W ciągu ostatnich kilku lat bardziej skupiłem się na dokumentacji. Napisanie wyjaśniającego tekstu o tym, jak działa dany system, to w zasadzie dość proste. Naszkicowanie diagramu, na którym będą przedstawione wszystkie kluczowe obiekty i powiązania między nimi, również jest całkiem łatwe.
Jednak największym problemem jest utrzymanie tej dokumentacji w aktualnym stanie. I dobrze, że tekst, ale diagramy… Ponieważ cała dokumentacja jest online, czyli w formacie html, więc do tekstu dołączane są obrazy gif/jpeg/png, na których są przedstawione diagramy. A diagramy są rysowane w różnych programach, takich jak Visio lub w narzędziach online typu draw.io. Następnie eksportujesz diagram do formatu graficznego i dołączasz go do html. Wszystko proste.
Jaki jest problem?
Diagramy są zazwyczaj proste. Chociaż nie są zbyt skomplikowane. Tak, liczba obiektów to dziesiątki, liczba powiązań również w przybliżeniu tyle samo. Dodatkowo napisy, jakieś oznaczenia. Proste diagramy można opisać słowami, a zbyt skomplikowane, hm… (c) „nie zrozumieją-s”. Jest dużo diagramów, zmiany w nich muszą być wprowadzane okresowo-epizodycznie, czyli stale, ponieważ idą w parze z rozwojem naszych produktów.
Można przecież osadzać html serwisu. Próbowałeś?
Tak, oczywiście. Osobiście lubię grafiki z gliffy.com. Ale żeby wprowadzić zmiany, musisz iść do zewnętrznego serwisu i tam poprawiać. A trudniej jest zlecić poprawki koledze.
Co robić?
Ostatnio na githubie natknąłem się na polecany repozytorium . Diagram jako kod. To znaczy, opisujemy w js potrzebny nam diagram. Ten js piszemy bezpośrednio w tym samym html, w którym znajduje się pozostały tekst dokumentacji.
A tak przy okazji, ale nie piszę dokumentacji całkowicie w html. Zazwyczaj dokumentacja to zestaw plików z tekstem markdown, który następnie jest konwertowany na pełnoprawną stronę dokumentacji przez jakiś silnik, na przykład wintersmith. Lub system wiki.
To niezwykle wygodne: oto napisaliśmy tekst, następnie otwieramy tag script, a w nim opisany jest kod js diagramu.
Co znów jest nie tak?
To repozytorium mi się podoba, ale to nie jest jedyny przykład, kiedy diagram jest rysowany przy użyciu kodu lub tekstowego przedstawienia. (Na końcu artykułu będą linki do projektów i artykułów, które znalazłem na temat diagramu jako kod.)
I am not the only one editing the documentation. Sometimes my colleagues also contribute — correcting wording, changing descriptions, adding new images.
Therefore, I would like to see the diagram in a clear, understandable text format that doesn't require extensive training. In some places, you could even just copy-paste to speed up adding a new scheme.
Another colleague noted that while code is certainly good, using a structure can be much stricter and more expressive.
So I tried to represent the scheme as a set of several small arrays that describe nodes, connections, groups of nodes, and also the arrangement of nodes. In my humble opinion, it turned out to be quite convenient, although, of course, beauty is subjective.
How is this diagram represented in an array?
- Each node is described by an identifier that uniquely defines the node.
- You can also add an icon to the node and a label.
- You can specify a connection between two nodes.
- For the connection in the scheme, you can set a color and a label.
- The direction of the connection is determined from the source to the target. The source and target are specified by the node identifiers.
- One or more nodes can be added to a group.
- The connection can also be specified from a group to a group.
Using these simple rules, we get this scheme. Simple? Quite.

This is described by the following js code. The main part here is the elements object, which specifies nodes – the nodes, edges – the connections.
const elements = {
nodes: [ // describing the 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: [ // specifying the connections
{ source: 'client', target: 'server', label: 'request' },
{ source: 'server', target: 'db1', label: 'request' },
{ source: 'server', target: 'db2', label: 'request' },
],
};
Diagram('scheme1', elements);
Of course, I didn't come up with the diagram drawing myself; I used a library. — a very powerful visualization tool. I'm only using a fraction of its capabilities in my solution.
Of course, this is a simple example. Can we make it more complex?
Yes, please. To specify positions — we use positions, to specify groups — we list the groups in groups, and the elements themselves have the group attribute.

And here is the 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>
Ta schemat z jednej strony to prawie para ekranów kodu na laptopie, z drugiej struktura przypominająca json pozwala szybko wypełniać wszystkie dane w sposób analogiczny, można również kopiować i wklejać.
A dlaczego pozycje są oddzielone od węzłów?
Jest to wygodniejsze. Najpierw wskazujemy węzły. Następnie możemy wskazać kilka grup i podać je w węzłach. Potem określamy relacje. Dopiero później, gdy podstawowe obiekty i relacje między nimi są ustalone, przystępujemy do rozmieszczenia tych obiektów na schemacie. Lub odwrotnie.
Czy można obyć się bez pozycji?
Można i bez pozycji. Ale będzie to trochę chaotyczne, można zobaczyć taki wariant w przykładach. Jest to spowodowane tym, że dla cytoscape istnieje algorytm rozmieszczania węzłów. , który również uwzględnia istnienie grup. Wskazanie pozycji czyni schemat bardziej kontrolowanym, ale na etapie pierwszego szkicu schematu można się obejść bez pozycji.
Można także podać pozycje w stylu Gry Wojnę. Tzn. jeden węzeł jest umieszczany w a1, a inny w d5. Szczególnie pomocne jest to, że cytoscape tworzy obiekty na canvasie dynamicznie, tzn. możemy je przestawiać, zobaczyć różne układy, a następnie zablokować w kodzie preferowane rozmieszczenie elementów.
W sumie, rozumiem. Możemy spróbować?
Oczywiście, w celu szybkiego tworzenia schematów stworzyłem sobie niewielki , który sam aktualizuje schemat i w przeglądarce przechowuje ostatnią wersję (w localStorage).
Spróbowaliście? Teraz można dodać to do swojej strony.
W takim razie jeszcze raz:
1. Podłączamy skrypt
<script src="https://unpkg.com/@antirek/network-diagram@0.1.4/dist/code-full.min.js"></script>
2. Dodajemy do kodu 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. poprawiamy kod do potrzebnej nam schemy (myślę, że to prostsze niż narysowanie sowy 🙂
Jeszcze bardziej szczegółowo na na githubie.
Co z tego wynika?
Osiągnąłem swoje cele — wprowadzenie schematów inline w dokumentacji, format jest wystarczająco prosty i zrozumiały. Nie nadaje się do super schematów, ale dla małych schematów, które wyjaśniają strukturę relacji — bardzo dobrze. Zawsze można szybko poprawić coś i zmienić z biegiem czasu. Tak, i koledzy mogą sami coś poprawić w dokumencie, przynajmniej podpisy do obiektów bez specjalnego szkolenia))
Co można poprawić?
Jest tu oczywiście wiele możliwości. Dodać możliwość wstawiania dodatkowych ikon (wszystkie dostępne są dodane inline w skrypcie). Wybrać bardziej wyrazisty zestaw ikon. Zrealizować możliwość określenia stylu linii połączeń. Dodać tło.
A co wy o tym myślicie?
Już mam kilka pomysłów na realizację w issues, proszę, dodaj swoje w komentarzach.
Moje rozwiązanie definitywnie nadaje się do wąskiego zakresu zadań, a może znajdziesz bardziej wygodne narzędzie do rysowania diagramów, po prostu kodując je — jak mówi przysłowie: 'pokaż mi swój diagram w postaci kodu'
- (9 typów wykresów edytora online)
- A jeśli lubisz super szczegółowe i skomplikowane schematy — to ten projekt na pewno Cię zachwyci:
Źródło: habr.com
