Network diagram as code / Π‘Ρ…Π΅ΠΌΠ° сСти ΠΊΠ°ΠΊ ΠΊΠΎΠ΄

Π’ послСдниС ΠΏΠ°Ρ€Ρƒ Π»Π΅Ρ‚ стал большС Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒΡΡ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠ΅ΠΉ. ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠΎΡΡΠ½ΡΡŽΡ‰ΠΈΠΉ тСкст ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π° ΠΈΠ»ΠΈ иная систСма β€” Π² Ρ†Π΅Π»ΠΎΠΌ, это достаточно просто. ΠΠ°Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ схСму, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Ρ‹ всС ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, связи ΠΌΠ΅ΠΆΠ΄Ρƒ этими ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, Ρ‚ΠΎΠΆΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ Π»Π΅Π³ΠΊΠΎ.

Но самый ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ β€” это ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ эту Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ Π² Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΌ состоянии. И Π»Π°Π΄Π½ΠΎ Π±Ρ‹ тСкст, Π½ΠΎ схСмы… Π’.ΠΊ. вся докумСнтация ΠΎΠ½Π»Π°ΠΉΠ½, Ρ‚.Π΅. Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ html, Ρ‚ΠΎ ΠΊ тСксту ΠΏΡ€ΠΈΠ»Π°Π³Π°ΡŽΡ‚ΡΡ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ gif/jpeg/png, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… собствСнно ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Ρ‹ схСмы. А схСмы Ρ€ΠΈΡΡƒΡŽΡ‚ΡΡ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… Ρ‚ΠΈΠΏΠ° Visio ΠΈΠ»ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½-сСрвисах Π°-ля draw.io. Π—Π°Ρ‚Π΅ΠΌ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΡˆΡŒ схСму Π² графичСский Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π°Π΅ΡˆΡŒ ΠΊ html. ВсС просто.

Π’ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°?

Π‘Ρ…Π΅ΠΌΡ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ простыС. Π’ΠΎΡ‡Π½Π΅Π΅, Π½Π΅ сильно слоТныС. Π”Π°, количСство ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² дСсяток-Π΄Π²Π°, количСство связСй ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΆΠ΅. Плюс подписи, ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ обозначСния. ΠŸΡ€ΠΎΡΡ‚Ρ‹Π΅ схСмы ΠΈ Π½Π° словах ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΌΠΎΠΆΠ½ΠΎ, Π° слишком слоТныС, ΠΊΡ…-м… (с) Β«Π½Π΅ ΠΏΠΎΠΉΠΌΡƒΡ‚-с». Π‘Ρ…Π΅ΠΌ ΠΌΠ½ΠΎΠ³ΠΎ, измСнСния Π² Π½ΠΈΡ… Π½ΡƒΠΆΠ½ΠΎ Π²Π½ΠΎΡΠΈΡ‚ΡŒ пСриодичСски-эпизодичСски, Ρ‚.Π΅. постоянно, Ρ‚.ΠΊ. ΠΎΠ½ΠΈ ΠΈΠ΄ΡƒΡ‚ вслСд Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ Π½Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ².

МоТно ΠΆΠ΅ Π²ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ html сСрвиса. ΠŸΡ€ΠΎΠ±ΠΎΠ²Π°Π»?

Π”Π°, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ. МнС, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, нравятся Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ gliffy.com. Но для ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π°Π΄ΠΎ ΠΈΠ΄Ρ‚ΠΈ Π² сторонний сСрвис, Ρ‚Π°ΠΌ ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ. И слоТнСС Π΄Π΅Π»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΠΎΠΏΡ€Π°Π²ΠΊΠΈ ΠΊΠΎΠ»Π»Π΅Π³Π΅.

Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ?

НСдавно Π½Π° Π³ΠΈΡ‚Ρ…Π°Π±Π΅ ΠΌΠ½Π΅ попался Π² рСкомСндациях Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ github.com/RaoulMeyer/diagram-as-code. Π”ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° ΠΊΠ°ΠΊ ΠΊΠΎΠ΄. Π’.Π΅. ΠΌΡ‹ описываСм Π½Π° js Π½ΡƒΠΆΠ½ΡƒΡŽ Π½Π°ΠΌ схСму. Π­Ρ‚ΠΎΡ‚ js ΠΌΡ‹ пишСм прямо Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ html, Π³Π΄Π΅ ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠΉ тСкст Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.

