作為代碼的網路圖/作為代碼的網路圖

在過去的幾年裡,我更多地參與了文件工作。 編寫有關這個或那個系統如何運作的解釋性文字通常非常簡單。 繪製一個圖表來顯示所有關鍵物件以及這些物件之間的連接也非常容易。

但最有問題的方面是保持該文件的最新狀態。 文字可以,但是圖表……因為…… 所有文件均在線,即html 格式,然後文字附有 gif/jpeg/png 圖片,這些圖片實際上顯示了圖表。 圖表是在各種程序中繪製的,例如 Visio 或 ladraw.io 的線上服務。 然後將圖表匯出為圖形格式並將其附加到 html。 這很簡單。

В чем проблеma?

這些方案通常很簡單。 更準確地說,不是很複雜。 是的,物件的數量是十幾兩個,連接的數量大約是相同的。 加上簽名,一些名稱。 簡單的方案可以用語言描述,但太複雜的方案,咳嗽… (c)“他們不會理解,先生。” 方案有很多,需要定期、間歇性地對其進行更改,即不斷地,因為他們關注我們產品的開發。

您可以嵌入服務的 html。 你嘗試過嗎?

是的,當然。 例如,我喜歡 gliffy.com 的圖形。 但要進行更改,您需要訪問第三方服務並在那裡進行編輯。 而且將更正委託給同事也更加困難。

怎麼辦呢?

最近我在Github上的推薦中發現了一個儲存庫 github.com/RaoulMeyer/diagram-as-code。 圖表即代碼。 那些。 我們在js中描述我們需要的電路。 我們直接在其他文件文字所在的同一個 html 中編寫此 js。

順便說一下,我並不完全用 html 編寫文件。 通常,文件是一組帶有 Markdown 文字的文件,然後由某些引擎(例如 Wintersmith)將其轉換為成熟的文件網站。 或維基系統。

事實證明非常方便:我們已經編寫了文本,然後打開 script 標籤,其中描述了該方案的 JS 程式碼。

又出什麼問題了?

我喜歡這個存儲庫,但這並不是使用程式碼或文字表示繪製圖表的唯一範例。 (在文章的末尾,將提供我在主題圖上透過 Google 搜尋到的項目和文章的連結作為代碼。)

而且我並不是唯一一個編輯文檔的人。 有時同事也會做出貢獻 - 更正單字、更改描述、插入新圖片。 

因此,我希望以可讀、可理解的文字格式查看該圖,不需要很長的學習曲線。 在某些地方,您甚至可以簡單地複製貼上來加快添加新電路的速度。 

另一位同事指出,程式碼當然很好,但如果使用結構,一切都可以非常嚴格和富有表現力。

因此,我嘗試將該圖想像為一組幾個小數組,用於描述節點、連接、節點組以及節點的位置。 事實證明,以我的拙見,相當方便,當然,味道和顏色......

這是一個數組中的圖表嗎?

  • 每個節點由唯一標識該節點的識別碼來描述。
  • 您也可以為節點新增圖示並新增銘文。
  • 您可以指定兩個節點之間的關係。
  • 為了在圖表上進行通信,您可以設定顏色和銘文。
  • 通訊方向定義為從來源到目標。 來源和目標由節點標識符指示。
  • 可以將一個或多個節點新增到群組中。
  • 也可以從群組和到群組指定關係。

使用這些簡單的規則,我們得到下圖。 只是? 相當。

作為代碼的網路圖/作為代碼的網路圖

透過下面的js程式碼來描述。 這裡最主要的是 elements 物件。 其中節點被指示為-節點,邊緣-連接。
 

  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>

一方面,這樣的方案幾乎就是筆記型電腦上的幾屏代碼,另一方面,json 的結構讓你可以類比快速地填寫所有數據,並且可以複製貼上。

為什麼位置與節點分開放置?

更舒服。 首先我們指定節點。 然後我們可以指定幾個群組並在節點中指示它們。 然後我們指定連接。 只有這樣,當主要物件及其之間的連接都存在時,我們才能在圖表上確定這些物件的位置。 或相反亦然。

沒有職位可以嗎?

沒有職位也是可能的。 但它會有點皺巴巴的;你可以在範例中看到這個選項。 這是因為 cytoscape 有一個節點位置演算法 氟糖,這也考慮到了群體的存在。 指定位置使圖表更加可控,但在圖表初稿階段,沒有位置也是可能的。

位置也可以在戰艦樣式中指定。 那些。 一個節點位於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. 如果您喜歡超級詳細和複雜的圖表,那麼您一定會欣賞這個項目: 去畫網

來源: www.habr.com

添加評論