source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs @ 9963

Last change on this file since 9963 was 9963, checked in by bburlacu, 8 years ago

#1772: Merged changes from the trunk and other branches. Added new ExtendedSymbolicExpressionTreeCanvas control for the visual exploration of tree genealogies. Reorganized some files and folders.

File size: 11.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Core.Views;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
30using HeuristicLab.MainForm;
31using HeuristicLab.Problems.DataAnalysis.Symbolic;
32
33namespace HeuristicLab.EvolutionaryTracking.Views {
34  [View("SymbolicExpressionTreeGenealogyGraph")]
35  [Content(typeof(SymbolicExpressionTreeGenealogyGraph), IsDefaultView = true)]
36  public sealed partial class GenealogyGraphView : ItemView {
37    private VisualSymbolicExpressionTreeNode selectedVisualSymbExprTreeNode;
38    private SymbolicExpressionTreeNodeSimilarityComparer comparer;
39    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> clonedNodes;
40
41    public new SymbolicExpressionTreeGenealogyGraph Content {
42      get { return (SymbolicExpressionTreeGenealogyGraph)base.Content; }
43      set { base.Content = value; }
44    }
45
46    public GenealogyGraphView()
47      : base() {
48      InitializeComponent();
49      // set button icons here because if set in the designer file, they get overwritten
50      this.highlightAllButton.Image = Common.Resources.VSImageLibrary.Gradient;
51      this.simpleLineagesCheckBox.Image = Common.Resources.VSImageLibrary.ArrowDown;
52      this.lockGenealogyCheckBox.Image = Common.Resources.VSImageLibrary.ProtectForm;
53
54      comparer = new SymbolicExpressionTreeNodeSimilarityComparer {
55        MatchConstantValues = true,
56        MatchVariableWeights = true,
57        MatchVariableNames = true
58      };
59    }
60
61    protected override void DeregisterContentEvents() {
62      // TODO: Deregister your event handlers here
63      genealogyGraphChart.GenealogyGraphNodeClicked -= graphChart_GenealogyGraphNodeClicked;
64      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
65      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeDoubleClicked -= treeChart_SymbolicExpressionTreeNodeDoubleClicked;
66      Content.GraphUpdated -= genealogyGraphUpdated;
67      base.DeregisterContentEvents();
68    }
69
70    protected override void RegisterContentEvents() {
71      base.RegisterContentEvents();
72      // TODO: Register your event handlers here
73      genealogyGraphChart.GenealogyGraphNodeClicked += graphChart_GenealogyGraphNodeClicked;
74      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
75      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeDoubleClicked += treeChart_SymbolicExpressionTreeNodeDoubleClicked;
76      Content.GraphUpdated += genealogyGraphUpdated;
77    }
78
79    #region Event Handlers (Content)
80    // TODO: Put event handlers of the content here
81    protected override void OnContentChanged() {
82      base.OnContentChanged();
83      if (Content == null)
84        genealogyGraphChart.Graph = null;
85      else {
86        genealogyGraphChart.Graph = Content;
87        //        var best = Content.Nodes.OrderByDescending(x => x.Quality).First();
88        //        symbolicExpressionTreeChart.Tree = best.SymbolicExpressionTree;
89      }
90    }
91
92    private void Content_GraphChanged(object sender, EventArgs e) {
93    }
94
95    protected override void SetEnabledStateOfControls() {
96      base.SetEnabledStateOfControls();
97      genealogyGraphChart.Enabled = Content != null;
98    }
99    #endregion
100
101    #region Event Handlers (child controls)
102
103    // TODO: Put event handlers of child controls here.
104    private void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs e) {
105      // the type hierarchy goes like this: VisualGenealogyGraphNode --> GenealogyGraphNode --> SymbolicExpressionTree
106      var visualGenealogyGraphNode = (VisualGenealogyGraphNode)sender;
107      var genealogyGraphNode = visualGenealogyGraphNode.Data;
108      symbolicExpressionTreeChart.Tree = genealogyGraphNode.SymbolicExpressionTree;
109
110      if (genealogyGraphNode.InEdges == null) return;
111      var arc = genealogyGraphNode.InEdges.Last(x => x.Source != x.Target);
112      if (arc == null || arc.Data == null) return;
113      var fragment = (IFragment)arc.Data;
114      if (fragment.Root == null) return;
115      foreach (var node in fragment.Root.IterateNodesBreadth()) {
116        var visualSymbExprTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
117        visualSymbExprTreeNode.LineColor = Color.OrangeRed;
118      }
119      symbolicExpressionTreeChart.Repaint();
120    }
121
122    private void genealogyGraphUpdated(object sender, EventArgs args) {
123      genealogyGraphChart.Graph = Content;
124    }
125
126    private void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
127      genealogyGraphChart.Chart.UpdateEnabled = false;
128      switch (e.Button) {
129        case MouseButtons.Left: {
130            selectedVisualSymbExprTreeNode = (VisualSymbolicExpressionTreeNode)sender;
131            if (selectedVisualSymbExprTreeNode == null) return;
132            ISymbolicExpressionTreeNode selectedSubtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
133            var clonedSubtree = (ISymbolicExpressionTreeNode)selectedSubtree.Clone();
134            // map original nodes to cloned nodes
135            clonedNodes = selectedSubtree.IterateNodesPrefix()
136                                         .Zip(clonedSubtree.IterateNodesPrefix(), (original, clone) => new { original, clone })
137                                         .ToDictionary(p => p.original, p => p.clone);
138
139            foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
140              symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent;
141            }
142            foreach (var node in selectedSubtree.IterateNodesPrefix()) {
143              symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.LightBlue;
144            }
145            break;
146          }
147        case MouseButtons.Middle: {
148            var visualNode = (VisualSymbolicExpressionTreeNode)sender;
149            if (selectedVisualSymbExprTreeNode == null || selectedVisualSymbExprTreeNode == visualNode) return;
150            var selectedNode = visualNode.SymbolicExpressionTreeNode;
151            if (clonedNodes.ContainsKey(selectedNode)) {
152              var selectedClone = clonedNodes[selectedNode];
153              var parent = selectedClone.Parent;
154              if (parent == null) break;
155              int index = parent.IndexOfSubtree(selectedClone);
156              if (index == -1) break;
157              parent.RemoveSubtree(parent.IndexOfSubtree(selectedClone));
158              foreach (var node in selectedNode.IterateNodesPrefix()) {
159                symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent;
160              }
161            }
162            break;
163          }
164      }
165      if (selectedVisualSymbExprTreeNode == null || clonedNodes == null) return;
166      // update visual graph nodes that contain matching trees
167      MatchNodesAndRepaint();
168      // refresh the tree chart
169      symbolicExpressionTreeChart.Repaint();
170    }
171
172    void MatchNodesAndRepaint() {
173      genealogyGraphChart.Chart.UpdateEnabled = false;
174      genealogyGraphChart.ClearAllNodes(); // clear node colors
175      var fragment = new Fragment { Root = clonedNodes[selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode] };
176      var fragmentLength = fragment.Length;
177      // highlight nodes
178      genealogyGraphChart.HighlightNodes(from node in genealogyGraphChart.Graph.Nodes
179                                         let tree = node.SymbolicExpressionTree
180                                         where tree.Length >= fragmentLength
181                                         where tree.Root.ContainsFragment(fragment, comparer)
182                                         select tree);
183      // highlight edges that contain a matching fragment
184      var fragmentSimilarityComparer = new SymbolicExpressionTreeFragmentSimilarityComparer {
185        SimilarityComparer = comparer
186      };
187      var matchingEdges = genealogyGraphChart.Graph.Nodes.Where(n => n.InEdges != null)
188                           .SelectMany(n => n.InEdges).Where(edge => edge.Data != null && ((IFragment)edge.Data).Root != null)
189                           .Where(edge => fragmentSimilarityComparer.Equals(fragment, (IFragment)edge.Data));
190      genealogyGraphChart.HighlightArcs(matchingEdges, Color.DodgerBlue);
191
192
193      genealogyGraphChart.Chart.UpdateEnabled = true;
194      genealogyGraphChart.Chart.EnforceUpdate();
195    }
196
197    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
198    }
199    #endregion
200
201    private void matchConstantsCheckBox_CheckedChanged(object sender, EventArgs e) {
202      comparer.MatchConstantValues = matchConstantsCheckBox.Checked;
203      if (selectedVisualSymbExprTreeNode != null)
204        MatchNodesAndRepaint();
205    }
206
207    private void matchVariableWeightsCheckBox_CheckedChanged(object sender, EventArgs e) {
208      comparer.MatchVariableWeights = matchVariableWeightsCheckBox.Checked;
209      if (selectedVisualSymbExprTreeNode != null)
210        MatchNodesAndRepaint();
211    }
212
213    private void matchVariableNamesCheckBox_CheckedChanged(object sender, EventArgs e) {
214      comparer.MatchVariableNames = matchVariableNamesCheckBox.Checked;
215      if (selectedVisualSymbExprTreeNode != null)
216        MatchNodesAndRepaint();
217    }
218
219    private void simpleLineagesCheckBox_CheckedChanged(object sender, EventArgs e) {
220      genealogyGraphChart.SimpleLineages = simpleLineagesCheckBox.Checked;
221    }
222
223    private void highlightAllButton_Click(object sender, EventArgs e) {
224      symbolicExpressionTreeChart.Repaint();
225      genealogyGraphChart.HighlightAll();
226    }
227
228    private void lockGenealogyCheckBox_CheckedChanged(object sender, EventArgs e) {
229      genealogyGraphChart.LockGenealogy = lockGenealogyCheckBox.Checked;
230    }
231
232    private void highlightRootParentsButton_Click(object sender, EventArgs e) {
233      var nodes = genealogyGraphChart.Graph.Nodes.Where(n => n.InEdges != null && n.InEdges.Count == 2).Select(n => (SymbolicExpressionTreeGenealogyGraphNode)n.InEdges[0].Source).ToList();
234      genealogyGraphChart.HighlightNodes(nodes);
235    }
236
237    private void highlightSecondaryParentsButton_Click(object sender, EventArgs e) {
238      var nodes = genealogyGraphChart.Graph.Nodes.Where(n => n.InEdges != null && n.InEdges.Count == 2).Select(n => (SymbolicExpressionTreeGenealogyGraphNode)n.InEdges[1].Source).ToList();
239      genealogyGraphChart.HighlightNodes(nodes);
240    }
241  }
242}
Note: See TracBrowser for help on using the repository browser.