Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 11891 was 11881, checked in by bburlacu, 9 years ago

#1772:

  • TraceGraph: Improved saving of trace data, changed GetTraceNode method to AddTraceNode and made the code more clear.
  • SymbolicDataAnalysisGenealogyGraphView: added highlighting of trace information (when visualizing trace graphs)
  • GenealogyGraphChart: removed useless code
File size: 10.4 KB
RevLine 
[10650]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
[11503]22using System;
[10650]23using System.Collections.Generic;
24using System.Drawing;
25using System.Linq;
26using System.Windows.Forms;
[11852]27using HeuristicLab.Common;
[11881]28using HeuristicLab.Core;
[10650]29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
31using HeuristicLab.EvolutionTracking;
32using HeuristicLab.EvolutionTracking.Views;
33using HeuristicLab.MainForm;
34
35namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
[11817]36  [View("SymbolicDataAnalysisGenealogyGraphView")]
[10650]37  [Content(typeof(IGenealogyGraph<ISymbolicExpressionTree>), IsDefaultView = true)]
[11817]38  public partial class SymbolicDataAnalysisGenealogyGraphView : SymbolicDataAnalysisGenealogyGraphViewDesignable {
[10650]39    private readonly ISymbolicExpressionTreeNodeSimilarityComparer comparer;
40
[11817]41    public SymbolicDataAnalysisGenealogyGraphView() {
[10650]42      InitializeComponent();
43      comparer = new SymbolicExpressionTreeNodeSimilarityComparer();
[11817]44      viewHost.ViewType = typeof(GraphicalSymbolicExpressionTreeView);
[10650]45    }
46    #region event handlers
47    protected override void OnContentChanged() {
48      base.OnContentChanged();
[11817]49      if (Content != null) { genealogyGraphChart.GenealogyGraph = Content; }
50    }
51    #endregion
52
53    public SymbolicExpressionTreeChart SymbolicExpressionTreeChart {
54      get {
55        var view = (GraphicalSymbolicExpressionTreeView)base.viewHost.ActiveView;
56        return view == null ? null : view.SymbolicExpressionTreeChart;
[10650]57      }
58    }
59
60    protected override void RegisterContentEvents() {
61      base.RegisterContentEvents();
[11817]62      if (SymbolicExpressionTreeChart != null)
63        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionTreeNodeClicked;
[10650]64    }
65
66    protected override void DeregisterContentEvents() {
[11817]67      if (SymbolicExpressionTreeChart != null)
68        SymbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionTreeNodeClicked;
[10650]69      base.DeregisterContentEvents();
70    }
71
[11817]72    public override void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs args) {
73      base.graphChart_GenealogyGraphNodeClicked(sender, args);
[10650]74      var visualNode = (VisualGenealogyGraphNode)sender;
75      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)visualNode.Data;
[11852]76
[11864]77      nodeQualityLabel.Text = String.Format("{0:0.000}", graphNode.Quality);
78      nodeRankLabel.Text = String.Format("{0:0.0}", graphNode.Rank);
79      nodeDegreeLabel.Text = String.Format("{0} / {1}", graphNode.InDegree, graphNode.OutDegree);
80
[11852]81      if (openNew_CheckBox.Checked) {
82        // get the ancestors into a new view
83        var cloner = new Cloner();
[11881]84        // clone arcs and vertices and use them to create a new graph
85        // that will include just the individual and its ancestors
[11852]86        var graph = new GenealogyGraph<ISymbolicExpressionTree>();
87        var ancestors = new[] { graphNode }.Concat(graphNode.Ancestors);
88        var cloned = ancestors.ToDictionary(x => x, x => cloner.Clone(x));
89        graph.AddVertices(cloned.Values);
90        foreach (var arc in cloned.Keys.SelectMany(x => x.InArcs)) {
91          graph.AddArc(cloner.Clone(arc));
92        }
93        MainFormManager.MainForm.ShowContent(graph);
94      }
95
[10730]96      if (graphNode.InArcs.Any()) {
[11881]97        var data = graphNode.InArcs.Last().Data;
98        var fragment = data as IFragment<ISymbolicExpressionTreeNode>;
99        var td = data as TraceData;
[10752]100        if (fragment != null) {
[11253]101          treeChart_HighlightSubtree(graphNode.Data.NodeAt(fragment.Index1));
[11881]102        } else if (td != null) {
103          var nodes = graphNode.Data.IterateNodesPrefix().ToList();
104          treeChart_HighlightSubtree(nodes[td.LastSubtreeIndex], Color.Orange);
105          treeChart_HighlightSubtree(nodes[td.LastFragmentIndex], Color.DodgerBlue);
[10752]106        }
[10656]107      }
[10650]108    }
109
[11817]110    public void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs args) {
[10650]111      var visualNode = (VisualTreeNode<ISymbolicExpressionTreeNode>)sender;
112      var subtree = visualNode.Content;
113      // highlight the selected subtree inside the displayed tree on the right hand side
114      treeChart_ClearColors();
115      treeChart_HighlightSubtree(subtree);
116
[11817]117      bool trace = genealogyGraphChart.TraceFragments; // check whether we are in 'trace' or 'match' mode
[10650]118
119      if (trace) {
120        // perform fragment tracing
[10752]121        var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
[11253]122        var subtreeIndex = graphNode.Data.IterateNodesPrefix().ToList().IndexOf(subtree);
[11817]123        var traceGraph = TraceCalculator.TraceSubtree(graphNode, subtreeIndex);
124        if (traceGraph.Vertices.Any()) {
[11852]125          genealogyGraphChart.UpdateEnabled = false;
126          genealogyGraphChart.ClearArcs();
[11817]127          var genealogyNodes = traceGraph.Vertices.Select(v => Content.GetByContent(v.Data));
[11852]128          genealogyGraphChart.HighlightNodes(genealogyNodes, Color.Black, false);
129          genealogyGraphChart.UpdateEnabled = true;
130          genealogyGraphChart.EnforceUpdate();
[11817]131          MainFormManager.MainForm.ShowContent(traceGraph); // display the fragment graph on the screen
[10755]132        }
[10650]133      } else {
[10654]134        // perform matching like it was done before
135        // currently there is no possibility to specify the subtree matching criteria
[11253]136        var trees = Content.Vertices.Select(x => x.Data);
[10650]137        var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(subtree, comparer));
138
[11503]139        var matchingVertices = matchingTrees.Select(x => Content.GetByContent(x));
[11852]140        graphChart_HighlightMatchingVertices(matchingVertices);
[10650]141      }
142    }
143
[11852]144    private void graphChart_HighlightMatchingVertices(IEnumerable<IGenealogyGraphNode> vertices) {
[10650]145      genealogyGraphChart.Chart.UpdateEnabled = false;
146      genealogyGraphChart.ClearPrimitives();
147      genealogyGraphChart.HighlightNodes(vertices);
148      genealogyGraphChart.Chart.UpdateEnabled = true;
149      genealogyGraphChart.Chart.EnforceUpdate();
150    }
151
152    private void treeChart_ClearColors() {
[11817]153      foreach (var node in SymbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
154        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
[10650]155        if (visualNode != null) {
156          visualNode.LineColor = Color.Black;
157          visualNode.FillColor = Color.Transparent;
158        }
159      }
[11817]160      SymbolicExpressionTreeChart.RepaintNodes();
[10650]161    }
162
[11503]163    private void treeChart_HighlightSubtree(ISymbolicExpressionTreeNode subtree, Color? color = null) {
[11817]164      Color myColor = color ?? Color.RoyalBlue;
[10650]165      foreach (var s in subtree.IterateNodesPrefix()) {
[11817]166        var visualNode = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(s);
[11503]167        visualNode.LineColor = myColor;
[10650]168
169        foreach (var c in s.Subtrees) {
[11817]170          var visualArc = SymbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(s, c);
[11503]171          visualArc.LineColor = myColor;
[10650]172        }
173      }
[11817]174      SymbolicExpressionTreeChart.RepaintNodes();
[10650]175    }
[11864]176
177    private void navigateLeftButton_Click(object sender, EventArgs e) {
178      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
[11881]179      var inArcs = (List<IArc>)((IVertex)graphNode).InArcs;
180      if (inArcs.Count > 0) {
181        genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source;
[11864]182      }
183    }
184
185    private void navigateRightButton_Click(object sender, EventArgs e) {
186      var graphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)genealogyGraphChart.SelectedGraphNode;
[11881]187      var inArcs = (List<IArc>)((IVertex)graphNode).InArcs;
188      if (inArcs.Count > 0) {
189        var data = inArcs.Last().Data;
190        var fragment = (data as IFragment<ISymbolicExpressionTreeNode>);
191        var td = data as TraceData;
192        if (fragment != null) {
193          genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs.Last().Source;
194        } else if (td != null) {
195          if (inArcs.Count == 1) {
196            genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[0].Source;
197            return;
198          }
199          // the first arc from inArcs will always represent the connection to the root parent
200          // (tracing the body of the traced subtree)
201          // therefore, in order to follow the correct non-root parent, we have to find the correct arc
202          // But, the FragmentIndex recorded in the TraceData of the first arc has to match the SubtreeIndex recorded in the TraceData of the searched arc
203          td = (TraceData)inArcs[0].Data;
204          var f1 = (graphNode.Data).NodeAt(td.LastFragmentIndex);
205          for (int i = 1; i < inArcs.Count; ++i) {
206            td = (TraceData)inArcs[i].Data;
207            var f2 = ((ISymbolicExpressionTree)inArcs[i].Source.Data).NodeAt(td.SubtreeIndex);
208            // if the subtrees are the same we have found a match
209            // note: this is not necessarily 100% correct if in the trace graph we have identical fragments on different arcs
210            if (f1.Difference(f2) == null) {
211              genealogyGraphChart.SelectedGraphNode = (IGenealogyGraphNode<ISymbolicExpressionTree>)inArcs[i].Source;
212              return;
213            }
214          }
215          throw new InvalidOperationException("Error calculating the next step.");
216        }
[11864]217      }
218    }
[11817]219  }
[10650]220
[11817]221  public class SymbolicDataAnalysisGenealogyGraphViewDesignable : GenealogyGraphView<ISymbolicExpressionTree> { }
[10650]222}
Note: See TracBrowser for help on using the repository browser.