private static void CreateDiagramNodes(List <NodeShape> nodeShapes, GeometryGraph graph) { foreach (NodeShape nodeShape in nodeShapes) { ICurve graphRectangle = CurveFactory.CreateRectangle(nodeShape.Bounds.Width, nodeShape.Bounds.Height, new Point(nodeShape.Bounds.Center.X, nodeShape.Bounds.Center.Y)); Node diagramNode = new Node(graphRectangle, nodeShape); graph.Nodes.Add(diagramNode); } }
private static Cluster CreateCluster(IEnumerable <Node> nodes, double margin) { var cluster = new Cluster(nodes) { RectangularBoundary = new RectangularClusterBoundary { LeftMargin = margin, RightMargin = margin, BottomMargin = margin, TopMargin = margin }, BoundaryCurve = CurveFactory.CreateRectangle(1, 1, new Point()) }; cluster.CalculateBoundsFromChildren(0); return(cluster); }
private static Cluster AddCluster(double padding, GeometryGraph g, Cluster parent, params string[] vs) { var c = new Cluster(from v in vs select g.FindNodeByUserData(v)) { UserData = string.Concat(vs), RectangularBoundary = new RectangularClusterBoundary { LeftMargin = padding, RightMargin = padding, BottomMargin = padding, TopMargin = padding }, BoundaryCurve = CurveFactory.CreateRectangle(30, 30, new Point(15, 15)) }; parent.AddChild(c); return(c); }
public void CanDrawGeometryGraph() { Graph graph = new Graph(); GeometryGraph ge = new GeometryGraph(); graph.GeometryGraph = ge; SugiyamaLayoutSettings sugiyamaSettings = new SugiyamaLayoutSettings { Transformation = PlaneTransformation.Rotation(Math.PI / 2), EdgeRoutingSettings = { EdgeRoutingMode = EdgeRoutingMode.Spline }, MinNodeHeight = 10, MinNodeWidth = 20, }; sugiyamaSettings.NodeSeparation *= 2; graph.LayoutAlgorithmSettings = sugiyamaSettings; graph.AddNode("A"); graph.AddNode("B"); graph.AddNode("C"); graph.AddNode("D"); graph.AddEdge("A", "B"); foreach (Node n in graph.Nodes) { graph.GeometryGraph.Nodes.Add(new GeometryNode(CurveFactory.CreateRectangle(20, 10, new GeometryPoint()), n)); } foreach (Edge e in graph.Edges) { GeometryNode source = graph.FindGeometryNode(e.SourceNode.Id); GeometryNode target = graph.FindGeometryNode(e.TargetNode.Id); graph.GeometryGraph.Edges.Add(new GeometryEdge(source, target)); } ge.UpdateBoundingBox(); graph.GeometryGraph = ge; using (Bitmap bmp = new Bitmap(400, 400, PixelFormat.Format32bppPArgb)) using (Graphics g = Graphics.FromImage(bmp)) { g.Clear(System.DrawingCore.Color.White); Rectangle rect = new Rectangle(0, 0, 400, 400); //GdiUtils.SetGraphTransform(graph, rect, g); LayeredLayout layout = new LayeredLayout(graph.GeometryGraph, sugiyamaSettings); layout.Run(); GdiUtils.DrawFromGraph(rect, graph.GeometryGraph, g); bmp.Save("graph.bmp", ImageFormat.Bmp); } }
public void GraphModelGroupedLayeredTest() { LayoutAlgorithmSettings settings; var graph = LoadGraph("GraphModelGrouped.msagl.geom", out settings); foreach (var e in graph.Edges) { e.Labels.Add(new Label(40, 10, e)); } settings = new SugiyamaLayoutSettings { NodeSeparation = 5, PackingAspectRatio = 1.2, LayerSeparation = 5 }; var layout = new InitialLayoutByCluster(graph, settings); foreach (var c in graph.RootCluster.AllClustersDepthFirst().Where(c => c != graph.RootCluster)) { c.RectangularBoundary = new RectangularClusterBoundary { LeftMargin = 5, RightMargin = 5, BottomMargin = 5, TopMargin = 5 }; c.BoundaryCurve = CurveFactory.CreateRectangle(30, 30, new Point(15, 15)); } double progress = 0.0; EnableDebugViewer(); EventHandler <ProgressChangedEventArgs> handler = (s, e) => progress = e.RatioComplete; try { layout.ProgressChanged += handler; layout.Run(); } finally { layout.ProgressChanged -= handler; } Assert.AreEqual(1.0, progress, "Progress was never reported as 100%. Last update was at " + progress + "%"); ShowGraphInDebugViewer(graph); foreach (var e in graph.Edges) { Assert.IsNotNull(e.Curve, "Edge was not routed"); } }
public void GraphModelGroupedForceDirectedSplineTest() { LayoutAlgorithmSettings settings; var graph = LoadGraph("GraphModelGrouped.msagl.geom", out settings); settings = new FastIncrementalLayoutSettings { NodeSeparation = 5, PackingAspectRatio = 1.2, AvoidOverlaps = true }; settings.EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.Spline; settings.EdgeRoutingSettings.Padding = 2; var layout = new InitialLayoutByCluster(graph, settings); foreach (var c in graph.RootCluster.AllClustersDepthFirst().Where(c => c != graph.RootCluster)) { c.RectangularBoundary = new RectangularClusterBoundary { LeftMargin = 5, RightMargin = 5, BottomMargin = 5, TopMargin = 5 }; c.BoundaryCurve = CurveFactory.CreateRectangle(30, 30, new Point(15, 15)); } double progress = 0.0; EnableDebugViewer(); EventHandler <ProgressChangedEventArgs> handler = (s, e) => progress = e.RatioComplete; try { layout.ProgressChanged += handler; layout.Run(); } finally { layout.ProgressChanged -= handler; } // Ignore this assertion due to bug: 688960 - One MSAGL unit test is failing due to Parallel Linq which affects the Progress accounting. //Assert.AreEqual(1.0, progress, "Progress was never reported as 100%. Last update was at " + progress + "%"); ShowGraphInDebugViewer(graph); foreach (var e in graph.Edges) { Assert.IsNotNull(e.Curve, "Edge was not routed"); } }
internal static void ShowInitialRectangles(IEnumerable <VariableDef> variableDefs) { if (!ShowInitialRects) { return; } #if TEST_MSAGL var debugCurves = new List <DebugCurve>(); debugCurves.AddRange(variableDefs.Select( v => new Rectangle(v.InitialLeft, v.InitialTop, v.InitialRight, v.InitialBottom)).Select( rect => new DebugCurve(0.1, "black", CurveFactory.CreateRectangle(rect)))); SugiyamaLayoutSettings.ShowDebugCurvesEnumeration(debugCurves); #else // TEST_MSAGL System.Diagnostics.Debug.WriteLine("-show* options require TEST mode"); #endif // TEST_MSAGL }
void InsertNodeIntoGraph(Rectangle rectangle) { Node node = new Node("testNode"); node.Attr.FillColor = Color.Red; node.Attr.Shape = Shape.DrawFromGeometry; node.Label = null; var geomNode = node.GeometryNode = GeometryGraphCreator.CreateGeometryNode(gViewer.Graph, gViewer.Graph.GeometryGraph, node, ConnectionToGraph.Disconnected); var center = (rectangle.LeftBottom + rectangle.RightTop) / 2; geomNode.BoundaryCurve = CurveFactory.CreateRectangle(rectangle.Width, rectangle.Height, center); node.GeometryNode = geomNode; var dNode = gViewer.CreateIViewerNode(node); gViewer.AddNode(dNode, true); }
public void CreateBoundary() { var height = (this.Labels.FirstOrDefault()?.Height / 1.45) ?? 0d; // minimal height, the 1.45 is a magical number, found through experimentation var width = 100d; foreach (var label in this.Labels) { // the padding is 12 on each side, so we'll pad the label width with 24 if (label.Width + 24 > width) { width = label.Width + 24; } height += label.Height; } this.GeometryNode.BoundaryCurve = CurveFactory.CreateRectangle(width, height > 0 ? height : 50, new Point(0, 0)); }
public void GraphModelGroupedForceDirectedRectilinearTest() { LayoutAlgorithmSettings settings; var graph = LoadGraph("GraphModelGrouped.msagl.geom", out settings); settings = new FastIncrementalLayoutSettings { NodeSeparation = 5, PackingAspectRatio = 1.2, AvoidOverlaps = true, GravityConstant = 0.5 }; settings.EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode.Rectilinear; settings.EdgeRoutingSettings.Padding = 2; settings.EdgeRoutingSettings.CornerRadius = 2; var layout = new InitialLayoutByCluster(graph, settings); foreach (var c in graph.RootCluster.AllClustersDepthFirst().Where(c => c != graph.RootCluster)) { c.RectangularBoundary = new RectangularClusterBoundary { LeftMargin = 5, RightMargin = 5, BottomMargin = 5, TopMargin = 5 }; c.BoundaryCurve = CurveFactory.CreateRectangle(30, 30, new Point(15, 15)); } double progress = 0.0; EnableDebugViewer(); EventHandler <ProgressChangedEventArgs> handler = (s, e) => progress = e.RatioComplete; try { layout.ProgressChanged += handler; layout.Run(); } finally { layout.ProgressChanged -= handler; } Assert.IsTrue(1.0 <= progress, "Progress was never reported as 100%. Last update was at " + progress + "%"); ShowGraphInDebugViewer(graph); foreach (var e in graph.Edges) { Assert.IsNotNull(e.Curve, "Edge was not routed"); } }
public void SimpleClusterGraphRectilinear() { var g = new GeometryGraph(); var node0 = new Node(CurveFactory.CreateRectangle(10, 10, new Point()), 0); var node1 = new Node(CurveFactory.CreateRectangle(10, 10, new Point()), 1); var cluster = new Cluster(new[] { node1 }); cluster.UserData = 2; cluster.BoundaryCurve = CurveFactory.CreateRectangle(10, 10, new Point()); var edge = new Edge(node0, node1) { Length = 100 }; g.Nodes.Add(node0); g.Nodes.Add(node1); g.Edges.Add(edge); var cluster2 = new Cluster(new[] { node0 }, new[] { cluster }); cluster2.UserData = 3; cluster2.BoundaryCurve = CurveFactory.CreateRectangle(10, 10, new Point()); g.RootCluster = cluster2; InitialLayout initialLayout = new InitialLayout(g, new FastIncrementalLayoutSettings() { AvoidOverlaps = true }); initialLayout.Run(); RectilinearEdgeRouter router = new RectilinearEdgeRouter(g, 1, 1, false); router.Run(); EnableDebugViewer(); ShowGraphInDebugViewer(g); var bb0 = node0.BoundingBox; bb0.Pad(1); Assert.IsTrue(bb0.Contains(edge.EdgeGeometry.Curve.Start)); var bb1 = node1.BoundingBox; bb1.Pad(1); Assert.IsTrue(bb1.Contains(edge.EdgeGeometry.Curve.End)); }
public GameObject AddNode() { var go = GameObject.Instantiate(nodePrefab, units); //Following step required otherwise Size will return wrong rect Canvas.ForceUpdateCanvases(); var unode = go.GetComponent <UNode>(); double w = ToGraphSpace(unode.Size.width); double h = ToGraphSpace(unode.Size.height); Node node = new Node(CurveFactory.CreateRectangle(w, h, new Point())); node.UserData = go; unode.GraphNode = node; graph.Nodes.Add(node); return(go); }
public void NestedDeepTranslationTest() { EnableDebugViewer(); List <Node> nodes = new[] { new Node(CurveFactory.CreateRectangle(30, 20, new Point())), new Node(CurveFactory.CreateRectangle(30, 20, new Point(100, 0))), new Node(CurveFactory.CreateRectangle(30, 20, new Point(200, 0))) } .ToList(); var graph = new GeometryGraph(); nodes.ForEach(graph.Nodes.Add); nodes.Add(CreateCluster(nodes.Take(2), 10)); Assert.AreEqual(nodes[3].BoundingBox.Width, 150, "Inner Cluster has incorrect width"); Assert.AreEqual(nodes[3].BoundingBox.Height, 40, "Inner Cluster has incorrect height"); nodes.Add(CreateCluster(new[] { nodes[3], nodes[2] }, 10)); graph.RootCluster = new Cluster(new Node[] { }, new[] { (Cluster)nodes[4] }); List <Edge> edges = new[] { new Edge(nodes[0], nodes[1]), new Edge(nodes[0], nodes[2]), new Edge(nodes[2], nodes[1]), new Edge(nodes[3], nodes[2]), new Edge(nodes[2], nodes[3]) } .ToList(); edges.ForEach(graph.Edges.Add); RouteEdges(graph, 10); var bounds = (from v in nodes select v.BoundingBox).Concat(from e in edges select e.BoundingBox).ToList(); var delta = new Point(10, 20); ((Cluster)nodes[4]).DeepTranslation(delta, true); ShowGraphInDebugViewer(graph); IEnumerable <GeometryObject> geometryObjects = (from v in nodes select(GeometryObject) v).Concat(from e in edges select(GeometryObject) e); foreach (var b in geometryObjects.Zip(bounds, (g, b) => new { G = g, Original = b, Target = g.BoundingBox })) { Assert.IsTrue(ApproximateComparer.Close(Rectangle.Translate(b.Original, delta), b.Target), "object was not translated: " + b.G); } }
private ICurve CreateLabelAndBoundary(NavigationPoint navigationPoint, Microsoft.Msagl.Drawing.Node node) { node.Attr.LabelMargin *= 2; node.Label.IsVisible = false; var y = (navigationPoint.Latitude - airfield.Latitude) * 200000; var x = (navigationPoint.Longitude - airfield.Longitude) * 200000; var positionalPoint = new Microsoft.Msagl.Core.Geometry.Point(x, y); switch (navigationPoint) { case Runway _: node.Attr.Color = Color.Green; return(CurveFactory.CreateCircle(50, positionalPoint)); case Junction _: node.Attr.Shape = Shape.Hexagon; node.Attr.Color = Color.Blue; return(CurveFactory.CreateHexagon(100, 30, positionalPoint)); case ParkingSpot _: node.Attr.Color = Color.Orange; return(CurveFactory.CreateOctagon(100, 30, positionalPoint)); case WayPoint _: node.Attr.Color = Color.Purple; return(CurveFactory.CreateRectangle(100, 30, positionalPoint)); case NavigationPoint _: if (navigationPoint == highlightPoint) { node.Attr.Color = Color.Red; } else { node.Attr.Color = Color.Black; } return(CurveFactory.CreateCircle(100, positionalPoint)); } return(CurveFactory.CreateCircle(5, positionalPoint)); }
static ICurve GetRandomShape(Random random) { //we support rectangle, roundedRectangle, circle, ellipse, diamond, Octagon, triangle, star int index = random.Next(3); var center = new Microsoft.Msagl.Core.Geometry.Point(); switch (index) { case 0: return(CurveFactory.CreateRectangle(20 + random.Next(10), 10 + random.Next(10), center)); case 1: return(CurveFactory.CreateRectangleWithRoundedCorners(30 + random.Next(10), 20 + random.Next(10), 1 + random.Next(8), 1 + random.Next(8), center)); case 2: return(CurveFactory.CreateEllipse(26, 18, center)); } return(null); }
public override void AfterVisitTree() { LayoutSettings = new SugiyamaLayoutSettings { Transformation = PlaneTransformation.Rotation(System.Math.PI), EdgeRoutingSettings = { EdgeRoutingMode = EdgeRoutingMode.Spline }, MinNodeHeight = 10, MinNodeWidth = 20, }; //LayoutSettings.NodeSeparation *= 2; Graph.LayoutAlgorithmSettings = LayoutSettings; foreach (Node n in Graph.Nodes) { Graph.GeometryGraph.Nodes.Add( new GeometryNode(CurveFactory.CreateRectangle(20, 10, new GeometryPoint()), n)); } foreach (Edge e in Graph.Edges) { GeometryNode source = Graph.FindGeometryNode(e.SourceNode.Id); GeometryNode target = Graph.FindGeometryNode(e.TargetNode.Id); Graph.GeometryGraph.Edges.Add(new GeometryEdge(source, target)); } Graph.GeometryGraph.UpdateBoundingBox(); using (Bitmap bmp = new Bitmap(1200, 1200, PixelFormat.Format32bppPArgb)) using (Graphics g = Graphics.FromImage(bmp)) { Rectangle rect = new Rectangle(0, 0, 1200, 1200); g.Clear(System.Drawing.Color.White); GraphDiagramUtil.SetGraphTransform(Graph.GeometryGraph, rect, g); LayeredLayout layout = new LayeredLayout(Graph.GeometryGraph, LayoutSettings); layout.Run(); GraphDiagramUtil.DrawFromGraph(rect, Graph.GeometryGraph, g); bmp.Save("graph.bmp", ImageFormat.Bmp); } }
private static Cluster CreateCluster(IEnumerable <Node> nodes, double margin, string name = "") { var cluster = new Cluster(nodes.Where(n => !(n is Cluster))) { RectangularBoundary = new RectangularClusterBoundary { LeftMargin = margin, RightMargin = margin, BottomMargin = margin, TopMargin = margin }, BoundaryCurve = CurveFactory.CreateRectangle(1, 1, new Point()) }; cluster.CalculateBoundsFromChildren(0); cluster.UserData = name; var nc = nodes.Where(n => n is Cluster); foreach (var b in nc) { cluster.AddCluster((Cluster)b); } return(cluster); }
/// <summary> /// Creates a small, non-trivial clustered and disconnected graph for tests /// ( A B-)-C /// D-(-(-E F)-G) /// H-I /// J /// (K L-)-(-M N) /// </summary> /// <returns>returns a disconnected clustered graph</returns> public static GeometryGraph CreateClusteredGraph(double padding) { var graph = new GeometryGraph(); for (int i = 0; i < 14; ++i) { graph.Nodes.Add(new Node(CurveFactory.CreateRectangle(10, 10, new Point()), GetCharacter(i))); } AddEdge(graph, "B", "C"); AddEdge(graph, "D", "E"); AddEdge(graph, "H", "I"); var root = AddRootCluster(graph, "C", "D", "H", "I", "J"); AddCluster(padding, graph, root, "A", "B"); var parent = AddCluster(padding, graph, root, "G"); var child = AddCluster(padding, graph, parent, "E", "F"); graph.Edges.Add(new Edge(graph.FindNodeByUserData("G"), child)); graph.Edges.Add(new Edge(AddCluster(padding, graph, root, "K", "L"), AddCluster(padding, graph, root, "M", "N"))); return(graph); }
private Node CreateEventNode(string eventName, NodeType type, Color color) { Node eventNode; if (eventNodes.TryGetValue(eventName, out eventNode)) { Debug.LogError("Event node already exists " + eventName); return(eventNode); } var info = new GameEventNodeInfo(eventName) { type = type, color = color }; ICurve curve = CurveFactory.CreateRectangle(info.baseSize.x, info.baseSize.y, new Point()); eventNode = new Node(curve, info); eventNodes.Add(eventName, eventNode); graph.Nodes.Add(eventNode); return(eventNode); }
/// <summary> /// Controlling the draw because a need to control the size. /// /// Supporting these shapes : /// Box /// Ellipse /// Circle /// Plaintext /// Point /// </summary> /// <param name="node"></param> /// <param name="centerLocation"></param> /// <param name="width"></param> /// <param name="hight"></param> /// <returns></returns> ICurve DrawCurve(Microsoft.Msagl.Drawing.Node node) { ICurve shape = null; switch (node.Attr.Shape) { case Shape.Box: shape = CurveFactory.CreateRectangle(NodeWidth, NodeHeight, NodeCenter); break; case Shape.Ellipse: shape = CurveFactory.CreateEllipse(NodeWidth, NodeHeight, NodeCenter); break; case Shape.Circle: shape = CurveFactory.CreateCircle(NodeWidth, NodeCenter); break; case Shape.Point: shape = CurveFactory.CreateCircle(0.5, NodeCenter); break; case Shape.Diamond: shape = CurveFactory.CreateDiamond(NodeWidth, NodeHeight, NodeCenter); break; case Shape.Hexagon: shape = CurveFactory.CreateHexagon(NodeWidth, NodeHeight, NodeCenter); break; case Shape.Octagon: shape = CurveFactory.CreateOctagon(NodeWidth, NodeHeight, NodeCenter); break; } return(shape); }
static internal GeometryGraph CreateAndLayoutGraph() { double w = 30; double h = 20; GeometryGraph graph = new GeometryGraph(); Node a = new Node(new Ellipse(w, h, new P()), "a"); Node b = new Node(CurveFactory.CreateRectangle(w, h, new P()), "b"); Node c = new Node(CurveFactory.CreateRectangle(w, h, new P()), "c"); Node d = new Node(CurveFactory.CreateRectangle(w, h, new P()), "d"); graph.Nodes.Add(a); graph.Nodes.Add(b); graph.Nodes.Add(c); graph.Nodes.Add(d); Edge e = new Edge(a, b) { Length = 10 }; graph.Edges.Add(e); graph.Edges.Add(new Edge(b, c) { Length = 3 }); graph.Edges.Add(new Edge(b, d) { Length = 4 }); //graph.Save("c:\\tmp\\saved.msagl"); var settings = new Microsoft.Msagl.Layout.MDS.MdsLayoutSettings(); LayoutHelpers.CalculateLayout(graph, settings, null); return(graph); }
/// <summary> /// Executes the algorithm. /// </summary> /// <summary> /// Executes the actual algorithm. /// </summary> protected override void RunInternal() { var g = new GeometryGraph(); foreach (var v in graph.Nodes) { Debug.Assert(!(v is Cluster)); var u = new Node(v.BoundaryCurve.Clone()) { UserData = v }; v.AlgorithmData = new PivotMDSNodeWrap(u); g.Nodes.Add(u); } double avgLength = 0; foreach (var e in graph.Edges) { avgLength += e.Length; if (e.Source is Cluster || e.Target is Cluster) { continue; } var u = e.Source.AlgorithmData as PivotMDSNodeWrap; var v = e.Target.AlgorithmData as PivotMDSNodeWrap; var ee = new Edge(u.node, v.node) { Length = e.Length }; g.Edges.Add(ee); } if (graph.Edges.Count != 0) { avgLength /= graph.Edges.Count; } else { avgLength = 100; } // create edges from the children of each parent cluster to the parent cluster node foreach (var c in graph.RootCluster.AllClustersDepthFirst()) { if (c == graph.RootCluster) { continue; } var u = new Node(CurveFactory.CreateRectangle(10, 10, new Point())); u.UserData = c; c.AlgorithmData = new PivotMDSNodeWrap(u); g.Nodes.Add(u); foreach (var v in c.Nodes.Concat(from cc in c.Clusters select(Node) cc)) { var vv = v.AlgorithmData as PivotMDSNodeWrap; g.Edges.Add(new Edge(u, vv.node) { Length = avgLength }); } } // create edges between clusters foreach (var e in graph.Edges) { if (e.Source is Cluster || e.Target is Cluster) { var u = e.Source.AlgorithmData as PivotMDSNodeWrap; var v = e.Target.AlgorithmData as PivotMDSNodeWrap; var ee = new Edge(u.node, v.node) { Length = e.Length }; g.Edges.Add(ee); } } // with 0 majorization iterations we just do PivotMDS MdsLayoutSettings settings = new MdsLayoutSettings { ScaleX = this.Scale, ScaleY = this.Scale, IterationsWithMajorization = 0, RemoveOverlaps = false, AdjustScale = false }; MdsGraphLayout mdsLayout = new MdsGraphLayout(settings, g); this.RunChildAlgorithm(mdsLayout, 1.0); g.UpdateBoundingBox(); foreach (var v in graph.Nodes) { var m = v.AlgorithmData as PivotMDSNodeWrap; v.Center = m.node.Center; } }
static ICurve Box(Point p) { // ReSharper restore UnusedMember.Local return(CurveFactory.CreateRectangle(2, 2, p)); }
public static ICurve CreateCurve(double w, double h) { return(CurveFactory.CreateRectangle(w, h, new Point())); }
public static Node CreateNode(string id) { return(new Node(CurveFactory.CreateRectangle(50, 50, new Point(0, 0)), id)); }
protected static void ShowGraphInDebugViewer(GeometryGraph graph) { if (graph == null) { return; } Microsoft.Msagl.GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions(); //FixNullCurveEdges(graph.Edges); var debugCurves = graph.Nodes.Select(n => n.BoundaryCurve).Select(c => new DebugCurve("red", c)); debugCurves = debugCurves.Concat(graph.RootCluster.AllClustersDepthFirst().Select(c => c.BoundaryCurve).Select(c => new DebugCurve("green", c))); debugCurves = debugCurves.Concat(graph.Edges.Select(e => new DebugCurve(120, 1, "blue", e.Curve))); debugCurves = debugCurves.Concat(graph.Edges.Where(e => e.Label != null).Select(e => new DebugCurve("green", CurveFactory.CreateRectangle(e.LabelBBox)))); var arrowHeadsAtSource = from e in graph.Edges where e.Curve != null && e.EdgeGeometry.SourceArrowhead != null select new DebugCurve(120, 2, "black", new LineSegment(e.Curve.Start, e.EdgeGeometry.SourceArrowhead.TipPosition)); var arrowHeadsAtTarget = from e in graph.Edges where e.Curve != null && e.EdgeGeometry.TargetArrowhead != null select new DebugCurve(120, 2, "black", new LineSegment(e.Curve.End, e.EdgeGeometry.TargetArrowhead.TipPosition)); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(debugCurves.Concat(arrowHeadsAtSource).Concat(arrowHeadsAtTarget)); }
static ICurve CreateDot() { return(CurveFactory.CreateRectangle(5, 5, new Point())); }
static ICurve CreateRectangle() { return(CurveFactory.CreateRectangle(20, 10, new Point())); }
// double GetAverageOverlap(List<Tuple<int, int, double, double>> proximityEdgesWithDistance, // Point[] positions, Rectangle[] rectangles) { // double overlap = 0; // int counter = 0; // foreach (Tuple<int, int, double, double> tuple in proximityEdgesWithDistance) { // int nodeId1 = tuple.Item1; // int nodeId2 = tuple.Item2; // Point point1 = positions[nodeId1]; // Point point2 = positions[nodeId2]; // // if (nodeBoxes == null) throw new ArgumentNullException("nodeBoxes"); // if (nodeBoxes.Length <= nodeId1) return 0; // if (nodeBoxes.Length <= nodeId2) return 0; // double box1Width = nodeBoxes[nodeId1].Width; // double box1Height = nodeBoxes[nodeId1].Height; // double box2Width = nodeBoxes[nodeId2].Width; // double box2Height = nodeBoxes[nodeId2].Height; // // //Gansner et. al Scaling factor of distance // double tw = (box1Width/2 + box2Width/2)/Math.Abs(point1.X - point2.X); // double th = (box1Height/2 + box2Height/2)/Math.Abs(point1.Y - point2.Y); // double t = Math.Max(Math.Min(tw, th), 1); // // if (t == 1) continue; // no overlap between the bounding boxes // // double distance = (t - 1)*(point1 - point2).Length; // overlap += distance; // counter++; // } // // overlap /= counter; // return overlap; // } /// <summary> /// For debugging only /// </summary> /// <param name="currentIteration"></param> /// <param name="nodeSizes"></param> /// <param name="nodePositions"></param> /// <param name="newPositions"></param> /// <param name="proximityEdgesWithDistance"></param> /// <param name="finalGridVectors"></param> static void ShowCurrentMovementVectors(int currentIteration, Size[] nodeSizes, Point[] nodePositions, List <Point> newPositions, List <Tuple <int, int, double, double> > proximityEdgesWithDistance, Point[] finalGridVectors) { #if DEBUG && !SILVERLIGHT && !SHARPKIT if (DebugMode && currentIteration % 1 == 0) { List <DebugCurve> curveList = new List <DebugCurve>(); var nodeBoxes = new Rectangle[nodeSizes.Length]; for (int i = 0; i < nodeBoxes.Length; i++) { nodeBoxes[i] = new Rectangle(nodeSizes[i], nodePositions[i]); } var nodeCurves = nodeBoxes.Select( v => new DebugCurve(220, 1, "black", Curve.PolylineAroundClosedCurve(CurveFactory.CreateRectangle(v)))); curveList.AddRange(nodeCurves); var vectors = nodePositions.Select( (p, i) => new DebugCurve(220, 2, "red", new Polyline(p, newPositions[i]))).ToList(); foreach (Tuple <int, int, double, double> tuple in proximityEdgesWithDistance) { if (tuple.Item3 > 0) { curveList.Add(new DebugCurve(220, 1, "gray", new Polyline(nodePositions[tuple.Item1], nodePositions[tuple.Item2]))); } } curveList.AddRange(vectors); if (finalGridVectors != null) { var gridFlowVectors = nodePositions.Select((p, i) => new DebugCurve(220, 2, "blue", new Polyline(p, p + finalGridVectors[i]))) .ToList(); curveList.AddRange(gridFlowVectors); } LayoutAlgorithmSettings.ShowDebugCurves(curveList.ToArray()); } #endif }
private static ICurve CreateCurve(double w, double h) { return(CurveFactory.CreateRectangle(w, h, new Microsoft.Msagl.Core.Geometry.Point())); }