Under de senaste åren har jag blivit mer involverad i dokumentation. Att skriva en förklarande text om hur ett visst system fungerar är överlag ganska enkelt. Att rita en diagram som visar alla nyckelobjekt och relationer mellan dessa objekt är också relativt lätt.
Men den största utmaningen är att hålla denna dokumentation uppdaterad. Det skulle vara okej om det bara var texten, men diagrammen... Eftersom all dokumentation är online, det vill säga i html-format, så medföljer bilder i gif/jpeg/png-format som faktiskt visar diagrammen. Dessa diagram ritas i olika program som Visio eller online-tjänster som draw.io. Därefter exporterar man diagrammet i ett grafiskt format och fäster det i html. Allt är enkelt.
Vad är problemet?
Diagrammen är vanligtvis enkla. Mer exakt, inte särskilt svåra. Ja, antal objekt är ett tiotal, antalet relationer är ungefär lika många. Plus etiketter och några symboler. Enkla diagram kan även beskrivas med ord, men alltför komplexa, ehm... (c) "kommer inte att förstå-s". Det finns många diagram, och förändringar måste göras periodiskt, det vill säga ständigt, eftersom de följer utvecklingen av våra produkter.
Man kan integrera html-tjänster. Har du försökt?
Ja, självklart. Jag gillar till exempel grafikerna från gliffy.com. Men för att göra ändringar måste man gå till en extern tjänst och ändra där. Det är också svårare att delegera ändringar till en kollega.
Vad göra?
Häromdagen snubblade jag över ett repository på GitHub som rekommenderades för mig. . Diagram som kod. Det vill säga, vi beskriver det javascript som vi behöver för vårt diagram. Denna javascript skriver vi direkt i samma html där övrig dokumentation finns.
För att nämna, jag skriver dokumentation inte helt i html. Vanligtvis är dokumentationen en uppsättning filer med markdown-text som sedan konverteras till en fullständig dokumentationswebbplats av någon motor, till exempel wintersmith. Eller ett wikisystem.
Det blir mycket bekvämt: vi skriver text, och sedan öppnas script-taggen där js-koden för diagrammet är beskriven.
Vad är nu problemet?
Detta repository gillade jag, men det är inte det enda exemplet där man ritar diagram med hjälp av kod eller textuella representationer. (I slutet av artikeln kommer det att finnas länkar till projekt och artiklar som jag har hittat om diagram som kod.)
Och jag är inte ensam om att rätta dokumentationen. Ibland bidrar kollegor med sina insatser — genom att rätta ord, ändra beskrivningar eller införa nya bilder.
Därför skulle jag vilja se diagrammet i ett läsbart och förståeligt textformat som inte kräver lång inlärning. Ibland kan det även vara bra att helt enkelt kopiera och klistra in för att snabba upp tillägg av nya scheman.
En annan kollega påpekade att kod är bra, men om man använder en struktur, kan allt bli mycket strikt och uttrycksfullt.
Därför försökte jag föreställa mig schemat som en uppsättning små arrayer som beskriver noder, kopplingar, grupper av noder och även placeringen av noder. Det blev enligt min blygsamma åsikt ganska praktiskt, även om smaken är som baken.
Hur ser diagrammet ut i en array?
- Varje nod beskrivs med ett identifieringsnummer som entydigt definierar noden.
- Man kan också lägga till en ikon till noden samt ett label.
- Mellan två noder kan man ange en koppling.
- För kopplingen i schemat kan man ange färg och label.
- Kopplingens riktning definieras som från källa till mål. Källa och mål anges med nodernas identifierare.
- En eller flera noder kan läggas till i en grupp.
- Kopplingen kan också anges från gruppen och till gruppen.
Genom att använda dessa enkla regler får man ett sådant schema. Enkelt? Absolut.

