Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1772: Merged trunk changes. Updated PhenotypicSimilarityCalculator, updated FragmentGraphView.

File size: 8.7 KB
RevLine 
[10884]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
[10833]23using System.Collections.Generic;
[10685]24using System.Drawing;
[10655]25using System.Linq;
[11638]26using System.Windows.Forms;
[10655]27using HeuristicLab.Core.Views;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
30using HeuristicLab.MainForm;
[10730]31using HeuristicLab.Visualization;
[10655]32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
34  [View("FragmentGraphView")]
[10888]35  [Content(typeof(FragmentGraph), IsDefaultView = true)]
[10655]36  public sealed partial class FragmentGraphView : ItemView {
[10746]37    private const int PreferredHorizontalSpacing = 10;
38    private const int PreferredVerticalSpacing = 25;
[10685]39
[11318]40    private readonly ReingoldTilfordLayoutEngine<TileLayoutNode> layoutEngine;
41    private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> symbolicExpressionEngine;
[10655]42
[11318]43    private readonly Dictionary<FragmentNode, TileLayoutNode> nodeToTileMap;
[10655]44
45    private SymbolicExpressionTreeTile Root { get; set; }
46
[10888]47    public new FragmentGraph Content {
48      get { return (FragmentGraph)base.Content; }
[10677]49      set { base.Content = value; }
[10655]50    }
51
52    public FragmentGraphView() {
53      InitializeComponent();
54
[10729]55      layoutEngine = new ReingoldTilfordLayoutEngine<TileLayoutNode>(n => n.Children) {
[10746]56        HorizontalSpacing = PreferredHorizontalSpacing,
57        VerticalSpacing = PreferredVerticalSpacing,
[10729]58      };
59      symbolicExpressionEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) {
[10746]60        HorizontalSpacing = PreferredHorizontalSpacing,
61        VerticalSpacing = PreferredVerticalSpacing,
[10729]62        NodeWidth = 80,
63        NodeHeight = 40
64      };
[11318]65      nodeToTileMap = new Dictionary<FragmentNode, TileLayoutNode>();
[10655]66    }
67
68    private void MakeTiles() {
69      var chart = symbolicExpressionChartControl.Chart;
[11318]70      nodeToTileMap.Clear();
[11015]71      foreach (var node in Content.Vertices) {
[10656]72        var tile = new SymbolicExpressionTreeTile(chart);
73        tile.LayoutEngine = symbolicExpressionEngine;
[11638]74        tile.Label = "Generation " + node.Rank + Environment.NewLine +
75                     "Quality " + String.Format("{0:0.000}", node.Quality);
76        tile.Root = node.Data.Root;
[10685]77        var tileNode = new TileLayoutNode { Tile = tile };
[11318]78        nodeToTileMap.Add(node, tileNode);
[10655]79      }
[11015]80      foreach (var node in Content.Vertices.Where(n => n.OutArcs.Any())) {
[11318]81        var layoutNode = nodeToTileMap[node];
82        layoutNode.Children = new List<TileLayoutNode>(node.OutArcs.Select(a => nodeToTileMap[(FragmentNode)a.Target]));
[10655]83      }
84    }
85
86    private void Draw() {
[10730]87      var chart = symbolicExpressionChartControl.Chart;
[11015]88      var nodes = Content.Vertices.ToList();
[10730]89      var root = nodes[0];
[11318]90      var fragmentRoot = nodeToTileMap[root];
[10728]91      int maxTileWidth = 0, maxTileHeight = 0;
[11318]92      var tiles = nodes.Select(x => nodeToTileMap[x].Tile).ToList();
[10730]93
94      foreach (var tile in tiles) {
[10728]95        var size = tile.Size;
96        if (maxTileWidth < size.Width) maxTileWidth = size.Width;
97        if (maxTileHeight < size.Height) maxTileHeight = size.Height;
98      }
99      layoutEngine.NodeWidth = maxTileWidth;
100      layoutEngine.NodeHeight = maxTileHeight;
[10746]101      layoutEngine.HorizontalSpacing = PreferredHorizontalSpacing;
102      layoutEngine.VerticalSpacing = PreferredVerticalSpacing;
[10728]103
[10677]104      var visualNodes = layoutEngine.CalculateLayout(fragmentRoot);
105
[10656]106      symbolicExpressionChartControl.UpdateEnabled = false;
107      foreach (var visualNode in visualNodes) {
108        var tile = visualNode.Content.Tile;
[10685]109        tile.Position = new Point(visualNode.X, visualNode.Y);
[10656]110        symbolicExpressionChartControl.Add(tile);
111      }
[10730]112
113      // add connections between the tiles
114      foreach (var node in nodes) {
[11318]115        var aTile = nodeToTileMap[node].Tile;
[10730]116        var aSize = aTile.Size;
117        var aPos = aTile.Position;
[11638]118        var tree = node.Data;
[10730]119
[10888]120        if (node.SubtreeIndex > 0) {
[11638]121          var subtree = tree.Root.NodeAt(node.SubtreeIndex);
[10797]122          foreach (var s in subtree.IterateNodesPrefix()) {
[10746]123            var primitive = aTile.GetPrimitive(s);
124            if (primitive != null) {
125              var rpb = primitive as RectangularPrimitiveBase;
126              if (rpb != null) {
[10838]127                rpb.Pen = new Pen(Color.Black);
[10746]128              }
129            }
130          }
131        }
[10888]132        if (node.FragmentIndex > 0) {
[11638]133          var subtree = tree.Root.NodeAt(node.FragmentIndex);
[10838]134          foreach (var s in subtree.IterateNodesPrefix()) {
135            var primitive = aTile.GetPrimitive(s);
136            if (primitive != null) {
137              var rpb = primitive as RectangularPrimitiveBase;
138              if (rpb != null) {
139                rpb.Brush = new SolidBrush(Color.LightGray);
140              }
141            }
142          }
143        }
[10730]144
[10888]145        if (node.InArcs.Any()) {
146          var parent = (FragmentNode)node.InArcs.First().Source;
147          if (parent.OutArcs.First().Target == node) {
148            var index = node.SubtreeIndex + (parent.FragmentIndex - parent.SubtreeIndex);
149            // some mutations create discontinuities which invalidate the index
[11638]150            if (index >= 0 && index < tree.Length) {
151              var subtree = tree.NodeAt(index);
[10888]152              var primitive = aTile.GetPrimitive(subtree);
153              primitive.Brush = new SolidBrush(Color.LightCoral);
154            }
[10840]155          }
[10838]156        }
157
[10888]158        foreach (var child in node.OutArcs.Select(x => (FragmentNode)x.Target)) {
[11318]159          var bTile = nodeToTileMap[child].Tile;
[10730]160          var bSize = bTile.Size;
161          var bPos = bTile.Position;
162
[10838]163          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)) {
164            Pen = Pens.DimGray
165          };
[10730]166          symbolicExpressionChartControl.Add(line);
167        }
168      }
[10833]169      // center display on the root of the fragment graph
[11318]170      symbolicExpressionChartControl.Chart.Move(nodeToTileMap[root].Tile.Position.X, nodeToTileMap[root].Tile.Position.Y);
[10656]171      symbolicExpressionChartControl.UpdateEnabled = true;
172      symbolicExpressionChartControl.EnforceUpdate();
[10655]173    }
174
175    protected override void DeregisterContentEvents() {
176      // TODO: Deregister your event handlers here
177      base.DeregisterContentEvents();
178    }
179
180    protected override void RegisterContentEvents() {
181      base.RegisterContentEvents();
182      // TODO: Register your event handlers here
183    }
184
185    #region Event Handlers (Content)
186    // TODO: Put event handlers of the content here
187    protected override void OnContentChanged() {
188      base.OnContentChanged();
[10677]189      if (Content != null) {
190        MakeTiles();
191        Draw();
[10655]192      }
193    }
[10677]194    #endregion
[10655]195
196    protected override void SetEnabledStateOfControls() {
197      base.SetEnabledStateOfControls();
198      // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
199    }
200
[11638]201    private void FragmentGraphView_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) {
202      if (e.KeyChar == 'i') {
203        // highlight node impacts
204      }
205    }
206
[10655]207    #region Event Handlers (child controls)
208
209    // TODO: Put event handlers of child controls here.
210
211    #endregion
212  }
213
[10752]214  internal static class Util {
215    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTree tree, int position) {
216      return NodeAt(tree.Root, position);
217    }
218    internal static ISymbolicExpressionTreeNode NodeAt(this ISymbolicExpressionTreeNode root, int position) {
219      return root.IterateNodesPrefix().ElementAt(position);
220    }
221  }
222
[10655]223  internal class TileLayoutNode {
224    public SymbolicExpressionTreeTile Tile { get; set; }
[10685]225
226    private List<TileLayoutNode> children;
227    public IEnumerable<TileLayoutNode> Children {
228      get { return children ?? Enumerable.Empty<TileLayoutNode>(); }
229      set { children = value.ToList(); }
230    }
[10655]231  }
232}
Note: See TracBrowser for help on using the repository browser.