Creating the visual for a node

In this recipe, we will create the building block for our relational network: the node. This is basically a circle with a label in the middle. If it is not the center node (the parent), then it will also display how many children it has.

Creating the visual for a node

Getting ready

Open the files downloaded from the Packt Publishing website for Chapter 8 | Recipe 2 folder to follow along.

How to do it...

The following are the steps required to do the visuals for a node:

  1. Create the NodeVisual.as class where everything will happen.
  2. Add in the constructor code to draw the under circle and the gradient circle:
    _underCircle = new Shape();
    _underCircle.graphics.beginFill(0xffffff);
    _underCircle.graphics.drawCircle(0, 0, _radius);
    addChild(_underCircle);
    
    _circle = new Sprite();
    var matrix:Matrix = new Matrix();
    matrix.createGradientBox(_radius*2, _radius*2, 0, -_radius, -_radius);
    _circle.graphics.lineStyle(1, _color);
    _circle.graphics.beginGradientFill(GradientType.RADIAL, [0xffffff, _color], [0.2, 0.65], [20, 255], matrix);
    _circle.graphics.drawCircle(0, 0, _radius);
    addChild(_circle);
  3. Instantiate Textfield and adjust its properties:
    _label = new TextField();
    _label.selectable = false;
    _label.defaultTextFormat = textFormat;
    _label.text = node.name;
    _label.width = _label.textWidth + 3;
    _label.height = _label.textHeight + 3;
    _label.x = -_label.width / 2;
    _label.y = -_label.height / 2;
  4. Create the label background based on the layer height and width:
    _labelBackground = new Sprite();
    _labelBackground.graphics.beginFill(_color);
    _labelBackground.graphics.drawRoundRect(_label.x - 6, _label.y - 3, _label.width + 12, _label.height + 6, 10, 10);
    addChild(_labelBackground);
    addChild(_label);
  5. Create a function to show the children of this node and if this node indeed has children, call the function:
    private function _addChildren():void {
      var circle:Shape;
      var length:int = _node.children.length;
      if (length > 26) {
        length = 26;
      }
    
      for (var i:int = 0; i < length ; i++) {
        circle = new Shape();
        circle.graphics.beginFill(_color);
        circle.graphics.drawCircle(0, 0, 7);
        circle.x = (_radius + 7) * Math.cos((i * 14) * Math.PI / 180 );
        circle.y = (_radius + 7) * Math.sin((i * 14) * Math.PI / 180);
        _childrenHolder.addChild(circle);
      }
      _childrenHolder.rotation = (length - 1) * 14 / -2 + _angle;
    }
  6. In Main.as, instantiate the root node based on the data.

How it works...

Our representation of a node will be a circle with a label on top of it. This circle will have a radial gradient in it. Now, since that gradient will have some transparency, we will actually need two circles. One will be underneath the one with the gradient with full white color just so that our node is not transparent anymore. In the code that circle is called _underCircle.

To create a radial gradient in ActionScript, you first have to delimit its frontiers. You do so by creating a Matrix object and by using its createGradientBox function. The next thing you need to do is to tell it how you want the colors to blend; this is done in the graphics.createGradientFill function. The first parameter of that function is the type of gradient you want, in our case radial. The second parameter is the colors that are going to be used for our gradient. Next is the transparency of those colors. After that, we will tell it, using a number from 0 to 255, where those colors meet. Finally, we will give it the matrix we created earlier to store the bounding box of the gradient. Gradients are always a bit tricky but by playing with different settings, mostly different parameters (three and four), you can achieve various effects.

Next up, we create the label and the box under it. We draw a rounded rectangle, which is mostly like drawing a normal rectangle except you need to give it information about how rounded you want it to be.

We want to give an idea of how many children a child node has. This will give more information to the user when he will eventually want to navigate to the relational network. We will display each child as a little circle around our main circle. With the size of circle we chose, we can't show more than 26 children, so we start by checking for that. After that we place these circles at radius distances from the center and spaced at an angle of 14 degrees.

There's more...

By allowing some customizable styles, we could improve on our relational network.

Styling

Indeed, right now the style for our nodes is pretty rigid; the only thing that is customizable is the color. We could allow the data to provide font and size for each node along with many other styling options. Allowing this would make our relational network more useful.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.44.23