private double EvaluateEdgeLength(
            CompoundGraph <object, IEdge <object> > compoundGraph,
            CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            Dictionary <object, Size> sizes,
            double idealEdgeLength,
            double nestingFactor)
        {
            double edgeLengthError = 0.0;

            foreach (var edge in compoundGraph.Edges)
            {
                var uPos  = algorithm.VertexPositions[edge.Source];
                var vPos  = algorithm.VertexPositions[edge.Target];
                var uSize = sizes[edge.Source];
                var vSize = sizes[edge.Target];

                var uPoint = LayoutUtil.GetClippingPoint(uSize, uPos, vPos);
                var vPoint = LayoutUtil.GetClippingPoint(vSize, vPos, uPos);

                double length      = (uPoint - vPoint).Length;
                bool   isInterEdge = compoundGraph.GetParent(edge.Source) != compoundGraph.GetParent(edge.Target);
                var    iel         = isInterEdge
                              ? idealEdgeLength *
                                     (algorithm.LevelOfVertex(edge.Source) + algorithm.LevelOfVertex(edge.Target) + 1) *
                                     nestingFactor
                              : idealEdgeLength;
                double err = Math.Pow(length - iel, 2);
                edgeLengthError += err;
            }
            return(edgeLengthError);
        }
        private static double EvaluateEdgeLength(
            [NotNull] ICompoundGraph <object, IEdge <object> > compoundGraph,
            [NotNull] CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            [NotNull] IReadOnlyDictionary <object, Size> verticesSizes,
            double idealEdgeLength,
            double nestingFactor)
        {
            double edgeLengthError = 0.0;

            foreach (IEdge <object> edge in compoundGraph.Edges)
            {
                Point uPos  = algorithm.VerticesPositions[edge.Source];
                Point vPos  = algorithm.VerticesPositions[edge.Target];
                Size  uSize = verticesSizes[edge.Source];
                Size  vSize = verticesSizes[edge.Target];

                Point uPoint = LayoutUtils.GetClippingPoint(uSize, uPos, vPos);
                Point vPoint = LayoutUtils.GetClippingPoint(vSize, vPos, uPos);

                double length      = (uPoint - vPoint).Length;
                bool   isInterEdge = compoundGraph.GetParent(edge.Source) != compoundGraph.GetParent(edge.Target);
                double iel         = isInterEdge
                              ? idealEdgeLength *
                                     (algorithm.LevelOfVertex(edge.Source) + algorithm.LevelOfVertex(edge.Target) + 1) *
                                     nestingFactor
                              : idealEdgeLength;
                double error = Math.Pow(length - iel, 2);
                edgeLengthError += error;
            }

            return(edgeLengthError);
        }
Пример #3
0
        /// <summary>
        /// Uses GraphSharp CompoundFDPLayoutAlgorithm, i.e. a force-based algorithm.
        ///
        /// Pretty effective - for not too complicated graphs it is capable of providing flawless solution.
        /// </summary>
        /// <returns>raw set of coordinates of vertices</returns>
        private IDictionary <string, Point> Create4()
        {
            var algo4 = new CompoundFDPLayoutAlgorithm <string, Edge <string>, BidirectionalGraph <string, Edge <string> > >(
                graph, vertexSizes, vertexBorders, new Dictionary <string, CompoundVertexInnerLayoutType>());

            algo4.Compute();
            //while (algo4.State != ComputationState.Finished)
            //	Thread.Sleep(250);

            return(algo4.VertexPositions);
        }
