Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1772: Improved FragmentGraphView.

File size: 5.9 KB
Line 
1using System.Collections.Generic;
2using System.Drawing;
3using System.Linq;
4using HeuristicLab.Core.Views;
5using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
6using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
7using HeuristicLab.EvolutionTracking;
8using HeuristicLab.MainForm;
9using HeuristicLab.Visualization;
10
11namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
12  [View("FragmentGraphView")]
13  [Content(typeof(IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>>), IsDefaultView = true)]
14  public sealed partial class FragmentGraphView : ItemView {
15    private int PreferredSpacing = 50;
16
17    private ReingoldTilfordLayoutEngine<TileLayoutNode> layoutEngine;
18    private ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> symbolicExpressionEngine;
19
20    private Dictionary<IGenealogyGraphNode<IFragment<ISymbolicExpressionTreeNode>>, TileLayoutNode> tileDictionary;
21
22    private SymbolicExpressionTreeTile Root { get; set; }
23
24    public new IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>> Content {
25      get { return (IGenealogyGraph<IFragment<ISymbolicExpressionTreeNode>>)base.Content; }
26      set { base.Content = value; }
27    }
28
29    public FragmentGraphView() {
30      InitializeComponent();
31
32      layoutEngine = new ReingoldTilfordLayoutEngine<TileLayoutNode>(n => n.Children) {
33        HorizontalSpacing = 50,
34        VerticalSpacing = 50,
35      };
36      symbolicExpressionEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) {
37        HorizontalSpacing = 50,
38        VerticalSpacing = 50,
39        NodeWidth = 80,
40        NodeHeight = 40
41      };
42      tileDictionary = new Dictionary<IGenealogyGraphNode<IFragment<ISymbolicExpressionTreeNode>>, TileLayoutNode>();
43    }
44
45    private void MakeTiles() {
46      var chart = symbolicExpressionChartControl.Chart;
47      tileDictionary.Clear();
48      foreach (var node in Content.Nodes) {
49        var tile = new SymbolicExpressionTreeTile(chart);
50        tile.LayoutEngine = symbolicExpressionEngine;
51        tile.Root = node.Content.Root;
52        var tileNode = new TileLayoutNode { Tile = tile };
53        tileDictionary.Add(node, tileNode);
54      }
55      foreach (var node in Content.Nodes.Where(n => n.Children.Any())) {
56        var layoutNode = tileDictionary[node];
57        layoutNode.Children = new List<TileLayoutNode>(node.Children.Select(x => tileDictionary[x]));
58      }
59    }
60
61    private void Draw() {
62      var chart = symbolicExpressionChartControl.Chart;
63      var nodes = Content.Nodes.ToList();
64      var root = nodes[0];
65      var fragmentRoot = tileDictionary[root];
66      int maxTileWidth = 0, maxTileHeight = 0;
67      var tiles = nodes.Select(x => tileDictionary[x].Tile).ToList();
68
69      foreach (var tile in tiles) {
70        var size = tile.Size;
71        if (maxTileWidth < size.Width) maxTileWidth = size.Width;
72        if (maxTileHeight < size.Height) maxTileHeight = size.Height;
73      }
74      layoutEngine.NodeWidth = maxTileWidth;
75      layoutEngine.NodeHeight = maxTileHeight;
76      layoutEngine.HorizontalSpacing = PreferredSpacing;
77      layoutEngine.VerticalSpacing = PreferredSpacing;
78
79      var visualNodes = layoutEngine.CalculateLayout(fragmentRoot);
80
81      symbolicExpressionChartControl.UpdateEnabled = false;
82      foreach (var visualNode in visualNodes) {
83        var tile = visualNode.Content.Tile;
84        tile.Position = new Point(visualNode.X, visualNode.Y);
85        symbolicExpressionChartControl.Add(tile);
86      }
87
88      // add connections between the tiles
89      foreach (var node in nodes) {
90        var aTile = tileDictionary[node].Tile;
91        var aSize = aTile.Size;
92        var aPos = aTile.Position;
93
94        var lowerLeftMarker = new FixedSizeCircle(chart, aTile.Position, 5, new Pen(Color.Red), new SolidBrush(Color.Transparent));
95        var upperRightMarker = new FixedSizeCircle(chart, new PointD(aPos.X + aSize.Width, aPos.Y + aSize.Height), 5,
96          new Pen(Color.Blue), new SolidBrush(Color.Transparent));
97        symbolicExpressionChartControl.Add(lowerLeftMarker); symbolicExpressionChartControl.Add(upperRightMarker);
98
99        foreach (var child in node.Children) {
100          var bTile = tileDictionary[child].Tile;
101          var bSize = bTile.Size;
102          var bPos = bTile.Position;
103
104          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));
105          symbolicExpressionChartControl.Add(line);
106        }
107      }
108      //      symbolicExpressionChartControl.FlipVertical();
109      symbolicExpressionChartControl.UpdateEnabled = true;
110      symbolicExpressionChartControl.EnforceUpdate();
111    }
112
113    protected override void DeregisterContentEvents() {
114      // TODO: Deregister your event handlers here
115      base.DeregisterContentEvents();
116    }
117
118    protected override void RegisterContentEvents() {
119      base.RegisterContentEvents();
120      // TODO: Register your event handlers here
121    }
122
123    #region Event Handlers (Content)
124    // TODO: Put event handlers of the content here
125    protected override void OnContentChanged() {
126      base.OnContentChanged();
127      if (Content != null) {
128        MakeTiles();
129        Draw();
130      }
131    }
132    #endregion
133
134    protected override void SetEnabledStateOfControls() {
135      base.SetEnabledStateOfControls();
136      // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
137    }
138
139    #region Event Handlers (child controls)
140
141    // TODO: Put event handlers of child controls here.
142
143    #endregion
144  }
145
146  internal class TileLayoutNode {
147    public SymbolicExpressionTreeTile Tile { get; set; }
148
149    private List<TileLayoutNode> children;
150    public IEnumerable<TileLayoutNode> Children {
151      get { return children ?? Enumerable.Empty<TileLayoutNode>(); }
152      set { children = value.ToList(); }
153    }
154  }
155}
Note: See TracBrowser for help on using the repository browser.