Exemple #1
0
        private static object[] GetPartitionNodeDimensionAndPosition(GraphMapData graphMapData, PartitionNode partitionNode)
        {
            Point topLeft     = new Point(double.MaxValue, double.MaxValue);
            Point bottomRight = new Point(double.MinValue, double.MinValue);

            // Loop through all node view models to get the bounding area
            foreach (NodeViewModelBase nodeViewModelBase in partitionNode.Nodes)
            {
                NodeMapData nodeMapData = graphMapData.Nodes[nodeViewModelBase.ParentNode.ID];

                topLeft.X = Math.Min(topLeft.X, nodeMapData.Position.X - nodeMapData.Dimension.Width / 2D);
                topLeft.Y = Math.Min(topLeft.Y, nodeMapData.Position.Y - nodeMapData.Dimension.Height / 2D);

                bottomRight.X = Math.Max(bottomRight.X, nodeMapData.Position.X + nodeMapData.Dimension.Width / 2D);
                bottomRight.Y = Math.Max(bottomRight.Y, nodeMapData.Position.Y + nodeMapData.Dimension.Height / 2D);
            }

            // Set the new dimensions based on the calculation performed
            double width  = Math.Max(bottomRight.X - topLeft.X, 1D);
            double height = Math.Max(bottomRight.Y - topLeft.Y, 1D);

            Size dimension = new Size(width, height);

            // get the center of the partitionNode
            Point position = new Point(topLeft.X + width / 2D, topLeft.Y + height / 2D);

            object[] result = new object[] { dimension, position };
            return(result);
        }
Exemple #2
0
 /// <summary>
 /// Calulcates the length of the chord for the provided NodeViewModelBase
 /// object.  A 'chord' is a line segment that connects two points on a
 /// curve.
 /// </summary>
 /// <param name="node">Node for which to calculate the chord length for</param>
 /// <returns>The chord length for the givenn node</returns>
 private static double CalculateChordLength(NodeMapData node)
 {
     // Use the Pythagorean theorem to calculate the length of the chord
     // segment between each node based on the height and width of the
     // provided node.
     return(Math.Sqrt(node.Width * node.Width + node.Height * node.Height + 1));
 }
Exemple #3
0
        private static void WriteNode(XmlWriter writer, NodeMapData objNode)
        {
            writer.WriteStartElement("node");
            writer.WriteAttributeString("id", objNode.Id);

            if (objNode.GetType().Equals(typeof(IconNodeMapData)))
            {
                WritePropData(writer, NODE_PROPERTY_PREFIX, "ImageSource", ((IconNodeMapData)objNode).ImageSource.ToString());
            }

            WritePropData(writer, NODE_PROPERTY_PREFIX, "Description", objNode.Description);
            WritePropData(writer, NODE_PROPERTY_PREFIX, "DisplayValue", objNode.Label);
            WritePropData(writer, NODE_PROPERTY_PREFIX, "Height", objNode.Dimension.Height.ToString());
            WritePropData(writer, NODE_PROPERTY_PREFIX, "Width", objNode.Dimension.Width.ToString());
            WritePropData(writer, NODE_PROPERTY_PREFIX, "Position", objNode.Position.ToString());
            WritePropData(writer, NODE_PROPERTY_PREFIX, "IsHidden", objNode.IsHidden.ToString());

            string backgroundColor = GetSnaglStrColor(objNode.BackgroundColor);

            WritePropData(writer, NODE_PROPERTY_PREFIX, "BackgroundColor", backgroundColor);

            string selectionColor = GetSnaglStrColor(objNode.SelectionColor);

            WritePropData(writer, NODE_PROPERTY_PREFIX, "SelectionColor", selectionColor);

            foreach (KeyValuePair <string, AttributeMapData> kvp in objNode.Attributes)
            {
                string description = "{\"Name\":\"" + kvp.Value.Name + "\",\"PreferredSimilarityMeasure\":\"" + kvp.Value.SimilarityMeasure + "\",\"SemanticType\":" + (int)kvp.Value.SemanticType + ",\"Visible\":" + (!kvp.Value.IsHidden).ToString().ToLower() + "}";
                WriteAttrData(writer, NODE_ATTRIBUTE_PREFIX, kvp.Value.Name, description, kvp.Value.Value);
            }

            writer.WriteEndElement();
        }