К слову ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Π½ΠΎ я ΠΏΠΈΡˆΡƒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ Π½Π΅ совсСм Π² html. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ докумСнтация β€” это Π½Π°Π±ΠΎΡ€ Ρ„Π°ΠΉΠ»ΠΎΠ² с markdown-тСкстом, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Ρ‚Π΅ΠΌ конвСртируСтся Π² ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ сайт Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΊΠ°ΠΊΠΈΠΌ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Π²ΠΈΠΆΠΊΠΎΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ wintersmith. Или wiki-систСма.

ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ΡΡ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ΄ΠΎΠ±Π½ΠΎ: Π²ΠΎΡ‚ ΠΌΡ‹ написали тСкст, Π·Π°Ρ‚Π΅ΠΌ открываСтся Ρ‚Π΅Π³ script ΠΈ Π² Π½Π΅ΠΌ описан js ΠΊΠΎΠ΄ схСмы.

Π§Ρ‚ΠΎ ΠΎΠΏΡΡ‚ΡŒ Π½Π΅ Ρ‚Π°ΠΊ?

Π­Ρ‚ΠΎΡ‚ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ ΠΌΠ½Π΅ понравился, Π½ΠΎ это Π½Π΅ СдинствСнный ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ³Π΄Π° Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡƒ Ρ€ΠΈΡΡƒΡŽΡ‚ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠ΄Π° ΠΈΠ»ΠΈ тСкстового прСдставлСния. (Π’ ΠΊΠΎΠ½Ρ†Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ссылки ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ статСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π°Π³ΡƒΠ³Π»ΠΈΠ» ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅ diagram as code.)

И вСдь я Π½Π΅ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€Π°Π²Π»ΡŽ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ. Иногда свою Π»Π΅ΠΏΡ‚Ρƒ вносят ΠΈ ΠΊΠΎΠ»Π»Π΅Π³ΠΈ β€” слово ΠΏΠΎΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ, описаниС ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ, Π½ΠΎΠ²Ρ‹Π΅ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ Π²ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ.Β 

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡƒ Π²ΠΈΠ΄Π΅Ρ‚ΡŒ Π² Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΌ понятном тСкстовом Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π±Ρ‹ Π½Π΅ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π΄ΠΎΠ»Π³ΠΎ ΠΎΠ±ΡƒΡ‡Π°Ρ‚ΡŒΡΡ. А мСстами Π΄Π°ΠΆΠ΅ просто copy-paste ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ для ускорСния добавлСния Π½ΠΎΠ²ΠΎΠΉ схСмы.Β 

А Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ»Π»Π΅Π³Π° Π·Π°ΠΌΠ΅Ρ‚ΠΈΠ», Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ΄ это, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρ…ΠΎΡ€ΠΎΡˆΠΎ, Π½ΠΎ Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ структуру, всС ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ строго ΠΈ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ.

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Π» ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ схСму ΠΊΠ°ΠΊ Π½Π°Π±ΠΎΡ€ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ ΡƒΠ·Π»Ρ‹, связи, Π³Ρ€ΡƒΠΏΠΏΡ‹ ΡƒΠ·Π»ΠΎΠ², Π° Ρ‚Π°ΠΊΠΆΠ΅ располоТСниС ΡƒΠ·Π»ΠΎΠ². ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ Π½Π° ΠΌΠΎΠΉ скромный взгляд достаточно ΡƒΠ΄ΠΎΠ±Π½ΠΎ, хотя, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½Π° вкус ΠΈ цвСт…

Как это Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° Π² массивС?

  • ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠ·Π΅Π» описываСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ опрСдСляСт ΡƒΠ·Π΅Π».
  • Π’Π°ΠΊΠΆΠ΅ ΠΊ ΡƒΠ·Π»Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΈΠΊΠΎΠ½ΠΊΡƒ, Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ надпись.
  • ΠœΠ΅ΠΆΠ΄Ρƒ двумя ΡƒΠ·Π»Π°ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ связь.
  • Для связи Π½Π° схСмС ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ Ρ†Π²Π΅Ρ‚, надпись.
  • НаправлСниС связи опрСдСляСтся ΠΊΠ°ΠΊ ΠΎΡ‚ источника ΠΊ Ρ†Π΅Π»ΠΈ. А источник ΠΈ Ρ†Π΅Π»ΡŒ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌΠΈ ΡƒΠ·Π»Π°.
  • Один ΠΈ Π±ΠΎΠ»Π΅Π΅ ΡƒΠ·Π»ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ.
  • Бвязь Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚ Π³Ρ€ΡƒΠΏΠΏΡ‹, ΠΈ ΠΊ Π³Ρ€ΡƒΠΏΠΏΠ΅.

