Ignore:
Timestamp:
09/13/13 14:42:38 (8 years ago)
Author:
bburlacu
Message:

#1772: Merged changes from the trunk and other branches. Added new ExtendedSymbolicExpressionTreeCanvas control for the visual exploration of tree genealogies. Reorganized some files and folders.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs

    r9835 r9963  
    2424using System.Drawing;
    2525using System.Drawing.Imaging;
     26using System.IO;
     27using System.Linq;
    2628using System.Windows.Forms;
    2729using Point = System.Drawing.Point;
     
    3335    private Dictionary<ISymbolicExpressionTreeNode, VisualSymbolicExpressionTreeNode> visualTreeNodes;
    3436    private Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualSymbolicExpressionTreeNodeConnection> visualLines;
     37    private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> { MinHorizontalSpacing = 5, MinVerticalSpacing = 5 };
     38    private readonly SymbolicExpressionTreeLayoutAdapter layoutAdapter = new SymbolicExpressionTreeLayoutAdapter();
     39
    3540
    3641    public SymbolicExpressionTreeChart() {
     
    160165        graphics.Clear(backgroundColor);
    161166        if (tree != null) {
    162           int height = this.Height / tree.Depth;
    163           DrawFunctionTree(tree, graphics, 0, 0, this.Width, height);
     167          DrawFunctionTree(tree, graphics, 70, 46, 20, 50);
    164168        }
    165169      }
     
    254258    #region methods for painting the symbolic expression tree
    255259
    256     private void DrawFunctionTree(ISymbolicExpressionTree tree, Graphics graphics, int x, int y, int width, int height) {
    257       //      DrawFunctionTree(tree.Root, graphics, x, y, width, height, Point.Empty);
    258       AlternateDraw(tree, graphics, 70, 46, 20, 50);
    259     }
    260 
    261     private void AlternateDraw(ISymbolicExpressionTree tree, Graphics graphics, int preferredWidth, int preferredHeight, int minDistance, int maxDistance) {
    262       var tl = new TreeLayout();
    263       tl.Distance = 5;
    264       tl.SymbolicExpressionTree = tree;
    265 
    266       var nodePositions = tl.GetNodeCoordinates();
    267       var bounds = tl.Bounds();
     260    private void DrawFunctionTree(ISymbolicExpressionTree tree, Graphics graphics, int preferredWidth, int preferredHeight, int minDistance, int maxDistance) {
     261      var layoutNodes = layoutAdapter.Convert(tree).ToList();
     262      layoutEngine.Reset();
     263      layoutEngine.Root = layoutNodes[0];
     264      foreach (var ln in layoutNodes)
     265        layoutEngine.AddNode(ln.Content, ln);
     266      layoutEngine.CalculateLayout();
     267      var nodePositions = layoutEngine.GetNodeCoordinates();
     268      var bounds = layoutEngine.Bounds();
    268269
    269270      double sx = Width / bounds.Width;
    270271      double sy = Height / bounds.Height;
    271272
    272       double dx = tl.Distance * sx; // scaled horizontal distance
    273       double dy = tl.Distance * sy; // scaled vertical distance
     273      double dx = layoutEngine.MinHorizontalSpacing * sx; // scaled horizontal distance
     274      double dy = layoutEngine.MinVerticalSpacing * sy; // scaled vertical distance
    274275
    275276      int maxWidth = (int)Math.Round(dx);
     
    307308            graphics.DrawLine(linePen, origin, target);
    308309          }
    309         }
    310       }
    311     }
    312 
    313     /// <summary>
    314     ///
    315     /// </summary>
    316     /// <param name="node">the root of the function tree to draw</param>
    317     /// <param name="graphics">graphics object to draw on</param>
    318     /// <param name="x">x coordinate of drawing area</param>
    319     /// <param name="y">y coordinate of drawing area</param>
    320     /// <param name="width">width of drawing area</param>
    321     /// <param name="height">height of drawing area</param>
    322     private void DrawFunctionTree(ISymbolicExpressionTreeNode node, Graphics graphics, int x, int y, int width, int height, Point connectionPoint) {
    323       VisualSymbolicExpressionTreeNode visualTreeNode = visualTreeNodes[node];
    324       float center_x = x + width / 2;
    325       float center_y = y + height / 2;
    326       int actualWidth = width - spacing;
    327       int actualHeight = height - spacing;
    328 
    329       using (var textBrush = new SolidBrush(visualTreeNode.TextColor))
    330       using (var nodeLinePen = new Pen(visualTreeNode.LineColor))
    331       using (var nodeFillBrush = new SolidBrush(visualTreeNode.FillColor)) {
    332 
    333         //calculate size of node
    334         if (actualWidth >= visualTreeNode.PreferredWidth && actualHeight >= visualTreeNode.PreferredHeight) {
    335           visualTreeNode.Width = visualTreeNode.PreferredWidth;
    336           visualTreeNode.Height = visualTreeNode.PreferredHeight;
    337           visualTreeNode.X = (int)center_x - visualTreeNode.Width / 2;
    338           visualTreeNode.Y = (int)center_y - visualTreeNode.Height / 2;
    339         }
    340           //width too small to draw in desired sized
    341         else if (actualWidth < visualTreeNode.PreferredWidth && actualHeight >= visualTreeNode.PreferredHeight) {
    342           visualTreeNode.Width = actualWidth;
    343           visualTreeNode.Height = visualTreeNode.PreferredHeight;
    344           visualTreeNode.X = x;
    345           visualTreeNode.Y = (int)center_y - visualTreeNode.Height / 2;
    346         }
    347           //height too small to draw in desired sized
    348         else if (actualWidth >= visualTreeNode.PreferredWidth && actualHeight < visualTreeNode.PreferredHeight) {
    349           visualTreeNode.Width = visualTreeNode.PreferredWidth;
    350           visualTreeNode.Height = actualHeight;
    351           visualTreeNode.X = (int)center_x - visualTreeNode.Width / 2;
    352           visualTreeNode.Y = y;
    353         }
    354           //width and height too small to draw in desired size
    355         else {
    356           visualTreeNode.Width = actualWidth;
    357           visualTreeNode.Height = actualHeight;
    358           visualTreeNode.X = x;
    359           visualTreeNode.Y = y;
    360         }
    361 
    362         //draw terminal node
    363         if (node.SubtreeCount == 0) {
    364           graphics.FillRectangle(nodeFillBrush, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    365           graphics.DrawRectangle(nodeLinePen, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    366         } else {
    367           graphics.FillEllipse(nodeFillBrush, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    368           graphics.DrawEllipse(nodeLinePen, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    369         }
    370 
    371         //draw name of symbol
    372         var text = node.ToString();
    373         graphics.DrawString(text, textFont, textBrush, new RectangleF(visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height), stringFormat);
    374 
    375         //draw connection line to parent node
    376         if (!connectionPoint.IsEmpty && node.Parent != null) {
    377           var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node.Parent, node);
    378           using (Pen linePen = new Pen(visualLine.LineColor)) {
    379             linePen.DashStyle = visualLine.DashStyle;
    380             graphics.DrawLine(linePen, connectionPoint, new Point(visualTreeNode.X + visualTreeNode.Width / 2, visualTreeNode.Y));
    381           }
    382         }
    383 
    384         //calculate areas for the subtrees according to their tree size and call drawFunctionTree
    385         Point connectFrom = new Point(visualTreeNode.X + visualTreeNode.Width / 2, visualTreeNode.Y + visualTreeNode.Height);
    386         int[] xBoundaries = new int[node.SubtreeCount + 1];
    387         xBoundaries[0] = x;
    388         for (int i = 0; i < node.SubtreeCount; i++) {
    389           xBoundaries[i + 1] = (int)(xBoundaries[i] + (width * (double)node.GetSubtree(i).GetLength()) / (node.GetLength() - 1));
    390           DrawFunctionTree(node.GetSubtree(i), graphics, xBoundaries[i], y + height, xBoundaries[i + 1] - xBoundaries[i], height, connectFrom);
    391310        }
    392311      }
     
    455374    }
    456375    #endregion
     376    #region export pgf/tikz
     377    private void exportLatexToolStripMenuItem_Click(object sender, EventArgs e) {
     378      using (var dialog = new SaveFileDialog { Filter = "Tex (*.tex)|*.tex" }) {
     379        if (dialog.ShowDialog() != DialogResult.OK) return;
     380        string filename = dialog.FileName.ToLower();
     381        var formatter = new SymbolicExpressionTreeLatexFormatter();
     382        File.WriteAllText(filename, formatter.Format(Tree));
     383      }
     384    }
     385    #endregion
    457386  }
    458387}
Note: See TracChangeset for help on using the changeset viewer.