Exemple #4
0
        private static int NodeSizeComparer(NodeMapData first, NodeMapData second)
        {
            double areaFirst  = first.Dimension.Width * first.Dimension.Height;
            double areaSecond = second.Dimension.Width * second.Dimension.Height;

            return(-areaFirst.CompareTo(areaSecond));
        }
Exemple #5
0
        public void AddNode(ScriptableNodeMapData scriptableNode)
        {
            NodeMapData objNode = ScriptableMapper.GetNode(scriptableNode);

            GraphComponents graphComponents = GraphManager.Instance.DefaultGraphComponentsInstance;

            MappingExtensions.AddNode(graphComponents, CreationType.Live, objNode);
        }
Exemple #6
0
        /// <summary>
        /// Adds the provided node view model to the specified layer
        /// </summary>
        /// <param name="node">The node view model to be added</param>
        /// <param name="currentLayer">The layer to add the view model too</param>
        private void AddToLayer(NodeMapData node, int currentLayer)
        {
            // Loop over all the layers up to the specified layer
            while (layers.Count <= currentLayer)
            {
                layers.Add(new List <NodeMapData>());
            }

            // Add the provided node view model to the layer
            layers[currentLayer].Add(node);
        }
Exemple #7
0
 private NodeMapData GetOppositeNode(GraphMapData graph, EdgeMapData edge, NodeMapData node)
 {
     if (edge.Source.Equals(node.Id))
     {
         return(graph.Nodes[edge.Target]);
     }
     else
     {
         return(graph.Nodes[edge.Source]);
     }
 }
Exemple #8
0
        private static double GetNumberOfEdges(GraphMapData graph, NodeMapData node)
        {
            double numEdges = 0D;

            foreach (EdgeMapData edge in graph.GetEdges())
            {
                if (edge.Source.Equals(node.Id) || edge.Target.Equals(node.Id))
                {
                    numEdges++;
                }
            }

            return(numEdges);
        }
Exemple #9
0
        private static ICollection <EdgeMapData> GetNodesEdges(GraphMapData graph, NodeMapData node)
        {
            ICollection <EdgeMapData> edges = new List <EdgeMapData>();

            foreach (EdgeMapData edge in graph.GetEdges())
            {
                if (edge.Source.Equals(node.Id) || edge.Target.Equals(node.Id))
                {
                    edges.Add(edge);
                }
            }

            return(edges);
        }
Exemple #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lastNode"></param>
        /// <param name="thisNode"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        private static double GetAngle(NodeMapData thisNode, double radius)
        {
            // Is this the first node?
            //if (lastNode == null) return 0;

            // Lay out node after the
            double circumference = 2 * Math.PI * radius;

            double chordLength = CalculateChordLength(thisNode);

            // Percent of the total circumference we need to move
            double percent = (MIN_NODE_ARC_SPACING + chordLength) / circumference;

            return(360.0 * percent);
        }
Exemple #11
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)
        {
            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();
        }
Exemple #12
0
 /// <summary>
 /// Determines the ranking of the provided node
 /// </summary>
 /// <param name="graph">The object containing the graph data</param>
 /// <param name="node">The node to get the rank for</param>
 /// <returns>the rank for this node</returns>
 private double GetNodeRanking(GraphMapData graph, NodeMapData node)
 {
     // Check if we have a custom ranker to use.  A custom ranker
     // is a custom delegate that is used to determine the nodes
     // rank.
     if (CustomRootRanker != null)
     {
         return(CustomRootRanker(node));
     }
     else
     {
         // As a fallback, determine the nodes rank base on the
         // number of edges that it has
         return(GetNumberOfEdges(graph, node));
     }
 }
Exemple #13
0
        /// <summary>
        /// Executes the JavaScript function specified by <paramref name="callbackName"/>
        /// </summary>
        /// <param name="sender">The NodeViewModel that raised the event</param>
        /// <param name="callbackName">The name of the JavaScript function to execute</param>
        private static void ExecuteNodeJSCallback(object sender, string callbackName)
        {
            //TODO:  VALIDATE CALLBACK
            try
            {
                NodeViewModelBase     nodeVM                = (NodeViewModelBase)sender;
                NodeMapData           nodeMapData           = MappingExtensions.GetNode(nodeVM);
                ScriptableNodeMapData scriptableNodeMapData = ScriptableMapper.GetNode(nodeMapData);

                HtmlPage.Window.Invoke(callbackName, scriptableNodeMapData);
            }
            catch (InvalidOperationException)
            {
                MessageBox.Show("Unable to find the '" + callbackName + "' method in the host application", "Unknown callback", MessageBoxButton.OK);
                // Swallow error for now
                //TODO:  LOG THIS CASE
            }
        }
