Пример #1
0
        /// <summary>
        /// Positions the nodes
        /// </summary>
        /// <param name="isAnimated">Indicates whether or not the layout should be animated</param>
        /// <param name="graphComponents">The object containing the graph data</param>
        /// <param name="rootNode">Root node</param>
        public void ComputeLayout(bool isAnimated, GraphComponents graphComponents, INode rootNode)
        {
            nodeVMs       = graphComponents.GetNodeViewModels().Where(node => !node.IsHidden).ToArray();
            positions     = new Point[nodeVMs.Length];
            edgeCounts    = new int[nodeVMs.Length];
            nodeIDToIndex = new Dictionary <string, int>();

            for (int i = 0; i < nodeVMs.Length; i++)
            {
                // Save this nodes position
                positions[i] = nodeVMs[i].Position;

                if (nodeVMs[i] is PartitionNode)
                {
                    nodeIDToIndex[(nodeVMs[i] as PartitionNode).ID] = i;
                }
                else
                {
                    nodeIDToIndex[(nodeVMs[i] as NodeViewModelBase).ParentNode.ID] = i;
                }

                // Get a count of all the edges for this node

                //testcount += GraphComponents.GetNumberOfEdges(nodeVMs[i].ParentNode);

                List <INodeShape> visitedNeighbors = new List <INodeShape>();
                Model.INode       currentNode      = null;

                if (nodeVMs[i] is PartitionNode)
                {
                    currentNode = nodeVMs[i] as Model.INode;
                }
                else
                {
                    currentNode = (nodeVMs[i] as NodeViewModelBase).ParentNode;
                }

                // Loop over all the edges for this node
                foreach (Model.IEdge edge in graphComponents.GetEdges(currentNode))
                {
                    // Get the node at the opposite end of this edge
                    INodeShape oppositeNode = graphComponents.GetOppositeNode(edge, currentNode);

                    // Ensure that this edge is not a similarity edge and that
                    // the opposite node has not been visited already
                    if (!(edge is Model.SimilarityDataEdge) && !visitedNeighbors.Contains(oppositeNode))
                    {
                        edgeCounts[i]++;
                        visitedNeighbors.Add(oppositeNode);
                    }
                }
            }

            // Old version is doing this next call asynchronously
            if (nodeVMs.Length > 1)
            {
                CalculatePositions(graphComponents);
            }
        }
Пример #2
0
        /// <summary>Converts a RomanticWeb's <see cref="Node"/> into dotNetRDF's <see cref="VDS.RDF.INode"/>.</summary>
        public static VDS.RDF.INode UnWrapNode(this Model.INode node, INodeFactory nodeFactory)
        {
            if (node.IsUri)
            {
                return(nodeFactory.CreateUriNode(node.Uri));
            }

            if (node.IsLiteral)
            {
                if (node.Language != null)
                {
                    return(nodeFactory.CreateLiteralNode(node.Literal, node.Language));
                }

                if (node.DataType != null)
                {
                    return(nodeFactory.CreateLiteralNode(node.Literal, node.DataType));
                }

                return(nodeFactory.CreateLiteralNode(node.Literal));
            }

            return(nodeFactory.CreateBlankNode(node.BlankNode));
        }
