In de afgelopen paar jaar ben ik meer bezig geweest met documentatie. Het schrijven van een uitleg over hoe een bepaald systeem werkt is over het algemeen vrij eenvoudig. Een diagram tekenen dat alle belangrijke objecten en de relaties tussen deze objecten weergeeft, is ook vrij gemakkelijk.
Maar het grootste probleem is om deze documentatie actueel te houden. En laat het nog gaan om de tekst, maar de diagrammen... Omdat alle documentatie online is, dus in HTML-formaat, worden de teksten vergezeld door gif/jpeg/png-afbeeldingen waarop de diagrammen zijn afgebeeld. Deze diagrammen worden getekend in verschillende programma's zoals Visio of online diensten zoals draw.io. Vervolgens exporteer je de diagram naar een grafisch formaat en voeg je deze toe aan de HTML. Heel eenvoudig.
Wat is het probleem?
De diagrammen zijn meestal eenvoudig. Om precies te zijn, niet bijzonder complex. Ja, het aantal objecten is een tiental of twee, en het aantal relaties ongeveer hetzelfde. Plus de labels en bepaalde aanduidingen. Eenvoudige diagrammen kunnen zelfs met woorden beschreven worden, maar te complexe, tja… (c) 'ze begrijpen het niet'. Er zijn veel diagrammen, en veranderingen daarin moeten regelmatig worden aangebracht, dat wil zeggen constant, omdat ze volgen op de ontwikkeling van onze producten.
Je kunt de HTML-service integreren. Heb je dat geprobeerd?
Ja, natuurlijk. Persoonlijk vind ik de grafieken van gliffy.com leuk. Maar voor wijzigingen moet je naar een externe service gaan om het daar aan te passen. En het is lastiger om een collega de aanpassingen te laten doen.
Wat te doen?
Onlangs kwam ik op GitHub een aanbeveling tegen voor een repository. . Diagram als code. Dat wil zeggen, we beschrijven de benodigde diagram in JS. Deze JS schrijven we direct in dezelfde HTML waar de rest van de documentatietekst staat.
Trouwens, ik schrijf documentatie niet helemaal in HTML. Meestal is documentatie een verzameling bestanden met markdown-tekst, die vervolgens wordt geconverteerd naar een volwaardige documentatiesite met behulp van een of andere engine, zoals wintersmith. Of een wiki-systeem.
Het is erg handig: we hebben de tekst geschreven, dan opent het script-tag en daarin is de JS-code van de diagram beschreven.
Wat is er weer niet goed?
Deze repository vond ik leuk, maar dit is niet het enige voorbeeld waarbij diagrammen worden gemaakt met behulp van code of tekstuele weergave. (Aan het einde van het artikel zullen links naar projecten en artikelen die ik over het onderwerp diagram als code heb gevonden, worden gegeven.)
En ik ben niet de enige die de documentatie bewerkt. Soms dragen ook collega's hun steentje bij - een woord corrigeren, een beschrijving wijzigen, nieuwe afbeeldingen invoegen.
Daarom zou ik graag de diagram in een leesbaar en begrijpelijk tekstformaat willen zien, dat niet veel training vereist. Op sommige plaatsen kan het zelfs gewoon copy-paste zijn om de toevoeging van nieuwe schema's te versnellen.
Een andere collega merkte op dat code natuurlijk goed is, maar als je de structuur gebruikt, kan alles heel strikt en expressief zijn.
Daarom heb ik geprobeerd het schema voor te stellen als een set van verschillende kleine arrays die de knooppunten, verbindingen, knooppuntgroepen en de locatie van de knooppunten beschrijven. Het is naar mijn bescheiden mening vrij handig gelukt, hoewel smaken verschillen...
Hoe ziet dit schema in een array eruit?
- Elk knooppunt wordt beschreven door een identificator die het knooppunt ondubbelzinnig identificeert.
- Je kunt ook een pictogram aan het knooppunt toevoegen of een label toevoegen.
- Tussen twee knooppunten kan een verbinding worden aangegeven.
- Voor de verbinding in het schema kun je een kleur en een label opgeven.
- De richting van de verbinding wordt gedefinieerd van de bron naar het doel. De bron en het doel worden aangegeven met de identificatoren van de knooppunten.
- Eén of meer knooppunten kunnen aan een groep worden toegevoegd.
- De verbinding kan ook van en naar een groep worden aangegeven.
Met deze eenvoudige regels ontstaat het volgende schema. Eenvoudig? Absoluut.