Exemple #14
0
        /// <summary>
        /// Pushes over all nodes in the specified layer by the specified amount
        /// </summary>
        /// <param name="layer">The current layer being analyzed</param>
        /// <param name="endNode">The last node view model to be processed</param>
        /// <param name="amount">The amount to shove the nodes over</param>
        private void PushNodesOver(int layer, NodeMapData endNode, double amount)
        {
            // Ensure that we have any layers
            if (layers.Count > layer)
            {
                // push the nodes over
                foreach (NodeMapData currentNode in layers[layer])
                {
                    if (currentNode.Id.Equals(endNode.Id))
                    {
                        break;
                    }

                    currentNode.Position = new Point(currentNode.Position.X + amount, currentNode.Position.Y);
                }

                // Continue pushing nodes over for each layer (recursively)
                PushNodesOver(layer + 1, endNode, amount);
            }
        }
Exemple #15
0
        private static void ApplyOffsetToSubGraphs(GraphMapData graph, GraphComponents clusteredGraphComponents, IDictionary <string, Point> originalPositions, GraphMapData partitionGraph)
        {
            IEnumerable <INodeShape> clusteredComponents = clusteredGraphComponents.GetNodeViewModels();

            foreach (PartitionNode clusteredComponent in clusteredComponents)
            {
                Point  originalPosition = originalPositions[clusteredComponent.ID];
                double xOffset          = partitionGraph.Nodes[clusteredComponent.ID].Position.X - originalPosition.X;
                double yOffset          = partitionGraph.Nodes[clusteredComponent.ID].Position.Y - originalPosition.Y;

                IList <NodeViewModelBase> viewModelNodes = clusteredComponent.Nodes;
                foreach (NodeViewModelBase viewModelNode in viewModelNodes)
                {
                    NodeMapData nodeMapData = graph.Nodes[viewModelNode.ParentNode.ID];

                    Point offsetPosition = new Point(nodeMapData.Position.X + xOffset, nodeMapData.Position.Y + yOffset);
                    nodeMapData.Position = offsetPosition;
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Converts the provided GraphComponents instance to a GraphMapData
        /// instance that can be exported to a target file format
        /// </summary>
        /// <param name="graphComponents">The graph to be exported</param>
        /// <returns>A GraphMapData instance ready to be exported to the target format</returns>
        public static GraphMapData ExportGraph(this GraphComponents graphComponents)
        {
            GraphMapData graph = new GraphMapData();

            // Nodes
            IEnumerable <INodeShape> uiNodeViewModels = graphComponents.GetNodeViewModels();

            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData objNode = GetNode(uiNodeVM);
                graph.Add(objNode);
            }

            // Edges
            IEnumerable <IEdgeViewModel> edgeViewModels = graphComponents.GetEdgeViewModels();

            foreach (EdgeViewModelBase uiEdge in edgeViewModels)
            {
                EdgeMapData objEdge = GetEdge(uiEdge);
                graph.Add(objEdge);
            }

            return(graph);
        }
Exemple #17
0
        private static GraphMapData GetGraph(GraphMapData graphMapData, GraphComponents clusteredGraph)
        {
            GraphMapData clusteredGraphMapData = new GraphMapData();

            // Nodes
            IEnumerable <INodeShape> uiNodeViewModels = clusteredGraph.GetNodeViewModels();

            foreach (NodeViewModelBase uiNodeVM in uiNodeViewModels)
            {
                NodeMapData nodeMapData = graphMapData.Nodes[uiNodeVM.ParentNode.ID];
                clusteredGraphMapData.Add(nodeMapData);

                // Edges
                IEnumerable <IEdge> uiEdgeViewModels = clusteredGraph.GetEdges(uiNodeVM.ParentNode);
                foreach (IEdge uiEdgeVM in uiEdgeViewModels)
                {
                    string      edgeKey     = uiEdgeVM.Source.ID + uiEdgeVM.Target.ID;
                    EdgeMapData edgeMapData = graphMapData.Edges[edgeKey];
                    clusteredGraphMapData.Add(edgeMapData);
                }
            }

            return(clusteredGraphMapData);
        }
Exemple #18
0
        /// <summary>
        /// Calulates the subtrees overall position
        /// </summary>
        /// <param name="graph">The object containing the graph data</param>
        /// <param name="node">The root node view model for this tree</param>
        /// <param name="layer">The layer (or row in the tree) being analyzed</param>
        private void CalulateSubtreePosition(GraphMapData graph, NodeMapData node, int layer)
        {
            IList <NodeMapData> children = new List <NodeMapData>();
            double totalWidth            = 0D;

            //TODO:  MAYBE REVISE TO USE GET NEIGHBORS

            // Loop over the provided nodes edges in order to get its children
            foreach (EdgeMapData edge in GetNodesEdges(graph, node))
            {
                // TODO:  HANDLE EDGE VISIBILITY

                // Get the node at the opposite end of this edge
                NodeMapData childNode = GetOppositeNode(graph, edge, node);

                // Ensure that the node has not already been positioned
                if (childNode != null && !childNode.IsHidden && !processedNodes.Contains(childNode.Id))
                {
                    // Position the node
                    children.Add(childNode);
                    totalWidth += childNode.Dimension.Width;
                    processedNodes.Add(childNode.Id);
                }
            }

            // If there are no children, then we are done
            if (children.Count == 0)
            {
                return;
            }

            // Now we need to analyze and lay out all the children as a unit
            totalWidth += (children.Count - 1D) * NODE_SPACING;

            double currentX = node.Position.X - ((totalWidth - children[0].Dimension.Width) / 2D);
            double currentY = node.Position.Y + node.Dimension.Height + LAYER_SPACING;

            // Determine if the layers overlap
            double intersectAmount = IntersectsOnLayer(layer, currentX, currentX + totalWidth);

            // Check if we had an intersection
            if (intersectAmount != 0)
            {
                double pushAmount = intersectAmount / 2D;
                currentX -= pushAmount;

                // Give the nodes a little shove so they no longer
                // intersect with another subtree
                PushNodesOver(layer, node, pushAmount);

                // Make sure to push over the nodes in the root layer as well
            }

            AddSpanToLayer(layer, currentX, currentX + totalWidth);

            // Once we get here we have a good position, so we need to set it
            foreach (NodeMapData currentChildNode in children)
            {
                SaveNodePosition(currentChildNode, currentX, currentY);
                AddToLayer(currentChildNode, layer);

                currentX += currentChildNode.Dimension.Width + NODE_SPACING;
            }

            // Now we need to do the same thing for each
            // of the children node, recursively
            foreach (NodeMapData currentChildNode in children)
            {
                CalulateSubtreePosition(graph, currentChildNode, layer + 1);
            }
        }
Exemple #19
0
        /// <summary>
        /// Adds the specificed node
        /// </summary>
        /// <param name="graphComponents">The Graph that data is being imported into</param>
        /// <param name="creationType">The specified CreationType</param>
        /// <param name="objNode">Node to be added</param>
        public static void AddNode(GraphComponents graphComponents, CreationType creationType, NodeMapData objNode)
        {
            // Create new node
            Node uiNode = new Node(objNode.Id);

            uiNode.SourceMechanism = creationType;

            // TODO as NodeMapData types expands, this needs to be adjusted
            NodeTypes uiNodeType = NodeTypes.Simple;

            if (objNode is IconNodeMapData)
            {
                uiNodeType = NodeTypes.Icon;
            }
            else if (objNode is TextNodeMapData)
            {
                uiNodeType = NodeTypes.Text;
            }

            NodeViewModelBase uiNodeVM = NodeViewModelBase.GetNodeViewModel(uiNodeType, uiNode, graphComponents.Scope);

            // Properties
            if (uiNodeType == NodeTypes.Icon)
            {
                IconNodeMapData objIconNode = (IconNodeMapData)objNode;
                if (objIconNode.ImageSource != null)
                {
                    ((IconNodeViewModel)uiNodeVM).ImageSource = objIconNode.ImageSource.ToString();
                }
            }

            uiNodeVM.Description  = objNode.Description;
            uiNodeVM.DisplayValue = objNode.Label;
            uiNodeVM.Width        = objNode.Dimension.Width;
            uiNodeVM.Height       = objNode.Dimension.Height;
            uiNodeVM.Position     = objNode.Position;
            uiNodeVM.IsHidden     = objNode.IsHidden;

            SolidColorBrush uiBackgroundColorBrush = new SolidColorBrush(objNode.BackgroundColor);

            uiNodeVM.BackgroundColor = uiBackgroundColorBrush;

            SolidColorBrush uiSelectionColorBrush = new SolidColorBrush(objNode.SelectionColor);

            uiNodeVM.SelectionColor = uiSelectionColorBrush;

            if (uiNodeVM.Height == 0)
            {
                uiNodeVM.Height = 45;
            }

            if (uiNodeVM.Width == 0)
            {
                uiNodeVM.Width = 45;
            }

            // Add the node to the graph
            graphComponents.AddNodeViewModel(uiNodeVM);

            // Attributes
            foreach (KeyValuePair <string, AttributeMapData> objNodeAttrKVP in objNode.Attributes)
            {
                Attributes.Attribute uiNodeAttribute      = new Attributes.Attribute(objNodeAttrKVP.Value.Name);
                AttributeValue       uiNodeAttributeValue = new AttributeValue(objNodeAttrKVP.Value.Value);

                uiNode.Attributes.Add(uiNodeAttribute.Name, uiNodeAttributeValue);
                GlobalAttributeCollection.GetInstance(graphComponents.Scope).Add(uiNodeAttribute, uiNodeAttributeValue);

                uiNodeAttribute.SemanticType = objNodeAttrKVP.Value.SemanticType;
                uiNodeAttribute.PreferredSimilarityMeasure = objNodeAttrKVP.Value.SimilarityMeasure;
                uiNodeAttribute.Visible = !objNodeAttrKVP.Value.IsHidden;
            }
        }
Exemple #20
0
 private void SaveNodePosition(NodeMapData node, double x, double y)
 {
     node.Position = new Point(x, y);
     maxXPosition  = Math.Max(x + node.Dimension.Width, maxXPosition);
 }
Exemple #21
0
        /// <summary>
        /// Performs the actual import for the given GraphML or SnaglML data.
        /// The Import method should be called rather than calling
        /// this method directly.
        /// </summary>
        /// <param name="data">GraphML or SnaglML</param>
        /// <returns>The graph data mapped as a <see cref="GraphMapData"/> object</returns>
        internal override GraphMapData ImportData(string data)
        {
            // TODO Should validate against XSD
            // TODO Processing should conform to GraphML defined processing rules

            GraphMapData graph = new GraphMapData();

            bool haveEncounteredGraph = false;

            using (TextReader stringReader = new StringReader(data))
            {
                XmlReaderSettings settings = new XmlReaderSettings
                {
                    CloseInput       = true,
                    ConformanceLevel = ConformanceLevel.Document,
                    DtdProcessing    = DtdProcessing.Parse,
                    IgnoreWhitespace = true
                };
                using (XmlReader reader = XmlReader.Create(stringReader, settings))
                {
                    // while we know the graph element must be first as per the schema the compiler does not, so these is assigned a value here
                    NodeTypes defaultNodeType = NodeTypes.Text;
                    //GraphType defaultGraphType = GraphType.Undirected;

                    while (reader.Read())
                    {
                        if (reader.IsStartElement())
                        {
                            switch (reader.LocalName)
                            {
                            case "graph":
                                if (!haveEncounteredGraph)
                                {
                                    haveEncounteredGraph = true;

                                    string nodeType = reader.GetAttribute("nodeType", BERICO_NAMESPACE_URI);
                                    defaultNodeType = GetDefaultNodeType(nodeType);

                                    //string edgeDefault = reader.GetAttribute("edgedefault");
                                    //defaultGraphType = GetDefaultEdgeType(edgeDefault);
                                }
                                else
                                {
                                    throw new Exception("Both multiple graphs per file and nested graphs are unsupported.");
                                }
                                break;

                            case "node":
                                NodeMapData node = ReadNode(reader, defaultNodeType);
                                graph.Add(node);
                                break;

                            case "edge":
                                EdgeMapData edge = ReadEdge(reader);
                                graph.Add(edge);
                                break;
                            }
                        }
                    }
                }
            }

            return(graph);
        }