經常寫完文章, 收到的第一個問題是: 你的圖是用啥畫的; 其實自己也經常問別人. 最近強化了一下這方面的知識, 總結一下.
特指寫文章或者做架構設計中用到的圖.
畫圖的場景
個人將畫圖的場景分為兩種: PPT/文章中使用和系統中使用
- PPT/文章中使用, 特指在 PPT 演示或者技術文章/文檔中使用, 這種畫圖場景有幾個特點
- 美觀. 審美能力不行也不能作為馬虎了事的借口,用心與不用心總是有差別的
- 一次性. 基本上一個場景僅需要畫一次
- 手動. 可以使用任何工具, 手動各種擺放, 著色.
- 系統中使用, 特指在自己的系統中需要通過程序, 將一些流程通過可視化的方式展現. 這種場景有如下特點:
- 程序畫圖, 因此選擇的是畫圖的 library 而不是 GUI 軟件(感覺是廢話)
- 調色/擺位等需求, 必須要 library 支持, 但對于我這種對前端 GUI 相關開發能力極度弱的人來說, library 不支持也只有換一個, 找不到替代也只有忍了; 而使用畫圖軟件, 大不了自己手動擺放, 雖然耗時費力, 但至少是可以完成的.
可能有人覺得系統中畫圖
需求不多, 個人感覺還是有必要的. 經常遇到費勁開發了一個系統, 遇到各路用戶問問題. 如果有辦法在系統中將執行流程直接生成流程圖, 你好我好大家好.
PPT/文章畫圖
GUI 畫圖工具有很多可選, 個人比較推薦的是 OmniGraffle, 在線工具推薦 lucidchart. 當然, 我也見過用 KeyNote 畫出漂亮的系統圖的, 工具不重要, 關鍵看人(說多了都是淚)
程序畫圖
重點說一下程序畫圖. 最近反省了一下, 畫圖最多的就是那幾個:
-
塊圖. 經常用來表示系統間關系的.
塊圖 -
序列圖. 用來表示程序間調用關系
序列圖 -
網絡圖. 用于網絡相關的領域.
網絡圖
沒了. 真的沒了. 會這幾個就可以行走江湖了.
然后, 推薦兩個 library: blockdiag 和 graphviz.
blockdiag
blockdiag 是一個神奇的 python libary. 可以通過使用類似 graphviz 的語法, 畫出 塊圖, 序列圖, 網絡圖, 活動圖. 還提供了一個交互式的 shell, 用于調試上述幾種圖. 例如, shell 中輸入:
blockdiag {
A -> B -> C;
B -> D;
}
立即的到如下圖:
點擊右上角切換成序列圖, 輸入如下內容:
seqdiag {
// simple notation
browser -> webserver [label = "GET /index.html"];
browser <-- webserver;
browser -> webserver [label = "POST /blog/comment"];
webserver -> database [label = "INSERT comment"];
webserver <-- database;
browser <-- webserver;
}
有可以輕松得到如下序列圖:
但是說好的 library 呢? 以 seqdiag 為例,
安裝
$ pip install seqdiag
命令行使用
$ seqdiag -Tsvg simple.diag
程序使用
import tempfile
from seqdiag import parser, builder, drawer
import os
def generate_svg_sequence_diagram(text):
"""
:param text:
:return:
"""
tree = parser.parse_string(text)
_, filename = tempfile.mkstemp(suffix='.svg')
diagram = builder.ScreenNodeBuilder.build(tree)
draw = drawer.DiagramDraw("SVG", diagram, filename=filename)
draw.draw()
draw.save()
with open(filename) as f:
svg_content = f.read()
os.remove(filename)
return svg_content
Graphviz
Graphviz 可謂是一代畫圖神器, 通過官網的示例圖就知道有多強大. blockdiag 也是參考 Graphviz 的實現. 通過類似的語法描述, 生成所需的圖形. 對于顏色的選擇, 可以參考文檔中 Colors 一節, 非常全面.
程序方面, 同名的 graphviz
library 可以使用 pip install graphviz
安裝, 非常方便. 示例python 程序如下:
from graphviz import Digraph
dot = Digraph(comment='demo dot graph', format='svg')
dot.node('A', 'King Arthur')
dot.node('B', 'Sir Bedevere the Wise')
dot.node('L', 'Sir Lancelot the Brave')
dot.edges(['AB', 'AL'])
dot.edge('B', 'L', constraint='false')
總結
既然有了 library 可以畫圖, 強烈建議在自己的系統中將一些復雜的流程化的事情通過根據當前系統狀態畫出圖的方式展現給用戶, 可以避免很多疑惑.