Пример #4
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)
        {
            BidirectionalGraph<string, WeightedEdge<string>> bGraph = GraphSharpUtility.GetBidirectionalGraph(graph);
            IDictionary<string, Size> nodeSizes = GraphSharpUtility.GetNodeSizes(graph);
            IDictionary<string, Vector> nodePositions = GraphSharpUtility.GetNodePositions(graph);
            CompoundFDPLayoutParameters compoundFDPLayoutParameters = new CompoundFDPLayoutParameters();

            CompoundFDPLayoutAlgorithm<string, WeightedEdge<string>, BidirectionalGraph<string, WeightedEdge<string>>> compoundFDPLayoutAlgorithm = new CompoundFDPLayoutAlgorithm<string, WeightedEdge<string>, BidirectionalGraph<string, WeightedEdge<string>>>(bGraph, nodeSizes, null, null, nodePositions, compoundFDPLayoutParameters);
            compoundFDPLayoutAlgorithm.Compute();

            GraphSharpUtility.SetNodePositions(graph, compoundFDPLayoutAlgorithm.VertexPositions);
        }
        private int EvaluateEdgeCrossing(
            CompoundGraph <object, IEdge <object> > compoundGraph,
            CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            Dictionary <object, Size> sizes)
        {
            int crossings = 0;

            foreach (var edge in compoundGraph.Edges)
            {
                var uPos1  = algorithm.VertexPositions[edge.Source];
                var vPos1  = algorithm.VertexPositions[edge.Target];
                var uSize1 = sizes[edge.Source];
                var vSize1 = sizes[edge.Target];

                var uPoint1 = LayoutUtil.GetClippingPoint(uSize1, uPos1, vPos1);
                var vPoint1 = LayoutUtil.GetClippingPoint(vSize1, vPos1, uPos1);
                foreach (var edge2 in compoundGraph.Edges)
                {
                    if (edge == edge2)
                    {
                        continue;
                    }

                    var uPos2  = algorithm.VertexPositions[edge.Source];
                    var vPos2  = algorithm.VertexPositions[edge.Target];
                    var uSize2 = sizes[edge.Source];
                    var vSize2 = sizes[edge.Target];

                    var uPoint2 = LayoutUtil.GetClippingPoint(uSize2, uPos2, vPos2);
                    var vPoint2 = LayoutUtil.GetClippingPoint(vSize2, vPos2, uPos2);

                    Vector v1 = (vPoint1 - uPoint1);
                    Vector v2 = (vPoint2 - uPoint2);

                    if (v1 == v2 || v1 == -v2)
                    {
                        continue; //parallel edges
                    }
                    var t2 = (uPoint1.Y - uPoint2.Y + (uPoint2.X - uPoint1.X) * v1.Y / v1.X) / (v2.Y - v2.X * v1.Y / v1.X);
                    var t1 = (uPoint2.X - uPoint1.X + t2 * v2.X) / v1.X;

                    var p  = uPoint1 + t1 * v1;
                    var b1 = t1 > 0 && (p - uPoint1).Length < (vPoint1 - uPoint1).Length;
                    var b2 = t2 > 0 && (p - uPoint2).Length < (vPoint2 - uPoint2).Length;

                    if (b1 && b2)
                    {
                        crossings++;
                    }
                }
            }
            return(crossings);
        }
        private static void EvaluateNodeDistances(
            [NotNull] ICompoundGraph <object, IEdge <object> > compoundGraph,
            [NotNull] CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            [NotNull] IReadOnlyDictionary <object, Size> verticesSizes,
            out double minimalMinDistance,
            out double averageMinDistance,
            out double maximalMinDistance)
        {
            minimalMinDistance = 0.0;
            averageMinDistance = 0.0;
            maximalMinDistance = 0.0;
            foreach (HashSet <object> level in algorithm.Levels)
            {
                foreach (object u in level)
                {
                    double m = double.PositiveInfinity;
                    foreach (object v in level)
                    {
                        if (ReferenceEquals(u, v) || compoundGraph.GetParent(u) != compoundGraph.GetParent(v))
                        {
                            continue;
                        }

                        Point uPoint = LayoutUtils.GetClippingPoint(
                            verticesSizes[u],
                            algorithm.VerticesPositions[u],
                            algorithm.VerticesPositions[v]);

                        Point vPoint = LayoutUtils.GetClippingPoint(
                            verticesSizes[v],
                            algorithm.VerticesPositions[v],
                            algorithm.VerticesPositions[u]);
                        double distance = (uPoint - vPoint).Length;
                        m = Math.Min(m, distance);
                    }

                    if (double.IsPositiveInfinity(m))
                    {
                        continue;
                    }

                    minimalMinDistance  = Math.Min(minimalMinDistance, m);
                    averageMinDistance += m;
                    maximalMinDistance  = Math.Max(maximalMinDistance, m);
                }
            }
        }
        public void Constructor()
        {
            var graph               = new BidirectionalGraph <string, Edge <string> >();
            var verticesPositions   = new Dictionary <string, Point>();
            var verticesSizes       = new Dictionary <string, Size>();
            var verticesThicknesses = new Dictionary <string, Thickness>();
            var verticesTypes       = new Dictionary <string, CompoundVertexInnerLayoutType>();

            var algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesSizes, verticesThicknesses, verticesTypes);

            AssertFDPAlgorithmProperties(algorithm, graph);

            algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesSizes, verticesThicknesses, verticesTypes);
            algorithm.IterationEnded += (sender, args) => { };
            AssertFDPAlgorithmProperties(algorithm, graph, expectedReportIterationEnd: true);

            algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesSizes, verticesThicknesses, verticesTypes);
            algorithm.ProgressChanged += (sender, args) => { };
            AssertFDPAlgorithmProperties(algorithm, graph, expectedReportProgress: true);

            algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesSizes, verticesThicknesses, verticesTypes);
            algorithm.IterationEnded  += (sender, args) => { };
            algorithm.ProgressChanged += (sender, args) => { };
            AssertFDPAlgorithmProperties(algorithm, graph, expectedReportIterationEnd: true, expectedReportProgress: true);

            algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesPositions, verticesSizes, verticesThicknesses, verticesTypes);
            AssertFDPAlgorithmProperties(algorithm, graph, verticesPositions);

            var parameters = new CompoundFDPLayoutParameters();

            algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesSizes, verticesThicknesses, verticesTypes, parameters);
            AssertFDPAlgorithmProperties(algorithm, graph, p: parameters);

            algorithm = new CompoundFDPLayoutAlgorithm <string, Edge <string>, IBidirectionalGraph <string, Edge <string> > >(graph, verticesPositions, verticesSizes, verticesThicknesses, verticesTypes, parameters);
            AssertFDPAlgorithmProperties(algorithm, graph, verticesPositions, p: parameters);

            #region Local function

            void AssertFDPAlgorithmProperties <TVertex, TEdge, TGraph>(
                CompoundFDPLayoutAlgorithm <TVertex, TEdge, TGraph> algo,
                TGraph g,
                IDictionary <TVertex, Point> pos = null,
                bool expectedReportIterationEnd  = false,
                bool expectedReportProgress      = false,
                CompoundFDPLayoutParameters p    = null)
                where TVertex : class
        private static void CheckCompoundFDPLayout <TVertex, TEdge, TGraph>(
            [NotNull] IBidirectionalGraph <TVertex, TEdge> graph,
            [NotNull] CompoundFDPLayoutAlgorithm <TVertex, TEdge, TGraph> algorithm)
            where TVertex : class
            where TEdge : IEdge <TVertex>
            where TGraph : IBidirectionalGraph <TVertex, TEdge>
        {
            CollectionAssert.AreEquivalent(graph.Vertices, algorithm.Levels.SelectMany(level => level));

            if (graph is ICompoundGraph <TVertex, TEdge> compoundGraph)
            {
                CollectionAssert.AreEquivalent(compoundGraph.CompoundVertices, algorithm.InnerCanvasSizes.Keys);
            }
            else
            {
                CollectionAssert.IsEmpty(algorithm.InnerCanvasSizes.Keys);
            }
        }
        private void EvaluateNodeDistances(
            CompoundGraph <object, IEdge <object> > compoundGraph,
            CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            Dictionary <object, Size> sizes,
            out double minimalMinDistance,
            out double averageMinDistance,
            out double maximalMinDistance)
        {
            minimalMinDistance = 0.0;
            averageMinDistance = 0.0;
            maximalMinDistance = 0.0;
            double count = 0;

            foreach (var level in algorithm.Levels)
            {
                foreach (var u in level)
                {
                    double m = double.PositiveInfinity;
                    foreach (var v in level)
                    {
                        if (u == v || compoundGraph.GetParent(u) != compoundGraph.GetParent(v))
                        {
                            continue;
                        }

                        var uPoint = LayoutUtil.GetClippingPoint(sizes[u], algorithm.VertexPositions[u],
                                                                 algorithm.VertexPositions[v]);
                        var vPoint = LayoutUtil.GetClippingPoint(sizes[v], algorithm.VertexPositions[v],
                                                                 algorithm.VertexPositions[u]);
                        double distance = (uPoint - vPoint).Length;
                        m = Math.Min(m, distance);
                    }
                    if (double.IsPositiveInfinity(m))
                    {
                        continue;
                    }
                    minimalMinDistance  = Math.Min(minimalMinDistance, m);
                    averageMinDistance += m;
                    count++;
                    maximalMinDistance = Math.Max(maximalMinDistance, m);
                }
            }
        }
        private static double EvaluateNodeOverlaps(
            [NotNull] ICompoundGraph <object, IEdge <object> > compoundGraph,
            [NotNull] CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            [NotNull] IDictionary <object, Size> verticesSizes)
        {
            double overlapArea = 0.0;

            foreach (HashSet <object> level in algorithm.Levels)
            {
                foreach (object u in level)
                {
                    foreach (object v in level)
                    {
                        if (ReferenceEquals(u, v) || compoundGraph.GetParent(u) != compoundGraph.GetParent(v))
                        {
                            continue;
                        }

                        Point uPosition = algorithm.VerticesPositions[u];
                        Point vPosition = algorithm.VerticesPositions[v];
                        Size  uSize     = verticesSizes[u];
                        Size  vSize     = verticesSizes[v];

                        var uRect = new Rect(uPosition, uSize);
                        var vRect = new Rect(vPosition, vSize);

                        // Get the overlap size
                        uRect.Intersect(vRect);
                        if (double.IsNegativeInfinity(uRect.Width) || double.IsNegativeInfinity(uRect.Height))
                        {
                            continue;
                        }

                        overlapArea += uRect.Width * uRect.Height;
                    }
                }
            }

            return(overlapArea);
        }
        private double EvaluateNodeOverlaps(
            CompoundGraph <object, IEdge <object> > compoundGraph,
            CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            IDictionary <object, Size> vertexSizes)
        {
            double overlapArea = 0.0;

            foreach (var level in algorithm.Levels)
            {
                foreach (var u in level)
                {
                    foreach (var v in level)
                    {
                        if (u == v || compoundGraph.GetParent(u) != compoundGraph.GetParent(v))
                        {
                            continue;
                        }

                        var uSize     = vertexSizes[u];
                        var vSize     = vertexSizes[v];
                        var uPosition = algorithm.VertexPositions[u];
                        var vPosition = algorithm.VertexPositions[v];

                        var uRect = new Rect(uPosition, uSize);
                        var vRect = new Rect(vPosition, vSize);

                        //get the overlap size
                        uRect.Intersect(vRect);
                        if (double.IsNegativeInfinity(uRect.Width) || double.IsNegativeInfinity(uRect.Height))
                        {
                            continue;
                        }

                        overlapArea += uRect.Width * uRect.Height;
                    }
                }
            }
            return(overlapArea);
        }
        private Size EvaluateCanvasSize(
            CompoundGraph <object, IEdge <object> > compoundGraph,
            CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > > algorithm,
            Dictionary <object, Size> sizes)
        {
            Point topLeft     = new Point(double.PositiveInfinity, double.PositiveInfinity);
            Point bottomRight = new Point(double.NegativeInfinity, double.NegativeInfinity);

            foreach (var v in compoundGraph.Vertices)
            {
                var pos  = algorithm.VertexPositions[v];
                var size = sizes[v];

                topLeft.X = Math.Min(topLeft.X, pos.X - size.Width / 2.0);
                topLeft.Y = Math.Min(topLeft.Y, pos.Y - size.Height / 2.0);

                bottomRight.X = Math.Max(bottomRight.X, pos.X + size.Width / 2.0);
                bottomRight.Y = Math.Max(bottomRight.Y, pos.Y + size.Height / 2.0);
            }
            var sizeVector = bottomRight - topLeft;

            return(new Size(sizeVector.X, sizeVector.Y));
        }
