的初衷是为了模拟服务端-客户端的通信。我将整个需求简化为今天的例子。3D机房的模拟一般需要鹰眼的辅助,这样对产品的搜索和对整个空间的概览会更加清晰。在这个例子中,我也添加了它。这篇文章是我对这个项目的总结。.对了,这个例子是我参考了一个DEMO完成的,和例子中的显示有点出入,大家不要惊讶。例子链接:http://www.hightopo.com/demo/3DEdgeFlow/index.html本文动图:这个例子没有设计师的参与,大家会安于样式,但是我觉得还不错,哈哈~进入正题,整个例子实现了差不多200行代码,这也是我喜欢用HT的原因。现在Web3d技术兴起,大致分为两大派系:插件派和HTML5派。HT是基于HTML5的,不需要安装任何插件啊,扯远了。..首先,从场景的搭建开始。该接口在body中添加了三个部分:3d组件、property组件和topology组件(2d组件)。添加方式是这样的:为了最外层组件加载填充窗口方便,HT所有组件都有addToDOM函数,其实现逻辑如下,其中iv是invalidate的缩写:addToDOM=function(){varself=this,view=self.getView(),style=view.style;document.body.appendChild(视图);style.left='0';style.right='0';style.top='0';样式.bottom='0';window.addEventListener('resize',function(){self.iv();},false);}因为这个函数固定了样式中的位置,所以所有的组件不能都使用这个函数,我们根据这个函数在界面中添加topology组件和property组件,3d组件可以直接使用addToDOM函数:dm=newht.DataModel();g3d=newht.graph3d.Graph3dView(dm);//3d组件g3d.addToDOM();//添加组件到bodyg3d.setDashDisabled(false);//启用虚线流g3d.setMovableFunc(function(){//重载移动函数returnfalse;//返回false,所有图元不可移动});g3d.setEye([-813,718,1530]);//设置眼睛g3d.setCenter([140,-25,217]);//设置中心(target)gv=newht.graph.GraphView(dm);//二维组件gv.getView().className='graphview';//HT组件的根层是一个div,通过getView()函数获取document.body.appendChild(gv.getView());//将拓扑组件添加到主体gv.fitContent(true);//缩放和平移整个拓扑以显示所有图元propertyView=newht.widget.PropertyView(dm);//属性组件propertyView.getView()。className='property';propertyView.setWidth(240);//设置组件宽度propertyView.setHeight(150);//高度document.body.appendChild(propertyView.getView());拓扑组件和属性组件的样式不再赘述,只设置背景颜色和左右上下位置。这里要声明一下,HT组件一般都是使用设置position为absolute的绝对定位方式。你可能想知道,这个鹰眼是怎么来的?在HT中,只要2D和3D共享同一个数据容器dataModel,就可以共享这个dataModel中的所有元素,位置都是对应的,就像这样:dm=newht.DataModel();g3d=newht.graph3d.Graph3dView(dm);gv=newht.graph.GraphView(dm);是不是很简单。..可以节省大量的开发时间。..本例中除了connection之外的所有元素都是ht.Node类型的节点,所以我们封装了这个节点的创建方法以便复用:functioncreateNode(p3,s3,name,shape){//CreateNodevarnode=newht.Node();//创建一个ht.Node类型的节点dm.add(node);//将节点添加到数据容器dataModelnode.s({//设置节点的样式,s是的缩写setStyle'shape3d':shape,//指定节点的形状,这里是传入3d模型的json文件'label.position':23,//文字显示位置'label.transparent':true,//是否文字在3d中是透明的可以消除字体周围的锯齿'label.color':'#eee',//文字颜色'label.t3':\[0,0,-151\],//文字是inOffsetunder3d'label.r3':\[0,Math.PI,0\],//Rotationoftextunder3d'label.scale':2//文本缩放});node.r3(0,Math.PI,0);//节点旋转node.p3(p3);//设置节点在3d下的位置node.s3(s3);//设置节点在3d下的大小3dnode.setName(name);//设置节点的显示名称returnnode;//返回节点}并创建连接:functioncreateEdge(exchange,service){//创建连接varedge=newht.边缘(交换、服务);分米。添加(边缘);edge.s({'edge.width':4,//连线宽度'edge.color':'red',//连线颜色'edge.dash':true,//是否显示虚线'edge.dash.color':'yellow',//虚线颜色'edge.dash.pattern':\[32,32\],//默认虚线样式为\[16,16\]});edge.a({//用户自定义属性是setAttr的缩写'flow.enable':true,//是否开启flow'flow.direction':1,//direction'flow.step':4//步进});returnedge;}我们界面显示的连接都是虚线流,HT默认关闭虚线流功能,使用下面一句开启虚线流功能:g3d.setDashDisabled(false);//打开虚线流,我们还需要设置动画,控制时间间隔,让虚线偏移,形成“流”的状态。动画请参考调度手册:flowTask={interval:40,action:function(data){if(data.a('flow.enable')){data.s('edge.dash.offset',data.s('edge.dash.offset')+(data.a('flow.step')\*data.a('flow.direction')));}}};dm.addScheduleTask(flowTask);//添加flowTask动画下面是界面上出现的所有server和client节点声明,都是基于createNode和createEdge函数创建的:floor=createNode(\[0,5,0\],\[1000,10,500\]);//floor元素floor.s({//设置元素s的样式为setStyle的缩写'all.color':'rgb(47,79,79)'//六面体的整体颜色});exchange\=createNode(\[0,300,-400\],\[200,20,150\],'H3C核心交换机','机型/机房/机柜相关/机柜设备6.json');//switch//五台不同功能的服务器service1=createNode(\[-400,140,0\],\[100,260,100\],'Standby','机型/机房/机柜相关/cabinet2.json');service2\=createNode(\[-200,140,0\],\[100,260,100\],'网站','机型/机房/机柜相关/cabinet2.json');service3\=createNode(\[0,140,0\],\[100,260,100\],'OA','机型/机房/机柜相关/cabinet2.json');service4\=createNode(\[200,140,0\],\[100,260,100\],'广告','机型/机房/机柜相关/cabinet2.json');service5\=createNode(\[400,140,0\],\[100,260,100\],'验收','机型/机房/机柜相关/cabinet2.json');//创建交换机和服务器之间的连接//第二台交换机exchange2=createNode(\[-100,60,400\],\[200,20,150\],'ProcurveSwitch2010-23交换机','机型/机房/机柜相关/机柜设备6.json').s('label.color','#000');createEdge(exchange2,service1);createEdge(exchange2,service2);createEdge(exchange2,service3);createEdge(exchange2,service4);createEdge(exchange2,service5);floor2\=createNode(\[-100,5,800\],\[1000,10,500\]);floor2.s({'all.color':'rgb(47,79,79)'});device1\=createNode(\[-400,20,650\],\[200,20,100\],'VLS12000(top)','机型/机房/机柜相关/机柜设备6.json');device2\=createNode(\[100,20,650\],\[200,20,100\],'VLS12000(下)','机型/机房/机柜相关/机柜设备6.json');device3\=createNode(\[-200,20,800\],\[200,20,100\],'HPStrageWorks8/8SAN交换机(上)','机型/机房/机柜相关/机柜设备6.json');device4\=createNode(\[200,20,800\],\[200,20,100\],'HPStrageWorks8/8SAN交换机(下)','机型/机房/机柜相关/机柜设备6.json');device5\=createNode(\[-300,20,950\],\[200,20,100\],'EVA8400HSV450(top)','机型/机房/机柜相关/机柜设备6.json');device6\=createNode(\[100,20,950\],\[200,20,100\],'EVA8400HSV450(下)','机型/机房/机柜相关/机柜设备6.json');createEdge(exchange2,device1);edge1\=createEdge(exchange2,device2);createEdge(device1,device3);createEdge(device1,device4);createEdge(device2,device3);createEdge(device2,device4);createEdge(device3,device5);createEdge(device3,device5);创建eEdge(device3,device6);createEdge(device4,device5);createEdge(device4,device6);dm.sm().ss(edge1);//设置并选中edge1最后需要在属性栏中添加属性,这里我们只显示和调整“连接”的属性,一共5个属性,包括属性流。.dash.color我们通过name属性结合accessType属性实现对Data节点的访问://连接的属性edgeProperties=\[{name:'flow.enable',//用于访问name属性accessType:'attr',//操作访问属性类型displayName:'EnableFlow',//用于访问属性名称的显示文本值,如果为空,则显示名称属性的值valueType:'boolean',//使用提示组件提供合适的renderer渲染,boolean类型,显示为checkboxeditable:true//设置属性是否可编辑},{name:'flow.direction',accessType:'attr',displayName:'FlowDirection',enum:{//number传递类型属性值的数字和文字数组:\[-1,1\],labels:\['forwardflow','reverseflow'\]},editable:true},{name:'flow.step',displayName:'FlowStep',editable:true,accessType:'attr',slider:{//表单插件中的slider应该添加到ht-form.jsmin:0,//最小值max:10,//最大值step:0.1//step}},{name:'edge.color',accessType:'style',displayName:'EdgeColor',editable:true,价值eType:'color',//颜色类型,通过填充背景色来显示colorPicker:{//颜色选择框instant:true//获取和设置是否为即时状态,默认为true,代表表单和propertypage编辑时,模型值会实时变化}},{name:'edge.dash.color',displayName:'DashColor',accessType:'style',valueType:'color',editable:true,colorPicker:{instant:true}}\];propertyView.setEditable(true);//设置属性组件可编辑propertyView.addProperties(edgeProperties);//添加连接属性是不是很简单~来实践一下吧!
