Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 9070 was 8556, checked in by bburlacu, 12 years ago

#1772: Modified genealogy graph chart and view to reflect changes in the class hierarchy.

File size: 12.8 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;
32using HeuristicLab.Visualization;
33
34namespace HeuristicLab.EvolutionaryTracking.Views {
35  [View("SymbolicExpressionTreeGenealogyGraph")]
36  [Content(typeof(SymbolicExpressionTreeGenealogyGraph), IsDefaultView = true)]
37  public sealed partial class GenealogyGraphView : ItemView {
38    private VisualSymbolicExpressionTreeNode selectedVisualSymbExprTreeNode;
39    public new SymbolicExpressionTreeGenealogyGraph Content {
40      get { return (SymbolicExpressionTreeGenealogyGraph)base.Content; }
41      set { base.Content = value; }
42    }
43
44    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> clonedNodeMap;
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.moveModeButton.Image = Common.Resources.VSImageLibrary.Pointer;
51      this.zoomModeButton.Image = Common.Resources.VSImageLibrary.Zoom;
52      this.selectModeButton.Image = Common.Resources.VSImageLibrary.Object;
53
54
55      similarityModeSelector.SelectedIndex = 0; // set default similarity mode to "exact"
56    }
57
58    protected override void DeregisterContentEvents() {
59      // TODO: Deregister your event handlers here
60      genealogyGraphChart.GenealogyGraphNodeClicked -= graphChart_GenealogyGraphNodeClicked;
61      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
62      base.DeregisterContentEvents();
63    }
64
65    protected override void RegisterContentEvents() {
66      base.RegisterContentEvents();
67      // TODO: Register your event handlers here
68      genealogyGraphChart.GenealogyGraphNodeClicked += graphChart_GenealogyGraphNodeClicked;
69      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
70      symbolicExpressionTreeChart.SymbolicExpressionTreeNodeDoubleClicked += treeChart_SymbolicExpressionTreeNodeDoubleClicked;
71    }
72
73    #region Event Handlers (Content)
74    // TODO: Put event handlers of the content here
75    protected override void OnContentChanged() {
76      base.OnContentChanged();
77      if (Content == null)
78        genealogyGraphChart.Graph = null;
79      else {
80        genealogyGraphChart.Graph = Content;
81        var best = Content.Nodes.OrderByDescending(x => x.Quality).First();
82        symbolicExpressionTreeChart.Tree = best.SymbolicExpressionTree;
83      }
84    }
85
86    private void Content_GraphChanged(object sender, EventArgs e) {
87    }
88
89    protected override void SetEnabledStateOfControls() {
90      base.SetEnabledStateOfControls();
91      genealogyGraphChart.Enabled = Content != null;
92    }
93    #endregion
94
95    #region Event Handlers (child controls)
96
97    // TODO: Put event handlers of child controls here.
98    private void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs e) {
99      // the type hierarchy goes like this: VisualGenealogyGraphNode --> GenealogyGraphNode --> symbolicExpressionTree
100      var visualGenealogyGraphNode = (VisualGenealogyGraphNode)sender;
101      var genealogyGraphNode = (SymbolicExpressionGenealogyGraphNode)visualGenealogyGraphNode.Data;
102      symbolicExpressionTreeChart.Tree = genealogyGraphNode.SymbolicExpressionTree;
103      // highlight the relevant fragment in the symbolic expression tree
104      selectedVisualSymbExprTreeNode = null;
105
106      bool repaint = false;
107
108      // paint highlighted nodes in symbolic expression tree
109      if (selectedVisualSymbExprTreeNode != null) {
110        // clear selected subtree from the tree chart
111        var nodes = symbolicExpressionTreeChart.Tree.IterateNodesBreadth() as List<ISymbolicExpressionTreeNode>;
112        var fragments = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode.IterateNodesBreadth() as List<ISymbolicExpressionTreeNode>;
113        var similarityLevel = Enum.GetNames(typeof(SimilarityLevel))[similarityModeSelector.SelectedIndex];
114        int index = SymbolicExpressionTreeMatching.FindMatch(nodes, fragments, (SimilarityLevel)Enum.Parse(typeof(SimilarityLevel), similarityLevel));
115        if (index != -1) {
116          selectedVisualSymbExprTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(nodes[index]);
117          var subtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
118          foreach (var node in subtree.IterateNodesBreadth()) {
119            var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
120            visualNode.LineColor = Color.Blue;
121          }
122          repaint = true;
123        }
124      }
125      // paint graph nodes
126      var tree = symbolicExpressionTreeChart.Tree;
127      var graphNodes = Content.Nodes.Where(n => n.SymbolicExpressionTree == tree).ToList();
128      if (graphNodes.Count > 0) {
129        foreach (var graphNode in graphNodes)
130          if (graphNode != null && graphNode.InEdges != null) {
131            var arc = graphNode.InEdges.Find(a => a.Data != null);
132            if (arc != null) {
133              var fragment = arc.Data as ISymbolicExpressionTreeNode;
134              foreach (var node in fragment.IterateNodesBreadth()) {
135                var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
136                if (visualNode == null)
137                  continue;
138                visualNode.LineColor = Color.Orange;
139              }
140            }
141            repaint = true;
142          }
143      }
144      if (repaint)
145        symbolicExpressionTreeChart.Repaint();
146    }
147
148    private void moveModeButton_CheckedChanged(object sender, EventArgs e) {
149      var btn = (RadioButton)sender;
150      if (btn.Checked) { genealogyGraphChart.Chart.Mode = ChartMode.Move; }
151    }
152
153    private void zoomModeButton_CheckedChanged(object sender, EventArgs e) {
154      var btn = (RadioButton)sender;
155      if (btn.Checked) { genealogyGraphChart.Chart.Mode = ChartMode.Zoom; }
156    }
157
158    private void selectModeButton_CheckedChanged(object sender, EventArgs e) {
159      var btn = (RadioButton)sender;
160      if (btn.Checked) { genealogyGraphChart.Chart.Mode = ChartMode.Select; }
161    }
162
163    private void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
164      ISymbolicExpressionTreeNode selectedSubtree = null;
165      genealogyGraphChart.Chart.UpdateEnabled = false;
166      switch (e.Button) {
167        case MouseButtons.Left: {
168            selectedVisualSymbExprTreeNode = (VisualSymbolicExpressionTreeNode)sender;
169            if (selectedVisualSymbExprTreeNode == null) return;
170            // find out which individuals in the genealogy graph contain this specific subtree
171            selectedSubtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
172            // clone every node in the selected subtree so that edit operations are possible without altering the original subtree
173            // save the originalNode-->clone mapping to make it easier to work with subtrees
174            if (clonedNodeMap == null)
175              clonedNodeMap = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
176            clonedNodeMap.Clear();
177            var selectedSubtreeClone = selectedSubtree.Clone() as SymbolicExpressionTreeNode;
178            var subtreeNodes = selectedSubtree.IterateNodesPostfix().ToList();
179            var cloneNodes = selectedSubtreeClone.IterateNodesPostfix().ToList();
180            for (int i = 0; i != subtreeNodes.Count; ++i)
181              clonedNodeMap.Add(subtreeNodes[i], cloneNodes[i]);
182            // highlight subtree nodes in the tree chart
183            foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPostfix()) {
184              var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
185              visualNode.FillColor = Color.Transparent;
186            }
187            selectedSubtree.ForEachNodePostfix(node => {
188              symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.LightBlue;
189            });
190          }
191          break;
192        case MouseButtons.Middle: {
193            var visualNode = (VisualSymbolicExpressionTreeNode)sender;
194            if (selectedVisualSymbExprTreeNode == null || selectedVisualSymbExprTreeNode == visualNode)
195              return;
196            selectedSubtree = clonedNodeMap[selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode];
197            var selectedNode = visualNode.SymbolicExpressionTreeNode;
198            if (clonedNodeMap.ContainsKey(selectedNode)) {
199              var selected = clonedNodeMap[selectedNode];
200              var parent = selected.Parent;
201              parent.RemoveSubtree(parent.IndexOfSubtree(selected));
202              selectedNode.ForEachNodePostfix(node => {
203                symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent;
204                clonedNodeMap.Remove(node);
205              });
206            }
207          }
208          break;
209      }
210      // update visual graph nodes that contain matching trees
211      Color[] colors = { Color.LightSkyBlue, Color.PaleGreen, Color.Tan };
212      genealogyGraphChart.ClearAllNodes(); // clear node colors
213      // color each graph node according to the degree to which it matches the selected tree fragment
214      var similarityValues = Enum.GetValues(typeof(SimilarityLevel)).Cast<SimilarityLevel>().ToList();
215      foreach (var graphNode in genealogyGraphChart.Graph.Nodes) {
216        var tree = graphNode.SymbolicExpressionTree;
217        for (int i = 0; i != similarityValues.Count; ++i) {
218          if (tree.ContainsFragment(selectedSubtree, similarityValues[i])) {
219            genealogyGraphChart.HighlightNode(graphNode, colors[i]);
220            break;
221          }
222        }
223      }
224      genealogyGraphChart.Chart.UpdateEnabled = true;
225      genealogyGraphChart.Chart.EnforceUpdate();
226      // refresh the tree chart
227      symbolicExpressionTreeChart.Repaint();
228    }
229
230    private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
231    }
232
233    private void similarityModeSelector_SelectedIndexChanged(object sender, EventArgs e) {
234      if (selectedVisualSymbExprTreeNode == null) return;
235      var treeNode = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode;
236      var similarityLevel = Enum.GetNames(typeof(SimilarityLevel))[similarityModeSelector.SelectedIndex];
237      var owners = genealogyGraphChart.Graph.TraceFragment(treeNode, (SimilarityLevel)Enum.Parse(typeof(SimilarityLevel), similarityLevel)).ToList();
238      if (owners.Any()) {
239        genealogyGraphChart.Chart.UpdateEnabled = false;
240        genealogyGraphChart.ClearAllNodes(); // clear the fill color of all nodes
241        genealogyGraphChart.HighlightNodes(owners, Color.LightSkyBlue);
242        // highlight matching individuals from the genealogy
243        genealogyGraphChart.Chart.UpdateEnabled = true;
244      }
245      genealogyGraphChart.Chart.EnforceUpdate();
246      // highlight subtree nodes in the tree chart
247      foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPostfix()) {
248        var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
249        visualNode.FillColor = Color.Transparent;
250      }
251      foreach (var node in treeNode.IterateNodesPostfix()) {
252        var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
253        visualNode.FillColor = Color.LightBlue;
254      }
255    }
256    #endregion
257
258    private void inDegreeButton_Click(object sender, EventArgs e) {
259      genealogyGraphChart.HighlightInDegree();
260    }
261
262    private void outDegreeButton_Click(object sender, EventArgs e) {
263      genealogyGraphChart.HighlightOutDegree();
264    }
265  }
266}
Note: See TracBrowser for help on using the repository browser.