Ejemplo n.º 1
0
		public virtual bool Arrange(FlowChart chart)
		{
			chart.UndoManager.onStartLayout("Anneal layout");

			// Build the graph
			FCGraph graph = new FCGraph(chart, _keepGroupLayout);

			// Find the root adapter
			Layout.INode rootNode = null;
			if (_root != null)
			{
				foreach (FCNode node in graph.Nodes)
				{
					if (node.Node == _root)
					{
						rootNode = node;
						break;
					}
				}
			}

			// Split graph to subgraphs
			Layout.IGraph[] subgraphs = null;
			if (_splitGraph)
			{
				subgraphs = Layout.GraphSplitter.Split(
					graph, new FCGraphBuilder(chart, false));
			}
			else
			{
				subgraphs = new Layout.IGraph[] { graph };
			}
			
			// Create the layouter
			Layout.AnnealLayout layout = new Layout.AnnealLayout();

			Layout.LayoutProgress progress = null;
			if (_progress != null)
				progress = new Layout.LayoutProgress(this.OnLayoutProgress);

			Layout.AnnealLayoutInfo info = new Layout.AnnealLayoutInfo();

			info.DistributionFactor = this.DistributionFactor;
			info.BoundaryFactor = this.BoundaryFactor;
			info.EdgeLengthFactor = this.ArrowLengthFactor;
			info.CrossingEdgesCost = this.CrossingArrowsCost;
			info.NodeEdgeDistFactor = this.NodeArrowDistFactor;

			info.IterationsPerStage = this.IterationsPerStage;
			info.Stages = this.Stages;
			info.Temperature = this.InitialTemperature;
			info.TemperatureScale = this.TemperatureScale;

			info.LayoutArea = this.LayoutArea;
			info.WidthHeightRatio = this.WidthHeightRatio;
			info.Randomize = this.Randomize;

			float xOffset = 0;
			foreach (FCGraph subgraph in subgraphs)
			{
				// If a root node is specified and the subgraph
				// does not contain that node, do not arrange
				// the subgraph
				if (rootNode != null)
				{
					if (!subgraph.Nodes.Contains(rootNode))
						continue;
				}

				layout.Arrange(subgraph, info, progress);

				// Translate the whole subgraph
				RectangleF graphBounds = subgraph.GetBounds(false);
				float xToMove = xOffset - graphBounds.X;
				float yToMove = -graphBounds.Y;

				foreach (FCNode node in subgraph.Nodes)
				{
					RectangleF nodeBounds = node.Bounds;
					RectangleF oldBounds = node.Node.BoundingRect;
					nodeBounds.X += xToMove;
					nodeBounds.Y += yToMove;
					node.Bounds = nodeBounds;
					if (_layoutNode != null)
						_layoutNode(node.Node, oldBounds);
				}

				xOffset += graphBounds.Width;

				// Update arrows
				foreach (FCLink link in subgraph.Links)
				{
					Arrow arrow = link.Arrow;

					if (arrow.IgnoreLayout)
						continue;

					// If the arrow being arranged is dynamic,
					// ignore the anchoring flag?
					if (arrow.Dynamic)
						arrow.updatePosFromOrgAndDest(false);
					arrow.arrangePoints(_anchoring);

					if (_layoutLink != null)
						_layoutLink(arrow);
				}
			}

			chart.Invalidate();
			chart.UndoManager.onEndLayout();

			return true;
		}
Ejemplo n.º 2
0
		public virtual bool Arrange(FlowChart chart)
		{
			chart.UndoManager.onStartLayout("Grid layout");

			// Build the graph
			FCGraph graph = new FCGraph(chart, _keepGroupLayout);

			// Find the root adapter
			Layout.INode rootNode = null;
			if (_root != null)
			{
				foreach (FCNode node in graph.Nodes)
				{
					if (node.Node == _root)
					{
						rootNode = node;
						break;
					}
				}
			}

			// Split graph to subgraphs
			Layout.IGraph[] subgraphs = null;

			if (_splitGraph)
			{
				subgraphs = Layout.GraphSplitter.Split(
					graph, new FCGraphBuilder(chart, false));
			}
			else
			{
				subgraphs = new Layout.IGraph[] { graph };
			}

			// Create the layouter
			Layout.GridLayout layout = new Layout.GridLayout();

			Layout.LayoutProgress progress = null;
			if (_progress != null)
				progress = new Layout.LayoutProgress(this.OnLayoutProgress);

			Layout.GridLayoutInfo info = new Layout.GridLayoutInfo();
			info.GridSize = this.GridSize;
			info.Iterations = this.Iterations;
			info.XGap = this.XGap;
			info.YGap = this.YGap;
			info.RndSeed = this.RndSeed;

			float xOffset = XGap;
			foreach (FCGraph subgraph in subgraphs)
			{
				// If a root node is specified and the subgraph
				// does not contain that node, do not arrange
				// the subgraph
				if (rootNode != null)
				{
					if (!subgraph.Nodes.Contains(rootNode))
						continue;
				}

				// Set the start and end nodes
				info.StartNode = null;
				info.EndNode = null;
				foreach (FCNode node in subgraph.Nodes)
				{
					if (node.Node == _startNode)
						info.StartNode = node;
					if (node.Node == _endNode)
						info.EndNode = node;
				}

				// Ensure both start and end nodes are set
				if (info.StartNode == null || info.EndNode == null)
				{
					info.StartNode = null;
					info.EndNode = null;
				}

				layout.Arrange(subgraph, info, progress);

				// Translate the whole subgraph
				RectangleF graphBounds = subgraph.GetBounds(false);
				float xToMove = xOffset - graphBounds.X;
				float yToMove = info.YGap - graphBounds.Y;

				foreach (FCNode node in subgraph.Nodes)
				{
					RectangleF nodeBounds = node.Bounds;
					RectangleF oldBounds = node.Node.BoundingRect;
					nodeBounds.X += xToMove;
					nodeBounds.Y += yToMove;
					node.Bounds = nodeBounds;
					if (_layoutNode != null)
						_layoutNode(node.Node, oldBounds);
				}

				xOffset += graphBounds.Width + info.GridSize;

				// Update arrows
				foreach (FCLink link in subgraph.Links)
				{
					if (link.Arrow.IgnoreLayout)
						continue;

					link.Arrow.arrangePoints(_anchoring);
					if (_layoutLink != null)
						_layoutLink(link.Arrow);
				}
			}

			chart.RouteAllArrows();
			chart.Invalidate();
			chart.UndoManager.onEndLayout();

			return true;
		}