1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 3 <html> 4 <head> 5 <title>安防點位拓撲圖</title> 6 <!-- /* Copyright ?1998-2013 by Northwoods Software Corporation. */ --> 7 <link href="goSamples.css" rel="stylesheet" type="text/css" /> 8 <script type="text/javascript" src="go.js"></script> 9 <!-- <script type="text/javascript" src="goSamples.js"></script>--> 10 <script src="../resources/scripts/jquery-1.7.1.min.js" type="text/javascript"></script> 11 <script type="text/javascript"> 12 var AjaxRequestBack=false; 13 var IdList; 14 function init() { 15 if (window.goSamples) goSamples(); 16 var $ = go.GraphObject.make; 17 18 myDiagram = $(go.Diagram, "myDiagram", 19 { 20 initialContentAlignment: go.Spot.Center //整個拓撲圖的位置 21 }); 22 //節點的圖片,根據傳進來的參數獲取相對應的圖片 23 function nodeTypeImage(type) { 24 if (type.charAt(0) === "1") return "images/1.png"; 25 if (type.charAt(0) === "2") return "images/2.png"; 26 if (type.charAt(0) === "3") return "images/3.png"; 27 if (type.charAt(0) === "4") return "images/4.png"; 28 if (type.charAt(0) === "5") return "images/5.png"; 29 if (type.charAt(0) === "6") return "images/6.png"; 30 if (type.charAt(0) === "7") return "images/7.png"; 31 if (type.charAt(0) === "8") return "images/8.png"; 32 return "images/0.png"; 33 } 34 35 function nodeProblemConverter(msg) { 36 if (msg) return "red"; 37 return null; 38 } 39 //判斷節點左邊形狀 40 function nodeOperationConverter(s) { 41 if (s >= 2) return "TriangleDown"; 42 if (s >= 1) return "Rectangle"; 43 return "Circle"; 44 } 45 //判斷節點右邊形狀的顏色 46 function nodeStatusConverter(s) { 47 if (s >= 2) return "red"; 48 if (s >= 1) return "green"; 49 return "green"; 50 } 51 //可以通過 problem控制節點的連線和邊框的顏色 52 //data.status = 10.1;//控制節點內部圖標的顏色 53 //data.operation //控制節點內圖標的形狀 54 myDiagram.nodeTemplate = 55 $(go.Node, "Vertical", 56 { selectable: false,//是否可以選擇節點並移動 57 mouseOver: function (e, obj) {//鼠標進入響應的事件方法 58 nodeDoubleClick(e, obj) //事件調用方法 59 } 60 }, 61 // { doubleClick: nodeDoubleClick },//鼠標雙擊事件函數 62 //{click: nodeDoubleClick }, //鼠標單擊事件函數 63 {locationObjectName: "ICON" }, 64 // new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), //這裏使用節點的位置參數,也可以不知用,不使用的時候,就的使用插件的佈局屬性 65 $(go.Panel, "Spot", 66 $(go.Panel, "Auto", 67 { name: "ICON" }, //這個參數無所謂 68 $(go.Shape, 69 { fill: null, portId: "", 70 strokeWidth: 0,stroke: null },//這兩個屬性和起來去掉邊框 71 new go.Binding("background", "problem", nodeProblemConverter)), //這裏使用節點的問題描述 problem值爲空時:控制線條和邊框的顏色,即設備是否出現問題 72 $(go.Picture, 73 //{ stroke: ""}, 74 { margin: 0 }, //這裏控制圖片和外圍邊框的邊距 75 { desiredSize: new go.Size(60, 60) }, 76 new go.Binding("source", "type", nodeTypeImage))), //這裏是用節點的類型,即是用的圖片 77 //這段代碼是控制節點內部左邊圖標初始顏色 形狀等,位子信息 78 // $(go.Shape, "Circle", 79 // { alignment: go.Spot.TopLeft, alignmentFocus: go.Spot.TopLeft, //TopLeft顯示的位置 80 // width: 10, height: 10, fill: "Green"//這裏的顏色是控制節點內部左邊圖標的顏色 81 // }, 82 83 // new go.Binding("figure", "operation", nodeOperationConverter)) //這裏是用節點形狀參數 84 85 //這段代碼是控制節點內部右邊圖標初始顏色 形狀等,位子信息 86 $(go.Shape, "Circle", 87 { alignment: go.Spot.TopRight, alignmentFocus: go.Spot.TopRight, //TopLeft顯示的位置 88 width: 15, height: 15, fill: "Green" 89 }, 90 new go.Binding("fill", "status", nodeStatusConverter)) //這裏是用節點狀態參數 91 ), 92 //這裏是節點文字的樣式 93 $(go.TextBlock, 94 { font: "bold 7px Helvetica, bold Arial, sans-serif", 95 stroke: "black", margin: 3 }, 96 new go.Binding("text"))); 97 98 //設置線條的顏色 99 function linkProblemConverter(msg) { 100 if (msg) return "red"; 101 return "#ccc"; 102 } 103 104 105 106 myDiagram.linkTemplate = 107 $(go.Link, go.Link.AvoidsNodes, 108 { corner: 3 }, //控制線的轉彎的弧度值越小 越呈現直角 109 $(go.Shape, 110 { strokeWidth: 1 }, //控制線條的粗細,值越大 線越粗 111 new go.Binding("stroke", "problem", linkProblemConverter))); 112 113 //節點的佈局 114 myDiagram.layout = $(go.LayeredDigraphLayout, 115 { direction: 270, //拓撲圖的方向 116 layerSpacing: 10, 117 columnSpacing: 15, 118 setsPortSpots: false 119 }); 120 121 122 //在這裏加載數據 123 load(); 124 //利用隨機數隨機設備出現問題的方法 125 function randomProblems() { 126 if(AjaxRequestBack) 127 { 128 129 130 var model = myDiagram.model; 131 //nodeDataArray 132 //設置問題節的顏色 133 var arr = model.nodeDataArray; 134 for (var i = 0; i < arr.length; i++) { 135 data = arr[i]; 136 137 //console.log(data.key); 138 for(var t=0;t<IdList.length;t++) 139 { 140 if(data.key==IdList[t]) 141 { 142 data.status = 3; 143 } 144 else{ 145 //data.status = 1; 146 } 147 } 148 149 //data.problem = (Math.random() < 0.8) ? "" : "Power loss due to ...";//0.8是一個零界點 150 //data.problem = ""; //當爲空的時候就是沒問題 151 //data.problem = "Power loss due to ...";//當這個的時候就是有問題 152 //data.status = 10.1;//這個數據是用於判斷節點右邊正方形 圓形 三角形還有形狀的顏色(右邊形狀不變) 153 //data.operation = 0.1; //設置節點左邊正方形 圓形 三角形還有形狀的顏色(左邊的形狀顏色不變) 154 155 //data.operation = 0.3; 156 model.updateTargetBindings(data); 157 data.status = 1; 158 } 159 160 161 //獲取JSON數據中的linkDataArray 162 //設置節點之間線的顏色 163 /* 164 arr = model.linkDataArray; 165 for (i = 0; i < arr.length; i++) { 166 data = arr[i]; 167 data.problem = (0.1 < 0.7) ? "" : "No Power"; 168 model.updateTargetBindings(data); 169 } 170 */ 171 AjaxRequestBack=false; 172 } 173 } 174 //設置間隔時間獲取設備的狀態 175 function loop1() 176 { 177 setTimeout(function () { GetStatus(); loop1(); }, 4000); 178 } 179 loop1(); 180 function loop() { 181 setTimeout(function () { randomProblems(); loop(); }, 5500); 182 } 183 loop(); // start the simulation 184 myDiagram.makeImage({ 185 scale: 1, 186 background: "AntiqueWhite", 187 type: "image/jpeg", 188 details: 0.05 189 }); 190 } 191 function load() { 192 var str = <%=Result%>; 193 myDiagram.model = go.Model.fromJson(str); 194 195 var arr = myDiagram.model.nodeDataArray; 196 for (var i = 0; i < arr.length; i++) { 197 // alert(arr[i].text); 198 } 199 200 201 } 202 203 function GetStatus() { 204 $.ajax({ 205 url: 'GetEleStatus.ashx', 206 type:'post', 207 success: function (data) { 208 var result = eval("(" + data + ")"); 209 IdList = result.IdList; 210 211 AjaxRequestBack=true; 212 } 213 }); 214 215 } 216 217 function highlightNode(e, node) { 218 alert(node.data.text); 219 } 220 221 function nodeDoubleClick(e, node) { 222 $("#Loading").html("正在加載..."); 223 $.ajax({ 224 url: 'GetElementInfo.ashx', 225 data: { "ElementID": node.data.key }, 226 success: function (data) { 227 if (data != "false") { 228 data = eval("(" + data + ")"); 229 var name = data.name; 230 var commont = data.commont; 231 232 $("#Info").html("<span>點位名稱:"+name+"</span></br><span>點位描述:"+commont+"</span>") 233 234 $("#Info").show();; 235 tag=true; 236 237 } 238 } 239 }); 240 } 241 242 </script> 243 </head> 244 <body onload="init()"> 245 <div id='Info' style="position: fixed; padding-top: 5px; margin: 1px; line-height: 20px; 246 border-radius: 3px; background-color: #FFC435; width: 150px; height: 50px; z-index: 999; 247 border: 1px solid #ccc; top: 7px; left: 7px;"> 248 <div id="Loading" style="text-align: center; width: 150px; margin-top: 15px;"> 249 選擇點位</div> 250 </div> 251 252 <div id="myDiagram" style="border: solid 0px black; width: 100%; height: 900px;"> 253 </div> 254 255 <br /> 256 <%--</div>--%> 257 </body> 258 </html>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Text; 8 using System.Data; 9 10 namespace Maticsoft.Web.test 11 { 12 public partial class DrowNode : System.Web.UI.Page 13 { 14 15 public string Result; 16 protected void Page_Load(object sender, EventArgs e) 17 { 18 DataSet set = new DataSet(); 19 set = new Maticsoft.BLL.RD_Element().Query("");//這裏是寫的SQL語句 去獲取你數據庫的數據。這裏我刪除掉了。而是利用下面構造的數據。這裏你獲取的數據必須包含兩個字段,一個是父節點編號,一個是子節點編號。 20 if (set != null && set.Tables.Count > 0) 21 { 22 23 StringBuilder result = new StringBuilder(); 24 StringBuilder node = new StringBuilder();//這個對象是存放着節點信息 25 StringBuilder link = new StringBuilder();//這個節點是存放每個節點的關聯關係 26 27 //這兩個是節點的位置。但是我用了另一種佈局方式,這裏已經沒用了。 28 int y = 0; 29 int x = 0; 30 Random r = new Random(); 31 int count = set.Tables[0].Rows.Count; 32 // 下面是構造的數據。該插件是利用後臺生成的Json格式數據來解析的; 33 //key 是節點編號 text是節點下面的文字。type是節點的類型。在html代碼有一個方法nodeTypeImage就是根據這個來返回圖片路徑的。problem則是用來標識節點數否異常。這裏有一個可能會混淆,那就是節點異常和節點之間的連接異常。具體在js代碼有註釋,當然這裏還有其他的屬性,就不一一介紹了。 34 node.Append("{\"key\":\"0\", \"text\":\"北京\", \"type\":\"0\", \"problem\":\"\"},"); 35 node.Append("{\"key\":\"-1\", \"text\":\"中國\", \"type\":\"0\", \"problem\":\"\"},"); 36 node.Append("{\"key\":\"-2\", \"text\":\"福建\", \"type\":\"0\", \"problem\":\"\"},"); 37 node.Append("{\"key\":\"10000\", \"text\":\"風扇\", \"type\":\"2\", \"problem\":\"\"},"); 38 node.Append("{\"key\":\"10001\", \"text\":\"風扇風扇\", \"type\":\"2\", \"problem\":\"\"},"); 39 node.Append("{\"key\":\"10002\", \"text\":\"風扇\", \"type\":\"4\", \"problem\":\"\"},"); 40 node.Append("{\"key\":\"10003\", \"text\":\"風扇\", \"type\":\"5\", \"problem\":\"\"},"); 41 node.Append("{\"key\":\"10004\", \"text\":\"發電機\", \"type\":\"1\", \"problem\":\"\"},"); 42 node.Append("{\"key\":\"10005\", \"text\":\"水龍頭\", \"type\":\"5\", \"problem\":\"\"},"); 43 node.Append("{\"key\":\"10006\", \"text\":\"發電站\", \"type\":\"7\", \"problem\":\"\"},"); 44 node.Append("{\"key\":\"10007\", \"text\":\"火箭\", \"type\":\"8\", \"problem\":\"\"},"); 45 node.Append("{\"key\":\"10008\", \"text\":\"衛星\", \"type\":\"3\", \"problem\":\"\"},"); 46 node.Append("{\"key\":\"10009\", \"text\":\"衛星\", \"type\":\"5\", \"problem\":\"\"},"); 47 node.Append("{\"key\":\"100010\", \"text\":\"衛星\", \"type\":\"6\", \"problem\":\"\"},"); 48 node.Append("{\"key\":\"100011\", \"text\":\"火箭\", \"type\":\"3\", \"problem\":\"\"},"); 49 node.Append("{\"key\":\"100012\", \"text\":\"發電機\", \"type\":\"3\", \"problem\":\"\"},"); 50 node.Append("{\"key\":\"100013\", \"text\":\"發電機\", \"type\":\"5\", \"problem\":\"\"},"); 51 node.Append("{\"key\":\"100014\", \"text\":\"風扇\", \"type\":\"6\", \"problem\":\"\"},"); 52 node.Append("{\"key\":\"100015\", \"text\":\"拖拉機\", \"type\":\"3\", \"problem\":\"\"},"); 53 node.Append("{\"key\":\"100016\", \"text\":\"公交車\", \"type\":\"5\", \"problem\":\"\"},"); 54 node.Append("{\"key\":\"100017\", \"text\":\"廣場控燈\", \"type\":\"6\", \"problem\":\"\"},"); 55 node.Append("{\"key\":\"100018\", \"text\":\"演出屏幕\", \"type\":\"3\", \"problem\":\"\"},"); 56 node.Append("{\"key\":\"100019\", \"text\":\"話筒\", \"type\":\"3\", \"problem\":\"\"},"); 57 node.Append("{\"key\":\"100020\", \"text\":\"音箱\", \"type\":\"5\", \"problem\":\"\"},"); 58 node.Append("{\"key\":\"100021\", \"text\":\"核武器\", \"type\":\"6\", \"problem\":\"\"},"); 59 //這裏的數據是關聯各個節點的。from是線出來的節點編號,to則是連線到達的節點編號。這樣就能把兩節點關聯起來 60 link.Append("{\"from\":\"0\", \"to\":\"-1\",\"problem\":\"\"},"); 61 link.Append("{\"from\":\"-2\", \"to\":\"-1\",\"problem\":\"\"},"); 62 link.Append("{\"from\":\"10000\", \"to\":\"0\",\"problem\":\"\"},"); 63 link.Append("{\"from\":\"10001\", \"to\":\"0\",\"problem\":\"\"},"); 64 link.Append("{\"from\":\"10002\", \"to\":\"0\",\"problem\":\"\"},"); 65 link.Append("{\"from\":\"10003\", \"to\":\"10002\",\"problem\":\"\"},"); 66 link.Append("{\"from\":\"10004\", \"to\":\"10002\",\"problem\":\"\"},"); 67 link.Append("{\"from\":\"10005\", \"to\":\"-2\",\"problem\":\"\"},"); 68 link.Append("{\"from\":\"10006\", \"to\":\"-2\",\"problem\":\"\"},"); 69 link.Append("{\"from\":\"10007\", \"to\":\"-2\",\"problem\":\"\"},"); 70 link.Append("{\"from\":\"10008\", \"to\":\"100017\",\"problem\":\"\"},"); 71 link.Append("{\"from\":\"10009\", \"to\":\"-2\",\"problem\":\"\"},"); 72 link.Append("{\"from\":\"100010\", \"to\":\"-2\",\"problem\":\"\"},"); 73 link.Append("{\"from\":\"100011\", \"to\":\"100019\",\"problem\":\"\"},"); 74 link.Append("{\"from\":\"100012\", \"to\":\"10005\",\"problem\":\"\"},"); 75 link.Append("{\"from\":\"100013\", \"to\":\"10005\",\"problem\":\"\"},"); 76 link.Append("{\"from\":\"100014\", \"to\":\"10005\",\"problem\":\"\"},"); 77 link.Append("{\"from\":\"100015\", \"to\":\"10007\",\"problem\":\"\"},"); 78 link.Append("{\"from\":\"100016\", \"to\":\"10007\",\"problem\":\"\"},"); 79 link.Append("{\"from\":\"100017\", \"to\":\"10009\",\"problem\":\"\"},"); 80 link.Append("{\"from\":\"100018\", \"to\":\"10007\",\"problem\":\"\"},"); 81 link.Append("{\"from\":\"100019\", \"to\":\"10009\",\"problem\":\"\"},"); 82 link.Append("{\"from\":\"100020\", \"to\":\"100011\",\"problem\":\"\"},"); 83 link.Append("{\"from\":\"100021\", \"to\":\"100011\",\"problem\":\"\"},"); 84 85 //這段代碼是我本來用來構造數據庫中數據的JSON格式的,但是因爲沒用了。不過來是貼出來,如果你有用可以照着這個寫 86 //foreach (DataRow row in set.Tables[0].Rows) 87 //{ 88 // x = r.Next(count*20)+40; 89 // y = r.Next(count*20)+100; 90 // node.Append("{\"key\":\"" + row["id"] + "\", \"text\":\"" + row["name"] + "\", \"type\":\"" + row["type"] + "\", \"loc\":\"" + x + " "+y+"\",\"problem\":\"\"},"); 91 92 // //elemodel = new BLL.RD_Element().GetModel(int.Parse(row["parentid"].ToString ())); 93 // link.Append("{\"from\":\"" + row["id"] + "\", \"to\":\"" + row["parentid"].ToString() + "\",\"problem\":\"\"},"); 94 //} 95 string nodestr = node.ToString().Substring(0, node.ToString().Length - 1); 96 string linkstr = link.ToString().Substring(0, link.ToString().Length - 1); 97 98 99 result.Append("{\"nodeDataArray\": [ "); 100 result.Append(nodestr); 101 result.Append("],\"linkDataArray\": [ "); 102 result.Append(linkstr); 103 result.Append("]}"); 104 Result = result.ToString(); 105 } 106 } 107 108 } 109 }
然後是異步獲取設備狀態的C#代碼。這裏因爲沒有真正的設備信息。所以獲取的異常設備都是利用隨機函數構造出來的 代碼如下 其中返回的是json格式的數據,數據爲異常設備的編號
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 6 namespace Maticsoft.Web.test 7 { 8 /// <summary> 9 /// GetEleStatus 的摘要說明 10 /// </summary> 11 public class GetEleStatus : IHttpHandler 12 { 13 14 public void ProcessRequest(HttpContext context) 15 { 16 context.Response.ContentType = "text/plain"; 17 18 string result="{\"IdList\":["; 19 20 Random r = new Random(); 21 for (int i = 0; i < 10; i++) 22 { 23 result += r.Next(100000,100022)+","; 24 } 25 result = result.Substring(0, result.Length - 1); 26 result += "]}"; 27 context.Response.Write(result); 28 } 29 30 public bool IsReusable 31 { 32 get 33 { 34 return false; 35 } 36 } 37 } 38 }
最後是獲取設備的詳細信息,這個是在鼠標移動到設備節點上的時候異步請求獲取的。這裏就不詳細說了,大家可以根據自己的需求來做,也不難。
然後做一下總結。插件首先是解析你構造的Json數據,然後放在myDiagram.model對象裏。在數據中有兩個數據:nodeDataArray和linkDataArray分別存放節點信息和節點關聯信息;然後js去遍歷迭代這是兩個數組中的數據來構造拓撲圖。那麼在迭代的過程中。我們可以利用自己的需求去添加代碼實現我們想要的拓撲圖!
這裏的話我分享下我是這麼做的吧。首先 如果你的英語水平很好並且文檔閱讀能力較強,那麼可以不用往下看了。因爲直接去看文檔理解得也深一些,也能明白一些實現原理。
首先 你的明白你的需求是什麼。即你要實現什麼樣的拓撲圖。然後 你去官網他的例子裏面找。找到和你想要的差不多的拓撲圖,或者某個拓撲圖有你要的某個樣式或者佈局方式,或者交互方式等等。然後看他的代碼。那麼這裏你有的先了解整個插件的實現過程。你可以通過詳細分析我的代碼和註釋,應該就能大概明白某寫代碼是什麼功能。某個功能是那個方法實現的,因爲整個插件的實現原理都是一樣的。所以一些方法和屬性也是一樣的,只不過根據屬性的值,能得到不同的拓撲圖;比如佈局屬性myDiagram.layout 比如節點連接屬性:myDiagram.linkTemplate 那麼這裏就那佈局屬性說事,可能你想要的佈局不是我這個例子中的樣子,那麼你就可以到其他拓撲圖找到你想要的佈局方式,然後把他的代碼拿過來。替換掉現有的佈局代碼,當然這裏佈局有兩種方式,一種是插件自動給你佈局,就像我這個例子,還有一種是你自己構造每個節點的位置。 其他的也都大同小異。其實這就是一個組裝拼接的過程。有時候一些外國插件沒有什麼文檔的時候,我都是這乾的,而且效果不錯,速度也快。當然可能這樣做對整個插件的理解就沒有那麼透徹了;
(這裏插播一條廣告:http://xiamiwage.taobao.com/這是本人的淘寶店。唉 苦逼的挨踢男。希望大家多多支持吧)
最後 因爲這個插件是帶有水印的。如果要去水印。就得到他的官網註冊購買。當然我這也有一個破解版的,不過如果你真的要用,還是希望支持正版。
下載地址如下:http://pan.baidu.com/share/link?shareid=203307637&uk=370619680
最後 因爲是第一次寫博客,有什麼需要改進的地方請多多批評 多多建議。謝謝,也希望多多交流。哈哈
源碼地址:http://files.cnblogs.com/zhijiang/DrowNode.rar