Dit wordt beschreven door de volgende js-code. Het belangrijkste hier is het object elements. Daarin worden de nodes – knooppunten, en edges – verbindingen aangegeven.
const elements = {
nodes: [ // beschrijf de knooppunten
{ id: 'client', type: 'smartphone', label: 'Mobiele App'},
{ id: 'server', type: 'server', label: 'Hoofdsysteem'},
{ id: 'db1', type: 'database', label: 'DB 1'},
{ id: 'db2', type: 'database', label: 'DB 2'},
],
edges: [ // geef de verbindingen aan
{ source: 'client', target: 'server', label: 'verzoek' },
{ source: 'server', target: 'db1', label: 'verzoek' },
{ source: 'server', target: 'db2', label: 'verzoek' },
],
};
Diagram('scheme1', elements);
Natuurlijk heb ik de tekening van het schema niet zelf bedacht, maar gebruik de bibliotheek — een zeer krachtige visualisatietool. Van de mogelijkheden gebruik ik er maar een klein gedeelte in mijn oplossing.
Dat is duidelijk, dit is een eenvoudig voorbeeld. Kunnen we het moeilijker maken?
Ja, graag. Voor het opgeven van posities gebruiken we positions, voor het opgeven van groepen geven we een lijst van groepen in groups op, en bij de elementen zelf gebruiken we het attribuut group.

En dit is de 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>
Dit schema aan de ene kant is bijna een paar schermen code op een laptop, aan de andere kant stelt de json-achtige structuur me in staat om alle gegevens op dezelfde manier in te vullen, snel en met copy-paste.
Waarom zijn de positions apart van de knooppunten opgenomen?
Dit is handiger. Eerst geven we de nodes op. Vervolgens kunnen we een paar groepen opgeven en deze in de nodes plaatsen. Daarna duiden we de verbindingen aan. Pas als de hoofdobjecten en hun verbindingen zijn aangegeven, gaan we het hebben over de plaatsing van deze objecten op de diagram. Of omgekeerd.
En is het mogelijk zonder positions?
Het kan ook zonder positions. Maar het zal een beetje rommelig zijn, je kunt zo'n variant in de voorbeelden bekijken. Dit komt doordat er voor Cytoscape een plaatsingsalgoritme bestaat. , dat ook rekening houdt met de aanwezigheid van groepen. Het opgeven van positions maakt het diagram beter beheersbaar, maar in de fase van de eerste schets van het diagram kan dat ook zonder positions.
Je kunt positions ook aangeven in de stijl van Battleship. Dat wil zeggen, één node bevindt zich op a1, en de andere op d5. Het helpt ook dat Cytoscape objecten op het canvas beweeglijk maakt, dus we kunnen ze verplaatsen, verschillende opmaakvarianten bekijken en vervolgens de gewenste plaatsing in de code vastleggen.
In het algemeen is het duidelijk. Kunnen we het proberen?
Zeker, voor het snel creëren van diagrammen heb ik voor mezelf een kleine , die de diagram automatisch bijwerkt en in de browser de laatste versie opslaat (in localStorage).
Heb je het geprobeerd? Je kunt het nu ook op je eigen pagina toevoegen.
Dan nogmaals:
1. We verbinden het script
<script src="https://unpkg.com/@antirek/network-diagram@0.1.4/dist/code-full.min.js"></script>
2. We voegen toe aan de HTML-code
<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. we passen de code aan naar het gewenste diagram (ik denk dat dit eenvoudiger is dan een uil tekenen 🙂
Meer details op op GitHub.
Wat is het resultaat?
Ik heb mijn doelen bereikt - het toevoegen van diagrammen inline in de documentatie, het formaat is eenvoudig en duidelijk genoeg. Voor superdiagrammen is het misschien niet geschikt, maar voor kleine diagrammen die de structuur van verbindingen uitleggen, is het heel goed. Het kan altijd snel worden aangepast en iets kan in de loop van de tijd worden veranderd. Ja, en collega's kunnen zelf iets in de documentatie aanpassen, minimaal de labels voor de objecten zonder veel opleiding.))
Wat kan worden verbeterd?
Hier zijn natuurlijk talloze opties. Het toevoegen van extra iconen (alle bestaande zijn inline in het script toegevoegd). Een meer expressieve set iconen kiezen. De mogelijkheid om de stijl van de verbindingslijnen aan te geven. Een achtergrondafbeelding toevoegen.
Wat denken jullie?
Ik heb al een paar ideeën in de issues staan, voeg gerust je eigen ideeën toe in de opmerkingen.
Mijn oplossing is zeker toepasbaar in een smalle reeks taken, en misschien vind je een handigere tool voor het tekenen van diagrammen door ze gewoon te coderen - zoals het gezegde luidt: 'show me your diagram as code'
- (9 soorten grafieken online-editor)
- En als je super gedetailleerde en complexe diagrammen waardeert, dan zal dit project je zeker imponeren:
Bron: habr.com