Пример #13
0
        private void ShowGraph(int graphIndex)
        {
            CompoundGraph <object, IEdge <object> > g = graphs[graphIndex];

            _rectDict.Clear();
            _lineDict.Clear();
            lc.Children.Clear();
            var origo = new Ellipse();

            origo.Width       = 100;
            origo.Height      = 100;
            origo.Fill        = Brushes.Black;
            origo.OpacityMask = new RadialGradientBrush(Colors.Black, Colors.Transparent);
            Canvas.SetLeft(origo, -5);
            Canvas.SetTop(origo, -5);
            lc.Children.Add(origo);
            var sizes      = new Dictionary <object, Size>();
            var borders    = new Dictionary <object, Thickness>();
            var layoutType = new Dictionary <object, CompoundVertexInnerLayoutType>();

            var s = new Size(20, 20);

            foreach (var v in g.SimpleVertices)
            {
                sizes[v] = s;
            }

            var b = new Thickness(5, 10, 5, 5);

            foreach (var v in g.CompoundVertices)
            {
                sizes[v]      = new Size();
                borders[v]    = b;
                layoutType[v] = CompoundVertexInnerLayoutType.Automatic;
            }

            var worker = new BackgroundWorker();

            worker.WorkerReportsProgress = true;
            worker.DoWork += (sender, e) =>
            {
                var layoutAlgorithm =
                    new CompoundFDPLayoutAlgorithm
                    <object, IEdge <object>, ICompoundGraph <object, IEdge <object> > >(
                        g, sizes, borders, layoutType, null,
                        parameters);
                layoutAlgorithm.IterationEnded += (o, evt) =>
                {
                    var args        = evt as TestingCompoundLayoutIterationEventArgs <object, IEdge <object>, TestingCompoundVertexInfo, object>;
                    var positions   = args.VertexPositions;
                    var innerSizes  = (args as ICompoundLayoutIterationEventArgs <object>).InnerCanvasSizes;
                    var vertexInfos = args.VertexInfos;

                    Dispatcher.Invoke(new Action(delegate
                    {
                        var pDict = new Dictionary <object, Point>();

                        var compoundVerticesToCheck =
                            new Queue <object>();
                        var compoundVertices = new List <object>();
                        var root             =
                            g.CompoundVertices.Where(
                                cv => g.GetParent(cv) == null);
                        foreach (var r in root)
                        {
                            compoundVerticesToCheck.Enqueue(r);
                        }
                        while (compoundVerticesToCheck.Count > 0)
                        {
                            var next = compoundVerticesToCheck.Dequeue();
                            if (!g.IsCompoundVertex(next))
                            {
                                continue;
                            }
                            compoundVertices.Add(next);
                            foreach (
                                var childrenVertex in
                                g.GetChildrenVertices(next))
                            {
                                compoundVerticesToCheck.Enqueue(
                                    childrenVertex);
                            }
                        }

                        //draw the compound vertices
                        foreach (var v in compoundVertices)
                        {
                            var size     = innerSizes[v];
                            size.Width  += b.Left + b.Right;
                            size.Height += b.Top + b.Bottom;

                            var pos  = positions[v];
                            pDict[v] = pos;
                            AddRect(v, pos, size);
                        }

                        //draw the simple vertices
                        foreach (var v in g.SimpleVertices)
                        {
                            var pos  = positions[v];
                            pDict[v] = pos;
                            AddRect(v, pos, s);
                        }

                        //draw the simple edges
                        foreach (var edge in g.Edges)
                        {
                            var pos1 = pDict[edge.Source];
                            var pos2 = pDict[edge.Target];
                            AddLine(edge, pos1, pos2, true);
                        }

                        //draw the containment edges

                        /*foreach (var v in g.CompoundVertices)
                         * {
                         *  var pos1 = pDict[v];
                         *  foreach (var c in g.GetChildrenVertices(v))
                         *  {
                         *      var pos2 = pDict[c];
                         *      AddLine(c, pos1, pos2, false);
                         *  }
                         * }*/

                        //draw the lines of the forces
                        foreach (var forceLine in _forceLines)
                        {
                            lc.Children.Remove(forceLine);
                        }

                        var springColor      = Brushes.Orange;
                        var repulsionColor   = Brushes.Red;
                        var gravityColor     = Brushes.Green;
                        var applicationColor = Brushes.Yellow;

                        foreach (var kvp in vertexInfos)
                        {
                            var line = CreateLine(pDict[kvp.Key],
                                                  kvp.Value.SpringForce,
                                                  springColor);
                            lc.Children.Add(line);
                            _forceLines.Add(line);
                            line = CreateLine(pDict[kvp.Key],
                                              kvp.Value.RepulsionForce,
                                              repulsionColor);
                            lc.Children.Add(line);
                            _forceLines.Add(line);
                            line = CreateLine(pDict[kvp.Key],
                                              kvp.Value.GravityForce,
                                              gravityColor);
                            lc.Children.Add(line);
                            _forceLines.Add(line);
                            line = CreateLine(pDict[kvp.Key],
                                              kvp.Value.ApplicationForce,
                                              applicationColor);
                            lc.Children.Add(line);
                            _forceLines.Add(line);
                        }


                        //set the position of the gravity center
                        Animate(origo, Canvas.LeftProperty, args.GravitationCenter.X - origo.Width / 2.0, animationDuration);
                        Animate(origo, Canvas.TopProperty, args.GravitationCenter.Y - origo.Height / 2.0, animationDuration);
                        txtMessage.Text = args.Message;
                    }));
                    do
                    {
                        Thread.Sleep((int)animationDuration.TimeSpan.TotalMilliseconds);
                    } while (_paused);
                };
                layoutAlgorithm.Compute();
            };
            worker.RunWorkerAsync();
        }