ΠŸΠΎΠ»ΡŒΠ·ΡƒΡΡΡŒ этими простыми ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌΠΈ получаСтся Π²ΠΎΡ‚ такая схСма. ΠŸΡ€ΠΎΡΡ‚ΠΎ? Π’ΠΏΠΎΠ»Π½Π΅.

Network diagram as code / Π‘Ρ…Π΅ΠΌΠ° сСти ΠΊΠ°ΠΊ ΠΊΠΎΠ΄

А описываСтся ΠΎΠ½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ js-ΠΊΠΎΠ΄ΠΎΠΌ. ОсновноС здСсь β€” это ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ elements. Π’ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΡƒΠΊΠ°Π·Π°Π½Ρ‹ nodes β€” ΡƒΠ·Π»Ρ‹, edges β€” связи.
Β 

  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 β€” ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. Π’ΠΎΠ»ΠΈΠΊΡƒ возмоТностСй ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π² своСм Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ лишь.Β 

ΠŸΠΎΠ½ΡΡ‚Π½ΠΎ, это простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€. МоТно послоТнСС?

Π”Π°, поТалуйста. Для указания ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ β€” ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ positions, для указания Π³Ρ€ΡƒΠΏΠΏ β€” ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ список Π³Ρ€ΡƒΠΏΠΏ Π² groups, Π° Ρƒ самих элСмСнтов Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ group.

Network diagram as 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>

Вакая схСма с ΠΎΠ΄Π½ΠΎΠΉ стороны β€” это ΠΏΠΎΡ‡Ρ‚ΠΈ ΠΏΠ°Ρ€Π° экранов ΠΊΠΎΠ΄Π° Π½Π° Π½ΠΎΡƒΡ‚Π΅, с Π΄Ρ€ΡƒΠ³ΠΎΠΉ структура Π°-ля json позволяСт Π·Π°ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ всС Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ, быстро ΠΈ ΠΌΠΎΠΆΠ½ΠΎ copy-paste.

А ΠΏΠΎΡ‡Π΅ΠΌΡƒ positions вынСсСны ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚ ΡƒΠ·Π»ΠΎΠ²?

Π’Π°ΠΊ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ nodes. Π—Π°Ρ‚Π΅ΠΌ ΠΌΠΎΠΆΠ΅ΠΌ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Ρƒ-Ρ‚Ρ€ΠΎΠΉΠΊΡƒ Π³Ρ€ΡƒΠΏΠΏ ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈΡ… Π² ΡƒΠ·Π»Π°Ρ…. Π—Π°Ρ‚Π΅ΠΌ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°Π΅ΠΌ связи. А ΡƒΠΆ Π·Π°Ρ‚Π΅ΠΌ, ΠΊΠΎΠ³Π΄Π° основныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ связи ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Π΅ΡΡ‚ΡŒ, бСрСмся Π·Π° располоТСниС этих ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π½Π° схСмС. Или Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚.

А моТно бСз positions?

МоТно ΠΈ Π±Π΅Π· positions. Но это Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ скомкано, Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚. Π­Ρ‚ΠΎ обусловлСно Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ для cytoscape Π΅ΡΡ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ располоТСния ΡƒΠ·Π»ΠΎΠ² fcose, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π³Ρ€ΡƒΠΏΠΏ. Π£ΠΊΠ°Π·Π°Π½ΠΈΠ΅ positions Π΄Π΅Π»Π°Π΅Ρ‚ схСму Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ, Π½ΠΎ Π½Π° стадии ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ наброска схСмы ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Π±Π΅Π· positions.

