前端繪製流程圖--流程圖JS外掛:dagre-d3
阿新 • • 發佈:2018-12-12
後臺返回的資料為WEBSOCKET實時推送 ,每推送一條資料來,自動生成一個分支和資料塊,一個子可能會對應多個父。
每個綠色方塊點選 出現對應的灰色方塊
效果圖如下:
html如下
<!doctype html> <head> <meta charset="utf-8"> <title>域名關係圖</title> <link rel="stylesheet" href="{{ STATIC_URL }}css/index.css"> </head> <body> <div class="content"> <svg id="svgCanvas"></svg> </div> <ul id="myMenu"> <li>http://192.68.102.11:/test/fileupload</li> </ul> </body> <script type="text/javascript" src="{{ STATIC_URL }}js/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}js/d3.min.js" charset="utf-8"></script> <script type="text/javascript" src="{{ STATIC_URL }}js/dagre-d3.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}js/diag.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}js/index.js"></script> </html>
css 如下
*{ font-family: 'Microsoft YaHei'; list-style: none; padding: 0; margin: 0; } html,body{ background-color: #f1f4f5; overflow: hidden; width: 100%; height: 100%; } .content{ width: 100%; height: 100%; } .content svg{ width: 100%; } .content svg >g{ width: 100%; height: 100%; } /*漏洞資訊*/ .looplist{ position: absolute; right: 0; top: 0; width: 250px; background-color: #fff; height: 100%; padding-left: 10px; padding-right: 10px; box-sizing: border-box; border-left: 1px solid #d8e1e4; } .looplist >div{ position: relative; height: 100%; } .looplist >div label{ position: absolute; width: 20px; height: 32px; top: 50%; margin-top: -16px; left: -32px; background-color: #fff; border:1px solid #d8e1e4; color: #a1b0b5; text-align: center; line-height: 32px; cursor: pointer; } .looplist >div strong{ display: inline-block; width: 100%; font-size: 14px; color: #687386; padding-top: 10px; padding-bottom: 10px; } .looplist >div li{ color: #687386; font-size: 12px; height: 40px; line-height: 40px; border-bottom: 1px solid #d8e1e4; display:block; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; } /* This sets the color for "TK" nodes to a light blue green. */ g.type-suss>rect { fill: #ddefd3; } .node text { font-weight: bold; font-family: "Microsoft YaHei" ; font-size: 12px; pointer-events: none; text-anchor: middle; fill: white; } /*.label g text tspan:last-child { font-size: 10px; margin-top: 5px; dy: 1.5em; }*/ .label g { transform: translate(0, -13px); } .node rect { fill: white; stroke-width: 0px; color: white; } .edgePath path { stroke: #ccc; stroke-width: 1px; } g.type-suss >rect{ fill:#f68440 } g.type-security>rect{ fill:#3fc96e; } g.type-init>rect { stroke: #dee6e8; stroke-width: 1px; } .type-init text tspan:nth-child(1) { display: inline-block; fill:#4487f4; font-weight: bold; text-align: left; } .type-init text tspan { fill:#687386; font-size: 12px; font-weight: 100; } g.type-server>rect{ stroke: #dee6e8; stroke-width: 1px; } .type-server text{ fill:#687386; font-size: 14px; } g.type-port>rect{ fill:#dff0e7; stroke: #3fc96e; stroke-width: 1px; } .type-port text{ fill:#3fc96e; font-size: 14px; } g.type-domain>rect{ fill: rgba(0,0,0,0); } .type-domain text{ fill:#4487f4; font-size: 24px; } #myMenu{ position: absolute; display: none; min-width: 120px; max-width:550px; min-height: 50px; max-height: 100px; background: #fff; border:1px solid #d8e1e4; padding: 5px; border-radius: 14px; background: #a5e0ee; border: 1px solid rgb(153, 153, 153); } #myMenu li{ width: 100%; } .systemlist{ position: absolute; left: 20px; top: 20px; width: 220px; height: 138px; background-color: #fff; border:1px solid #d8e1e4; border-radius: 4px; padding: 20px; padding-bottom: 0; box-sizing: border-box; font-size: 12px; color: #687386; } .systemlist ul{ margin:0; } .systemlist ul li{ width: 100%; margin-bottom: 10px; } .systemlist ul li label{ display: inline-block; font-weight: bold; } .systemlist ul li span{ }
js如下
$(function(){ state = []; edg = []; var websocket = null; if ('WebSocket' in window) { //判斷當前瀏覽器是否支援WebSocket websocket = new WebSocket("ws://" + window.location.host + "/testWs"); }else { alert('當前瀏覽器 不支援WebSocket'); } websocket.onerror = function () { //連線發生錯誤的回撥方法 console.log('發生異常'); }; websocket.onopen = function () { //連線成功建立的回撥方法 console.log('連線成功'); } websocket.onmessage = function (event) { //接收到訊息的回撥方法,此處新增處理接收訊息方法,當前是將接收到的資訊顯示在網頁上 try{ node_message = JSON.parse(event.data); setTimeout(paint_node(node_message), 1000); console.log(node_message) }catch (e){ console.log(e); } } websocket.onclose = function () { //連線關閉的回撥方法 console.log('連線關閉'); } window.onbeforeunload = function () { //監聽視窗關閉事件,當視窗關閉時,主動去關閉websocket連線,防止連線還沒斷開就關閉視窗,server端會拋異常。 closeWebSocket(); } // 繪製的關鍵 function paint_node(node_message) { //將訊息顯示在網頁上,如果不需要顯示在網頁上,則不呼叫該方法 if (node_message.node_indentity == 1){ var statePoint = 1; state.push({id: node_message.node_indentity, label: node_message.node_title, class: 'type-domain'}); diagGraph.init(statePoint, state, edg); //建立關係圖 }else{ try{ fatherNode = eval(node_message.fathernode); // console.log("!!!"+node_message.node_content); try{ $(fatherNode).each(function(index){ //有多個父節點的要遍歷 自動生成一子對應多父 var nodeid=this; edg.push({start: parseInt(nodeid), end: node_message.node_indentity, option: {}}); state.push({id: node_message.node_indentity, label: node_message.node_title, class: 'type-port', "value": node_message.node_content}); diagGraph.renderG() }) }catch (e){ console.log(e); } }catch(e){ console.log(); } } } var totalw = $('.content').width(); var totalh = $('.content').height(); $('#svgCanvas').attr({ width:totalw, height:totalh }); var myMenu = document.getElementById("myMenu"); $('#svgCanvas').on('click',function(e){ e.preventDefault(); if (e.target.tagName === 'rect') { var id = e.target.parentNode.id; diagGraph.changePoint(id); var value=""; // console.log(state) $(state).each(function(){ if(this.id==id){ value=this.value; return false; } }) $('#myMenu').html("<li>"+value+"</li>"); $('#myMenu').css({left:event.clientX, top: event.clientY}).show(); } else { $('#myMenu').hide(); } }) });