Пример #14
0
        public void Evaluate(int SpreadMax)
        {
            if (FBuild[0] || (pd.InputChanged && init))
            {
                graph.Clear();
                VSize.Clear();
                VThickness.Clear();
                VType.Clear();
                VPos.Clear();
                VCache.Clear();

                for (int i = 0; i < FVertices.SliceCount; i++)
                {
                    graph.AddVertex(FVertices[i]);
                    VSize.Add(FVertices[i], new Size(FVSize[i], FVSize[i]));
                    VThickness.Add(FVertices[i], new Thickness(1.0));
                    VType.Add(FVertices[i], FVType[i]);
                    VPos.Add(FVertices[i], new Point(FVPos[i].x, FVPos[i].y));
                    VCache.Add(FVertices[i]);
                }
                for (int i = 0; i < Math.Max(FEdgeFrom.SliceCount, FEdgeTo.SliceCount); i++)
                {
                    graph.AddEdge(new Edge <string>(FEdgeFrom[i], FEdgeTo[i]));
                }

                var cparams = new CompoundFDPLayoutParameters();
                foreach (var prop in typeof(CompoundFDPLayoutParameters).GetProperties())
                {
                    var input = pd.InputPins[prop.Name].Spread[0];
                    if (!(input.ToString().StartsWith("0") && input.ToString().EndsWith("0")))
                    {
                        prop.SetValue(cparams, pd.InputPins[prop.Name].Spread[0]);
                    }
                }
                layout = new CompoundFDPLayoutAlgorithm <string, IEdge <string>, CompoundGraph <string, IEdge <string> > >(graph, VSize, VThickness, VType, VPos, cparams);
                foreach (var prop in typeof(CompoundFDPLayoutParameters).GetProperties())
                {
                    var input = pd.InputPins[prop.Name].Spread[0];
                    if (!(input.ToString().StartsWith("0") && input.ToString().EndsWith("0")))
                    {
                        prop.SetValue(layout.Parameters, pd.InputPins[prop.Name].Spread[0]);
                    }
                }
                layout.Finished += (sender, args) =>
                {
                    FPosOut.SliceCount = VCache.Count;
                    for (int i = 0; i < VCache.Count; i++)
                    {
                        var point = layout.VertexPositions[VCache[i]];
                        FPosOut[i] = new Vector2D(point.X, point.Y);
                    }
                };
                if (FAsync[0])
                {
                    Task.Run(() =>
                    {
                        layout.Compute();
                    });
                }
                else
                {
                    layout.Compute();
                }
                init = true;
            }
            if (layout != null)
            {
                FState[0] = layout.State.ToString();
            }
        }
        public void StandardFactory()
        {
            var positions     = new Dictionary <TestVertex, Point>();
            var sizes         = new Dictionary <TestVertex, Size>();
            var borders       = new Dictionary <TestVertex, Thickness>();
            var layoutTypes   = new Dictionary <TestVertex, CompoundVertexInnerLayoutType>();
            var graph         = new BidirectionalGraph <TestVertex, Edge <TestVertex> >();
            var simpleContext = new LayoutContext <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(
                graph,
                positions,
                sizes,
                LayoutMode.Simple);
            var compoundContext1 = new LayoutContext <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(
                graph,
                positions,
                sizes,
                LayoutMode.Compound);
            var compoundContext2 = new CompoundLayoutContext <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(
                graph,
                positions,
                sizes,
                LayoutMode.Compound,
                borders,
                layoutTypes);
            var nullGraphContext = new LayoutContext <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(
                null,
                positions,
                sizes,
                LayoutMode.Simple);

            var factory = new StandardLayoutAlgorithmFactory <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >();

            CollectionAssert.AreEqual(
                new[]
            {
                "Circular", "Tree", "FR", "BoundedFR", "KK",
                "ISOM", "LinLog", "Sugiyama", "CompoundFDP",
                "Random"
            },
                factory.AlgorithmTypes);


            Assert.IsNull(
                factory.CreateAlgorithm(
                    string.Empty,
                    simpleContext,
                    new CircularLayoutParameters()));

            Assert.IsNull(
                factory.CreateAlgorithm(
                    "NotExist",
                    simpleContext,
                    new CircularLayoutParameters()));

            Assert.IsNull(
                factory.CreateAlgorithm(
                    "Circular",
                    nullGraphContext,
                    new CircularLayoutParameters()));

            Assert.IsInstanceOf <CircularLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "Circular",
                    simpleContext,
                    new CircularLayoutParameters()));

            Assert.IsInstanceOf <SimpleTreeLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "Tree",
                    simpleContext,
                    new SimpleTreeLayoutParameters()));

            Assert.IsInstanceOf <FRLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "FR",
                    simpleContext,
                    new FreeFRLayoutParameters()));

            Assert.IsInstanceOf <FRLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "BoundedFR",
                    simpleContext,
                    new BoundedFRLayoutParameters()));

            Assert.IsInstanceOf <KKLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "KK",
                    simpleContext,
                    new KKLayoutParameters()));

            Assert.IsInstanceOf <ISOMLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "ISOM",
                    simpleContext,
                    new ISOMLayoutParameters()));

            Assert.IsInstanceOf <LinLogLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "LinLog",
                    simpleContext,
                    new LinLogLayoutParameters()));

            Assert.IsInstanceOf <SugiyamaLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "Sugiyama",
                    simpleContext,
                    new SugiyamaLayoutParameters()));

            Assert.IsInstanceOf <CompoundFDPLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "CompoundFDP",
                    simpleContext,
                    new CompoundFDPLayoutParameters()));

            Assert.IsInstanceOf <RandomLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "Random",
                    simpleContext,
                    new RandomLayoutParameters()));

            Assert.IsNull(
                factory.CreateAlgorithm(
                    "CompoundFDP",
                    compoundContext1,
                    new CompoundFDPLayoutParameters()));

            Assert.IsNull(
                factory.CreateAlgorithm(
                    "Circular",
                    compoundContext2,
                    new CompoundFDPLayoutParameters()));

            Assert.IsInstanceOf <CompoundFDPLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > > >(
                factory.CreateAlgorithm(
                    "CompoundFDP",
                    compoundContext2,
                    new CompoundFDPLayoutParameters()));


            var testParameters     = new TestLayoutParameters();
            var circularParameters = new CircularLayoutParameters();
            ILayoutParameters createdParameters = factory.CreateParameters(string.Empty, circularParameters);

            Assert.IsNull(createdParameters);

            createdParameters = factory.CreateParameters("NotExist", circularParameters);
            Assert.IsNull(createdParameters);

            createdParameters = factory.CreateParameters("Circular", null);
            Assert.IsInstanceOf <CircularLayoutParameters>(createdParameters);
            Assert.AreNotSame(circularParameters, createdParameters);

            createdParameters = factory.CreateParameters("Circular", testParameters);
            Assert.IsInstanceOf <CircularLayoutParameters>(createdParameters);
            Assert.AreNotSame(testParameters, createdParameters);

            createdParameters = factory.CreateParameters("Circular", circularParameters);
            Assert.IsInstanceOf <CircularLayoutParameters>(createdParameters);
            Assert.AreNotSame(circularParameters, createdParameters);

            var treeParameters = new SimpleTreeLayoutParameters();

            createdParameters = factory.CreateParameters("Tree", null);
            Assert.IsInstanceOf <SimpleTreeLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("Tree", testParameters);
            Assert.IsInstanceOf <SimpleTreeLayoutParameters>(createdParameters);
            Assert.AreNotSame(testParameters, createdParameters);

            createdParameters = factory.CreateParameters("Tree", treeParameters);
            Assert.IsInstanceOf <SimpleTreeLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            var frParameters = new FreeFRLayoutParameters();

            createdParameters = factory.CreateParameters("FR", null);
            Assert.IsInstanceOf <FreeFRLayoutParameters>(createdParameters);
            Assert.AreNotSame(frParameters, createdParameters);

            createdParameters = factory.CreateParameters("FR", testParameters);
            Assert.IsInstanceOf <FreeFRLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("FR", frParameters);
            Assert.IsInstanceOf <FreeFRLayoutParameters>(createdParameters);
            Assert.AreNotSame(frParameters, createdParameters);

            var boundedFrParameters = new BoundedFRLayoutParameters();

            createdParameters = factory.CreateParameters("BoundedFR", null);
            Assert.IsInstanceOf <BoundedFRLayoutParameters>(createdParameters);
            Assert.AreNotSame(boundedFrParameters, createdParameters);

            createdParameters = factory.CreateParameters("BoundedFR", testParameters);
            Assert.IsInstanceOf <BoundedFRLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("BoundedFR", boundedFrParameters);
            Assert.IsInstanceOf <BoundedFRLayoutParameters>(createdParameters);
            Assert.AreNotSame(boundedFrParameters, createdParameters);

            var kkParameters = new KKLayoutParameters();

            createdParameters = factory.CreateParameters("KK", null);
            Assert.IsInstanceOf <KKLayoutParameters>(createdParameters);
            Assert.AreNotSame(kkParameters, createdParameters);

            createdParameters = factory.CreateParameters("KK", testParameters);
            Assert.IsInstanceOf <KKLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("KK", kkParameters);
            Assert.IsInstanceOf <KKLayoutParameters>(createdParameters);
            Assert.AreNotSame(kkParameters, createdParameters);

            var isomParameters = new ISOMLayoutParameters();

            createdParameters = factory.CreateParameters("ISOM", null);
            Assert.IsInstanceOf <ISOMLayoutParameters>(createdParameters);
            Assert.AreNotSame(isomParameters, createdParameters);

            createdParameters = factory.CreateParameters("ISOM", testParameters);
            Assert.IsInstanceOf <ISOMLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("ISOM", isomParameters);
            Assert.IsInstanceOf <ISOMLayoutParameters>(createdParameters);
            Assert.AreNotSame(isomParameters, createdParameters);

            var linLogParameters = new LinLogLayoutParameters();

            createdParameters = factory.CreateParameters("LinLog", null);
            Assert.IsInstanceOf <LinLogLayoutParameters>(createdParameters);
            Assert.AreNotSame(linLogParameters, createdParameters);

            createdParameters = factory.CreateParameters("LinLog", testParameters);
            Assert.IsInstanceOf <LinLogLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("LinLog", linLogParameters);
            Assert.IsInstanceOf <LinLogLayoutParameters>(createdParameters);
            Assert.AreNotSame(linLogParameters, createdParameters);

            var sugiyamaParameters = new SugiyamaLayoutParameters();

            createdParameters = factory.CreateParameters("Sugiyama", null);
            Assert.IsInstanceOf <SugiyamaLayoutParameters>(createdParameters);
            Assert.AreNotSame(sugiyamaParameters, createdParameters);

            createdParameters = factory.CreateParameters("Sugiyama", testParameters);
            Assert.IsInstanceOf <SugiyamaLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("Sugiyama", sugiyamaParameters);
            Assert.IsInstanceOf <SugiyamaLayoutParameters>(createdParameters);
            Assert.AreNotSame(sugiyamaParameters, createdParameters);

            var compoundFDPParameters = new CompoundFDPLayoutParameters();

            createdParameters = factory.CreateParameters("CompoundFDP", null);
            Assert.IsInstanceOf <CompoundFDPLayoutParameters>(createdParameters);
            Assert.AreNotSame(compoundFDPParameters, createdParameters);

            createdParameters = factory.CreateParameters("CompoundFDP", testParameters);
            Assert.IsInstanceOf <CompoundFDPLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("CompoundFDP", compoundFDPParameters);
            Assert.IsInstanceOf <CompoundFDPLayoutParameters>(createdParameters);
            Assert.AreNotSame(compoundFDPParameters, createdParameters);

            var randomParameters = new RandomLayoutParameters();

            createdParameters = factory.CreateParameters("Random", null);
            Assert.IsInstanceOf <RandomLayoutParameters>(createdParameters);
            Assert.AreNotSame(randomParameters, createdParameters);

            createdParameters = factory.CreateParameters("Random", testParameters);
            Assert.IsInstanceOf <RandomLayoutParameters>(createdParameters);
            Assert.AreNotSame(treeParameters, createdParameters);

            createdParameters = factory.CreateParameters("Random", randomParameters);
            Assert.IsInstanceOf <RandomLayoutParameters>(createdParameters);
            Assert.AreNotSame(randomParameters, createdParameters);


            Assert.IsFalse(factory.IsValidAlgorithm(null));
            Assert.IsFalse(factory.IsValidAlgorithm(string.Empty));
            Assert.IsTrue(factory.IsValidAlgorithm("Circular"));
            Assert.IsFalse(factory.IsValidAlgorithm("circular"));
            Assert.IsTrue(factory.IsValidAlgorithm("Tree"));
            Assert.IsTrue(factory.IsValidAlgorithm("FR"));
            Assert.IsTrue(factory.IsValidAlgorithm("BoundedFR"));
            Assert.IsTrue(factory.IsValidAlgorithm("KK"));
            Assert.IsTrue(factory.IsValidAlgorithm("ISOM"));
            Assert.IsTrue(factory.IsValidAlgorithm("LinLog"));
            Assert.IsTrue(factory.IsValidAlgorithm("Sugiyama"));
            Assert.IsTrue(factory.IsValidAlgorithm("CompoundFDP"));
            Assert.IsTrue(factory.IsValidAlgorithm("Random"));


            var algorithm1 = new TestLayoutAlgorithm();

            Assert.IsEmpty(factory.GetAlgorithmType(algorithm1));

            var algorithm2 = new CircularLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, sizes, circularParameters);

            Assert.AreEqual("Circular", factory.GetAlgorithmType(algorithm2));

            var algorithm3 = new SimpleTreeLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, sizes, treeParameters);

            Assert.AreEqual("Tree", factory.GetAlgorithmType(algorithm3));

            var algorithm4 = new FRLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, frParameters);

            Assert.AreEqual("FR", factory.GetAlgorithmType(algorithm4));

            var algorithm5 = new FRLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, boundedFrParameters);

            Assert.AreEqual("BoundedFR", factory.GetAlgorithmType(algorithm5));

            var algorithm6 = new KKLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, kkParameters);

            Assert.AreEqual("KK", factory.GetAlgorithmType(algorithm6));

            var algorithm7 = new ISOMLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, isomParameters);

            Assert.AreEqual("ISOM", factory.GetAlgorithmType(algorithm7));

            var algorithm8 = new LinLogLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph);

            Assert.AreEqual("LinLog", factory.GetAlgorithmType(algorithm8));

            var algorithm9 = new SugiyamaLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, positions, sizes, sugiyamaParameters);

            Assert.AreEqual("Sugiyama", factory.GetAlgorithmType(algorithm9));

            var algorithm10 = new CompoundFDPLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, sizes, borders, layoutTypes);

            Assert.AreEqual("CompoundFDP", factory.GetAlgorithmType(algorithm10));

            var algorithm11 = new RandomLayoutAlgorithm <TestVertex, Edge <TestVertex>, BidirectionalGraph <TestVertex, Edge <TestVertex> > >(graph, sizes, null, randomParameters);

            Assert.AreEqual("Random", factory.GetAlgorithmType(algorithm11));


            Assert.IsFalse(factory.NeedEdgeRouting(string.Empty));
            Assert.IsTrue(factory.NeedEdgeRouting("Circular"));
            Assert.IsTrue(factory.NeedEdgeRouting("Tree"));
            Assert.IsTrue(factory.NeedEdgeRouting("FR"));
            Assert.IsTrue(factory.NeedEdgeRouting("BoundedFR"));
            Assert.IsTrue(factory.NeedEdgeRouting("KK"));
            Assert.IsTrue(factory.NeedEdgeRouting("ISOM"));
            Assert.IsTrue(factory.NeedEdgeRouting("LinLog"));
            Assert.IsFalse(factory.NeedEdgeRouting("Sugiyama"));
            Assert.IsTrue(factory.NeedEdgeRouting("CompoundFDP"));
            Assert.IsTrue(factory.NeedEdgeRouting("Random"));


            Assert.IsFalse(factory.NeedOverlapRemoval(string.Empty));
            Assert.IsFalse(factory.NeedOverlapRemoval("Circular"));
            Assert.IsFalse(factory.NeedOverlapRemoval("Tree"));
            Assert.IsTrue(factory.NeedOverlapRemoval("FR"));
            Assert.IsTrue(factory.NeedOverlapRemoval("BoundedFR"));
            Assert.IsTrue(factory.NeedOverlapRemoval("KK"));
            Assert.IsTrue(factory.NeedOverlapRemoval("ISOM"));
            Assert.IsTrue(factory.NeedOverlapRemoval("LinLog"));
            Assert.IsFalse(factory.NeedOverlapRemoval("Sugiyama"));
            Assert.IsFalse(factory.NeedOverlapRemoval("CompoundFDP"));
            Assert.IsTrue(factory.NeedOverlapRemoval("Random"));
        }
        private double EvaluateFitnessForGraph(CompoundFDPLayoutParameters chromosome, CompoundGraph <object, IEdge <object> > compoundGraph)
        {
            var sizes      = new Dictionary <object, Size>();
            var borders    = new Dictionary <object, Thickness>();
            var layoutType = new Dictionary <object, CompoundVertexInnerLayoutType>();

            var s = new Size(20, 20);

            foreach (var v in compoundGraph.SimpleVertices)
            {
                sizes[v] = s;
            }

            var b = new Thickness(5, 10, 5, 5);

            foreach (var v in compoundGraph.CompoundVertices)
            {
                sizes[v]      = new Size();
                borders[v]    = b;
                layoutType[v] = CompoundVertexInnerLayoutType.Automatic;
            }

            //run the compound FDP algorithm
            var algorithm =
                new CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > >(
                    compoundGraph, sizes, borders, layoutType, null, chromosome);

            algorithm.Compute();

            double fitness = 0.0;

            //refresh the sizes of the compound vertices
            foreach (var v in compoundGraph.CompoundVertices)
            {
                var border          = borders[v];
                var innerCanvasSize = algorithm.InnerCanvasSizes[v];
                var size            = new Size(
                    border.Left + innerCanvasSize.Width + border.Right,
                    border.Top + innerCanvasSize.Height + border.Bottom
                    );
                sizes[v] = size;
            }

            //NODE OVERLAP
            double overlaps = EvaluateNodeOverlaps(compoundGraph, algorithm, sizes);

            /*if (overlaps > 0.0)
             *  return double.NaN;*/
            fitness += overlaps * NODE_OVERLAP_MULTIPLIER;

            //CANVAS SIZE
            Size canvasSize = EvaluateCanvasSize(compoundGraph, algorithm, sizes);

            fitness += canvasSize.Width * canvasSize.Height * CANVAS_SIZE_MULTIPLIER;

            //CANVAS RATIO
            double canvasRatio = canvasSize.Width / canvasSize.Height;

            canvasRatio = canvasRatio < 1 ? 1 / canvasRatio : canvasRatio;
            fitness    += canvasRatio * CANVAS_RATIO_MULTIPLIER;

            //NODE DISTANCES
            double minimalMinDistance, averageMinDistance, maximalMinDistance;
            double idealDistance = chromosome.IdealEdgeLength;

            EvaluateNodeDistances(compoundGraph, algorithm, sizes, out minimalMinDistance, out averageMinDistance, out maximalMinDistance);
            fitness += (averageMinDistance - idealDistance) * NODE_DISTANCE_MULTIPLIER;
            fitness += (minimalMinDistance - idealDistance) * NODE_DISTANCE_MULTIPLIER;
            fitness += (maximalMinDistance - idealDistance) * NODE_DISTANCE_MULTIPLIER;

            //EDGE LENGTH
            double edgeLength = EvaluateEdgeLength(compoundGraph, algorithm, sizes, chromosome.IdealEdgeLength, chromosome.NestingFactor);

            fitness += edgeLength * EDGE_LENGTH_MULTIPLIER;

            //EDGE CROSSING
            double edgeCrossing = EvaluateEdgeCrossing(compoundGraph, algorithm, sizes);

            fitness += edgeCrossing * EDGE_CROSSING_MULTIPLIER;

            //PHASE_LENGTH
            double phaseLength = (chromosome.Phase1Iterations + chromosome.Phase2Iterations +
                                  chromosome.Phase3Iterations) * PHASE_LENGTH_MULTIPLIER;

            fitness += phaseLength;

            return(fitness);
        }
        private void ShowGraph(int graphIndex)
        {
            CompoundGraph<object, IEdge<object>> g = graphs[graphIndex];
            _rectDict.Clear();
            _lineDict.Clear();
            lc.Children.Clear();
            var origo = new Ellipse();
            origo.Width = 100;
            origo.Height = 100;
            origo.Fill = Brushes.Black;
            origo.OpacityMask = new RadialGradientBrush(Colors.Black, Colors.Transparent);
            Canvas.SetLeft(origo, -5);
            Canvas.SetTop(origo, -5);
            lc.Children.Add(origo);
            var sizes = new Dictionary<object, Size>();
            var borders = new Dictionary<object, Thickness>();
            var layoutType = new Dictionary<object, CompoundVertexInnerLayoutType>();

            var s = new Size(20, 20);
            foreach (var v in g.SimpleVertices)
            {
                sizes[v] = s;
            }

            var b = new Thickness(5, 10, 5, 5);
            foreach (var v in g.CompoundVertices)
            {
                sizes[v] = new Size();
                borders[v] = b;
                layoutType[v] = CompoundVertexInnerLayoutType.Automatic;
            }

            var worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += (sender, e) =>
                                 {
                                     var layoutAlgorithm =
                                         new CompoundFDPLayoutAlgorithm
                                             <object, IEdge<object>, ICompoundGraph<object, IEdge<object>>>(
                                             g, sizes, borders, layoutType, null,
                                             parameters);
                                     layoutAlgorithm.IterationEnded += (o, evt) =>
                                     {
                                         var args = evt as TestingCompoundLayoutIterationEventArgs<object, IEdge<object>, TestingCompoundVertexInfo, object>;
                                         var positions = args.VertexPositions;
                                         var innerSizes = (args as ICompoundLayoutIterationEventArgs<object>).InnerCanvasSizes;
                                         var vertexInfos = args.VertexInfos;

                                         Dispatcher.Invoke(new Action(delegate
                                                                          {
                                                                              var pDict = new Dictionary<object, Point>();

                                                                              var compoundVerticesToCheck =
                                                                                  new Queue<object>();
                                                                              var compoundVertices = new List<object>();
                                                                              var root =
                                                                                  g.CompoundVertices.Where(
                                                                                      cv => g.GetParent(cv) == null);
                                                                              foreach (var r in root)
                                                                                  compoundVerticesToCheck.Enqueue(r);
                                                                              while (compoundVerticesToCheck.Count > 0)
                                                                              {
                                                                                  var next = compoundVerticesToCheck.Dequeue();
                                                                                  if (!g.IsCompoundVertex(next))
                                                                                      continue;
                                                                                  compoundVertices.Add(next);
                                                                                  foreach (
                                                                                      var childrenVertex in
                                                                                          g.GetChildrenVertices(next))
                                                                                  {
                                                                                      compoundVerticesToCheck.Enqueue(
                                                                                          childrenVertex);
                                                                                  }
                                                                              }

                                                                              //draw the compound vertices
                                                                              foreach (var v in compoundVertices)
                                                                              {
                                                                                  var size = innerSizes[v];
                                                                                  size.Width += b.Left + b.Right;
                                                                                  size.Height += b.Top + b.Bottom;

                                                                                  var pos = positions[v];
                                                                                  pDict[v] = pos;
                                                                                  AddRect(v, pos, size);
                                                                              }

                                                                              //draw the simple vertices
                                                                              foreach (var v in g.SimpleVertices)
                                                                              {
                                                                                  var pos = positions[v];
                                                                                  pDict[v] = pos;
                                                                                  AddRect(v, pos, s);
                                                                              }

                                                                              //draw the simple edges
                                                                              foreach (var edge in g.Edges)
                                                                              {
                                                                                  var pos1 = pDict[edge.Source];
                                                                                  var pos2 = pDict[edge.Target];
                                                                                  AddLine(edge, pos1, pos2, true);
                                                                              }

                                                                              //draw the containment edges
                                                                              /*foreach (var v in g.CompoundVertices)
                                                                              {
                                                                                  var pos1 = pDict[v];
                                                                                  foreach (var c in g.GetChildrenVertices(v))
                                                                                  {
                                                                                      var pos2 = pDict[c];
                                                                                      AddLine(c, pos1, pos2, false);
                                                                                  }
                                                                              }*/

                                                                              //draw the lines of the forces
                                                                              foreach (var forceLine in _forceLines)
                                                                                  lc.Children.Remove(forceLine);

                                                                              var springColor = Brushes.Orange;
                                                                              var repulsionColor = Brushes.Red;
                                                                              var gravityColor = Brushes.Green;
                                                                              var applicationColor = Brushes.Yellow;

                                                                              foreach (var kvp in vertexInfos)
                                                                              {
                                                                                  var line = CreateLine(pDict[kvp.Key],
                                                                                                        kvp.Value.SpringForce,
                                                                                                        springColor);
                                                                                  lc.Children.Add(line);
                                                                                  _forceLines.Add(line);
                                                                                  line = CreateLine(pDict[kvp.Key],
                                                                                             kvp.Value.RepulsionForce,
                                                                                             repulsionColor);
                                                                                  lc.Children.Add(line);
                                                                                  _forceLines.Add(line);
                                                                                  line = CreateLine(pDict[kvp.Key],
                                                                                             kvp.Value.GravityForce,
                                                                                             gravityColor);
                                                                                  lc.Children.Add(line);
                                                                                  _forceLines.Add(line);
                                                                                  line = CreateLine(pDict[kvp.Key],
                                                                                             kvp.Value.ApplicationForce,
                                                                                             applicationColor);
                                                                                  lc.Children.Add(line);
                                                                                  _forceLines.Add(line);
                                                                              }

                                                                              //set the position of the gravity center
                                                                              Animate(origo, Canvas.LeftProperty, args.GravitationCenter.X - origo.Width / 2.0, animationDuration);
                                                                              Animate(origo, Canvas.TopProperty, args.GravitationCenter.Y - origo.Height / 2.0, animationDuration);
                                                                              txtMessage.Text = args.Message;
                                                                          }));
                                         do
                                         {
                                             Thread.Sleep((int) animationDuration.TimeSpan.TotalMilliseconds);
                                         } while (_paused);
                                     };
                                     layoutAlgorithm.Compute();
                                 };
            worker.RunWorkerAsync();
        }