Det beskrivs med följande js-kod. Det viktigaste här är objektet elements. Där noderna anger nodes och kopplingarna edges.
const elements = {
nodes: [ // beskriver noder
{ id: 'client', type: 'smartphone', label: 'Mobilapp'},
{ id: 'server', type: 'server', label: 'Huvudserver'},
{ id: 'db1', type: 'database', label: 'DB 1'},
{ id: 'db2', type: 'database', label: 'DB 2'},
],
edges: [ // anger kopplingar
{ source: 'client', target: 'server', label: 'begäran' },
{ source: 'server', target: 'db1', label: 'begäran' },
{ source: 'server', target: 'db2', label: 'begäran' },
],
};
Diagram('scheme1', elements);
Naturligtvis uppfann jag inte själva ritningen av schemat själv, utan använde ett bibliotek. — ett mycket kraftfullt visualiseringsverktyg. Jag använder endast en bråkdel av dess möjligheter i min lösning.
Självklart, det här är ett enkelt exempel. Kan vi göra det lite mer komplicerat?
Ja, självklart. För att ange positioner använder vi positions, för att ange grupper anger vi en lista över grupper i groups, och för själva elementen har vi attributet group.

Och här är koden:
<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>
Ett sådant schema från ena sidan är nästan ett par skärmar kod på en bärbar dator, å andra sidan gör strukturen liknande json det möjligt att fylla i alla data på analogt sätt, snabbt och går att kopiera och klistra in.
Och varför är positions separerade från noderna?
Det är enklare. Först anger vi noder. Sedan kan vi ange ett par grupper och ange dem i noderna. Därefter markerar vi relationerna. Och först när de grundläggande objekten och relationerna mellan dem finns, sätter vi oss ner för att placera dessa objekt på diagrammet. Eller tvärtom.
Kan man göra utan positions?
Ja, man kan göra utan positions. Men det blir lite klumpigt, i exemplen kan man se ett sådant alternativ. Detta beror på att det finns en algoritm för att placera noder i cytoscape. , som också tar hänsyn till grupper. Angivande av positions gör diagrammet mer kontrollerat, men i det första utkastet av diagrammet kan man klara sig utan positions.
Positions kan också anges i stil med Sjöslag. Dvs. en nod placeras i a1, och en annan i d5. Speciellt hjälpsamt är att cytoscape formar objekt på canvasen som är flyttbara, dvs. vi kan flytta dem, se olika placeringsalternativ och sedan fixa det vi gillar i koden.
Överlag, förstått. Kan vi försöka?
Självklart, för att snabbt skapa diagram har jag gjort mig en liten , som själv uppdaterar diagrammet och sparar den senaste versionen i webbläsaren (i localStorage).
Har ni provat? Nu kan ni också lägga till det på er egen sida.
Då en gång till:
1. Anslut skriptet
<script src="https://unpkg.com/@antirek/network-diagram@0.1.4/dist/code-full.min.js"><\/script>
2. Lägg till i html-koden
<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. justera koden till det diagram vi vill ha (jag tror att det är enklare än att rita en uggla 🙂
Ännu mer detaljerat på på GitHub.
Vad blir resultatet?
Mina mål har jag uppnått - att göra det enkelt att lägga till diagram inline i dokumentationen, formatet är tillräckligt enkelt och begripligt. Det passar inte för superdiagram, men för små diagram som förklarar strukturera relationer - är det helt okej. Man kan snabbt justera och något ändras över tid. Ja, och kollegor kan själva rätta till något i dokumentet, åtminstone rubriker till objekten utan särskild utbildning :)
Vad kan förbättras?
Det finns naturligtvis många alternativ. Göra tillägg av ytterligare ikoner (alla befintliga är tillagda inline i skriptet). Välja en mer uttrycksfull uppsättning ikoner. Göra det möjligt att ange stil för relationernas linjer. Lägga till en bakgrundsbild.
Vad tycker ni?
Jag har redan några idéer för genomförande i issues, ni kan också lägga till era egna i kommentarerna.
Min lösning är definitivt tillämplig inom ett smalt spektrum av uppgifter, och du kanske hittar ett mer praktiskt verktyg för att rita diagram genom att helt enkelt koda dem — som man säger 'show me your diagram as code'
- (9 typer av diagram online-redigerare)
- Och om du älskar super detaljerade och komplexa scheman — så kommer definitivt detta projekt att imponera på dig:
Källa: habr.com
