Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionTracking/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Tracking/FragmentGraphView.cs @ 10833

Last change on this file since 10833 was 10833, checked in by bburlacu, 10 years ago

#1772: Fixed another minor display bug concerning elite individuals. Fixed bug when saving fragments from mutation. Displayed quality as well in the SymbolicExpressionTreeTile.

File size: 7.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Drawing;
4using System.Linq;
5using HeuristicLab.Core.Views;
6using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
7using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
8using HeuristicLab.EvolutionTracking;
9using HeuristicLab.MainForm;
10using HeuristicLab.Visualization;
11
12namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
13  [View("FragmentGraphView")]
14  [Content(typeof(IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>>), IsDefaultView = true)]
15  public sealed partial class FragmentGraphView : ItemView {
16    private const int PreferredHorizontalSpacing = 10;
17    private const int PreferredVerticalSpacing = 25;
18
19    private ReingoldTilfordLayoutEngine<TileLayoutNode> layoutEngine;
20    private ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> symbolicExpressionEngine;
21
22    private Dictionary<IGenealogyGraphNode<IFragment<ISymbolicExpressionTreeNode>>, TileLayoutNode> tileDictionary;
23
24    private SymbolicExpressionTreeTile Root { get; set; }
25
26    public new IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>> Content {
27      get { return (IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>>)base.Content; }
28      set { base.Content = value; }
29    }
30
31    public FragmentGraphView() {
32      InitializeComponent();
33
34      layoutEngine = new ReingoldTilfordLayoutEngine<TileLayoutNode>(n => n.Children) {
35        HorizontalSpacing = PreferredHorizontalSpacing,
36        VerticalSpacing = PreferredVerticalSpacing,
37      };
38      symbolicExpressionEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) {
39        HorizontalSpacing = PreferredHorizontalSpacing,
40        VerticalSpacing = PreferredVerticalSpacing,
41        NodeWidth = 80,
42        NodeHeight = 40
43      };
44      tileDictionary = new Dictionary<IGenealogyGraphNode<IFragment<ISymbolicExpressionTreeNode>>, TileLayoutNode>();
45    }
46
47    private void MakeTiles() {
48      var chart = symbolicExpressionChartControl.Chart;
49      tileDictionary.Clear();
50      foreach (var node in Content.Nodes) {
51        var tile = new SymbolicExpressionTreeTile(chart);
52        tile.LayoutEngine = symbolicExpressionEngine;
53        tile.Label = "Generation " + node.Rank + Environment.NewLine +
54                     "Quality " + String.Format("{0:0.000}", node.Quality);
55        tile.Root = node.Content.Root;
56        var tileNode = new TileLayoutNode { Tile = tile };
57        tileDictionary.Add(node, tileNode);
58      }
59      foreach (var node in Content.Nodes.Where(n => n.Children.Any())) {
60        var layoutNode = tileDictionary[node];
61        layoutNode.Children = new List<TileLayoutNode>(node.Children.Select(x => tileDictionary[x]));
62      }
63    }
64
65    private void Draw() {
66      var chart = symbolicExpressionChartControl.Chart;
67      var nodes = Content.Nodes.ToList();
68      var root = nodes[0];
69      var fragmentRoot = tileDictionary[root];
70      int maxTileWidth = 0, maxTileHeight = 0;
71      var tiles = nodes.Select(x => tileDictionary[x].Tile).ToList();
72
73      foreach (var tile in tiles) {
74        var size = tile.Size;
75        if (maxTileWidth < size.Width) maxTileWidth = size.Width;
76        if (maxTileHeight < size.Height) maxTileHeight = size.Height;
77      }
78      layoutEngine.NodeWidth = maxTileWidth;
79      layoutEngine.NodeHeight = maxTileHeight;
80      layoutEngine.HorizontalSpacing = PreferredHorizontalSpacing;
81      layoutEngine.VerticalSpacing = PreferredVerticalSpacing;
82
83      var visualNodes = layoutEngine.CalculateLayout(fragmentRoot);
84
85      symbolicExpressionChartControl.UpdateEnabled = false;
86      foreach (var visualNode in visualNodes) {
87        var tile = visualNode.Content.Tile;
88        tile.Position = new Point(visualNode.X, visualNode.Y);
89        symbolicExpressionChartControl.Add(tile);
90      }
91
92      // add connections between the tiles
93      foreach (var node in nodes) {
94        var aTile = tileDictionary[node].Tile;
95        var aSize = aTile.Size;
96        var aPos = aTile.Position;
97
98        if (node.Content.Index1 > 0) {
99          var subtree = node.Content.Root.NodeAt(node.Content.Index1);
100          foreach (var s in subtree.IterateNodesPrefix()) {
101            var primitive = aTile.GetPrimitive(s);
102            if (primitive != null) {
103              var rpb = primitive as RectangularPrimitiveBase;
104              if (rpb != null) {
105                rpb.Pen = Pens.RoyalBlue;
106              }
107            }
108          }
109        }
110
111        foreach (var child in node.Children) {
112          var bTile = tileDictionary[child].Tile;
113          var bSize = bTile.Size;
114          var bPos = bTile.Position;
115
116          var line = new Line(chart, new PointD(aPos.X + aSize.Width / 2.0, aPos.Y + aSize.Height), new PointD(bPos.X + bSize.Width / 2.0, bPos.Y));
117          symbolicExpressionChartControl.Add(line);
118
119          if (child == node.Children.First()) {
120            if (node.Content.Index1 > 0) {
121              var subtree = child.Content.Root.NodeAt(node.Content.Index1);
122              foreach (var s in subtree.IterateNodesPrefix()) {
123                var primitive = bTile.GetPrimitive(s);
124                if (primitive != null) {
125                  var rpb = primitive as RectangularPrimitiveBase;
126                  if (rpb != null) {
127                    rpb.Pen = Pens.DarkOrange;
128                  }
129                }
130              }
131            }
132          }
133        }
134      }
135      // center display on the root of the fragment graph
136      symbolicExpressionChartControl.Chart.Move(tileDictionary[root].Tile.Position.X, tileDictionary[root].Tile.Position.Y);
137      symbolicExpressionChartControl.UpdateEnabled = true;
138      symbolicExpressionChartControl.EnforceUpdate();
139    }
140
141    protected override void DeregisterContentEvents() {
142      // TODO: Deregister your event handlers here
143      base.DeregisterContentEvents();
144    }
145
146    protected override void RegisterContentEvents() {
147      base.RegisterContentEvents();
148      // TODO: Register your event handlers here
149    }
150
151    #region Event Handlers (Content)
152    // TODO: Put event handlers of the content here
153    protected override void OnContentChanged() {
154      base.OnContentChanged();
155      if (Content != null) {
156        MakeTiles();
157        Draw();
158      }
159    }
160    #endregion
161
162    protected override void SetEnabledStateOfControls() {
163      base.SetEnabledStateOfControls();
164      // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
165    }
166
167    #region Event Handlers (child controls)
168
169    // TODO: Put event handlers of child controls here.
170
171    #endregion
172  }
173
174  internal static class Util {
175    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTree tree, int position) {
176      return NodeAt(tree.Root, position);
177    }
178    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTreeNode root, int position) {
179      return root.IterateNodesPrefix().ElementAt(position);
180    }
181  }
182
183  internal class TileLayoutNode {
184    public SymbolicExpressionTreeTile Tile { get; set; }
185
186    private List<TileLayoutNode> children;
187    public IEnumerable<TileLayoutNode> Children {
188      get { return children ?? Enumerable.Empty<TileLayoutNode>(); }
189      set { children = value.ToList(); }
190    }
191  }
192}
Note: See TracBrowser for help on using the repository browser.