Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 10755 was 10755, checked in by bburlacu, 11 years ago

#1772: Simplified genealogy graph and fragment graph creation:

  • the genealogy graph now has a 1-1 mapping between content and vertices (as opposed to 1-n as it was previously, to account for elites); this required changes to the directed graph implementation
  • the fragment graph only contains bifurcation points (where the subtree contains the fragment so tracing must be done both ways (in the root parent AND in the other parent). in the other cases, tracing is restarted from the parent genealogy graph node.
File size: 7.5 KB
Line 
1using System.Collections.Generic;
2using System.Drawing;
3using System.Linq;
4using HeuristicLab.Common;
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.Root = node.Content.Root;
54        var tileNode = new TileLayoutNode { Tile = tile };
55        tileDictionary.Add(node, tileNode);
56      }
57      foreach (var node in Content.Nodes.Where(n => n.Children.Any())) {
58        var layoutNode = tileDictionary[node];
59        layoutNode.Children = new List<TileLayoutNode>(node.Children.Select(x => tileDictionary[x]));
60      }
61    }
62
63    private void Draw() {
64      var chart = symbolicExpressionChartControl.Chart;
65      var nodes = Content.Nodes.ToList();
66      var root = nodes[0];
67      var fragmentRoot = tileDictionary[root];
68      int maxTileWidth = 0, maxTileHeight = 0;
69      var tiles = nodes.Select(x => tileDictionary[x].Tile).ToList();
70
71      foreach (var tile in tiles) {
72        var size = tile.Size;
73        if (maxTileWidth < size.Width) maxTileWidth = size.Width;
74        if (maxTileHeight < size.Height) maxTileHeight = size.Height;
75      }
76      layoutEngine.NodeWidth = maxTileWidth;
77      layoutEngine.NodeHeight = maxTileHeight;
78      layoutEngine.HorizontalSpacing = PreferredHorizontalSpacing;
79      layoutEngine.VerticalSpacing = PreferredVerticalSpacing;
80
81      var visualNodes = layoutEngine.CalculateLayout(fragmentRoot);
82
83      symbolicExpressionChartControl.UpdateEnabled = false;
84      foreach (var visualNode in visualNodes) {
85        var tile = visualNode.Content.Tile;
86        tile.Position = new Point(visualNode.X, visualNode.Y);
87        symbolicExpressionChartControl.Add(tile);
88      }
89
90      // add connections between the tiles
91      foreach (var node in nodes) {
92        var aTile = tileDictionary[node].Tile;
93        var aSize = aTile.Size;
94        var aPos = aTile.Position;
95
96        if (node.Rank.IsAlmost(0)) {
97          foreach (var s in node.Content.Root.IterateNodesPrefix()) {
98            var primitive = aTile.GetPrimitive(s);
99            if (primitive != null) {
100              var rpb = primitive as RectangularPrimitiveBase;
101              if (rpb != null) {
102                rpb.Pen = new Pen(Color.ForestGreen);
103              }
104            }
105          }
106        } else {
107
108          if (node.Content.Index1 > 0) {
109            var subtree = node.Content.Root.NodeAt(node.Content.Index1);
110            foreach (var s in subtree.IterateNodesPrefix()) {
111              var primitive = aTile.GetPrimitive(s);
112              if (primitive != null) {
113                var rpb = primitive as RectangularPrimitiveBase;
114                if (rpb != null) {
115                  rpb.Pen = new Pen(Color.RoyalBlue);
116                }
117              }
118            }
119          }
120        }
121
122        foreach (var child in node.Children) {
123          var bTile = tileDictionary[child].Tile;
124          var bSize = bTile.Size;
125          var bPos = bTile.Position;
126
127          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));
128          symbolicExpressionChartControl.Add(line);
129
130          if (child == node.Children.First()) {
131            if (node.Content.Index1 > 0) {
132              var subtree = child.Content.Root.NodeAt(node.Content.Index1);
133              foreach (var s in subtree.IterateNodesPrefix()) {
134                var primitive = bTile.GetPrimitive(s);
135                if (primitive != null) {
136                  var rpb = primitive as RectangularPrimitiveBase;
137                  if (rpb != null) {
138                    rpb.Pen = new Pen(Color.DarkOrange);
139                  }
140                }
141              }
142            }
143          }
144        }
145      }
146      symbolicExpressionChartControl.UpdateEnabled = true;
147      symbolicExpressionChartControl.EnforceUpdate();
148    }
149
150    protected override void DeregisterContentEvents() {
151      // TODO: Deregister your event handlers here
152      base.DeregisterContentEvents();
153    }
154
155    protected override void RegisterContentEvents() {
156      base.RegisterContentEvents();
157      // TODO: Register your event handlers here
158    }
159
160    #region Event Handlers (Content)
161    // TODO: Put event handlers of the content here
162    protected override void OnContentChanged() {
163      base.OnContentChanged();
164      if (Content != null) {
165        MakeTiles();
166        Draw();
167      }
168    }
169    #endregion
170
171    protected override void SetEnabledStateOfControls() {
172      base.SetEnabledStateOfControls();
173      // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
174    }
175
176    #region Event Handlers (child controls)
177
178    // TODO: Put event handlers of child controls here.
179
180    #endregion
181  }
182
183  internal static class Util {
184    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTree tree, int position) {
185      return NodeAt(tree.Root, position);
186    }
187    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTreeNode root, int position) {
188      return root.IterateNodesPrefix().ElementAt(position);
189    }
190  }
191
192  internal class TileLayoutNode {
193    public SymbolicExpressionTreeTile Tile { get; set; }
194
195    private List<TileLayoutNode> children;
196    public IEnumerable<TileLayoutNode> Children {
197      get { return children ?? Enumerable.Empty<TileLayoutNode>(); }
198      set { children = value.ToList(); }
199    }
200  }
201}
Note: See TracBrowser for help on using the repository browser.