2012/07/12

.NET Realizing the Four-Layer Topological Structure

TWaver Java can present network topology with a wonderful effect. Recently, some clients have made requests that they want to present it by .NET. It will not be that difficult with the help of the powerful functions of TWaver and the previous examples of Swing. Now I will share with you this method.


It’s a typical four-layer network. The first way I thought of is to realize it by Group. We can set the corresponded properties of group as in the previous examples of Swing.
group.IsExpanded = true;
group.SetStyle(Styles.BODY_ALPHA, 0.8);
group.SetStyle(Styles.GROUP_FILL_COLOR, color);
group.SetStyle(Styles.GROUP_GRADIENT, Consts.GRADIENT_LINEAR_NORTHEAST);
group.SetStyle(Styles.LABEL_POSITION, Consts.POSITION_RIGHT);
group.SetStyle(Styles.LABEL_XOFFSET, 100);
group.SetStyle(Styles.LABEL_SIZE, 14);
group.SetStyle(Styles.LABEL_BOLD, true);
group.SetStyle(Styles.LABEL_FONT, new FontFamily("微软雅黑"));
This rectangle is not agreeable. We have found out that there seems to be no property to set parallelogram after reading TWaver's relating documents. This is quite troublesome, for we have to turn to the customized functions for help. Fortunately, thanks to TWaver’s user-friendliness, we can repaint it with the corresponded interface. In order to show the parallelogram with 3D effects, it is necessary to set two properties to 3D group: one being angle, which is the offset location of the upper two corners of the group (a parallelogram) in relation to the two lower corners of the rectangle. The other is depth, that is, the thickness of 3D. Now we are able to customize it with the two parameters. We need to rewrite group's method DrawContent(). First, we can draw the dots at the four corners of the parallelogram according to angle with the method bound from Group.
double angle = group.Angle;
double deep = group.Deep;
double gap = bounds.Height / Math.Tan(angle * Math.PI / 180);
PointCollection points = new PointCollection();
Point p1 = new Point(bounds.X - gap, bounds.Y + bounds.Height);
points.Add(p1);
Point p2 = new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height);
points.Add(p2);
Point p3 = new Point(bounds.X + bounds.Width + gap, bounds.Y);
points.Add(p3);
points.Add(new Point(bounds.X, bounds.Y));
// Add
path.Data = this.CreateGeometry(points);
this.AddComponent(path);
this.AddBodyBounds(path.Data.Bounds);
Next, we need to draw the 3D effects’ parts below and at the right side: draw a small parallelogram below. This is quite easy as long as we calculate accurately the position of the dots at the four corners of the parallelogram through the two dots at the two lower corners of the bigger parallelogram and the thickness of it.
// Add Bottom Rectangle
path = new Path();
// Set Fill
path.Fill = Utils.CreateSolidColorBrush(fillColor);
// Set Outline
this.SetStroke(path);
// Set Data
RectangleGeometry rectangleGeometry = new RectangleGeometry();
rectangleGeometry.Rect = new Rect(p1.X, p1.Y, p2.X-p1.X, deep);
// Add
path.Data = rectangleGeometry;
this.AddComponent(path);
this.AddBodyBounds(path.Data.Bounds);
Here the details to the parallelogram at the right side are omitted since it is the same as the parallelogram below. Let’s see the running effects:

The effect is quite agreeable as we have expected. Since the parallelogram is ready, we will add some nodes onto it.
Continue to create the four groups with the general method.

Now we will try to make the highlight in this Demo: the penetrating effect. This means that how can the links linking different layers penetrate group when the node at an upper layer is related to another node at another layer, which has something to do with "layer" in TWaver. The relationship among the nodes in the four above structures is shown through layers. The software business layer is set as the top one, overlapping elements at all of the layers below; the same as the penetrating of links. We can divide a link as two parts: the upper part, which is at the same layer as the from-nodes and the lower part, which is at the same layer as the to-nodes. The two parts are linked with a virtual node in the middle.
private void CreateCrossLayerLink(object fromID, object toID, bool left)
        {
            Node from = (Node)this.box.GetDataByID(fromID);
            Node to = (Node)this.box.GetDataByID(toID);
            if (from == null || to == null)
            {
                return;
            }
            ConnectPoint point = new ConnectPoint();
            point.LayerID = from.LayerID;
            double xOffset = -from.Width / 2 - 15;
            if (left)
            {
                xOffset = from.Width / 2 + 15;
            }
            double yOffset = from.Height / 2 + 20;
            double x = from.CenterLocation.X + xOffset;
            double y = from.CenterLocation.Y + yOffset;
            point.SetCenterLocation(x, y);
            point.Parent = from.Parent;
            this.box.Add(point);

            LayerLink upLink = new LayerLink(from, point, true);
            upLink.LayerID = from.LayerID;
            upLink.Parent = from.Parent;
            this.box.Add(upLink);

            LayerLink downLink = new LayerLink(point, to, false);
            downLink.LayerID = to.LayerID;
            downLink.Parent = to.Parent;
            this.box.Add(downLink);
        }
The effect is seen immediately. Let’s create more links.

No comments:

Post a Comment