#region License Information
/* HeuristicLab
* Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using HeuristicLab.Core.Views;
using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views;
using HeuristicLab.EvolutionTracking;
using HeuristicLab.EvolutionTracking.Views;
using HeuristicLab.MainForm;
namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
[View("SymboldDataAnalysisGenealogyView")]
[Content(typeof(IGenealogyGraph), IsDefaultView = true)]
public partial class SymboldDataAnalysisGenealogyView : ItemView {
private readonly ISymbolicExpressionTreeNodeSimilarityComparer comparer;
public SymboldDataAnalysisGenealogyView() {
InitializeComponent();
comparer = new SymbolicExpressionTreeNodeSimilarityComparer();
}
public new IGenealogyGraph Content {
get { return (IGenealogyGraph)base.Content; }
set { base.Content = value; }
}
#region event handlers
protected override void OnContentChanged() {
base.OnContentChanged();
if (Content != null) {
genealogyGraphChart.GenealogyGraph = Content;
}
}
#endregion
protected override void RegisterContentEvents() {
genealogyGraphChart.GenealogyGraphNodeClicked += graphChart_GenealogyGraphNodeClicked;
symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += treeChart_SymbolicExpressionNodeClicked;
base.RegisterContentEvents();
}
protected override void DeregisterContentEvents() {
base.DeregisterContentEvents();
genealogyGraphChart.GenealogyGraphNodeClicked -= graphChart_GenealogyGraphNodeClicked;
symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked -= treeChart_SymbolicExpressionNodeClicked;
}
public void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs args) {
var visualNode = (VisualGenealogyGraphNode)sender;
var graphNode = (IGenealogyGraphNode)visualNode.Data;
var tree = graphNode.Content;
symbolicExpressionTreeChart.Tree = tree;
if (graphNode.InArcs.Any()) {
var fragment = (IFragment)graphNode.InArcs.Last().Data;
if (fragment != null) {
treeChart_HighlightSubtree(graphNode.Content.NodeAt(fragment.Index1));
}
}
}
public void treeChart_SymbolicExpressionNodeClicked(object sender, MouseEventArgs args) {
var visualNode = (VisualTreeNode)sender;
var subtree = visualNode.Content;
// highlight the selected subtree inside the displayed tree on the right hand side
treeChart_ClearColors();
treeChart_HighlightSubtree(subtree);
bool trace = genealogyGraphChart.TraceFragments; // check whether the mode is 'trace' or 'match'
if (trace) {
// perform fragment tracing
var graphNode = (IGenealogyGraphNode)genealogyGraphChart.SelectedGraphNode;
var subtreeIndex = graphNode.Content.IterateNodesPrefix().ToList().IndexOf(subtree);
var fragmentGraph = SymbolicDataAnalysisExpressionTracing.TraceSubtree(graphNode, subtreeIndex);
if (fragmentGraph.Nodes.Any()) {
MainFormManager.MainForm.ShowContent(fragmentGraph); // display the fragment graph on the screen
}
} else {
// perform matching like it was done before
// currently there is no possibility to specify the subtree matching criteria
var trees = Content.Nodes.Select(x => x.Content);
var matchingTrees = trees.Where(x => x.Root.ContainsSubtree(subtree, comparer));
var matchingVertices = matchingTrees.Select(x => Content[x]).Cast>();
graphChart_highlightMatchingVertices(matchingVertices);
}
}
private void graphChart_highlightMatchingVertices(IEnumerable vertices) {
genealogyGraphChart.Chart.UpdateEnabled = false;
genealogyGraphChart.ClearPrimitives();
genealogyGraphChart.HighlightNodes(vertices);
genealogyGraphChart.Chart.UpdateEnabled = true;
genealogyGraphChart.Chart.EnforceUpdate();
}
private void treeChart_ClearColors() {
foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
if (visualNode != null) {
visualNode.LineColor = Color.Black;
visualNode.FillColor = Color.Transparent;
}
}
symbolicExpressionTreeChart.RepaintNodes();
}
private void treeChart_HighlightSubtree(ISymbolicExpressionTreeNode subtree) {
foreach (var s in subtree.IterateNodesPrefix()) {
var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(s);
visualNode.LineColor = Color.RoyalBlue;
visualNode.FillColor = Color.LightBlue;
foreach (var c in s.Subtrees) {
var visualArc = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(s, c);
visualArc.LineColor = Color.RoyalBlue;
}
}
symbolicExpressionTreeChart.RepaintNodes();
}
#region events for configuring the behavior of the genealogy chart (trace/match, simple lineages, etc)
private void trace_checkBox_CheckedChanged(object sender, System.EventArgs e) {
genealogyGraphChart.TraceFragments = trace_checkBox.Checked;
}
private void simpleLineages_checkBox_CheckedChanged(object sender, System.EventArgs e) {
genealogyGraphChart.SimpleLineages = simpleLineages_checkBox.Checked;
}
private void lockGraph_checkBox_CheckedChanged(object sender, System.EventArgs e) {
genealogyGraphChart.LockGenealogy = lockGraph_checkBox.Checked;
}
#endregion
}
}