首页 > 代码库 > 使用 jsPlumb 绘制拓扑图 —— 异步加载与绘制的实现
使用 jsPlumb 绘制拓扑图 —— 异步加载与绘制的实现
本文实现的方法可以边异步加载数据边绘制拓扑图。 有若干点需要说明一下:
1. 一次性获取所有数据并绘制拓扑图, 请参见文章: <使用 JsPlumb 绘制拓扑图的通用方法> ; 本文实现的最终显示效果与之类似, 所使用的基本方法与之类似。
2. 在此次实现中, 可以一边异步加载数据一边绘制拓扑图, 是动态可扩展的;
3. 所有影响节点位置、布局的配置均放置在最前面, 便于修改, 避免在代码中穿梭, 浪费时间;
4. 布局算法比之前的实现更加完善;
5. 此实现由于与业务逻辑绑得比较紧, 可复用的部分不多, 但是可以作为一个模板, 用在读者自己的场景中, 自行修改相应的节点类型、URL等。
6. 添加了附着点的点击事件处理, 可以刷新显示关联实体;
7. 主流程很简单: 发送 AJAX 请求获取数据 ---> 创建节点(实际上就是DIV) ---> 计算节点位置、布局 ---> 添加节点附着点 ---> 缓存节点连接 ---> 连接所有现有的缓存节点连接。 多个 AJAX 请求的处理是异步的, 顺序没有控制。
8. 代码:
/** * 使用 jsPlumb 根据指定的拓扑数据结构绘制拓扑图 * 使用 drawTopo_asyn(vmName, regionNo, parentDivId) 方法 */ /** * 初始化拓扑图实例及外观设置 */ (function() { jsPlumb.importDefaults({ DragOptions : { cursor: 'pointer', zIndex:2000 }, EndpointStyles : [{ fillStyle:'#225588' }, { fillStyle:'#558822' }], Endpoints : [ [ "Dot", { radius:2 } ], [ "Dot", { radius: 2 } ]], ConnectionOverlays : [ [ "Label", { location:1 } ], [ "Label", { location:0.1, id:"label", cssClass:"aLabel" }] ] }); var connectorPaintStyle = { lineWidth: 1, strokeStyle: "#096EBB", joinstyle:"round", outlineColor: "#096EBB", outlineWidth: 1 }; var connectorHoverStyle = { lineWidth: 2, strokeStyle: "#5C96BC", outlineWidth: 2, outlineColor:"white" }; var endpointHoverStyle = { fillStyle:"#5C96BC" }; window.topoDrawUtil = { sourceEndpoint: { endpoint:"Dot", paintStyle:{ strokeStyle:"#1e8151", fillStyle:"transparent", radius: 4, lineWidth:2 }, isSource:true, maxConnections:-1, connector:[ "Flowchart", { stub:[40, 60], gap:1, cornerRadius:5, alwaysRespectStubs:true } ], connectorStyle: connectorPaintStyle, hoverPaintStyle: endpointHoverStyle, connectorHoverStyle: connectorHoverStyle, dragOptions:{}, overlays:[ [ "Label", { location:[0.5, 1.5], label:"", cssClass:"endpointSourceLabel" } ] ] }, targetEndpoint: { endpoint: "Dot", paintStyle: { fillStyle:"#1e8151",radius: 2 }, hoverPaintStyle: endpointHoverStyle, maxConnections:-1, dropOptions:{ hoverClass:"hover", activeClass:"active" }, isTarget:true, overlays:[ [ "Label", { location:[0.5, -0.5], label:"", cssClass:"endpointTargetLabel" } ] ] }, initConnection: function(connection) { connection.getOverlay("label").setLabel(connection.sourceId + "-" + connection.targetId); connection.bind("editCompleted", function(o) { if (typeof console != "undefined") console.log("connection edited. path is now ", o.path); }); }, removeAllEndPoints: function(nodeDivId) { jsPlumb.removeAllEndpoints($('#'+nodeDivId)); }, addEndpoints: function(toId, sourceAnchors, targetAnchors) { for (var i = 0; i < sourceAnchors.length; i++) { var sourceUUID = toId + sourceAnchors[i]; var endPoint = jsPlumb.addEndpoint(toId, this.sourceEndpoint, { anchor:sourceAnchors[i], uuid:sourceUUID }); endPoint.bind("click", function(endpoint) { var anchorType = endpoint.anchor.type; var nodeType = toId.split('_')[0]; var content = toId.split('_')[1]; if (nodeType == VM_TYPE) { switch (anchorType) { case 'Right': cacheKey = 'VM-DEVICE-'+ vmNodeData.key; cacheConnectionData[cacheKey] = null; linkDevices(vmNodeData, vmNodeData.key); break; case 'Top': cacheKey = 'VM-ACCOUNT-'+ vmNodeData.key; cacheConnectionData[cacheKey] = null; vmName = vmNodeData.key; regionNo = vmNodeData.data.region_no; linkAccount(vmNodeData, vmName, regionNo); break; case 'Bottom': cacheKey = 'VM-NC-'+ vmNodeData.key; cacheConnectionData[cacheKey] = null; ncId = vmNodeData.data.nc_id; regionNo = vmNodeData.data.region_no; linkNc(vmNodeData, ncId, regionNo); break; case 'Left': cacheKey = 'VM-VIP-'+ vmNodeData.key; cacheConnectionData[cacheKey] = null; vmInnerIp = vmNodeData.data.vm_inner_ip; linkVips(vmNodeData, vmInnerIp); break; default: break; } } else if (nodeType == DEVICE_TYPE) { if (anchorType == 'Bottom') { cacheKey = 'DEVICE-SNAPSHOT-'+ content; cacheConnectionData[cacheKey] = null; deviceNodeData = http://www.mamicode.com/deviceNodeDataMapping[content];>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。