private void RebuildGraph() { // Clear prev Graph this.node_map.Clear(); this.in_edge_map.Clear(); this.out_edge_map.Clear(); this.Graph.Nodes.Clear(); this.Graph.Edges.Clear(); // Build new Graph if( this.grammar == null || this.canonical_sets == null ) return; // Make the layout with the Glee lib var layout_g = new Microsoft.Glee.Drawing.Graph("Fdsm"); layout_g.Directed = true; var layout_nodes = new Dictionary<Node, Microsoft.Glee.Drawing.Node>(); var layout_edges = new Dictionary<Edge, Microsoft.Glee.Drawing.Edge>(); // Create nodes for( int state_index = 0; state_index < this.canonical_sets.Sets.Count; ++state_index ) { var node = new Node(); node.Shape = NodeShape.Circle; node.Box = new RectangleF(this.node_diameter / -2, this.node_diameter / -2, this.node_diameter, this.node_diameter); node.BorderType = (this.canonical_sets.Sets[state_index].FirstOrDefault( item => item.CursorPosition == item.Rule.RightHandSide.Count) == null) ? NodeBorderType.Single : NodeBorderType.Double; node.LabelText = state_index.ToString(); node.LabelFont = this.Font; var label_size = this.Graph.MeasureString(this.Font, node.LabelText); node.LabelOffset = new PointF(label_size.Width / -2, label_size.Height / -2); node.BorderPen = this.border_pen; node.BackBrush = this.back_brush; node.LabelBrush = this.label_brush; this.Graph.Nodes.Add(node); this.node_map.Add(state_index, node); this.in_edge_map.Add(state_index, new Dictionary<SyntacticAnalysis.Symbol, Edge>()); this.out_edge_map.Add(state_index, new Dictionary<SyntacticAnalysis.Symbol, Edge>()); // Layout var layout_node = layout_g.AddNode(node.LabelText); layout_node.Attr.LabelMargin = 6; layout_nodes.Add(node, layout_node); } // Create edges for( int state_index = 0; state_index < this.canonical_sets.Sets.Count; ++state_index ) { // Terminals foreach( var symbol in this.grammar.Terminals ) { int transition_to = this.canonical_sets.GetTransition(state_index, symbol); if( transition_to != -1 ) { var edge = new Edge(); edge.StartNode = this.node_map[state_index]; edge.EndNode = this.node_map[transition_to]; edge.LabelText = symbol.Name; edge.LabelFont = this.Font; edge.LabelBrush = this.label_brush; edge.LinePen = this.edge_pen; this.Graph.Edges.Add(edge); this.out_edge_map[state_index][symbol] = edge; this.in_edge_map[transition_to][symbol] = edge; // Layout var layout_edge = layout_g.AddEdge(edge.StartNode.LabelText, edge.EndNode.LabelText); layout_edge.Attr.Label = edge.LabelText; layout_edges.Add(edge, layout_edge); } } // Grammaticals foreach( var symbol in this.grammar.Grammaticals ) { int transition_to = this.canonical_sets.GetTransition(state_index, symbol); if( transition_to != -1 ) { var edge = new Edge(); edge.StartNode = this.node_map[state_index]; edge.EndNode = this.node_map[transition_to]; edge.LabelText = symbol.Name; edge.LabelFont = this.Font; edge.LabelBrush = this.label_brush; edge.LinePen = this.edge_pen; this.Graph.Edges.Add(edge); this.out_edge_map[state_index][symbol] = edge; this.in_edge_map[transition_to][symbol] = edge; // Layout var layout_edge = layout_g.AddEdge(edge.StartNode.LabelText, edge.EndNode.LabelText); layout_edge.Attr.Label = edge.LabelText; layout_edges.Add(edge, layout_edge); } } } // Let Glee calculate a layout var layout_rnd = new Microsoft.Glee.GraphViewerGdi.GraphRenderer(layout_g); layout_rnd.CalculateLayout(); // Extract and replicate layout // Nodes foreach( var kv in layout_nodes ) kv.Key.Position = this.FromGleePoint(kv.Value.Attr.Pos); // Edges foreach( var kv in layout_edges ) { var edge = kv.Key; var layout_edge = kv.Value; var curve = layout_edge.Attr.EdgeCurve as Microsoft.Glee.Splines.Curve; if( curve != null ) { var segments = new List<CurveSegment>(); foreach( Microsoft.Glee.Splines.ICurve segment in curve.Segs ) { if( segment is Microsoft.Glee.Splines.CubicBezierSeg ) { var b = (Microsoft.Glee.Splines.CubicBezierSeg)segment; segments.Add(new CurveSegment(new PointF[] { this.FromGleePoint(b.B(0)), this.FromGleePoint(b.B(1)), this.FromGleePoint(b.B(2)), this.FromGleePoint(b.B(3)), })); } else // Fallback to linearity, even if it is not a LineSeg. { segments.Add(new CurveSegment(new PointF[] { this.FromGleePoint(segment.Start), this.FromGleePoint(segment.End), })); } } // Snap edge ends to nodes var e = new PointF( edge.StartNode.Position.X - segments[0].Points[0].X, edge.StartNode.Position.Y - segments[0].Points[0].Y); var diff = e.Norm().Multiply(e.Length() - this.node_radius); edge.StartPosition = segments[0].Points[0] = segments[0].Points[0].Add(diff); var seg = segments[segments.Count - 1]; e = new PointF( edge.EndNode.Position.X - seg.Points[seg.Points.Length - 1].X, edge.EndNode.Position.Y - seg.Points[seg.Points.Length - 1].Y); diff = e.Norm().Multiply(e.Length() - this.node_radius); edge.EndPosition = seg.Points[seg.Points.Length - 1] = seg.Points[seg.Points.Length - 1].Add(diff); edge.Segments = segments.ToArray(); } else { // Fallback to line edge.StartPosition = edge.StartNode.Position; edge.EndPosition = edge.EndNode.Position; // Snap edge ends to nodes var e = new PointF( edge.EndPosition.X - edge.StartPosition.X, edge.EndPosition.Y - edge.StartPosition.Y) .Norm().Multiply(this.node_radius); edge.StartPosition = edge.StartPosition.Add(e); edge.EndPosition = edge.EndPosition.Substract(e); } // Label edge.LabelPosition = new PointF( -(float)layout_edge.Attr.LabelTop, (float)layout_edge.Attr.LabelLeft); } // Add an 'in-edge' to the start state node var start_edge = new Edge(); start_edge.LinePen = this.edge_pen; start_edge.EndNode = this.node_map[0]; start_edge.EndPosition = new PointF( start_edge.EndNode.Position.X - this.node_radius, start_edge.EndNode.Position.Y); start_edge.StartPosition = new PointF( start_edge.EndPosition.X - this.node_diameter, start_edge.EndPosition.Y); this.Graph.Edges.Add(start_edge); }
static void Main() { Microsoft.Glee.Drawing.Graph graph = new Microsoft.Glee.Drawing.Graph(""); graph.AddEdge("A", "B"); graph.AddEdge("A", "B"); graph.FindNode("A").Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Red; graph.FindNode("B").Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Blue; Microsoft.Glee.GraphViewerGdi.GraphRenderer renderer = new Microsoft.Glee.GraphViewerGdi.GraphRenderer (graph); renderer.CalculateLayout(); int width = 500; Bitmap bitmap = new Bitmap(width, (int)(graph.Height * (width / graph.Width)), PixelFormat.Format32bppPArgb); renderer.Render(bitmap); bitmap.Save("test1.png"); // //create a form // System.Windows.Forms.Form form = new //System.Windows.Forms.Form(); // //create a viewer object // Microsoft.Glee.GraphViewerGdi.GViewer viewer //= new Microsoft.Glee.GraphViewerGdi.GViewer(); // //create a graph object // Microsoft.Glee.Drawing.Graph graph = new //Microsoft.Glee.Drawing.Graph("graph"); // //create the graph content // graph.AddEdge("A", "B"); // graph.AddEdge("B", "C"); // graph.AddEdge("A", "C").EdgeAttr.Color = //Microsoft.Glee.Drawing.Color.Green; // graph.FindNode("A").Attr.Fillcolor = //Microsoft.Glee.Drawing.Color.Magenta; // graph.FindNode("B").Attr.Fillcolor = //Microsoft.Glee.Drawing.Color.MistyRose; // Microsoft.Glee.Drawing.Node c = //graph.FindNode("C"); // c.Attr.Fillcolor = //Microsoft.Glee.Drawing.Color.PaleGreen; // c.Attr.Shape = //Microsoft.Glee.Drawing.Shape.Diamond; // //bind the graph to the viewer viewer.Graph = graph; // //associate the viewer with the form // form.SuspendLayout(); // viewer.Dock = //System.Windows.Forms.DockStyle.Fill; // form.Controls.Add(viewer); // form.ResumeLayout(); // ///show the form // /// //form.ShowDialog(); //Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); //Application.Run(new Form1()); }
//отрисовка графа private void DrawGraph(int currentTop) { this.GraphPanel.Controls.Clear(); Microsoft.Glee.GraphViewerGdi.GViewer viewer = new Microsoft.Glee.GraphViewerGdi.GViewer(); viewer.AsyncLayout = false; viewer.AutoScroll = true; nodes = new string[nodesCount]; for (int i = 0; i < nodesCount; ++i) { nodes[i] = (i + 1).ToString(); } graph = new Microsoft.Glee.Drawing.Graph("Graph"); for (int i = 0; i < nodesCount; ++i) { for (int j = 0; j < nodesCount; ++j) { if (adjancyMatrix[i, j] != 0) { graph.AddEdge(nodes[i], "" /*adjancyMatrix[i, j].ToString()*/, nodes[j]); } } } for (int i = 0; i < nodesCount; ++i) { Microsoft.Glee.Drawing.Node currentNode = graph.FindNode(nodes[i]); if (i == currentTop) { currentNode.Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Green; } else { currentNode.Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Yellow; } currentNode.Attr.Shape = Microsoft.Glee.Drawing.Shape.DoubleCircle; } Microsoft.Glee.GraphViewerGdi.GraphRenderer renderer = new Microsoft.Glee.GraphViewerGdi.GraphRenderer(graph); viewer.Graph = graph; this.GraphPanel.SuspendLayout(); viewer.Dock = System.Windows.Forms.DockStyle.Fill; this.GraphPanel.Controls.Add(viewer); this.GraphPanel.ResumeLayout(); //Bitmap graphImage = new Bitmap(GraphPanel.Width, GraphPanel.Height); //renderer.Render(graphImage); //GraphPanel.Image = graphImage; }
//отрисовка графа private void DrawGraph(int currentTop) { this.GraphPanel.Controls.Clear(); Microsoft.Glee.GraphViewerGdi.GViewer viewer = new Microsoft.Glee.GraphViewerGdi.GViewer(); viewer.AsyncLayout = false; viewer.AutoScroll = true; nodes = new string[nodesCount]; for (int i = 0; i < nodesCount; ++i) { nodes[i] = (i + 1).ToString(); } graph = new Microsoft.Glee.Drawing.Graph("Graph"); for (int i = 0; i < nodesCount; ++i) { for (int j = 0; j < nodesCount; ++j) { if (adjancyMatrix[i, j] != 0) { graph.AddEdge(nodes[i], ""/*adjancyMatrix[i, j].ToString()*/, nodes[j]); } } } for (int i = 0; i < nodesCount; ++i) { Microsoft.Glee.Drawing.Node currentNode = graph.FindNode(nodes[i]); if (i == currentTop) { currentNode.Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Green; } else { currentNode.Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Yellow; } currentNode.Attr.Shape = Microsoft.Glee.Drawing.Shape.DoubleCircle; } Microsoft.Glee.GraphViewerGdi.GraphRenderer renderer = new Microsoft.Glee.GraphViewerGdi.GraphRenderer(graph); viewer.Graph = graph; this.GraphPanel.SuspendLayout(); viewer.Dock = System.Windows.Forms.DockStyle.Fill; this.GraphPanel.Controls.Add(viewer); this.GraphPanel.ResumeLayout(); //Bitmap graphImage = new Bitmap(GraphPanel.Width, GraphPanel.Height); //renderer.Render(graphImage); //GraphPanel.Image = graphImage; }