一款用于绘制状态机转换图和流程图的web在线绘图工具
大型軟件系統(tǒng)中離不開各類狀態(tài)機(jī)的處理,日常工作中也涉及到各類事務(wù)處理流程;從表現(xiàn)力看文不如表,表不如圖;因此日常工作中經(jīng)常需要繪制各種狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)換圖和流程圖,以協(xié)助理解代碼邏輯和各類事務(wù)處理流程等。
繪制此類圖形的常用工具有visio,liberoffice draw等,這些軟件采用"所見即所得"的設(shè)計(jì)思想,完全由手動(dòng)放置形狀、填充文本、繪制線條、拖動(dòng)箭頭指向關(guān)系、調(diào)整文本格式、調(diào)整布局等等。此類工具優(yōu)點(diǎn)是繪圖直觀、布局可控;缺點(diǎn)一是需要安裝專門的軟件;二是過(guò)于繁瑣,以狀態(tài)機(jī)狀態(tài)轉(zhuǎn)換圖為例,當(dāng)狀態(tài)和激勵(lì)較多時(shí),表示狀態(tài)的矩形框和表示激勵(lì)的線條會(huì)顯得很凌亂,新添加狀態(tài)或者激勵(lì)時(shí)可能需要重新調(diào)整已有狀態(tài)和激勵(lì)的布局。
為了提高繪圖效率,同時(shí)讓繪圖在每臺(tái)電腦上隨時(shí)可用,以及隨時(shí)可以訪問(wèn)已經(jīng)繪制的圖形協(xié)助代碼分析,用python+graphviz開發(fā)了狀態(tài)機(jī)在線繪圖工具。
工具以下列格式的文本作為輸入:
source:XXX; trigger:YYY; destination:ZZZ; color="red"上述文本表示在XXX狀態(tài)下收到Y(jié)YY激勵(lì)會(huì)跳轉(zhuǎn)到新的ZZZ狀態(tài);color="red"表示該條邊繪制為紅色,可以設(shè)置其他顏色,不設(shè)置默認(rèn)為黑色。
注意:上述輸入文本格式中,source,tigger,destination后面必須要有英文冒號(hào)(:)和英文分號(hào)(;)。
只要在輸入框內(nèi)輸入多條上述語(yǔ)句,點(diǎn)擊按鈕即可一鍵自動(dòng)繪圖,只要有網(wǎng)絡(luò)訪問(wèn)即可,不需要安裝軟件,不需要手動(dòng)繪制各類形狀和線條。
下圖是工具繪圖的簡(jiǎn)單示例:
訪問(wèn)http://www.tasksteper.com:8099/flow/home/;以用戶名/密碼:testuser1/?testuser1登錄;進(jìn)入“集成工具”項(xiàng)目后;點(diǎn)擊“創(chuàng)建條目”;
概要欄隨便填寫,輸入欄輸入以下文本框中的內(nèi)容;點(diǎn)擊“創(chuàng)建”按鈕后;在刷新后的界面點(diǎn)擊“Graphviz繪圖”按鈕,即可在頁(yè)面右側(cè)看到繪制的狀態(tài)轉(zhuǎn)換圖;如下圖所示:
?
?
輸入內(nèi)容:
source:吃飯; trigger:goto睡覺(jué); destination:睡覺(jué); source:吃飯; trigger:goto打豆豆; destination:打豆豆; source:睡覺(jué); trigger:goto打豆豆; destination:打豆豆; source:睡覺(jué); trigger:goto吃飯; destination:吃飯; source:打豆豆; trigger:goto吃飯; destination:吃飯; source:打豆豆; trigger:goto睡覺(jué); destination:睡覺(jué);輸出:
繪圖的實(shí)現(xiàn)步驟如下:
1.后臺(tái)接收輸入表單中的文本內(nèi)容,并根據(jù)換行符,將一行內(nèi)容作為一個(gè)字符串;
2.循環(huán)判斷每個(gè)字符串是否滿足如下格式:
source:XXX; trigger:YYY; destination:ZZZ;若滿足,則在dot語(yǔ)言中生成XXX,ZZZ兩個(gè)節(jié)點(diǎn),以及一條XXX指向ZZZ的邊;節(jié)點(diǎn)信息記錄到node_database中,邊信息記錄到edge_string中;
3.所有字符串遍歷完成后,根據(jù)node_database和edge_string中記錄的信息生成用于graphviz繪圖的臨時(shí)dot語(yǔ)言腳本;
4.在后臺(tái)調(diào)用步驟3生成的dot語(yǔ)言腳本進(jìn)行繪圖,生成圖形后并將圖形顯示在web界面上,隨后刪除dot語(yǔ)言腳本;
?
接收輸入表單數(shù)據(jù),并生成dot語(yǔ)言進(jìn)行繪圖的python代碼如下所示:
1 def tools_draw_pygraphviz(request, model_instance): 2 prefix = '''digraph graphviz { 3 graph [ 4 //rankdir = "LR" 5 //splines=polyline 6 overlap=false 7 bgcolor="#FFFFCE" 8 ]; 9 10 node [ 11 fontsize = "16" 12 shape = "ellipse" 13 ]; 14 15 edge [ 16 ]; 17 ''' 18 edge_string = '' 19 space4 = ' ' 20 space8 = space4 + space4 21 node_database = {} 22 node_database['created'] = [] 23 tmpline = "" 24 for tmpchar in model_instance.detail: 25 if tmpchar == '\n': 26 m = re.search(r'source: *([^\s].*[^\s]) *;.*trigger: *([^\s].*[^\s]) *;.*destination: *([^\s].*[^\s]) *;(.*)', tmpline) 27 if m: 28 if m.group(1) not in node_database['created']: 29 node_database['created'].append(m.group(1)) 30 if m.group(3) not in node_database['created']: 31 node_database['created'].append(m.group(3)) 32 n = re.search(r'(color *= *\"[^\"]*\")', m.group(4)) 33 if n: 34 color_string = ', '+n.group(1) 35 else: 36 color_string = '' 37 edge_string = edge_string + "\"" + m.group(1) + "\"" + "->" + "\"" + m.group(3) + "\"" + "[ label = \"" + m.group(2) + "\"" +color_string+ "]\n" + space4 38 tmpline = "" 39 else: 40 tmpline = tmpline + tmpchar 41 42 m = re.search(r'source: *([^\s].*[^\s]) *;.*trigger: *([^\s].*[^\s]) *;.*destination: *([^\s].*[^\s]) *;(.*)', tmpline) 43 if m: 44 if m.group(1) not in node_database['created']: 45 node_database['created'].append(m.group(1)) 46 if m.group(3) not in node_database['created']: 47 node_database['created'].append(m.group(3)) 48 n = re.search(r'(color *= *\"[^\"]*\")', m.group(4)) 49 if n: 50 color_string = ', '+n.group(1) 51 else: 52 color_string = '' 53 edge_string = edge_string + "\"" + m.group(1) + "\"" + "->" + "\"" + m.group(3) + "\"" + "[ label = \"" + m.group(2) + "\"" +color_string+ "]\n" + space4 54 for tmp_node in node_database['created']: 55 tmp_node_string = space4 + "\"" + tmp_node + "\" [\n" + space8 + "label = \"" + tmp_node + "\"\n" + space8 + "shape = \"record\"\n" + space4 + "];\n" 56 prefix = prefix + tmp_node_string 57 image_path = '/root/virenv_python3/django_for_study/mysite/polls/static/polls/images/' 58 output_file = image_path + 'tools_graphviz_' + str(model_instance.id) + model_instance.graphviz_format 59 dot_file = image_path + 'dot_' + str(model_instance.id) 60 with open(dot_file,'w+') as f_output: 61 f_output.write(prefix + space4 + edge_string + "\n}") 62 if os.path.exists(output_file): 63 os.remove(output_file) 64 dot_cmd = model_instance.graphviz_style+' -T'+ model_instance.graphviz_format[1:] + ' ' + dot_file +' -o ' + output_file 65 os.system(dot_cmd) 66 os.remove(dot_file)由上述代碼python解析表單輸入自動(dòng)生成的dot腳本如下所示:
digraph graphviz {graph [//rankdir = "LR"//splines=polylineoverlap=falsebgcolor="#FFFFCE"];node [fontsize = "16"shape = "ellipse"];edge [];"吃飯" [label = "吃飯"shape = "record"];"睡覺(jué)" [label = "睡覺(jué)"shape = "record"];"打豆豆" [label = "打豆豆"shape = "record"];"吃飯"->"睡覺(jué)"[ label = "goto睡覺(jué)"]"吃飯"->"打豆豆"[ label = "goto打豆豆"]"睡覺(jué)"->"打豆豆"[ label = "goto打豆豆"]"睡覺(jué)"->"吃飯"[ label = "goto吃飯"]"打豆豆"->"吃飯"[ label = "goto吃飯"]"打豆豆"->"睡覺(jué)"[ label = "goto睡覺(jué)"]}?
下圖是實(shí)際工作中所涉及FC協(xié)議的端口狀態(tài)機(jī)跳轉(zhuǎn)流程:
其中紅色表示端口開工主流程,藍(lán)色表示端口停工流程;比代碼直觀許多。
該繪圖工具具有以下優(yōu)勢(shì):
1.自動(dòng)布局自動(dòng)繪圖,避免了手動(dòng)放置形狀、填充文本、繪制線條、拖動(dòng)箭頭指向關(guān)系、調(diào)整文本格式、調(diào)整布局等一系列繁瑣的操作;
添加新的狀態(tài)跳轉(zhuǎn)描述時(shí),只需要點(diǎn)擊按鈕一鍵重新繪圖即可,不需要關(guān)心之前的布局怎樣;
2. 代碼中的狀態(tài)轉(zhuǎn)換描述可以輕易的經(jīng)腳本進(jìn)行格式化處理為如下格式:
source:XXX; trigger:YYY; destination:ZZZ;
隨后將格式化處理后的文本貼入網(wǎng)頁(yè)就可以一鍵繪圖;對(duì)于一些復(fù)雜的狀態(tài)機(jī)(比如20+個(gè)狀態(tài),20+個(gè)激勵(lì))手動(dòng)繪制可能需要兩天左右,利用腳本預(yù)處理并利用網(wǎng)頁(yè)生成僅需要幾分鐘;
3.只要能訪問(wèn)網(wǎng)絡(luò)就隨時(shí)隨地可用,不需要安裝visio等繪圖工具,節(jié)約繪圖前等待軟件啟動(dòng)的時(shí)間;
4.支持設(shè)置顏色,將主要流程以顏色區(qū)分顯示,便于理解;如上圖中的端口啟動(dòng)和停止流程分別以紅色和藍(lán)色顯示。
5.純文本的輸入便于批量修改,比如LLL, MMM, NNN等多個(gè)狀態(tài)下都收到Y(jié)YY激勵(lì),我們需要加上激勵(lì)編號(hào)將YYY修改為YYY(05),在visio等繪圖工具中需要手動(dòng)修改多個(gè)狀態(tài)下YYY激勵(lì)對(duì)應(yīng)的線條上的描述;使用web繪圖工具只需要將輸入中的YYY全文替換成YYY(05), 點(diǎn)擊按鈕重新繪圖即可。
總結(jié)
以上是生活随笔為你收集整理的一款用于绘制状态机转换图和流程图的web在线绘图工具的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 前缀表达式(波兰表达式)介绍及其代码实现
- 下一篇: the crosswalk [proje