Пример #18
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)
        {
            BidirectionalGraph <string, WeightedEdge <string> > bGraph = GraphSharpUtility.GetBidirectionalGraph(graph);
            IDictionary <string, Size>   nodeSizes     = GraphSharpUtility.GetNodeSizes(graph);
            IDictionary <string, Vector> nodePositions = GraphSharpUtility.GetNodePositions(graph);
            CompoundFDPLayoutParameters  compoundFDPLayoutParameters = new CompoundFDPLayoutParameters();

            CompoundFDPLayoutAlgorithm <string, WeightedEdge <string>, BidirectionalGraph <string, WeightedEdge <string> > > compoundFDPLayoutAlgorithm = new CompoundFDPLayoutAlgorithm <string, WeightedEdge <string>, BidirectionalGraph <string, WeightedEdge <string> > >(bGraph, nodeSizes, null, null, nodePositions, compoundFDPLayoutParameters);

            compoundFDPLayoutAlgorithm.Compute();

            GraphSharpUtility.SetNodePositions(graph, compoundFDPLayoutAlgorithm.VertexPositions);
        }
Пример #19
0
        private void ShowGraph(int graphIndex)
        {
            CompoundGraph <object, IEdge <object> > graph = _graphs[graphIndex];

            _rectangles.Clear();
            _lines.Clear();
            Layout.Children.Clear();

            var origo = new Ellipse
            {
                Width       = 100,
                Height      = 100,
                Fill        = System.Windows.Media.Brushes.Black,
                OpacityMask = new RadialGradientBrush(Colors.Black, Colors.Transparent)
            };

            Canvas.SetLeft(origo, -5);
            Canvas.SetTop(origo, -5);
            Layout.Children.Add(origo);

            var sizes      = new Dictionary <object, Size>();
            var borders    = new Dictionary <object, Thickness>();
            var layoutType = new Dictionary <object, CompoundVertexInnerLayoutType>();

            var size = new Size(20, 20);

            foreach (object vertex in graph.SimpleVertices)
            {
                sizes[vertex] = size;
            }

            var thickness = new Thickness(5, 10, 5, 5);

            foreach (object vertex in graph.CompoundVertices)
            {
                sizes[vertex]      = default;
                borders[vertex]    = thickness;
                layoutType[vertex] = CompoundVertexInnerLayoutType.Automatic;
            }

            var worker = new BackgroundWorker
            {
                WorkerReportsProgress = true
            };

            worker.DoWork += (sender, args) =>
            {
                var layoutAlgorithm = new CompoundFDPLayoutAlgorithm <object, IEdge <object>, ICompoundGraph <object, IEdge <object> > >(
                    graph,
                    sizes,
                    borders,
                    layoutType,
                    _parameters);

                layoutAlgorithm.IterationEnded += (s, iterationArgs) =>
                {
                    var testIterationArgs = iterationArgs as TestingCompoundLayoutIterationEventArgs <object, IEdge <object>, TestingCompoundVertexInfo, object>;

                    IDictionary <object, Point> positions = testIterationArgs?.VerticesPositions;
                    if (positions is null)
                    {
                        return;
                    }

                    IDictionary <object, Size> innerSizes = ((ICompoundLayoutIterationEventArgs <object>)testIterationArgs).InnerCanvasSizes;
                    IDictionary <object, TestingCompoundVertexInfo> verticesInfos = testIterationArgs.VerticesInfos;

                    Dispatcher.Invoke(() =>
                    {
                        var points = new Dictionary <object, Point>();

                        var compoundVerticesToCheck = new Queue <object>();
                        var compoundVertices        = new List <object>();
                        var roots = graph.CompoundVertices.Where(vertex => graph.GetParent(vertex) is null);
                        foreach (object root in roots)
                        {
                            compoundVerticesToCheck.Enqueue(root);
                        }

                        while (compoundVerticesToCheck.Count > 0)
                        {
                            object next = compoundVerticesToCheck.Dequeue();
                            if (!graph.IsCompoundVertex(next))
                            {
                                continue;
                            }

                            compoundVertices.Add(next);
                            foreach (object childrenVertex in graph.GetChildrenVertices(next))
                            {
                                compoundVerticesToCheck.Enqueue(childrenVertex);
                            }
                        }

                        // Draw the compound vertices
                        foreach (object vertex in compoundVertices)
                        {
                            Size innerSize    = innerSizes[vertex];
                            innerSize.Width  += thickness.Left + thickness.Right;
                            innerSize.Height += thickness.Top + thickness.Bottom;

                            Point pos      = positions[vertex];
                            points[vertex] = pos;
                            AddRectangle(vertex, pos, innerSize);
                        }

                        // Draw the simple vertices
                        foreach (object vertex in graph.SimpleVertices)
                        {
                            Point pos      = positions[vertex];
                            points[vertex] = pos;
                            AddRectangle(vertex, pos, size);
                        }

                        // Draw the simple edges
                        foreach (IEdge <object> edge in graph.Edges)
                        {
                            Point pos1 = points[edge.Source];
                            Point pos2 = points[edge.Target];
                            AddLine(edge, pos1, pos2, true);
                        }

                        // Draw the containment edges
                        foreach (object vertex in graph.CompoundVertices)
                        {
                            Point pos1 = points[vertex];
                            foreach (object child in graph.GetChildrenVertices(vertex))
                            {
                                Point pos2 = points[child];
                                AddLine(child, pos1, pos2, false);
                            }
                        }

                        // Draw the lines of the forces
                        foreach (Line forceLine in _forceLines)
                        {
                            Layout.Children.Remove(forceLine);
                        }

                        SolidColorBrush springColor      = System.Windows.Media.Brushes.Orange;
                        SolidColorBrush repulsionColor   = System.Windows.Media.Brushes.Red;
                        SolidColorBrush gravityColor     = System.Windows.Media.Brushes.Green;
                        SolidColorBrush applicationColor = System.Windows.Media.Brushes.Yellow;

                        foreach (KeyValuePair <object, TestingCompoundVertexInfo> pair in verticesInfos)
                        {
                            Line line = CreateLine(points[pair.Key], pair.Value.SpringForce, springColor);
                            Layout.Children.Add(line);
                            _forceLines.Add(line);

                            line = CreateLine(points[pair.Key], pair.Value.RepulsionForce, repulsionColor);
                            Layout.Children.Add(line);
                            _forceLines.Add(line);

                            line = CreateLine(points[pair.Key], pair.Value.GravityForce, gravityColor);
                            Layout.Children.Add(line);
                            _forceLines.Add(line);

                            line = CreateLine(points[pair.Key], pair.Value.ApplicationForce, applicationColor);
                            Layout.Children.Add(line);
                            _forceLines.Add(line);
                        }

                        // Set the position of the gravity center
                        Animate(
                            origo,
                            Canvas.LeftProperty,
                            testIterationArgs.GravitationCenter.X - origo.Width / 2.0,
                            _animationDuration);
                        Animate(
                            origo,
                            Canvas.TopProperty,
                            testIterationArgs.GravitationCenter.Y - origo.Height / 2.0,
                            _animationDuration);
                        TxtMessage.Text = testIterationArgs.Message;
                    });

                    do
                    {
                        Thread.Sleep((int)_animationDuration.TimeSpan.TotalMilliseconds);
                    } while (_paused);
                };

                layoutAlgorithm.Compute();
            };

            worker.RunWorkerAsync();
        }
        private static double EvaluateFitnessForGraph(
            [NotNull] CompoundFDPLayoutParameters chromosome,
            [NotNull] CompoundGraph <object, IEdge <object> > compoundGraph)
        {
            var verticesSizes   = new Dictionary <object, Size>();
            var verticesBorders = new Dictionary <object, Thickness>();
            var layoutTypes     = new Dictionary <object, CompoundVertexInnerLayoutType>();

            var size = new Size(20, 20);

            foreach (object v in compoundGraph.SimpleVertices)
            {
                verticesSizes[v] = size;
            }

            var border = new Thickness(5, 10, 5, 5);

            foreach (object v in compoundGraph.CompoundVertices)
            {
                verticesSizes[v]   = new Size();
                verticesBorders[v] = border;
                layoutTypes[v]     = CompoundVertexInnerLayoutType.Automatic;
            }

            // Run the compound FDP algorithm
            var algorithm = new CompoundFDPLayoutAlgorithm <object, IEdge <object>, CompoundGraph <object, IEdge <object> > >(
                compoundGraph,
                verticesSizes,
                verticesBorders,
                layoutTypes,
                chromosome);

            algorithm.Compute();

            double fitness = 0.0;

            // Refresh the sizes of the compound vertices
            foreach (object v in compoundGraph.CompoundVertices)
            {
                Thickness b = verticesBorders[v];
                Size      innerCanvasSize = algorithm.InnerCanvasSizes[v];
                var       s = new Size(
                    b.Left + innerCanvasSize.Width + b.Right,
                    b.Top + innerCanvasSize.Height + b.Bottom);
                verticesSizes[v] = s;
            }

            // NODE OVERLAP
            double overlaps = EvaluateNodeOverlaps(compoundGraph, algorithm, verticesSizes);

            fitness += overlaps * NodeOverlapMultiplier;

            // CANVAS SIZE
            Size canvasSize = EvaluateCanvasSize(compoundGraph, algorithm, verticesSizes);

            fitness += canvasSize.Width * canvasSize.Height * CanvasSizeMultiplier;

            // CANVAS RATIO
            double canvasRatio = canvasSize.Width / canvasSize.Height;

            canvasRatio = canvasRatio < 1 ? 1 / canvasRatio : canvasRatio;
            fitness    += canvasRatio * CanvasRatioMultiplier;

            // NODE DISTANCES
            double idealDistance = chromosome.IdealEdgeLength;

            EvaluateNodeDistances(
                compoundGraph,
                algorithm,
                verticesSizes,
                out double minimalMinDistance,
                out double averageMinDistance,
                out double maximalMinDistance);
            fitness += (averageMinDistance - idealDistance) * NodeDistanceMultiplier;
            fitness += (minimalMinDistance - idealDistance) * NodeDistanceMultiplier;
            fitness += (maximalMinDistance - idealDistance) * NodeDistanceMultiplier;

            // EDGE LENGTH
            double edgeLength = EvaluateEdgeLength(
                compoundGraph,
                algorithm,
                verticesSizes,
                chromosome.IdealEdgeLength,
                chromosome.NestingFactor);

            fitness += edgeLength * EdgeLengthMultiplier;

            // EDGE CROSSING
            double edgeCrossing = EvaluateEdgeCrossing(compoundGraph, algorithm, verticesSizes);

            fitness += edgeCrossing * EdgeCrossingMultiplier;

            // PHASE_LENGTH
            double phaseLength = chromosome.Phase1Iterations + chromosome.Phase2Iterations + chromosome.Phase3Iterations;

            phaseLength *= PhaseLengthMultiplier;
            fitness     += phaseLength;

            return(fitness);
        }