canvas版的拓撲圖(topo)展示工具:ctopo
ctopo
canvas版的拓撲圖(topo)展示工具.
起因
總在使用別人的開源插件來繪制拓撲,總是不能滿足公司各個項目的各種需求,痛定思痛自己搞一套吧.
ps: 感謝UI設計師yoki對topo圖做的UI設計,很贊!!!
ps: 因為ff,chrome不支持本地請求json文件, 將整體工程放到本服務器下運行最為適宜.
適用場景和環境
(1)適用于監控網絡ip節點互聯關系的場景
(2)適用于社交網絡的群組互聯訪問關系
兼容性
ie9+,firefox,chrome,safari.
性能說明
300+節點毫無壓力,順暢的沒有朋友,正常使用盡量控制在300左右.
節點的碰撞檢測5千節點1ms左右,連線的碰撞檢測5千連線1ms左右,(ff,chrome一樣)
如果需要展示上千節點請參考以下調優方案
調優方案參考
(1)將力導向布局的迭代次數從300次下降到150次,布局時間縮小一倍,例:10s---優化后5s (2)將布局算法放在后臺執行,將前臺布局設置為[預設],按java舉例,例:10s---優化后2s (3)將節點的顯示標簽Label隱藏,下面列舉了繪制label的性能影響,例:10s---優化后3s (4)用空間換時間,將坐標保留,不用每次draw都要重新計算布局
ps: 繪制節點標簽還是挺吃性能的
繪制節點不帶label //ff 直接掛了 //chrome nodes count=1000,edges count=1000,layout time=4838,draw time=9 //ff nodes count=500,edges count=500,layout time=9543,draw time=19 //chrome nodes count=500,edges count=500,layout time=1272,draw time=6 //ff nodes count=300,edges count=300,layout time=3445,draw time=11 //chrome nodes count=300,edges count=300,layout time=475,draw time=4 //ff nodes count=200,edges count=200,layout time=1551,draw time=7 //chrome nodes count=200,edges count=200,layout time=233,draw time=4 繪制節點帶label //ff 直接掛了 //chrome nodes count=1000,edges count=1000,layout time=4838,draw time=39 //ff nodes count=500,edges count=500,layout time=9543,draw time=125 //chrome nodes count=500,edges count=500,layout time=1272,draw time=23 //ff nodes count=300,edges count=300,layout time=3445,draw time=77 //chrome nodes count=300,edges count=300,layout time=475,draw time=16 //ff nodes count=200,edges count=200,layout time=1551,draw time=49 //chrome nodes count=200,edges count=200,layout time=233,draw time=10
缺點
(1)力導向布局算法性能差一點,還需要進一步優化
(2)不支持節點圖片和圖標
(3)不支持框選操作
特性
(1)提供控制面板;
(2)支持鼠標滑輪和拖拽的放大,縮小;
(3)上下左右鍵盤平移;
(4)拖拽單個節點和屏幕;
(5)支持點擊和懸停節點;
(6)支持點擊和懸停連線;
(7)支持懸停節點的關聯節點高亮;
(8)提供事件回調接口;
(9)支持連線箭頭;
(10)支持連線的流動動畫;
(11)支持力導向布局定位,即每次刷新頁面,坐標不變;
實現原理
(1)使用html5的canvas標簽來實現的;
(2)布局算法使用力導向布局(庫侖斥力公式和胡克定律公式)來自網絡;
(3)節點的碰撞檢測使用勾股定理測距;
(4)連線的碰撞檢測使用反正切計算夾角;
界面展示
版權
MIT(隨意使用,免費開源)
基礎實例
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <canvas id="canvas"></canvas> <script type="text/javascript" src="ctopo.js"></script> <script type="text/javascript"> //調用ctopo ctopo({ id:"canvas", //說明: canvas標簽的id, 寫法: canvas , #canvas width:"auto", //說明: canvas的寬度, 寫法: 500,500px,50%,auto height:"auto", //說明: canvas的高度, 寫法: 500,500px,50%,auto style:{ //說明: 樣式省略了..... global:{}, node:{}, edge:{} }, layout:{}, //說明: 布局省略了..... data:{}, //說明: 數據省略了..... event:{} //說明: 事件回調省略了..... }); </script> </body> </html>
api接口
使用方法
//取得ctopo對象, 點出api方法即可 var ctopo = ctopo({..各種基礎配置..}); var nodeA = ctopo.node("1108"); //獲取節點A var nodeB = ctopo.node("0724"); //獲取節點B var edge = ctopo.edge("1108","0724"); //獲取連線
屬性和方法
屬性名 | 描述 |
version | 版本 |
option | 配置對象 |
canvas | 畫布對象 |
context | 畫布上下文對象 |
nodes | 節點數組 |
edges | 連線對象 |
方法名 | 描述 | 參數 | 返回值 |
addEdge(edge,isDrawNow) | 添加連線 | 參數1: edge添加的連線對象 參數2: isDrawNow是否立刻渲染到屏幕 |
空 |
addNode(node,isDrawNow) | 添加節點 | 參數1: edge添加的節點對象 參數2: isDrawNow是否立刻渲染到屏幕 |
空 |
draw(option) | 重新繪制畫布, 用法等于ctopo(option) |
參數1: option初始的配置對象 |
空 |
drawData(data,isApplyLayout) | 局部刷新,只刷新數據 | 參數1: data格式=optioin.data 參數2: isApplyLayout是否重新應用布局 |
成功true,失敗false |
edge(sid,tid) | 取得連線對象 ps:區分方向 |
參數1: 開始節點id 參數2: 結束節點id |
查到: 連線對象 沒查到: null |
edgeArray() | 取得所有的連線對象數組 | 無 | 連線對象數組 |
firstNeighbors(nid) | 返回與之關聯的連線和節點數組對象 | 參數1: nid待匹配的節點id |
查到:關聯數據對象; 沒查到:空數組對象 { edgeNeighbors:[], nodeNeighbors:[] } |
layout(layout) | 重置切換布局 | (可選)參數1: layout==option.layout |
無參數: 返回option.layout 有參數: 重置布局, 成功true,失敗false |
node(id) | 取得節點對象 | 參數1: 節點id |
查到:節點對象 沒查到:null |
nodeLabelsVisible(visible) | 設置節點標簽是否顯示 | 參數1: visible是否顯示標簽, 布爾型true,false |
空 |
edgeLabelsVisible(visible) | 設置連線標簽是否顯示 | 參數1: visible是否顯示標簽, 布爾型true,false |
空 |
edgeArrowsVisible(visible) | 設置連線箭頭是否顯示 | 參數1: visible是否顯示箭頭, 布爾型true,false |
空 |
nodeArray() | 取得所有節點對象數組 | 無 | 節點對象數組 |
nodeTooltipsVisible(visible) | 設置節點提示框是否顯示 | 參數1: visible是否顯示提示框, 布爾型true,false |
空 |
edgeTooltipsVisible(visible) | 設置連線提示框是否顯示 | 參數1: visible是否顯示提示框, 布爾型true,false |
空 |
edgeAnimateBallsVisible(visible) | 設置連線動畫球是否顯示 | 參數1: visible是否顯示動畫球, 布爾型true,false |
空 |
consolePanelVisible(visible) | 設置控制臺是否顯示 | 參數1: visible是否顯示控制臺, 布爾型true,false |
空 |
removeEdge(sid,tid,isDrawNow) | 刪除連線 | 參數1: 開始節點id 參數2: 結束節點id 參數3: 是否立刻渲染到屏幕 |
空 |
removeNode(id,isDrawNow) | 刪除節點,與之關聯的線也刪除 | 參數1: 節點id 參數2: 是否立刻渲染到屏幕 |
空 |
updateEdge(edge,isDrawNow) | 更新連線 | 參數1: 連線對象 參數3: 是否立刻渲染到屏幕 |
空 |
updateNode(node,isDrawNow) | 更新節點 | 參數1: 節點對象 參數2: 是否立刻渲染到屏幕 |
空 |
style(style) | 重置切換樣式 | (可選)參數1: style==option.style |
無參數: 返回option.style 有參數: 重置樣式, 成功true,失敗false |
zoom(scale) | 設置縮放比例(0-1) | (可選)參數1: scale比例0-1,100%=0.5 |
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!