예제 #1
0
        /// <summary>
        /// Performs the actual layout algorithm. This will execute on a background thread.
        /// </summary>
        /// <param name="graphData">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        protected override Dictionary<INodeShape, NodePosition> PerformLayout(GraphMapData graphData, INode rootNode)
        {
            IList<NodeMapData> nodeVMs = new List<NodeMapData>(graphData.GetNodes());
            IDictionary<INodeShape, NodePosition> nodes = new Dictionary<INodeShape, NodePosition>();

            double currentAngle = 0; // Represents the current angle
            double radius = GetRadius(nodeVMs); // The computed radius of the circle

            // Loop through each visible node, perform the appropriate calculations,
            // then move it to the correct position on the graph.
            bool firstPass = true;
            foreach (NodeMapData nodeVM in nodeVMs)
            {
                // Determine the angle for the current node
                if (!firstPass)
                    currentAngle += GetAngle(nodeVM, radius);

                //Calculate radians (radians = degrees * PI/180)
                double radians = currentAngle * Math.PI / 180;
                double x = Math.Cos(radians) * radius;
                double y = Math.Sin(radians) * radius;

                // We're no longer on the first pass
                firstPass = false;

                // Return the node position
                nodes.Add(nodeVM, new NodePosition(new Point(x, y), currentAngle));
            }

            return nodes;
        }