Пример #3
0
        protected void CalculatePositions(GraphComponents graphComponents)
        {
            double   deltaNorm;
            double   otherNorm;
            bool     converged           = false;
            double   T                   = K;
            double   tolerance           = 0.02;
            double   coolingConstant     = 0.99;
            Point    tempDelta           = new Point();
            Point    displacement        = new Point();
            TimeSpan globalForceTimespan = new TimeSpan();
            TimeSpan localForceTimespan  = new TimeSpan();
            TimeSpan indexOfTime         = new TimeSpan();
            DateTime start;

            Model.INode currentNode = null;

            List <int> listOfAllNodeIndices = new List <int>();

            // If we aren't partitioning into grids then use all the nodes every time
            if (!useGraphPartitioning)
            {
                for (int i = 0; i < nodeVMs.Length; i++)
                {
                    listOfAllNodeIndices.Add(i);
                }
            }

            for (int loop = 0; loop < maxIterations && !converged; loop++)
            {
                double max = 200;
                double min = 65;
                double R   = max - ((loop / maxIterations) * (max - min) + min);

                if (useGraphPartitioning)
                {
                    // Put all vertices into appropraite cells
                    CalculateNodeCells(R);
                }

                converged = true;

                // Loop over nodes
                for (int currentNodeIndex = 0; currentNodeIndex < nodeVMs.Length; currentNodeIndex++)
                {
                    if (nodeVMs[currentNodeIndex] is PartitionNode)
                    {
                        currentNode = nodeVMs[currentNodeIndex] as Model.INode;
                    }
                    else
                    {
                        currentNode = (nodeVMs[currentNodeIndex] as NodeViewModelBase).ParentNode;
                    }

                    displacement = new Point(0, 0);

                    // global repulsive force (huh??)
                    start = DateTime.Now;

                    IList <int> repulsionNodes = null;
                    if (useGraphPartitioning)
                    {
                        // Find all nodes, within a certain distance, to perform repulstion on.
                        // Get nodes within maxDistance from this node.
                        double maxDistance = 50; //TODO:  MAKE THIS CONFIGURABLE
                        repulsionNodes = FindNodesForRepulsion(currentNodeIndex, R, maxDistance);
                    }
                    else
                    {
                        // Just repulse all nodes
                        repulsionNodes = listOfAllNodeIndices;
                    }

                    // Loop over all nodes in repulsion list
                    foreach (int i in repulsionNodes)
                    {
                        // We skip this calculation for the current node
                        if (i != currentNodeIndex)
                        {
                            tempDelta.X = positions[i].X - positions[currentNodeIndex].X;
                            tempDelta.Y = positions[i].Y - positions[currentNodeIndex].Y;

                            if (tempDelta.X == 0)
                            {
                                tempDelta.X = random.NextDouble() * .001 * K;
                            }
                            if (tempDelta.Y == 0)
                            {
                                tempDelta.Y = random.NextDouble() * .001 * K;
                            }

                            deltaNorm = Math.Max(1, Math.Abs(tempDelta.X) + Math.Abs(tempDelta.Y));
                            otherNorm = Math.Abs(positions[i].X + Math.Abs(positions[i].Y));

                            double globalForce = GlobalForce(deltaNorm, otherNorm);

                            displacement.X += (tempDelta.X / deltaNorm) * globalForce;
                            displacement.Y += (tempDelta.Y / deltaNorm) * globalForce;
                        }
                    }

                    globalForceTimespan += (DateTime.Now - start);

                    // Local forces
                    start = DateTime.Now;

                    // Loop over all the edges for this node
                    foreach (Model.IEdge edge in graphComponents.GetEdges(currentNode))
                    {
                        DateTime startIndex = DateTime.Now;

                        int    index  = -1;
                        string nodeID = string.Empty;

                        INodeShape oppositeNode = graphComponents.GetOppositeNode(edge, currentNode);
                        //NodeViewModelBase oppositeNodeVM = GraphComponents.GetOppositeNode(edgeVM.ParentEdge, nodeVMs[currentNode].ParentNode);

                        // Get the ID for the opposite node.  How we do this depends
                        // on the type of node that we are dealing with.
                        if (oppositeNode is PartitionNode)
                        {
                            nodeID = (oppositeNode as PartitionNode).ID;
                        }
                        else
                        {
                            nodeID = (oppositeNode as NodeViewModelBase).ParentNode.ID;
                        }

                        if (!nodeIDToIndex.TryGetValue(nodeID, out index))
                        {
                            continue;
                        }
                        indexOfTime += DateTime.Now - startIndex;

                        if (index != -1)
                        {
                            tempDelta = new Point(positions[index].X - positions[currentNodeIndex].X, positions[index].Y - positions[currentNodeIndex].Y);

                            if (tempDelta.X == 0)
                            {
                                tempDelta.X = random.NextDouble() * .001 * K;
                            }
                            if (tempDelta.Y == 0)
                            {
                                tempDelta.Y = random.NextDouble() * .001 * K;
                            }

                            deltaNorm = Math.Max(Math.Sqrt((tempDelta.X * tempDelta.X) + (tempDelta.Y * tempDelta.Y)), 1);
                            otherNorm = Math.Max(Math.Sqrt((oppositeNode.Position.X * oppositeNode.Position.X) + (oppositeNode.Position.Y * oppositeNode.Position.Y)), 1);

                            double localForce = LocalForce(deltaNorm, edgeCounts[currentNodeIndex], edge, graphComponents);

                            displacement.X += (tempDelta.X / deltaNorm) * localForce;
                            displacement.Y += (tempDelta.Y / deltaNorm) * localForce;
                        }
                    }

                    localForceTimespan += (DateTime.Now - start);

                    // Reposition node (huh??)
                    if (displacement.X == 0)
                    {
                        displacement.X = 1;
                    }

                    double displacementNorm = Math.Sqrt((displacement.X * displacement.X) + (displacement.Y * displacement.Y));
                    double newX             = positions[currentNodeIndex].X + (displacement.X / displacementNorm) * Math.Min(T, displacementNorm);
                    double newY             = positions[currentNodeIndex].Y + (displacement.Y / displacementNorm) * Math.Min(T, displacementNorm);

                    tempDelta = new Point(newX - positions[currentNodeIndex].X, newY - positions[currentNodeIndex].Y);

                    positions[currentNodeIndex].X = newX;
                    positions[currentNodeIndex].Y = newY;

                    // no clue what this is doing
                    if (Math.Sqrt((tempDelta.X * tempDelta.X) + (tempDelta.Y * tempDelta.Y)) > K * tolerance)
                    {
                        converged = false;
                    }
                }

                // cool (huh??)
                T *= coolingConstant;
            }

            //System.Diagnostics.Debug.WriteLine(globalForceTimespan);
            //System.Diagnostics.Debug.WriteLine(localForceTimespan);
            //System.Diagnostics.Debug.WriteLine(indexOfTime);
        }