In a large amount of data 2D scene, to find a specific model is difficult, and can only show a part of the model, the display is not intuitive, this time can quickly build a 3D scene there is a great demand. But building 3D scenarios and relying on 3DS Max or Maya professional 3D designers to model, Unity 3D engine to do graphics rendering, this is a challenge for users! However, the HT one-stop solution provides one-stop solutions from modeling to rendering, including component rendering and data fusion. The graphics component of HT's 3D technology based on WEBGL Ht.graph3dview components, which are packaged with WebGL's underlying technology, drive graphical displays based on the HT unified Datamodel data model, as with other HT components, greatly reducing the gate for 3D Graphics technology development Sill, on the basis of familiarity with the HT data model, the average programmer needs only 1 hours of learning to get started with 3D graphics development.
All right, no more nonsense, just attach the demo:http://www.hightopo.com/demo/blog_3dedge_20170630/index.html.
Of course, I'm just using simple graphics to represent the device, and you can certainly change it into a more interesting model.
Now let's see how we do it:
1. Preparatory work:
The 2D API is designed to maintain a lot of consistency, the 3D view component is Ht.graph3d.Graph3dView, the 2D view component is Ht.graph.GraphView, and both share the same data model Datamodel. In HT, in order to get close to the real three-dimensional objects of visual effects, we through the perspective projection so that the far objects become smaller, near objects become larger, parallel lines will appear in the first intersection and so closer to the visual effect of human eye observation:
As shown, the perspective projection ultimately shows the content of the truncated vertebral body only to the content on the screen, so Graphview provides eye,center,up,far,near, Fovy and aspect parameters to control the specific range of the truncated vertebral body, which we use more in the actual application Eye and Center:
Geteye () | Seteye ([x, Y, z]), determines the location of the eye (or Camera), the default value is [0, 300, 1000];
Getcenter () | SetCenter ([x, Y, z]), which determines the location of the target center point (or target), the default value is [0, 0, 0];
For more information, see the HT for Web 3D Manual (http://www.hightopo.com/guide/guide/core/3d/ht-3d-guide.html).
Newnew Ht.graph3d.Graph3dView (datamodel); G3d.seteye(1800, N, +), G3d.setcenter (0, 0); g3d.setdashdisabled (false = ' rgb (ten, +) '; G3d.addtodom ();
2. Create the device:
Server, the server in the Demo is actually the Addstyleicon way to add pictures in the location of the server, see the HT for Web Getting Started manual (http://www.hightopo.com/guide/guide/core/ beginners/ht-beginners-guide.html):
//Register PictureHt. Default.setimage (' server ', ' server.png ');varServer =Newht. Node (); SERVER.S3 (0, 0, 0); SERVER.P3 (0, 60, 0); Server.addstyleicon (' Icon ', {position:0, Width:200, Autorotate:true, Transparent:true, Height:200, names: [' Server '] }); Datamodel.add (server);
Workbench, where the workbench is actually represented by a three-dimensional cylinder, HT in the Graphview 2D graphics, rendering a variety of graphics is determined by the shape property of the style, similar HT on 3D provides Shape3d properties, pre-defined a variety of 3D of the body, details see HT For Web 3D Manual. But here I'm not using predefined graphics, but through HT. The default.createringmodel creates a cylinder that, depending on the curve of the XY plane, wraps around a week to form a 3D model, so it can be used to define a variety of circular 3D models.
var desktop = new ht. Node (); DESKTOP.S ({ ' 3d.selectable ': false ' Shape3d ' : Ht. Default.createringmodel ([ 0, 40 40, 0 0, 40, null , 20, false , false , 50 ' shape3d.color ': ' #003333 '
Device on the platform, we created 32 devices altogether:
varCount = 32; Radius= 400; Index= COUNT/2; for(vari = 1; I <= COUNT/2; i++) {varDevice1_angle1 = Math.PI * 2 * (index-i)/count; Device1_angle2= Math.PI * 2 * (index + i)/count; Device1_angle3= Math.PI * 2 * Index/count; varDevice1_1 = CreateDevice (device1_angle1, RADIUS, 60); Device1_2= CreateDevice (device1_angle2, RADIUS, 60); Device1_3= CreateDevice (device1_angle3, RADIUS, 60); LayoutDevice1 (Device1_1, device1_angle1); varDevice1_edge1 = Createedge (device1_1, Server, ' line1 '); Device1_edge1.s ({' Shape3d.color ': ' RGB (205, 211, 34) '}); Datamodel.add (device1_1); Datamodel.add (DEVICE1_EDGE1); LayoutDevice1 (Device1_2, device1_angle2); varDevice1_edge2 = Createedge (device1_2, Server, ' line1 '); Device1_edge2.s ({' Shape3d.color ': ' RGB (205, 211, 34) '}); Datamodel.add (device1_2); Datamodel.add (Device1_edge2); LayoutDevice1 (Device1_3, device1_angle3); varDevice1_edge3 = Createedge (device1_3, Server, ' line1 '); Device1_edge3.s ({' Shape3d.color ': ' RGB (205, 211, 34) '}); Datamodel.add (device1_3); Datamodel.add (Device1_edge3); }
To make the device layout more reasonable on the platform, the device placement angle is calculated based on index, and the position of each device is calculated according to the cylinder center, disc radius and angle:
function CreateDevice (angle, x, y) { varnew ht. Node (); = Math.Cos (angle); = Math.sin (angle); NODE.P3 (x*sin, y, x*cos); return node; }
Other equipment,
varnum = 18; varh = [800, 900, 1000, 1100, 1200]; varv = [40, 60, 80, 100]; varcolors = [' #fcfc63 ', ' #00E1E4 ']; for(varj = 0; J < num; J + +) { varDevice2_angle = Math.PI * J/num; varDevice2 =CreateDevice (Device2_angle, H[math.floor (Math.random (), V[math.floor (Math.random ())]); DEVICE2.S3 (100, 20, 100); Device2.s ({' Shape3d ': ' Cylinder ', ' Shape3d.color ': Colors[math.floor (Math.random () * *)] }); varDevice2_edge = Createedge (device2, Desktop, ' line2 '); DEVICE2_EDGE.S ({' Shape3d.color ': ' RGB (0, 203, 94) '}); Datamodel.add (DEVICE2); Datamodel.add (Device2_edge); }
3. Connection
The HT for Web provides a default line and multipoint connection type that satisfies most of the basic topology graphics applications, but here we need to draw the curve according to the actual requirements, so you need to use the custom connection type, see the HT for WEB connection type manual for details:
With HT. The Default.setedgetype (type, func, mutual) function can be used to customize the new wire type:
Type: String type, corresponding to the Edge.type property of the style;
Func: function type, return line to information according to incoming parameter (Edge,gap,graphview,samesourcewithfirstedge)
Edge: The current Connection object;
Gap: When multiple lines are bundled, the connection object corresponds to the distance between the center lines;
Graphview: The current corresponding topology component object;
Samesourcewithfirstedge:boolean type, whether to change the connection with the same group of the first homologous;
The return value is {points:new ht. List (...), segments:new ht. List (...)} Structure of the connection to information, segments the following values:
1, MoveTo, occupy 1 points of information;
2, LineTo, occupy 1 points of information;
3, Quadraticcurveto, occupy 2 points of information;
4, Beziercurveto, occupy 3 points of information;
5, Closepath, do not occupy a point of information;
Mutual: This parameter determines whether the connection affects all lines on the starting or ending node, and the default is false to indicate that only the lines in the Edgegroup with source and target are affected, and that the type of the HT predefined line type, with the suffix 2, is mutural true Type of complex connection.
Two types of connections are defined in the Demo, line1 and line:
Ht. Default.setedgetype (' line1 ',function(Edge) {varSourcePoint1 =edge.getsourceagent (). GetPosition (), TargetPoint1=edge.gettargetagent (). GetPosition (), Points1=Newht. List (); Points1.add (SOURCEPOINT1); Points1.add ({x: (sourcepoint1.x+ targetpoint1.x)/2 + 200,e:sourcepoint1.e, y: (Sourcepoint1.y+ targetpoint1.y)/2 }); Points1.add (TARGETPOINT1); return{points:points1, Segments:NewHt. List ([1, 3]) }; }); Ht. Default.setedgetype (' Line2 ',function(Edge) {varSourcepoint =edge.getsourceagent (). GetPosition (), TargetPoint=edge.gettargetagent (). GetPosition (), Points=Newht. List (); Points.Add (Sourcepoint); Points.Add ({x: (Sourcepoint.x+ targetpoint.x)/2, E: ((SOURCEPOINT.E + targetpoint.e)/2 | | 0)-+, Y: (sourcepoi Nt.y + targetpoint.y)/2 }); Points.Add ({x:targetpoint.x, e:targetpoint.e-80, y:targetpoint.y}); return{points:points, Segments:NewHt. List ([1, 3]) }; });
The connection type is defined, and the next step is to create the connection, but there is also a flow effect on the line, how can this be achieved? Our HT has an extended flow line plug-in that can be used in HT. Shape and HT. Increased flow on Edge, support for internal flow elements or user-defined flow elements along the path step, to use is also very convenient, just to introduce the Ht-flow.js file, details visible HT for web Mobile line manual (http://www.hightopo.com/ guide/guide/plugin/flow/ht-flow-guide.html), but plug-ins do not work in 3D models, what to do in a 3D model? Even if we can't use ready-made plug-ins, we can also achieve the flow effect, you can see the HT for Web Getting Started manual in the Wired section, we can use the line style through Edge.dash set to dashed, dynamic change edge.dash.offset dashed line offset, can achieve the flow effect, so, When we create a connection:
functionCreateedge (source, target, type) {varEdge =Newht. Edge (source, target); EDGE.S ({' Edge.color ': ' Yellow ', ' Edge.dash ':true, ' Edge.dash.3d ':true, ' Edge.dash.width ': 4, ' Edge.type ': Type,' Edge.dash.color ': ' RGB (10, 20, 36) ', ' Edge.dash.pattern ': [20, 25] }); Edge.a ({' Flow.enabled ':true, ' Flow.direction ':-1, ' Flow.step ': 4 }); returnEdge; }
Finally, to let the dashed line flow, you can use the scheduling in HT, details can be seen in the HT for WEB Dispatch manual (http://www.hightopo.com/guide/guide/core/schedule/ht-schedule- guide.html):
Flowtask = { , function(data) {if(DATA.A (' Flow.enabled ') { var offset = data.s (' edge.dash.offset ') + data.a (' flow.step ') * DATA.A (' Flow.direction '); DATA.S (' edge.dash.offset ', offset);}} ; Datamodel.addscheduletask (flowtask);
Here, the main technical point of the Demo has been introduced once, we can see the strength of our HT, of course, our official online has a lot of very interesting effect, we can also take a look, you can play with our HT feel its strong, again attached to the Demo address:/http Www.hightopo.com/demo/blog_3dedge_20170630/index.html.
3D network topology diagram based on HTML5 WebGL