/// <summary> /// Overriden to create the family tree template /// </summary> /// <param name="document">document in which to create the template</param> protected override void CreateTemplate(NDrawingDocument document) { NPoint pt; NShape node; NShape edge = null; NPage page = document.Content.ActivePage; // determine the elements dimensions double childrenWidth = m_nChildrenCount * m_VerticesSize.Width + (m_nChildrenCount - 1) * m_fHorizontalSpacing; double parentsWidth = m_VerticesSize.Width * 2 + m_fHorizontalSpacing; // determine the template dimensions double templateWidth = Math.Max(childrenWidth, parentsWidth); NRectangle templateBounds = new NRectangle(m_Origin.X, m_Origin.Y, templateWidth, m_VerticesSize.Height * 2 + m_fVerticalSpacing); NPoint center = templateBounds.Center; // create the parent nodes NShape father = CreateVertex(m_VerticesShape); pt = new NPoint(center.X - (m_VerticesSize.Width + m_fHorizontalSpacing / 2), templateBounds.Y); father.SetBounds(new NRectangle(pt, m_VerticesSize)); page.Items.AddChild(father); NShape mother = CreateVertex(m_VerticesShape); pt = new NPoint(center.X + m_fHorizontalSpacing / 2, templateBounds.Y); mother.SetBounds(new NRectangle(pt, m_VerticesSize)); page.Items.AddChild(mother); // create the children if (m_nChildrenCount > 0) { double childrenY = templateBounds.Y + m_VerticesSize.Height + m_fVerticalSpacing; for (int i = 0; i < m_nChildrenCount; i++) { // create the child node = CreateVertex(m_VerticesShape); pt = new NPoint(i * (m_VerticesSize.Width + m_fHorizontalSpacing), childrenY); node.SetBounds(new NRectangle(pt, m_VerticesSize)); page.Items.AddChild(node); // attach it to the parents edge = CreateEdge(ENConnectorShape.BottomToTop1); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(father); edge.GlueEndToShape(node); edge = CreateEdge(ENConnectorShape.BottomToTop1); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(mother); edge.GlueEndToShape(node); } } }
/// <summary> /// Overriden to create the rectangular grid template in the specified document /// </summary> /// <param name="document">document in which to create the template</param> protected override void CreateTemplate(NDrawingDocument document) { NPage page = document.Content.ActivePage; NShape edge = null; NShape vertex; NShape[,] vertexGrid = new NShape[m_nRows, m_nColumns]; for (int row = 0; row < m_nRows; row++) { for (int col = 0; col < m_nColumns; col++) { // create the vertex vertex = CreateVertex(m_VerticesShape); vertex.SetBounds(new NRectangle(m_Origin.X + col * (m_VerticesSize.Width + m_fHorizontalSpacing), m_Origin.Y + row * (m_VerticesSize.Height + m_fVerticalSpacing), m_VerticesSize.Width, m_VerticesSize.Height)); page.Items.AddChild(vertex); // connect it with its X and Y predecessors if (m_bConnectGrid == false) { continue; } vertexGrid[row, col] = vertex; // connect X if (col > 0) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(vertexGrid[row, col - 1]); edge.GlueEndToShape(vertex); } // connect Y if (row > 0) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(vertexGrid[row - 1, col]); edge.GlueEndToShape(vertex); } } } }
/// <summary> /// Overriden to create the triangular grid template in the specified document /// </summary> /// <param name="document">document in which to create the template</param> protected override void CreateTemplate(NDrawingDocument document) { NPage page = document.Content.ActivePage; NRectangle templateBounds = new NRectangle(m_Origin.X, m_Origin.Y, m_nLevels * m_VerticesSize.Width + (m_nLevels - 1) * m_fHorizontalSpacing, m_nLevels * m_VerticesSize.Height + (m_nLevels - 1) * m_fVerticalSpacing); NPoint location; NShape cur = null, prev = null; NShape edge = null; NList <NShape> curRowNodes = null; NList <NShape> prevRowNodes = null; for (int level = 1; level <= m_nLevels; level++) { // determine the location of the first node in the level location = new NPoint(templateBounds.X + (templateBounds.Width - level * m_VerticesSize.Width - (level - 1) * m_fHorizontalSpacing) / 2, templateBounds.Y + (level - 1) * (m_VerticesSize.Height + m_fVerticalSpacing)); curRowNodes = new NList <NShape>(); for (int i = 0; i < level; i++) { cur = CreateVertex(m_VerticesShape); cur.SetBounds(new NRectangle(location, m_VerticesSize)); page.Items.AddChild(cur); location.X += m_VerticesSize.Width + m_fHorizontalSpacing; // connect the current node with its ancestors and prev node if (m_bConnectGrid == false) { continue; } // connect with prev if (i > 0) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(prev); edge.GlueEndToShape(cur); } // connect with ancestors if (level > 1) { if (i < prevRowNodes.Count) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection((NShape)prevRowNodes[i]); edge.GlueEndToShape(cur); } if (i > 0) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection((NShape)prevRowNodes[i - 1]); edge.GlueEndToShape(cur); } } curRowNodes.Add(cur); prev = cur; } prevRowNodes = curRowNodes; } }
/// <summary> /// Overriden to create the elliptical grid template in the specified document /// </summary> /// <param name="document">document in which to create the template</param> protected override void CreateTemplate(NDrawingDocument document) { int i; NShape node; NShape edge = null; NPoint pt; NList <NShape> nodes = new NList <NShape>(); NPage page = document.Content.ActivePage; // create the ellipse nodes double curAngle = 0; double stepAngle = NMath.PI2 / m_nRimNodesCount; NPoint center = new NPoint(m_Origin.X + m_dRadiusX + m_VerticesSize.Width / 2, m_Origin.Y + m_dRadiusY + m_VerticesSize.Height / 2); for (i = 0; i < m_nRimNodesCount; i++) { pt = new NPoint(center.X + m_dRadiusX * (double)Math.Cos(curAngle) - m_VerticesSize.Width / 2, center.Y + m_dRadiusY * (double)Math.Sin(curAngle) - m_VerticesSize.Height / 2); node = CreateVertex(m_VerticesShape); node.SetBounds(new NRectangle(pt, m_VerticesSize)); page.Items.AddChild(node); nodes.Add(node); curAngle += stepAngle; } // connect the ellipse nodes if (m_bConnectGrid) { for (i = 0; i < m_nRimNodesCount; i++) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(nodes[i]); edge.GlueEndToGeometryIntersection(nodes[(i + 1) % m_nRimNodesCount]); } } if (m_bHasCenter == false) { return; } // create the center node = CreateVertex(m_VerticesShape); pt = new NPoint(center.X - m_VerticesSize.Width / 2, center.Y - m_VerticesSize.Height / 2); node.SetBounds(new NRectangle(pt, m_VerticesSize)); page.Items.AddChild(node); // connect the ellipse nodes with the center if (m_bConnectGrid) { for (i = 0; i < m_nRimNodesCount; i++) { edge = CreateEdge(ENConnectorShape.Line); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(node); edge.GlueEndToGeometryIntersection(nodes[i]); } } }
/// <summary> /// Overriden to create a random graph template in the specified document. /// </summary> /// <param name="document">The document to create a graph in.</param> protected override void CreateTemplate(NDrawingDocument document) { if (m_nEdgeCount < m_nVertexCount - 1) { throw new Exception("##The number of edges must be greater than or equal to the (number of vertices - 1) in order to generate a connected graph"); } if (m_nEdgeCount > MaxEdgeCount(m_nVertexCount)) { throw new Exception("##Too many edges wanted for the graph"); } int i; Random random = new Random(); NPage activePage = document.Content.ActivePage; NShape[] vertices = new NShape[m_nVertexCount]; NList <NPointI> edges = GetRandomMST(m_nVertexCount); NPointI edgeInfo; NSizeI minSize = m_MinVerticesSize.Round(); NSizeI maxSize = m_MaxVerticesSize.Round(); maxSize.Width++; maxSize.Height++; // Create the vertices for (i = 0; i < m_nVertexCount; i++) { vertices[i] = CreateVertex(m_VerticesShape); double width = random.Next(minSize.Width, maxSize.Width); double height = random.Next(minSize.Height, maxSize.Height); vertices[i].SetBounds(new NRectangle(0, 0, width, height)); activePage.Items.AddChild(vertices[i]); } // Generate the edges for (i = m_nVertexCount - 1; i < m_nEdgeCount; i++) { do { // Generate a new edge edgeInfo = new NPointI(random.Next(m_nVertexCount), random.Next(m_nVertexCount)); }while (edgeInfo.X == edgeInfo.Y || edges.Contains(edgeInfo) || edges.Contains(new NPointI(edgeInfo.Y, edgeInfo.X))); edges.Add(edgeInfo); } // Create the edges for (i = 0; i < m_nEdgeCount; i++) { edgeInfo = edges[i]; NShape edge = CreateEdge(ENConnectorShape.RoutableConnector); activePage.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(vertices[edgeInfo.X]); edge.GlueEndToShape(vertices[edgeInfo.Y]); } // Apply a table layout to the generated graph NTableFlowLayout tableLayout = new NTableFlowLayout(); tableLayout.MaxOrdinal = (int)Math.Sqrt(m_nVertexCount) + 1; tableLayout.HorizontalSpacing = m_VerticesSize.Width / 5; tableLayout.VerticalSpacing = m_VerticesSize.Width / 5; NDrawingLayoutContext context = new NDrawingLayoutContext(document, activePage); tableLayout.Arrange(new NList <object>(NArrayHelpers <NShape> .CastAll <object>(vertices)), context); }
/// <summary> /// Creates a tree in the specified document /// </summary> /// <param name="document">document in which to create a tree</param> /// <returns>tree elements</returns> protected virtual NList <NShape> CreateTree(NDrawingDocument document) { NPage page = document.Content.ActivePage; NList <NShape> elements = new NList <NShape>(); NShape cur = null; NShape edge = null; NList <NShape> curRowVertices = null; NList <NShape> prevRowVertices = null; int i, j, level; int childrenCount, levelNodesCount; Random rnd = new Random(); for (level = 1; level <= m_nLevels; level++) { curRowVertices = new NList <NShape>(); if (m_bBalanced) { //Create a balanced tree levelNodesCount = (int)Math.Pow(m_nBranchNodes, level - 1); for (i = 0; i < levelNodesCount; i++) { // create the cur node cur = CreateVertex(m_VerticesShape); cur.SetBounds(new NRectangle(m_Origin, GetSize(rnd))); page.Items.AddChild(cur); elements.Add(cur); // connect with ancestor if (level > 1) { edge = CreateEdge(m_ConnectorShape); page.Items.AddChild(edge); int parentIndex = (int)Math.Floor((double)(i / m_nBranchNodes)); edge.GlueBeginToGeometryIntersection(prevRowVertices[parentIndex]); edge.GlueEndToShape(cur); } curRowVertices.Add(cur); } } else { //Create an unbalanced tree if (level == 1) { // Create the current node cur = CreateVertex(m_VerticesShape); cur.SetBounds(new NRectangle(m_Origin, GetSize(rnd))); page.Items.AddChild(cur); elements.Add(cur); curRowVertices.Add(cur); } else { levelNodesCount = prevRowVertices.Count; do { // Ensure that the desired level depth is reached for (i = 0; i < levelNodesCount; i++) { childrenCount = rnd.Next(0, m_nBranchNodes + 1); for (j = 0; j < childrenCount; j++) { // Create the current node cur = CreateVertex(m_VerticesShape); cur.SetBounds(new NRectangle(m_Origin, GetSize(rnd))); page.Items.AddChild(cur); elements.Add(cur); curRowVertices.Add(cur); // Connect with ancestor edge = CreateEdge(m_ConnectorShape); page.Items.AddChild(edge); edge.GlueBeginToGeometryIntersection(prevRowVertices[i]); edge.GlueEndToShape(cur); } } }while (level < m_nLevels && curRowVertices.Count == 0); } } prevRowVertices = curRowVertices; } return(elements); }