예제 #2
0
        /// <summary>
        /// Performs the actual layout algorithm.
        /// </summary>
        /// <param name="graph">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        protected override void PerformLayout(GraphMapData graph, INode rootNode)
        {
            double currentAngle = 0D; // Represents the current angle

            int numNodes = graph.Nodes.Count;
            double angle = GetAngle(numNodes);
            double radius = GetRadius(numNodes); // The computed radius of the circle

            // Loop through each node, perform the appropriate calculations,
            // then move it to the correct position on the graph.
            foreach (NodeMapData node in graph.GetNodes())
            {
                if (rootNode != null && node.Id.Equals(rootNode.ID))
                {
                    Point position = new Point(0D, 0D);
                    node.Position = position;
                }
                else
                {
                    //Calculate radians
                    double radians = Math.PI * currentAngle / 180D;
                    double x = Math.Cos(radians) * radius;
                    double y = Math.Sin(radians) * radius;

                    Point position = new Point(x, y);
                    node.Position = position;

                    currentAngle += angle;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Removes node overlap occurring in the input graph
        /// </summary>
        /// <param name="graph">GraphMapData</param>
        public static void FSAOverlapRemoval(GraphMapData graph)
        {
            ICollection<NodeMapData> nodes = graph.GetNodes();
            IDictionary<string, Rect> rectangles = new Dictionary<string, Rect>(nodes.Count);

            foreach (NodeMapData node in nodes)
            {
                Point location = new Point(node.Position.X, node.Position.Y);
                Rect rect = new Rect(location, node.Dimension);
                rectangles[node.Id] = rect;
            }
            OverlapRemovalParameters overlapRemovalParameters = new OverlapRemovalParameters()
            {
                HorizontalGap = 0F,
                VerticalGap = 0F
            };

            FSAAlgorithm<string> overlapRemoval = new FSAAlgorithm<string>(rectangles, overlapRemovalParameters);
            overlapRemoval.Compute();

            foreach (NodeMapData node in nodes)
            {
                Rect rect = overlapRemoval.Rectangles[node.Id];
                Point pos = new Point(rect.X, rect.Y);
                node.Position = pos;
            }
        }
예제 #4
0
        public static Chart GraphToAnb(GraphMapData graph)
        {
            Chart chart = new Chart();
            chart.chartItemCollection = new ChartItemCollection();
            chart.chartItemCollection.chartItems = new Collection<ChartItem>();

            foreach (IconNodeMapData node in graph.GetNodes())
            {
                ChartItem chartItem = new ChartItem();
                chart.chartItemCollection.chartItems.Add(chartItem);

                chartItem.attrLabel = node.Label;

                string hexBackgroundColor = String.Format("#{0:x2}{1:x2}{2:x2}{3:x2}", node.BackgroundColor.A, node.BackgroundColor.R, node.BackgroundColor.G, node.BackgroundColor.B);
                chartItem.ciStyle = new CIStyle();
                chartItem.ciStyle.font = new Font();
                chartItem.ciStyle.font.attrBackColour = hexBackgroundColor;

                chartItem.end = new End();
                chartItem.end.entity = new Entity();
                chartItem.end.entity.icon = new Icon();
                chartItem.end.entity.icon.iconStyle = new IconStyle();

                chartItem.attributeCollection = new AttributeCollection();
                chartItem.attributeCollection.attributes = new Collection<Anb.Attribute>();
                foreach (KeyValuePair<string, AttributeMapData> kvp in node.Attributes)
                {
                    Anb.Attribute attribute = new Anb.Attribute();
                    chartItem.attributeCollection.attributes.Add(attribute);

                    attribute.attrAttributeClass = kvp.Key;
                    attribute.attrValue = kvp.Value.Value;
                }
            }

            foreach (EdgeMapData edge in graph.GetEdges())
            {
                ChartItem chartItem = new ChartItem();
                chart.chartItemCollection.chartItems.Add(chartItem);

                chartItem.link = new Link();
                chartItem.link.attrEnd1Id = edge.Source;
                chartItem.link.attrEnd2Id = edge.Target;

                chartItem.link.linkStyle = new LinkStyle();
                chartItem.link.linkStyle.attrType = edge.Label;
            }

            return chart;
        }
예제 #5
0
파일: GridLayout.cs 프로젝트: senfo/snaglV2
        /// <summary>
        /// Performs the actual layout algorithm.
        /// </summary>
        /// <param name="graph">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        protected override void PerformLayout(GraphMapData graph, INode rootNode)
        {
            ICollection<NodeMapData> nodes = graph.GetNodes();

            // First we determine the amount of space that we are dealing with
            double totalArea = 0D;
            foreach (NodeMapData node in nodes)
            {
                double nodeWidth = node.Dimension.Width + MARGIN.Left + MARGIN.Right;
                double nodeHeight = node.Dimension.Height + MARGIN.Top + MARGIN.Bottom;

                totalArea += nodeWidth * nodeHeight;
            }

            // TODO NEED TO DECOUPLE THIS
            GraphViewModel graphVM = ViewModelLocator.GraphDataStatic;

            // Calculate the bounding height and width of our square
            double boundingHeight = Math.Sqrt(totalArea);
            double boundingWidth = boundingHeight * (graphVM.Width / graphVM.Height);
            boundingHeight = boundingHeight / (graphVM.Width / graphVM.Height);

            //TODO: THE LINES ABOVE ARE THE ONLY REASON WE ARE COUPLED TO THE GRAPH VIEW MODEL

            double currentX = 0D;
            double currentY = 0D;
            double maxColumnWidth = 0D;

            double maxHeight = nodes.Max(node => node.Dimension.Height) + MARGIN.Top + MARGIN.Bottom;
            int columnSize = (int)Math.Round(boundingHeight / maxHeight);

            List<NodeMapData> nodesList = nodes.ToList<NodeMapData>();
            nodesList.Sort(NodeSizeComparer);
            foreach (NodeMapData node in nodesList)
            {
                if (currentY > boundingHeight)
                {
                    currentX += maxColumnWidth + MARGIN.Left + MARGIN.Right;
                    maxColumnWidth = 0D;
                    currentY = 0D;
                }

                maxColumnWidth = Math.Max(node.Dimension.Width, maxColumnWidth);

                Point position = new Point(currentX, currentY);
                node.Position = position;

                currentY += maxHeight;
            }
        }
예제 #6
0
        /// <summary>
        /// Get adjacency graph from input graph
        /// </summary>
        /// <param name="graph">GraphMapData</param>
        /// <returns>AdjacencyGraph</returns>
        public static AdjacencyGraph<string, Edge<string>> GetAdjacencyGraph(GraphMapData graph)
        {
            ICollection<NodeMapData> nodes = graph.GetNodes();
            AdjacencyGraph<string, Edge<string>> adjacencyGraph = new AdjacencyGraph<string, Edge<string>>(true, nodes.Count);

            foreach (NodeMapData node in nodes)
            {
                adjacencyGraph.AddVertex(node.Id);
            }

            foreach (EdgeMapData edge in graph.GetEdges())
            {
                Edge<string> quickGraphEdge = new Edge<string>(edge.Source, edge.Target);
                adjacencyGraph.AddEdge(quickGraphEdge);
            }

            return adjacencyGraph;
        }
예제 #7
0
파일: TreeLayout.cs 프로젝트: senfo/snaglV2
        /// <summary>
        /// Performs the actual layout algorithm.
        /// </summary>
        /// <param name="graph">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        protected override void PerformLayout(GraphMapData graph, INode rootNode)
        {
            NodeMapData nodeToProcess = null;
            if (rootNode != null)
            {
                nodeToProcess = graph.Nodes[rootNode.ID];
            }

            // Loop over the nodes until they have all been positioned
            while (processedNodes.Count != graph.Nodes.Count)
            {
                // Get the highest rank node that has not already been
                // positioned
                if (nodeToProcess == null)
                {
                    double maxRanking = double.MinValue;

                    // Loop over the nodes looking for the highest ranked one
                    foreach (NodeMapData node in graph.GetNodes())
                    {
                        double currentRanking = GetNodeRanking(graph, node);
                        if (!processedNodes.Contains(node.Id) && (nodeToProcess == null || maxRanking < currentRanking))
                        {
                            maxRanking = currentRanking;
                            nodeToProcess = node;
                        }
                    }
                }

                // Position the node
                SaveNodePosition(nodeToProcess, maxXPosition, 0D);

                processedNodes.Add(nodeToProcess.Id);
                AddToLayer(nodeToProcess, 0);

                // Layer the graph
                CalulateSubtreePosition(graph, nodeToProcess, 1);

                nodeToProcess = null;
            }

            // reset for next run
            maxXPosition = 0D;
            processedNodes.Clear();
            layers.Clear();
            layerSpans.Clear();
        }
예제 #8
0
        private static IDictionary<string, Point> GetOriginalPositions(GraphMapData clusteredGraphMapData)
        {
            ICollection<NodeMapData> nodes = clusteredGraphMapData.GetNodes();
            IDictionary<string, Point> originalPositions = new Dictionary<string, Point>(nodes.Count);

            foreach (NodeMapData node in nodes)
            {
                originalPositions[node.Id] = node.Position;
            }

            return originalPositions;
        }
예제 #9
0
        private static void WriteHeader(XmlWriter writer, GraphMapData graph)
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("graphml", "http://graphml.graphdrawing.org/xmlns");
            writer.WriteAttributeString("xmlns", "berico", string.Empty, BERICO_NAMESPACE_URI);
            writer.WriteAttributeString("xmlns", "xsi", string.Empty, "http://www.w3.org/2001/XMLSchema-instance");
            writer.WriteAttributeString("xsi", "schemaLocation", string.Empty, "http://graphml.graphdrawing.org.xmlns/1.0/graphml.xsd");

            if (graph.GetNodes().Count > 0)
            {
                bool graphHasIconNode = false;
                foreach (NodeMapData objNode in graph.GetNodes())
                {
                    if (objNode is IconNodeMapData)
                    {
                        graphHasIconNode = true;
                        break;
                    }
                }
                if (graphHasIconNode)
                {
                    WritePropKey(writer, NODE_PROPERTY_PREFIX, "ImageSource", "node");
                }

                WritePropKey(writer, NODE_PROPERTY_PREFIX, "Description", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "DisplayValue", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "Width", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "Height", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "Position", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "IsHidden", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "BackgroundColor", "node");
                WritePropKey(writer, NODE_PROPERTY_PREFIX, "SelectionColor", "node");
            }

            if (graph.GetEdges().Count > 0)
            {
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "DisplayValue", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "LabelTextUnderline", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "Thickness", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "Color", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "LabelBackgroundColor", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "LabelForegroundColor", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "LabelFontStyle", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "LabelFontWeight", "edge");
                WritePropKey(writer, EDGE_PROPERTY_PREFIX, "LabelFont", "edge");
            }

            ISet<string> seenAttributes = new HashSet<string>();
            foreach (NodeMapData objNode in graph.GetNodes())
            {
                foreach (KeyValuePair<string, AttributeMapData> kvp in objNode.Attributes)
                {
                    if (seenAttributes.Add(kvp.Key))
                    {
                        WriteAttrKey(writer, NODE_ATTRIBUTE_PREFIX, kvp.Value.Name, "node");
                    }
                }
            }

            seenAttributes.Clear();
            foreach (EdgeMapData objEdge in graph.GetEdges())
            {
                foreach (KeyValuePair<string, AttributeMapData> kvp in objEdge.Attributes)
                {
                    if (seenAttributes.Add(kvp.Key))
                    {
                        WriteAttrKey(writer, EDGE_ATTRIBUTE_PREFIX, kvp.Value.Name, "edge");
                    }
                }
            }
        }
예제 #10
0
        private static void WriteGraphContent(XmlWriter writer, GraphMapData graph)
        {
            writer.WriteStartElement("graph");
            writer.WriteAttributeString("id", "snagl_export_graph");

            GraphType edgedefault = GraphType.Undirected;
            foreach (EdgeMapData objEdge in graph.GetEdges())
            {
                if (objEdge.Type == EdgeType.Directed)
                {
                    edgedefault = GraphType.Directed;
                    break;
                }
            }
            writer.WriteAttributeString("edgedefault", edgedefault.ToString());

            NodeTypes defaultNodeType = NodeTypes.Text;
            foreach (NodeMapData objNode in graph.GetNodes())
            {
                if (objNode is IconNodeMapData)
                {
                    defaultNodeType = NodeTypes.Icon;
                    break;
                }
            }
            writer.WriteAttributeString("berico", "nodeType", BERICO_NAMESPACE_URI, defaultNodeType.ToString());

            foreach (NodeMapData objNode in graph.GetNodes())
            {
                WriteNode(writer, objNode);
            }

            foreach (EdgeMapData objEdge in graph.GetEdges())
            {
                WriteEdge(writer, objEdge);
            }

            writer.WriteEndElement();
        }
예제 #11
0
        /// <summary>
        /// Get bidirectional graph from input graph
        /// </summary>
        /// <param name="graph">GraphMapData</param>
        /// <returns>BidirectionalGraph</returns>
        public static BidirectionalGraph<string, WeightedEdge<string>> GetBidirectionalGraph(GraphMapData graph)
        {
            ICollection<NodeMapData> nodes = graph.GetNodes();
            BidirectionalGraph<string, WeightedEdge<string>> bidirectionalGraph = new BidirectionalGraph<string, WeightedEdge<string>>(true, nodes.Count);

            foreach (NodeMapData node in nodes)
            {
                bidirectionalGraph.AddVertex(node.Id);
            }

            foreach (EdgeMapData edge in graph.GetEdges())
            {
                WeightedEdge<string> weightedEdge = new WeightedEdge<string>(edge.Source, edge.Target, edge.Weight);
                bidirectionalGraph.AddEdge(weightedEdge);
            }

            return bidirectionalGraph;
        }
예제 #12
0
 /// <summary>
 /// Updates the input graph node positions with those from the input mapping
 /// </summary>
 /// <param name="graph">GraphMapData</param>
 /// <param name="vertexPositions">map of node id to vector</param>
 public static void SetNodePositions(GraphMapData graph, IDictionary<string, Vector> vertexPositions)
 {
     ICollection<NodeMapData> nodes = graph.GetNodes();
     foreach (NodeMapData node in nodes)
     {
         Vector vPos = vertexPositions[node.Id];
         Point pPos = new Point(vPos.X, vPos.Y);
         node.Position = pPos;
     }
 }
예제 #13
0
        /// <summary>
        /// Gets a mapping of node id to size
        /// </summary>
        /// <param name="graph">GraphMapData</param>
        /// <returns>map of node id to size</returns>
        public static IDictionary<string, Size> GetNodeSizes(GraphMapData graph)
        {
            ICollection<NodeMapData> nodes = graph.GetNodes();
            IDictionary<string, Size> nodeSizes = new Dictionary<string, Size>(nodes.Count);

            foreach (NodeMapData node in nodes)
            {
                nodeSizes[node.Id] = node.Dimension;
            }

            return nodeSizes;
        }
예제 #14
0
        /// <summary>
        /// Gets a mapping of node id to vector
        /// </summary>
        /// <param name="graph">GraphMapData</param>
        /// <returns>map of node id to vector</returns>
        public static IDictionary<string, Vector> GetNodePositions(GraphMapData graph)
        {
            ICollection<NodeMapData> nodes = graph.GetNodes();
            IDictionary<string, Vector> nodePositions = new Dictionary<string, Vector>(nodes.Count);

            foreach (NodeMapData node in nodes)
            {
                Vector vPos = new Vector(node.Position.X, node.Position.Y);
                nodePositions[node.Id] = vPos;
            }

            return nodePositions;
        }