Π’Π°ΠΊΠΆΠ΅ positions ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π² стилС ΠœΠΎΡ€ΡΠΊΠΎΠ³ΠΎ боя. Π’.Π΅. ΠΎΠ΄ΠΈΠ½ ΡƒΠ·Π΅Π» располагаСтся Π² a1, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π² d5. ОсобСнно ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ cytoscape Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π° canvas ΠΏΠΎΠ΄Π²ΠΈΠΆΠ½Ρ‹ΠΌΠΈ, Ρ‚.Π΅. ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡ… ΠΏΠΎΠ΄Π²ΠΈΠ³Π°Ρ‚ΡŒ, ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ располоТСния, Π° Π·Π°Ρ‚Π΅ΠΌ Π·Π°Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΊΠΎΠ΄Π΅ ΠΏΠΎΠ½Ρ€Π°Π²ΠΈΠ²ΡˆΠ΅Π΅ΡΡ располоТСниС элСмСнтов.

Π’ Ρ†Π΅Π»ΠΎΠΌ, понятно. МоТно ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ?
Β 
ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, для быстрого создания схСм сдСлал сСбС нСбольшой Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сам обновляСт схСму ΠΈ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ послСдний Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ (Π² 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. ΠΏΡ€Π°Π²ΠΈΠΌ ΠΊΠΎΠ΄ Π΄ΠΎ Π½ΡƒΠΆΠ½ΠΎΠΉ Π½Π°ΠΌ схСмы (Π΄ΡƒΠΌΠ°ΡŽ, это ΠΏΡ€ΠΎΡ‰Π΅ Ρ‡Π΅ΠΌ Π½Π°Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ сову πŸ™‚

Π•Ρ‰Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π½Π° страницС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π½Π° Π³ΠΈΡ‚Ρ…Π°Π±Π΅.

Π§Ρ‚ΠΎ Π² ΠΈΡ‚ΠΎΠ³Π΅?

Π‘Π²ΠΎΠΈΡ… Ρ†Π΅Π»Π΅ΠΉ я достиг β€” ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ схСм inline Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ, Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ достаточно простой ΠΈ понятный. Для супСрсхСм Π½Π΅ ΠΏΠΎΠ΄ΠΎΠΉΠ΄Π΅Ρ‚, Π° для Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… схСм, ΠΏΠΎΡΡΠ½ΡΡŽΡ‰ΠΈΡ… структуру связСй β€” ΠΎΡ‡Π΅Π½ΡŒ Π΄Π°ΠΆΠ΅ Π½ΠΈΡ‡Π΅Π³ΠΎ. ВсСгда ΠΌΠΎΠΆΠ½ΠΎ быстро ΠΏΠΎΠ΄ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΈ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ с Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΏΠΎΠΌΠ΅Π½ΡΡ‚ΡŒ. Π”Π°, ΠΈ ΠΊΠΎΠ»Π»Π΅Π³ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π² Π΄ΠΎΠΊΠ΅ сами Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ подписи ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ Π±Π΅Π· особого обучСния ))

Π§Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ?

Π’ΡƒΡ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ², ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, масса. Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠΊΠΎΠ½ΠΎΠΊ (всС ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ΡΡ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ inline Π² скрипт). ΠŸΠΎΠ΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ ΠΈΠΊΠΎΠ½ΠΎΠΊ. Π‘Π΄Π΅Π»Π°Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ указания стиля Π»ΠΈΠ½ΠΈΠΈ связСй. Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅.

А Ρ‡Ρ‚ΠΎ Π΄ΡƒΠΌΠ°Π΅Ρ‚Π΅ Π²Ρ‹?
Β 
Π£ мСня ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ нСсколько ΠΈΠ΄Π΅ΠΉ Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π² issues, Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ свои Π² ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ.

МоС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠΎ Π² ΡƒΠ·ΠΊΠΎΠΌ спСктрС Π·Π°Π΄Π°Ρ‡, ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ инструмСнт для рисования Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌ, просто Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π² ΠΈΡ… β€” ΠΊΠ°ΠΊ говорится ‘show me your diagram as code’

  1. Π₯ΠΎΡ€ΠΎΡˆΠ°Ρ ΠΏΠΎΠ΄Π±ΠΎΡ€ΠΊΠ°
  2. Π¨ΠΈΠΊΠ°Ρ€Π½Ρ‹ΠΉ сСрвис (9 Ρ‚ΠΈΠΏΠΎΠ² Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ² ΠΎΠ½Π»Π°ΠΉΠ½-Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€)
  3. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, mermaid.js
  4. И Ссли Π²Π°ΠΌ Π»ΡŽΠ±Ρ‹ супСр Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΈ слоТныС схСмы β€” Ρ‚ΠΎ вас ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎ восхитит этот ΠΏΡ€ΠΎΠ΅ΠΊΡ‚: go.drawthe.net

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