Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/12/14 13:26:18 (10 years ago)
Author:
pfleck
Message:
  • Merged trunk into preprocessing branch.
Location:
branches/DataPreprocessing
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/DataPreprocessing

  • branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views

  • branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs

    r10538 r11009  
    2727using System.Linq;
    2828using System.Windows.Forms;
    29 using Point = System.Drawing.Point;
     29
    3030
    3131namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
     
    3939    private const int preferredNodeWidth = 70;
    4040    private const int preferredNodeHeight = 46;
    41     private const int minHorizontalDistance = 30;
    42     private const int minVerticalDistance = 30;
     41    private int minHorizontalDistance = 30;
     42    private int minVerticalDistance = 30;
    4343
    4444    public SymbolicExpressionTreeChart() {
     
    5050      this.backgroundColor = Color.White;
    5151      this.textFont = new Font(FontFamily.GenericSansSerif, 12);
    52       layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> {
     52
     53      visualTreeNodes = new Dictionary<ISymbolicExpressionTreeNode, VisualTreeNode<ISymbolicExpressionTreeNode>>();
     54      visualLines = new Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualTreeNodeConnection>();
     55
     56      layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) {
    5357        NodeWidth = preferredNodeWidth,
    5458        NodeHeight = preferredNodeHeight,
     
    5660        VerticalSpacing = minVerticalDistance
    5761      };
     62      reingoldTilfordToolStripMenuItem.Checked = true;
    5863    }
    5964
     
    105110      set {
    106111        tree = value;
    107         if (tree != null) {
    108           //the layout engine needs to be initialized here so that the visualNodes and the visualLines dictionaries are populated
    109           InitializeLayout();
    110           Repaint();
    111         }
     112        Repaint();
    112113      }
    113114    }
     
    128129      if (this.Width <= 1 || this.Height <= 1)
    129130        this.image = new Bitmap(1, 1);
    130       else
     131      else {
    131132        this.image = new Bitmap(Width, Height);
     133      }
    132134      this.Repaint();
     135    }
     136
     137    public event EventHandler Repainted;//expose this event to notify the parent control that the tree was repainted
     138    protected virtual void OnRepaint(object sender, EventArgs e) {
     139      var repainted = Repainted;
     140      if (repainted != null) {
     141        repainted(sender, e);
     142      }
    133143    }
    134144
     
    137147        this.GenerateImage();
    138148        this.Refresh();
     149        OnRepaint(this, EventArgs.Empty);
    139150      }
    140151    }
     
    147158          foreach (var visualNode in visualTreeNodes.Values) {
    148159            DrawTreeNode(graphics, visualNode);
     160            if (visualNode.Content.SubtreeCount > 0) {
     161              foreach (var visualSubtree in visualNode.Content.Subtrees.Select(s => visualTreeNodes[s])) {
     162                DrawLine(graphics, visualNode, visualSubtree);
     163              }
     164            }
    149165          }
    150166        }
     
    170186        graphics.Clear(backgroundColor);
    171187        if (tree != null) {
    172           DrawFunctionTree(tree, graphics, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
     188          DrawFunctionTree(graphics, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
    173189        }
    174190      }
     
    236252
    237253    private void SymbolicExpressionTreeChart_MouseMove(object sender, MouseEventArgs e) {
    238 
    239254      VisualTreeNode<ISymbolicExpressionTreeNode> visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
    240255      if (draggedSymbolicExpressionTree != null &&
     
    262277    #endregion
    263278
    264     private void InitializeLayout() {
    265       var actualRoot = tree.Root.SubtreeCount == 1 ? tree.Root.GetSubtree(0) : tree.Root;
    266       layoutEngine.Initialize(actualRoot, n => n.Subtrees, n => n.GetLength(), n => n.GetDepth());
    267       layoutEngine.CalculateLayout(this.Width, this.Height);
    268       var visualNodes = layoutEngine.GetVisualNodes().ToList();
    269       //populate the visual nodes and visual connections dictionaries
     279    private void CalculateLayout(int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) {
     280      layoutEngine.NodeWidth = preferredWidth;
     281      layoutEngine.NodeHeight = preferredHeight;
     282      layoutEngine.HorizontalSpacing = minHDistance;
     283      layoutEngine.VerticalSpacing = minVDistance;
     284
     285      var actualRoot = tree.Root;
     286      if (actualRoot.Symbol is ProgramRootSymbol && actualRoot.SubtreeCount == 1) {
     287        actualRoot = tree.Root.GetSubtree(0);
     288      }
     289
     290      var visualNodes = layoutEngine.CalculateLayout(actualRoot, Width, Height).ToList();
    270291      visualTreeNodes = visualNodes.ToDictionary(x => x.Content, x => x);
    271292      visualLines = new Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualTreeNodeConnection>();
     
    278299
    279300    #region methods for painting the symbolic expression tree
    280     private void DrawFunctionTree(ISymbolicExpressionTree symbExprTree, Graphics graphics, int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) {
    281       //we assume here that the layout has already been initialized when the symbolic expression tree was changed
    282       //recalculate layout according to new node widths and spacing
    283       layoutEngine.NodeWidth = preferredWidth;
    284       layoutEngine.NodeHeight = preferredHeight;
    285       layoutEngine.HorizontalSpacing = minHDistance;
    286       layoutEngine.VerticalSpacing = minVDistance;
    287       layoutEngine.CalculateLayout(Width, Height);
     301    private void DrawFunctionTree(Graphics graphics, int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) {
     302      CalculateLayout(preferredWidth, preferredHeight, minHDistance, minVDistance);
    288303      var visualNodes = visualTreeNodes.Values;
    289304      //draw nodes and connections
    290305      foreach (var visualNode in visualNodes) {
    291         DrawTreeNode(visualNode);
     306        DrawTreeNode(graphics, visualNode);
    292307        var node = visualNode.Content;
    293308        foreach (var subtree in node.Subtrees) {
     
    302317          }
    303318        }
    304       }
    305     }
    306 
    307     protected void DrawTreeNode(VisualTreeNode<ISymbolicExpressionTreeNode> visualTreeNode) {
    308       using (var graphics = Graphics.FromImage(image)) {
    309         graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
    310         graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    311         DrawTreeNode(graphics, visualTreeNode);
    312319      }
    313320    }
     
    333340      }
    334341    }
     342
     343    protected void DrawLine(Graphics graphics, VisualTreeNode<ISymbolicExpressionTreeNode> startNode, VisualTreeNode<ISymbolicExpressionTreeNode> endNode) {
     344      var origin = new Point(startNode.X + startNode.Width / 2, startNode.Y + startNode.Height);
     345      var target = new Point(endNode.X + endNode.Width / 2, endNode.Y);
     346      graphics.Clip = new Region(new Rectangle(Math.Min(origin.X, target.X), origin.Y, Math.Max(origin.X, target.X), target.Y));
     347      var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(startNode.Content, endNode.Content);
     348      using (var linePen = new Pen(visualLine.LineColor)) {
     349        linePen.DashStyle = visualLine.DashStyle;
     350        graphics.DrawLine(linePen, origin, target);
     351      }
     352    }
    335353    #endregion
    336354    #region save image
     
    348366      Image image = new Bitmap(Width, Height);
    349367      using (Graphics g = Graphics.FromImage(image)) {
    350         DrawFunctionTree(tree, g, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
     368        DrawFunctionTree(g, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
    351369      }
    352370      image.Save(filename);
     
    358376        using (Metafile file = new Metafile(filename, g.GetHdc())) {
    359377          using (Graphics emfFile = Graphics.FromImage(file)) {
    360             DrawFunctionTree(tree, emfFile, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
     378            DrawFunctionTree(emfFile, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
    361379          }
    362380        }
     
    377395
    378396    private void reingoldTilfordToolStripMenuItem_Click(object sender, EventArgs e) {
    379       layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> {
     397      minHorizontalDistance = 30;
     398      minVerticalDistance = 30;
     399      layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) {
    380400        NodeWidth = preferredNodeWidth,
    381401        NodeHeight = preferredNodeHeight,
     
    383403        VerticalSpacing = minVerticalDistance
    384404      };
    385       InitializeLayout();
     405      reingoldTilfordToolStripMenuItem.Checked = true;
     406      boxesToolStripMenuItem.Checked = false;
    386407      Repaint();
    387408    }
    388409
    389410    private void boxesToolStripMenuItem_Click(object sender, EventArgs e) {
    390       layoutEngine = new BoxesLayoutEngine<ISymbolicExpressionTreeNode> {
     411      minHorizontalDistance = 5;
     412      minVerticalDistance = 5;
     413      layoutEngine = new BoxesLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees, n => n.GetLength(), n => n.GetDepth()) {
    391414        NodeWidth = preferredNodeWidth,
    392415        NodeHeight = preferredNodeHeight,
     
    394417        VerticalSpacing = minVerticalDistance
    395418      };
    396       InitializeLayout();
     419      reingoldTilfordToolStripMenuItem.Checked = false;
     420      boxesToolStripMenuItem.Checked = true;
    397421      Repaint();
    398422    }
Note: See TracChangeset for help on using the changeset viewer.