Example #1
0
        public override CircularNetwork MakeNetwork(IEnumerable <Node> nodes, IEnumerable <Link> links)
        {
            CircularNetwork net = base.MakeNetwork(nodes, links);
            // assume each Node has a constant diameter, ignoring any TextBlock
            double dia = 20;

            foreach (CircularVertex v in net.Vertexes)
            {
                v.Diameter = dia;
            }
            return(net);
        }
    /// <summary>
    /// Do a circular layout.
    /// </summary>
    /// <remarks>
    /// </remarks>
    public override void DoLayout(IEnumerable<Node> nodes, IEnumerable<Link> links) {
      // Create Network
      if (this.Network == null) {
        this.Network = MakeNetwork(nodes, links);
      }

      // If there's only one node, put it at the origin
      if (this.Network.Vertexes.Count() == 1) {
        CircularVertex cv = this.Network.Vertexes.ElementAt(0);
        cv.Center = new Point(0, 0);
        return;
      }

      List<CircularVertex> vertices;
      List<CircularVertex> evens; // for bidirectionals, nodes of even index are usually arranged separately from odd index nodes
      List<CircularVertex> odds;

      // this also sets all of the E... "Effective" canonicalized property values
      SetEffectiveValues(out vertices, out evens, out odds);

      if ((this.Direction == CircularDirection.BidirectionalLeft ||
           this.Direction == CircularDirection.BidirectionalRight) &&
          EArrangement == CircularArrangement.Packed) {
        // if Arrangement == Packed and Direction is bidirectional, this is achieved by using a rearrangement of the vertices, and shifting the StartAngle
        PackedLayout(vertices, ESweepAngle, EStartAngle - ESweepAngle / 2, CircularDirection.Clockwise);
      } else if (this.Direction == CircularDirection.BidirectionalLeft || this.Direction == CircularDirection.BidirectionalRight) {
        double dsa = 0; // change in start angle
        // bidirectionals are achieved by laying out the even nodes in one direction, then laying out the odds in the opposite direction.
        // StartAngles must be slightly different.  The switch below computes the difference
        switch (this.EArrangement) {
          case CircularArrangement.ConstantDistance:
            dsa = EllipseAngle(ERadius, Yradius, EStartAngle, constdist) * 180 / Math.PI;
            break;
          case CircularArrangement.ConstantSpacing: {
              double evendia = 0;
              double odddia = 0;
              CircularVertex firsteven = evens.FirstOrDefault();
              if (firsteven != null) evendia = firsteven.ComputeDiameter(Math.PI / 2);
              CircularVertex firstodd = odds.FirstOrDefault();
              if (firstodd != null) odddia = firstodd.ComputeDiameter(Math.PI / 2);
              dsa = EllipseAngle(ERadius, Yradius, EStartAngle, ESpacing + (evendia + odddia) / 2) * 180 / Math.PI;
              break;
            }
          case CircularArrangement.ConstantAngle:
            dsa = ESweepAngle / vertices.Count;
            break;
        }
        // layout evens, then odds
        if (this.Direction == CircularDirection.BidirectionalLeft) {
          switch (this.EArrangement) {
            case CircularArrangement.ConstantDistance: DistanceLayout(evens, ESweepAngle / 2, EStartAngle, CircularDirection.Counterclockwise); break;
            case CircularArrangement.ConstantSpacing: SpacingLayout(evens, ESweepAngle / 2, EStartAngle, CircularDirection.Counterclockwise); break;
            case CircularArrangement.ConstantAngle: AngleLayout(evens, ESweepAngle / 2, EStartAngle, CircularDirection.Counterclockwise); break;
          }
          switch (this.EArrangement) {
            case CircularArrangement.ConstantDistance: DistanceLayout(odds, ESweepAngle / 2, EStartAngle + dsa, CircularDirection.Clockwise); break;
            case CircularArrangement.ConstantSpacing: SpacingLayout(odds, ESweepAngle / 2, EStartAngle + dsa, CircularDirection.Clockwise); break;
            case CircularArrangement.ConstantAngle: AngleLayout(odds, ESweepAngle / 2, EStartAngle + dsa, CircularDirection.Clockwise); break;
          }
        } else {
          switch (this.EArrangement) {
            case CircularArrangement.ConstantDistance: DistanceLayout(odds, ESweepAngle / 2, EStartAngle, CircularDirection.Counterclockwise); break;
            case CircularArrangement.ConstantSpacing: SpacingLayout(odds, ESweepAngle / 2, EStartAngle, CircularDirection.Counterclockwise); break;
            case CircularArrangement.ConstantAngle: AngleLayout(odds, ESweepAngle / 2, EStartAngle, CircularDirection.Counterclockwise); break;
          }
          switch (this.EArrangement) {
            case CircularArrangement.ConstantDistance: DistanceLayout(evens, ESweepAngle / 2, EStartAngle + dsa, CircularDirection.Clockwise); break;
            case CircularArrangement.ConstantSpacing: SpacingLayout(evens, ESweepAngle / 2, EStartAngle + dsa, CircularDirection.Clockwise); break;
            case CircularArrangement.ConstantAngle: AngleLayout(evens, ESweepAngle / 2, EStartAngle + dsa, CircularDirection.Clockwise); break;
          }
        }
      } else {
        // if Direction isn't bidirectional, the nodes are laid out by calling one of these functions.
        switch (this.EArrangement) {
          case CircularArrangement.ConstantDistance: DistanceLayout(vertices, ESweepAngle, EStartAngle, Direction); break;
          case CircularArrangement.ConstantSpacing: SpacingLayout(vertices, ESweepAngle, EStartAngle, Direction); break;
          case CircularArrangement.ConstantAngle: AngleLayout(vertices, ESweepAngle, EStartAngle, Direction); break;
          case CircularArrangement.Packed: PackedLayout(vertices, ESweepAngle, EStartAngle, Direction); break;
        }
      }

      // Update the "physical" positions of the nodes and links.
      if (this.Diagram != null && !this.Diagram.CheckAccess()) {
        Diagram.InvokeLater(this.Diagram, UpdateParts);
      } else {
        UpdateParts();
      }

      this.Network = null;
    }
 /// <summary>
 /// Allocate a <see cref="CircularNetwork"/>.
 /// </summary>
 /// <returns></returns>
 public virtual CircularNetwork CreateNetwork() {
   CircularNetwork n = new CircularNetwork();
   n.Layout = this;
   return n;
 }
 private void UpdateParts() {
   VerifyAccess();
   Diagram diagram = this.Diagram;
   if (diagram != null) diagram.StartTransaction("CircularLayout");
   LayoutNodesAndLinks();
   if (diagram != null) diagram.CommitTransaction("CircularLayout");
   if (diagram != null && diagram.LayoutManager != null) {
     /* *****/
     CircularNetwork net = this.Network;
     diagram.LayoutManager.AddUpdateLinks(this, () => {
       this.Network = net;
       LayoutLinks();
       this.Network = null;
     });
   }
 }