Free cookie consent management tool by TermsFeed Policy Generator

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

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

#1772: Improved functionality of the SymbolicDataAnalysisGenealogyGraphView in terms of graph navigation and display of useful information. Fixed save of tree image to file in the SymbolicExpressionTreeChart.

File size: 9.0 KB
Line 
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;
23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Windows.Forms;
27using HeuristicLab.Common;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
30using HeuristicLab.EvolutionTracking;
31using HeuristicLab.EvolutionTracking.Views;
32using HeuristicLab.MainForm;
33
34namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
35  [View("SymbolicDataAnalysisGenealogyGraphView")]
36  [Content(typeof(IGenealogyGraph<ISymbolicExpressionTree>), IsDefaultView = true)]
37  public partial class SymbolicDataAnalysisGenealogyGraphView : SymbolicDataAnalysisGenealogyGraphViewDesignable {
38    private readonly ISymbolicExpressionTreeNodeSimilarityComparer comparer;
39
40    public SymbolicDataAnalysisGenealogyGraphView() {
41      InitializeComponent();
42      comparer = new SymbolicExpressionTreeNodeSimilarityComparer();
43      viewHost.ViewType = typeof(GraphicalSymbolicExpressionTreeView);
44    }
45    #region event handlers
46    protected override void OnContentChanged() {
47      base.OnContentChanged();
48      if (Content != null) { genealogyGraphChart.GenealogyGraph = Content; }
49    }
50    #endregion
51
52    public SymbolicExpressionTreeChart SymbolicExpressionTreeChart {
53      get {
54        var view = (GraphicalSymbolicExpressionTreeView)base.viewHost.ActiveView;
55        return view == null ? null : view.SymbolicExpressionTreeChart;
56      }
57    }
58
59    protected override void RegisterContentEvents() {
60      base.RegisterContentEvents();
61      if (SymbolicExpressionTreeChart != null)
62        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
63    }
64
65    protected override void DeregisterContentEvents() {
66      if (SymbolicExpressionTreeChart != null)
67        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
68      base.DeregisterContentEvents();
69    }
70
71    public override void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs args) {
72      base.graphChart_GenealogyGraphNodeClicked(sender, args);
73      var visualNode = (VisualGenealogyGraphNode)sender;
74      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)visualNode.Data;
75
76      nodeQualityLabel.Text = String.Format("{0:0.000}", graphNode.Quality);
77      nodeRankLabel.Text = String.Format("{0:0.0}", graphNode.Rank);
78      nodeDegreeLabel.Text = String.Format("{0} / {1}", graphNode.InDegree, graphNode.OutDegree);
79
80      if (openNew_CheckBox.Checked) {
81        // get the ancestors into a new view
82        var cloner = new Cloner();
83
84        var graph = new GenealogyGraph<ISymbolicExpressionTree>();
85        var ancestors = new[] { graphNode }.Concat(graphNode.Ancestors);
86        var cloned = ancestors.ToDictionary(x => x, x => cloner.Clone(x));
87        graph.AddVertices(cloned.Values);
88        foreach (var arc in cloned.Keys.SelectMany(x => x.InArcs)) {
89          graph.AddArc(cloner.Clone(arc));
90        }
91        //        graph.AddVertices(graphNode.Ancestors);
92        MainFormManager.MainForm.ShowContent(graph);
93      }
94
95      if (graphNode.InArcs.Any()) {
96        var fragment = graphNode.InArcs.Last().Data as IFragment<ISymbolicExpressionTreeNode>;
97        if (fragment != null) {
98          treeChart_HighlightSubtree(graphNode.Data.NodeAt(fragment.Index1));
99        }
100      }
101      if (graphNode.OutArcs.Any()) {
102        var td = graphNode.OutArcs.Last().Data as Tuple<int, int, int, int>;
103        if (td != null) {
104          var s = graphNode.Data.NodeAt(td.Item3); // subtree index
105          var f = graphNode.Data.NodeAt(td.Item4); // fragment index
106          treeChart_HighlightSubtree(s, Color.Orange);
107          treeChart_HighlightSubtree(f, Color.RoyalBlue);
108        }
109      }
110    }
111
112    public void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs args) {
113      var visualNode = (VisualTreeNode<ISymbolicExpressionTreeNode>)sender;
114      var subtree = visualNode.Content;
115      // highlight the selected subtree inside the displayed tree on the right hand side
116      treeChart_ClearColors();
117      treeChart_HighlightSubtree(subtree);
118
119      bool trace = genealogyGraphChart.TraceFragments; // check whether we are in 'trace' or 'match' mode
120
121      if (trace) {
122        // perform fragment tracing
123        var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
124        var subtreeIndex = graphNode.Data.IterateNodesPrefix().ToList().IndexOf(subtree);
125        var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex);
126        if (traceGraph.Vertices.Any()) {
127          genealogyGraphChart.UpdateEnabled = false;
128          genealogyGraphChart.ClearArcs();
129          //          genealogyGraphChart.ClearPrimitives();
130          var genealogyNodes = traceGraph.Vertices.Select(v => Content.GetByContent(v.Data));
131          //          genealogyGraphChart.HighlightNodes(graphNode.Ancestors, Color.Gray, false);
132          genealogyGraphChart.HighlightNodes(genealogyNodes, Color.Black, false);
133          //          foreach (var a in traceGraph.Arcs) {
134          //            genealogyGraphChart.HighlightArc(Content.GetByContent(a.Target.Data), Content.GetByContent(a.Source.Data));
135          //          }
136          genealogyGraphChart.UpdateEnabled = true;
137          genealogyGraphChart.EnforceUpdate();
138          MainFormManager.MainForm.ShowContent(traceGraph); // display the fragment graph on the screen
139        }
140      } else {
141        // perform matching like it was done before
142        // currently there is no possibility to specify the subtree matching criteria
143        var trees = Content.Vertices.Select(x => x.Data);
144        var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(subtree, comparer));
145
146        var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
147        graphChart_HighlightMatchingVertices(matchingVertices);
148      }
149    }
150
151    private void graphChart_HighlightMatchingVertices(IEnumerable<IGenealogyGraphNode> vertices) {
152      genealogyGraphChart.Chart.UpdateEnabled = false;
153      genealogyGraphChart.ClearPrimitives();
154      genealogyGraphChart.HighlightNodes(vertices);
155      genealogyGraphChart.Chart.UpdateEnabled = true;
156      genealogyGraphChart.Chart.EnforceUpdate();
157    }
158
159    private void treeChart_ClearColors() {
160      foreach (var node in SymbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
161        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
162        if (visualNode != null) {
163          visualNode.LineColor = Color.Black;
164          visualNode.FillColor = Color.Transparent;
165        }
166      }
167      SymbolicExpressionTreeChart.RepaintNodes();
168    }
169
170    private void treeChart_HighlightSubtree(ISymbolicExpressionTreeNode subtree, Color? color = null) {
171      Color myColor = color ?? Color.RoyalBlue;
172      foreach (var s in subtree.IterateNodesPrefix()) {
173        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(s);
174        visualNode.LineColor = myColor;
175
176        foreach (var c in s.Subtrees) {
177          var visualArc = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(s, c);
178          visualArc.LineColor = myColor;
179        }
180      }
181      SymbolicExpressionTreeChart.RepaintNodes();
182    }
183
184    private void navigateLeftButton_Click(object sender, EventArgs e) {
185      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
186      if (graphNode.Parents.Any()) {
187        genealogyGraphChart.SelectedGraphNode = graphNode.Parents.First();
188      }
189    }
190
191    private void navigateRightButton_Click(object sender, EventArgs e) {
192      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
193      if (graphNode.Parents.Any()) {
194        genealogyGraphChart.SelectedGraphNode = graphNode.Parents.Last(); // this will only work for genealogy graphs (not trace graphs)
195      }
196    }
197  }
198
199  public class SymbolicDataAnalysisGenealogyGraphViewDesignable : GenealogyGraphView<ISymbolicExpressionTree> { }
200}
Note: See TracBrowser for help on using the repository browser.