Changeset 9084 for branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views
- Timestamp:
- 12/20/12 16:27:58 (12 years ago)
- Location:
- branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphChart.cs
r8556 r9084 28 28 using HeuristicLab.Common; 29 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 30 using HeuristicLab.Problems.DataAnalysis.Symbolic; 30 31 using HeuristicLab.Visualization; 31 32 32 33 namespace HeuristicLab.EvolutionaryTracking.Views { 33 34 public partial class GenealogyGraphChart : ChartControl { 34 private Dictionary< IGenealogyGraphNode, VisualGenealogyGraphNode> visualNodeMap;35 private Dictionary<string, VisualGenealogyGraphNode> visualNodeMap; // map the uid of the genealogy graph vertex with a visual node (in this way each node is uniquely determined) 35 36 private Dictionary<Tuple<VisualGenealogyGraphNode, VisualGenealogyGraphNode>, VisualGenealogyGraphArc> visualArcMap; 36 37 private const int Diameter = 20; // node diameter … … 46 47 internal set { 47 48 graph = value; 48 visualNodeMap = new Dictionary<IGenealogyGraphNode, VisualGenealogyGraphNode>(); 49 // TODO: should move the subtree sorting code out of here and int the view 50 var canonicalSorter = new SymbolicExpressionTreeCanonicalSorter(); 51 // sort subtrees in order to improve matching 52 foreach (var tree in graph.Nodes.Select(n => n.SymbolicExpressionTree)) 53 canonicalSorter.SortSubtrees(tree); 54 55 visualNodeMap = new Dictionary<string, VisualGenealogyGraphNode>(); 49 56 visualArcMap = new Dictionary<Tuple<VisualGenealogyGraphNode, VisualGenealogyGraphNode>, VisualGenealogyGraphArc>(); 57 58 Chart.Group.Clear(); 50 59 DrawGraph(); 51 60 } 61 } 62 63 private VisualGenealogyGraphNode GetVisualGenealogyGraphNode(IVertex node) { 64 VisualGenealogyGraphNode visualNode; 65 visualNodeMap.TryGetValue(node.Id, out visualNode); 66 return visualNode; 52 67 } 53 68 … … 68 83 Chart.UpdateEnabled = false; 69 84 70 var layers = Graph.Nodes.GroupBy(n => n.Ranks[0]).OrderBy(g => g.Key).Select(g => new { Rank = g.Key, Nodes = g.ToList() }).ToList(); 85 var layers = Graph.Nodes.GroupBy(n => n.Rank).OrderBy(g => g.Key).Select(g => new { Rank = g.Key, Nodes = g.ToList() }).ToList(); 86 71 87 for (int i = 0; i != layers.Count; ++i) { 72 88 // sort descending by quality (using comparison defined in GenealogyGraphNode class) 73 89 layers[i].Nodes.Sort((b, a) => Graph.Compare(a, b)); 74 90 x = 0; // reset horizontal coordinate 75 // start laying out visual nodes76 91 foreach (var node in layers[i].Nodes) { 77 92 var pen = new Pen(Color.LightGray); … … 80 95 Data = node, 81 96 ToolTipText = "Id: " + node.Label + nl + 82 "Rank s: " + string.Join(",", node.Ranks)+ nl +97 "Rank: " + node.Rank + nl + 83 98 "Quality: " + String.Format("{0:0.0000}", node.Quality) + nl + 84 99 "IsElite: " + node.IsElite 85 100 }; 86 101 Chart.Group.Add(visualNode); 87 if (!visualNodeMap.ContainsKey(node)) 88 visualNodeMap[node] = visualNode; 102 visualNodeMap.Add(node.Id, visualNode); 89 103 90 104 x += Cx; // increment horizontal coordinate … … 94 108 95 109 // connect elites from successive layers with visual arcs 96 if (i > 0) { 97 for (int m = 0; m != layers[i].Nodes.Count; ++m) 98 for (int n = 0; n != layers[i - 1].Nodes.Count; ++n) { 99 if (layers[i].Nodes[m].SymbolicExpressionTree == layers[i - 1].Nodes[n].SymbolicExpressionTree) { 100 var v1 = visualNodeMap[layers[i].Nodes[m]]; 101 var v2 = visualNodeMap[layers[i - 1].Nodes[n]]; 102 var pen = new Pen(Color.LightGray); 103 visualArcMap[Tuple.Create(v2, v1)] = AddArc(Chart, v2, v1, pen); 104 } 105 } 110 if (i == 0) continue; 111 var currLayer = layers[i].Nodes; 112 var prevLayer = layers[i - 1].Nodes; 113 foreach (var n in currLayer) { 114 foreach (var m in prevLayer) { 115 if (n.SymbolicExpressionTree != m.SymbolicExpressionTree) continue; 116 var v1 = GetVisualGenealogyGraphNode(n); 117 var v2 = GetVisualGenealogyGraphNode(m); 118 119 var pen = new Pen(Color.LightGray); 120 visualArcMap[Tuple.Create(v2, v1)] = AddArc(Chart, v2, v1, pen); 121 } 106 122 } 107 123 } 108 124 // add arcs separately (to avoid some ordering problems) 109 foreach ( var node in visualNodeMap.Keys) {110 var visualNode = visualNodeMap[node];125 foreach (SymbolicExpressionGenealogyGraphNode node in Graph.Nodes) { 126 VisualGenealogyGraphNode visualNode = GetVisualGenealogyGraphNode(node); 111 127 if (node.InEdges == null) continue; 112 128 113 foreach ( vararc in node.InEdges) {114 var visualParent = visualNodeMap[arc.Target];129 foreach (Arc arc in node.InEdges) { 130 var visualParent = GetVisualGenealogyGraphNode(arc.Source); 115 131 var pen = new Pen(Color.Transparent); 116 132 visualArcMap[Tuple.Create(visualParent, visualNode)] = AddArc(Chart, visualParent, visualNode, pen); … … 134 150 135 151 protected override void pictureBox_MouseUp(object sender, MouseEventArgs e) { 136 if (Chart.Mode != ChartMode.Select) 152 if (Chart.Mode != ChartMode.Select) { 137 153 base.pictureBox_MouseUp(sender, e); 138 else { // select mode 139 // get selected node 140 var visualNodes = Chart.GetAllPrimitives(e.Location).Where(p => p is VisualGenealogyGraphNode).ToList(); 141 if (visualNodes.Count > 0) { 142 if (selectedGenealogyGraphNode == visualNodes[0]) return; 143 selectedGenealogyGraphNode = visualNodes[0] as VisualGenealogyGraphNode; 144 if (selectedGenealogyGraphNode == null) return; 145 // new node has been selected, clean up 146 Chart.UpdateEnabled = false; 147 // clear colors 148 ClearAllNodes(); 149 // use a rectangle to highlight the currently selected genealogy graph node 150 var center = selectedGenealogyGraphNode.Center; 151 var size = selectedGenealogyGraphNode.Size; 152 double x1 = center.X - size.Width / 2; 153 double x2 = x1 + size.Width; 154 double y1 = center.Y - size.Height / 2; 155 double y2 = y1 + size.Height; 156 if (targetRectangle == null) { 157 targetRectangle = new Visualization.Rectangle(Chart, x1, y1, x2, y2, new Pen(Color.Black), null); 158 Chart.Group.Add(targetRectangle); 159 } else { 160 targetRectangle.SetPosition(x1, y1, x2, y2); 161 } 162 var gNode = selectedGenealogyGraphNode.Data; // genealogy graph node (representing an individual in the population) 163 // double rank = Graph[gNode].Ranks[0]; 164 double rank = ((SymbolicExpressionGenealogyGraphNode)gNode).Ranks[0]; 165 // ancestors 166 var ancestors = gNode.Ancestors().Where(n => ((SymbolicExpressionGenealogyGraphNode)n).Ranks.Last() < rank).ToList(); 167 ancestors.Add(gNode); 168 // descendants 169 var descendants = gNode.Descendants().Where(n => ((SymbolicExpressionGenealogyGraphNode)n).Ranks.Last() > rank).ToList(); 170 descendants.Add(gNode); 171 // highlight ancestors 172 foreach (var node in ancestors.Select(n => visualNodeMap[n])) { 173 node.Brush = new SolidBrush(((SymbolicExpressionGenealogyGraphNode)node.Data).GetColor()); 174 if (node.IncomingArcs != null) 175 foreach (var arc in node.IncomingArcs) { 176 var start = new Point((int)arc.Start.X, (int)arc.Start.Y); 177 var end = new Point((int)arc.End.X, (int)arc.End.Y); 178 var srcNode = arc.Source.Data as SymbolicExpressionGenealogyGraphNode; 179 var destNode = arc.Target.Data as SymbolicExpressionGenealogyGraphNode; 180 arc.Pen.Brush = new LinearGradientBrush(start, end, srcNode.GetColor(), destNode.GetColor()); 181 } 182 } 183 // highlight descendants 184 foreach (var node in descendants.Select(n => visualNodeMap[n])) { 185 node.Brush = new SolidBrush((node.Data as SymbolicExpressionGenealogyGraphNode).GetColor()); 186 if (node.OutgoingArcs != null) 187 foreach (var arc in node.OutgoingArcs) { 188 var start = new Point((int)arc.Start.X, (int)arc.Start.Y); 189 var end = new Point((int)arc.End.X, (int)arc.End.Y); 190 var srcNode = arc.Source.Data as SymbolicExpressionGenealogyGraphNode; 191 var destNode = arc.Target.Data as SymbolicExpressionGenealogyGraphNode; 192 arc.Pen.Brush = new LinearGradientBrush(start, end, srcNode.GetColor(), destNode.GetColor()); 193 } 194 } 195 } else { 196 selectedGenealogyGraphNode = null; 197 } 198 // update 199 Chart.UpdateEnabled = true; 200 Chart.EnforceUpdate(); 201 if (selectedGenealogyGraphNode != null) 202 /* emit clicked event */ 203 OnGenealogyGraphNodeClicked(selectedGenealogyGraphNode, e); 154 return; 155 } 156 var visualNodes = Chart.GetAllPrimitives(e.Location).Where(p => p is VisualGenealogyGraphNode).ToList(); 157 if (visualNodes.Count <= 0) { 158 selectedGenealogyGraphNode = null; 159 return; 160 } 161 if (selectedGenealogyGraphNode == visualNodes[0]) return; 162 selectedGenealogyGraphNode = visualNodes[0] as VisualGenealogyGraphNode; 163 if (selectedGenealogyGraphNode == null) return; 164 // new node has been selected, clean up 165 Chart.UpdateEnabled = false; 166 // clear colors 167 ClearAllNodes(); 168 // use a rectangle to highlight the currently selected genealogy graph node 169 MarkSelectedNode(); 170 var gNode = selectedGenealogyGraphNode.Data; 171 var visualNode = GetVisualGenealogyGraphNode(gNode); 172 173 DrawLineage(visualNode, n => n.IncomingArcs, a => a.Source); 174 DrawLineage(visualNode, n => n.OutgoingArcs, a => a.Target); 175 176 // update 177 Chart.UpdateEnabled = true; 178 Chart.EnforceUpdate(); 179 180 if (selectedGenealogyGraphNode != null) 181 /* emit clicked event */ 182 OnGenealogyGraphNodeClicked(selectedGenealogyGraphNode, e); 183 } 184 185 private void DrawLineage(VisualGenealogyGraphNode node, 186 Func<VisualGenealogyGraphNode, IEnumerable<VisualGenealogyGraphArc>> arcSelector, 187 Func<VisualGenealogyGraphArc, VisualGenealogyGraphNode> nodeSelector) { 188 node.Brush = new SolidBrush(node.Data.GetColor()); 189 var arcs = arcSelector(node); 190 foreach (var arc in arcs) { 191 var source = arc.Source.Data; 192 var target = arc.Target.Data; 193 var start = new Point((int)arc.Start.X, (int)arc.Start.Y); 194 var end = new Point((int)arc.End.X, (int)arc.End.Y); 195 arc.Pen.Brush = new LinearGradientBrush(start, end, source.GetColor(), target.GetColor()); 196 DrawLineage(nodeSelector(arc), arcSelector, nodeSelector); 197 } 198 } 199 200 void MarkSelectedNode() { 201 var center = selectedGenealogyGraphNode.Center; 202 var size = selectedGenealogyGraphNode.Size; 203 double x1 = center.X - size.Width / 2; 204 double x2 = x1 + size.Width; 205 double y1 = center.Y - size.Height / 2; 206 double y2 = y1 + size.Height; 207 if (targetRectangle == null) { 208 targetRectangle = new Visualization.Rectangle(Chart, x1, y1, x2, y2, new Pen(Color.Black), null); 209 Chart.Group.Add(targetRectangle); 210 } else { 211 targetRectangle.SetPosition(x1, y1, x2, y2); 204 212 } 205 213 } … … 209 217 if (primitive is VisualGenealogyGraphArc) { 210 218 var arc = primitive as VisualGenealogyGraphArc; 211 var sourceData = (arc.Source.Data as SymbolicExpressionGenealogyGraphNode).SymbolicExpressionTree; 212 var targetData = (arc.Target.Data as SymbolicExpressionGenealogyGraphNode).SymbolicExpressionTree; 213 if (sourceData != targetData) { 214 primitive.Pen.Brush = new SolidBrush(Color.Transparent); 215 } else { 216 primitive.Pen.Brush = new SolidBrush(Color.LightGray); 217 } 219 var sourceData = arc.Source.Data.SymbolicExpressionTree; 220 var targetData = arc.Target.Data.SymbolicExpressionTree; 221 primitive.Pen.Brush = sourceData != targetData ? new SolidBrush(Color.Transparent) : new SolidBrush(Color.LightGray); 218 222 } else { 219 223 primitive.Brush = null; … … 222 226 } 223 227 224 public void HighlightLineage(IEnumerable<GenealogyGraphNode> nodes) {225 foreach (var node in nodes.Select(n => visualNodeMap[n])) {226 node.Brush = new SolidBrush((node.Data as SymbolicExpressionGenealogyGraphNode).GetColor());227 if (node.IncomingArcs == null || node != visualNodeMap[node.Data]) continue;228 foreach (var arc in node.IncomingArcs) {229 if (arc.Source.Data == node.Data) continue;230 var start = new Point((int)arc.Start.X, (int)arc.Start.Y);231 var end = new Point((int)arc.End.X, (int)arc.End.Y);232 var srcNode = arc.Source.Data as SymbolicExpressionGenealogyGraphNode;233 var destNode = arc.Target.Data as SymbolicExpressionGenealogyGraphNode;234 arc.Pen.Brush = new LinearGradientBrush(start, end, srcNode.GetColor(), destNode.GetColor());235 }236 }237 }238 239 228 // TODO: optimize and reduce complexity of this method 240 229 public void HighlightNodes(IEnumerable<ISymbolicExpressionTree> trees, Color color) { 241 foreach (var tree in trees) 242 foreach (var graphNode in Graph.Nodes) { 243 if (graphNode.SymbolicExpressionTree == tree) { 244 var visualNode = visualNodeMap[graphNode]; 245 visualNode.Brush = new SolidBrush(color); 246 } 247 } 230 foreach (var tree in trees) { 231 var graphNodes = graph.GetGraphNodes(tree); 232 foreach (var graphNode in graphNodes) { 233 GetVisualGenealogyGraphNode(graphNode).Brush = new SolidBrush(color); 234 } 235 } 248 236 } 249 237 250 238 public void HighlightNode(SymbolicExpressionGenealogyGraphNode graphNode, Color color) { 251 visualNodeMap[graphNode].Brush = new SolidBrush(color);239 GetVisualGenealogyGraphNode(graphNode).Brush = new SolidBrush(color); 252 240 } 253 241 … … 257 245 double max = Graph.Nodes.Max(x => x.InEdges == null ? 0 : x.InEdges.Count); 258 246 foreach (var graphNode in Graph.Nodes) { 259 var visualNode = visualNodeMap[graphNode];247 var visualNode = GetVisualGenealogyGraphNode(graphNode); 260 248 double deg = graphNode.InEdges == null ? 0 : graphNode.InEdges.Count; 261 249 int index = (int)(deg / max * ColorGradient.Colors.Count); … … 274 262 double max = graphNodes.Max(x => x.OutEdges == null ? 0 : x.OutEdges.Count); 275 263 foreach (var graphNode in graphNodes) { 276 var visualNode = visualNodeMap[graphNode];264 var visualNode = GetVisualGenealogyGraphNode(graphNode); 277 265 double deg = graphNode.OutEdges == null ? 0 : graphNode.OutEdges.Count; 278 266 int index = (int)(deg / max * ColorGradient.Colors.Count); -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.Designer.cs
r8556 r9084 25 25 /// </summary> 26 26 private void InitializeComponent() { 27 this.components = new System.ComponentModel.Container(); 27 28 this.mainTableLayout = new System.Windows.Forms.TableLayoutPanel(); 28 29 this.splitContainer = new System.Windows.Forms.SplitContainer(); 29 30 this.genealogyTableLayout = new System.Windows.Forms.TableLayoutPanel(); 31 this.genealogyGraphChart = new HeuristicLab.EvolutionaryTracking.Views.GenealogyGraphChart(); 30 32 this.symbolicExpressionTreeChart = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart(); 31 33 this.topControlBox = new System.Windows.Forms.GroupBox(); 34 this.matchVariableNamesCheckBox = new System.Windows.Forms.CheckBox(); 35 this.matchVariableWeightsCheckBox = new System.Windows.Forms.CheckBox(); 36 this.matchConstantsCheckBox = new System.Windows.Forms.CheckBox(); 37 this.similarityLabel = new System.Windows.Forms.Label(); 32 38 this.graphControlsPanel = new System.Windows.Forms.Panel(); 33 this.similarityModeLabel = new System.Windows.Forms.Label();34 this.similarityModeSelector = new System.Windows.Forms.ComboBox();35 39 this.selectModeButton = new System.Windows.Forms.RadioButton(); 36 40 this.moveModeButton = new System.Windows.Forms.RadioButton(); 37 41 this.zoomModeButton = new System.Windows.Forms.RadioButton(); 38 this.genealogyGraphChart = new HeuristicLab.EvolutionaryTracking.Views.GenealogyGraphChart();39 42 this.mainTableLayout.SuspendLayout(); 40 43 ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit(); … … 97 100 this.genealogyTableLayout.TabIndex = 4; 98 101 // 102 // genealogyGraphChart 103 // 104 this.genealogyGraphChart.BackColor = System.Drawing.SystemColors.Control; 105 this.genealogyGraphChart.Dock = System.Windows.Forms.DockStyle.Fill; 106 this.genealogyGraphChart.Location = new System.Drawing.Point(3, 3); 107 this.genealogyGraphChart.Name = "genealogyGraphChart"; 108 this.genealogyGraphChart.ScaleOnResize = true; 109 this.genealogyGraphChart.Size = new System.Drawing.Size(352, 520); 110 this.genealogyGraphChart.TabIndex = 2; 111 // 99 112 // symbolicExpressionTreeChart 100 113 // … … 113 126 // topControlBox 114 127 // 128 this.topControlBox.Controls.Add(this.matchVariableNamesCheckBox); 129 this.topControlBox.Controls.Add(this.matchVariableWeightsCheckBox); 130 this.topControlBox.Controls.Add(this.matchConstantsCheckBox); 131 this.topControlBox.Controls.Add(this.similarityLabel); 115 132 this.topControlBox.Controls.Add(this.graphControlsPanel); 116 this.topControlBox.Controls.Add(this.similarityModeLabel);117 this.topControlBox.Controls.Add(this.similarityModeSelector);118 133 this.topControlBox.Dock = System.Windows.Forms.DockStyle.Fill; 119 134 this.topControlBox.Location = new System.Drawing.Point(3, 3); … … 124 139 this.topControlBox.Text = "Controls"; 125 140 // 141 // matchVariableNamesCheckBox 142 // 143 this.matchVariableNamesCheckBox.AutoSize = true; 144 this.matchVariableNamesCheckBox.Checked = true; 145 this.matchVariableNamesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 146 this.matchVariableNamesCheckBox.Location = new System.Drawing.Point(436, 23); 147 this.matchVariableNamesCheckBox.Name = "matchVariableNamesCheckBox"; 148 this.matchVariableNamesCheckBox.Size = new System.Drawing.Size(98, 17); 149 this.matchVariableNamesCheckBox.TabIndex = 7; 150 this.matchVariableNamesCheckBox.Text = "Variable names"; 151 this.matchVariableNamesCheckBox.UseVisualStyleBackColor = true; 152 this.matchVariableNamesCheckBox.CheckedChanged += new System.EventHandler(this.matchVariableNamesCheckBox_CheckedChanged); 153 // 154 // matchVariableWeightsCheckBox 155 // 156 this.matchVariableWeightsCheckBox.AutoSize = true; 157 this.matchVariableWeightsCheckBox.Checked = true; 158 this.matchVariableWeightsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 159 this.matchVariableWeightsCheckBox.Location = new System.Drawing.Point(327, 23); 160 this.matchVariableWeightsCheckBox.Name = "matchVariableWeightsCheckBox"; 161 this.matchVariableWeightsCheckBox.Size = new System.Drawing.Size(103, 17); 162 this.matchVariableWeightsCheckBox.TabIndex = 6; 163 this.matchVariableWeightsCheckBox.Text = "Variable weights"; 164 this.matchVariableWeightsCheckBox.UseVisualStyleBackColor = true; 165 this.matchVariableWeightsCheckBox.CheckedChanged += new System.EventHandler(this.matchVariableWeightsCheckBox_CheckedChanged); 166 // 167 // matchConstantsCheckBox 168 // 169 this.matchConstantsCheckBox.AutoSize = true; 170 this.matchConstantsCheckBox.Checked = true; 171 this.matchConstantsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; 172 this.matchConstantsCheckBox.Location = new System.Drawing.Point(219, 23); 173 this.matchConstantsCheckBox.Name = "matchConstantsCheckBox"; 174 this.matchConstantsCheckBox.Size = new System.Drawing.Size(102, 17); 175 this.matchConstantsCheckBox.TabIndex = 5; 176 this.matchConstantsCheckBox.Text = "Constant values"; 177 this.matchConstantsCheckBox.UseVisualStyleBackColor = true; 178 this.matchConstantsCheckBox.CheckedChanged += new System.EventHandler(this.matchConstantsCheckBox_CheckedChanged); 179 // 180 // similarityLabel 181 // 182 this.similarityLabel.AutoSize = true; 183 this.similarityLabel.Location = new System.Drawing.Point(105, 24); 184 this.similarityLabel.Name = "similarityLabel"; 185 this.similarityLabel.Size = new System.Drawing.Size(108, 13); 186 this.similarityLabel.TabIndex = 3; 187 this.similarityLabel.Text = "Matching constraints:"; 188 // 126 189 // graphControlsPanel 127 190 // … … 129 192 this.graphControlsPanel.Controls.Add(this.moveModeButton); 130 193 this.graphControlsPanel.Controls.Add(this.zoomModeButton); 131 this.graphControlsPanel.Location = new System.Drawing.Point( 246, 14);194 this.graphControlsPanel.Location = new System.Drawing.Point(6, 14); 132 195 this.graphControlsPanel.Name = "graphControlsPanel"; 133 196 this.graphControlsPanel.Size = new System.Drawing.Size(93, 30); 134 197 this.graphControlsPanel.TabIndex = 2; 135 //136 // similarityModeLabel137 //138 this.similarityModeLabel.AutoSize = true;139 this.similarityModeLabel.Location = new System.Drawing.Point(6, 20);140 this.similarityModeLabel.Name = "similarityModeLabel";141 this.similarityModeLabel.Size = new System.Drawing.Size(80, 13);142 this.similarityModeLabel.TabIndex = 1;143 this.similarityModeLabel.Text = "Similarity Mode:";144 //145 // similarityModeSelector146 //147 this.similarityModeSelector.FormattingEnabled = true;148 this.similarityModeSelector.Items.AddRange(new object[] {149 "Exact",150 "High",151 "Relaxed"});152 this.similarityModeSelector.Location = new System.Drawing.Point(92, 17);153 this.similarityModeSelector.Name = "similarityModeSelector";154 this.similarityModeSelector.Size = new System.Drawing.Size(148, 21);155 this.similarityModeSelector.TabIndex = 0;156 this.similarityModeSelector.SelectedIndexChanged += new System.EventHandler(this.similarityModeSelector_SelectedIndexChanged);157 198 // 158 199 // selectModeButton … … 188 229 this.zoomModeButton.UseVisualStyleBackColor = true; 189 230 this.zoomModeButton.CheckedChanged += new System.EventHandler(this.zoomModeButton_CheckedChanged); 190 //191 // genealogyGraphChart192 //193 this.genealogyGraphChart.BackColor = System.Drawing.SystemColors.Control;194 this.genealogyGraphChart.Dock = System.Windows.Forms.DockStyle.Fill;195 this.genealogyGraphChart.Location = new System.Drawing.Point(3, 3);196 this.genealogyGraphChart.Name = "genealogyGraphChart";197 this.genealogyGraphChart.ScaleOnResize = true;198 this.genealogyGraphChart.Size = new System.Drawing.Size(352, 520);199 this.genealogyGraphChart.TabIndex = 2;200 231 // 201 232 // GenealogyGraphView … … 224 255 private System.Windows.Forms.SplitContainer splitContainer; 225 256 private System.Windows.Forms.GroupBox topControlBox; 226 private System.Windows.Forms.Label similarityModeLabel;227 private System.Windows.Forms.ComboBox similarityModeSelector;228 257 private Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart symbolicExpressionTreeChart; 229 258 private System.Windows.Forms.TableLayoutPanel genealogyTableLayout; … … 233 262 private System.Windows.Forms.RadioButton moveModeButton; 234 263 private System.Windows.Forms.RadioButton zoomModeButton; 264 private System.Windows.Forms.Label similarityLabel; 265 private System.Windows.Forms.CheckBox matchVariableNamesCheckBox; 266 private System.Windows.Forms.CheckBox matchVariableWeightsCheckBox; 267 private System.Windows.Forms.CheckBox matchConstantsCheckBox; 235 268 236 269 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/GenealogyGraphView.cs
r8556 r9084 37 37 public sealed partial class GenealogyGraphView : ItemView { 38 38 private VisualSymbolicExpressionTreeNode selectedVisualSymbExprTreeNode; 39 private SymbolicExpressionTreeNodeSimilarityComparer comparer; 40 private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> clonedNodes; 41 39 42 public new SymbolicExpressionTreeGenealogyGraph Content { 40 43 get { return (SymbolicExpressionTreeGenealogyGraph)base.Content; } 41 44 set { base.Content = value; } 42 45 } 43 44 private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> clonedNodeMap;45 46 46 47 public GenealogyGraphView() … … 51 52 this.zoomModeButton.Image = Common.Resources.VSImageLibrary.Zoom; 52 53 this.selectModeButton.Image = Common.Resources.VSImageLibrary.Object; 53 54 55 similarityModeSelector.SelectedIndex = 0; // set default similarity mode to "exact" 54 comparer = new SymbolicExpressionTreeNodeSimilarityComparer { 55 MatchConstantValues = true, 56 MatchVariableWeights = true, 57 MatchVariableNames = true 58 }; 56 59 } 57 60 … … 97 100 // TODO: Put event handlers of child controls here. 98 101 private void graphChart_GenealogyGraphNodeClicked(object sender, MouseEventArgs e) { 99 // the type hierarchy goes like this: VisualGenealogyGraphNode --> GenealogyGraphNode --> symbolicExpressionTree102 // the type hierarchy goes like this: VisualGenealogyGraphNode --> GenealogyGraphNode --> SymbolicExpressionTree 100 103 var visualGenealogyGraphNode = (VisualGenealogyGraphNode)sender; 101 var genealogyGraphNode = (SymbolicExpressionGenealogyGraphNode)visualGenealogyGraphNode.Data;104 var genealogyGraphNode = visualGenealogyGraphNode.Data; 102 105 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 } 106 if (genealogyGraphNode.InEdges == null) return; 107 var arc = genealogyGraphNode.InEdges.First(x => x.Source != x.Target && x.Data != null); 108 if (arc == null) return; 109 var fragment = (IFragment)arc.Data; 110 foreach (var node in fragment.Root.IterateNodesBreadth()) { 111 var visualSymbExprTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node); 112 visualSymbExprTreeNode.LineColor = Color.OrangeRed; 124 113 } 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(); 114 symbolicExpressionTreeChart.Repaint(); // pain orange nodes 146 115 } 147 116 … … 162 131 163 132 private void treeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) { 164 ISymbolicExpressionTreeNode selectedSubtree = null;165 133 genealogyGraphChart.Chart.UpdateEnabled = false; 166 134 switch (e.Button) { … … 168 136 selectedVisualSymbExprTreeNode = (VisualSymbolicExpressionTreeNode)sender; 169 137 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; 138 ISymbolicExpressionTreeNode selectedSubtree = selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode; 139 var clonedSubtree = (ISymbolicExpressionTreeNode)selectedSubtree.Clone(); 140 // map original nodes to cloned nodes 141 clonedNodes = selectedSubtree.IterateNodesPrefix() 142 .Zip(clonedSubtree.IterateNodesPrefix(), (original, clone) => new { original, clone }) 143 .ToDictionary(p => p.original, p => p.clone); 144 145 foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPrefix()) { 146 symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent; 186 147 } 187 selectedSubtree.ForEachNodePostfix(node =>{148 foreach (var node in selectedSubtree.IterateNodesPrefix()) { 188 149 symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.LightBlue; 189 }); 150 } 151 break; 190 152 } 191 break;192 153 case MouseButtons.Middle: { 193 154 var visualNode = (VisualSymbolicExpressionTreeNode)sender; 194 if (selectedVisualSymbExprTreeNode == null || selectedVisualSymbExprTreeNode == visualNode) 195 return; 196 selectedSubtree = clonedNodeMap[selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode]; 155 if (selectedVisualSymbExprTreeNode == null || selectedVisualSymbExprTreeNode == visualNode) return; 197 156 var selectedNode = visualNode.SymbolicExpressionTreeNode; 198 if (clonedNode Map.ContainsKey(selectedNode)) {199 var selected = clonedNodeMap[selectedNode];200 var parent = selected .Parent;201 parent.RemoveSubtree(parent.IndexOfSubtree(selected ));202 selectedNode.ForEachNodePostfix(node =>{157 if (clonedNodes.ContainsKey(selectedNode)) { 158 var selectedClone = clonedNodes[selectedNode]; 159 var parent = selectedClone.Parent; 160 parent.RemoveSubtree(parent.IndexOfSubtree(selectedClone)); 161 foreach (var node in selectedNode.IterateNodesPrefix()) { 203 162 symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node).FillColor = Color.Transparent; 204 clonedNodeMap.Remove(node); 205 }); 163 } 206 164 } 207 }208 break;209 }210 // update visual graph nodes that contain matching trees211 Color[] colors = { Color.LightSkyBlue, Color.PaleGreen, Color.Tan };212 genealogyGraphChart.ClearAllNodes(); // clear node colors213 // color each graph node according to the degree to which it matches the selected tree fragment214 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 165 break; 221 166 } 222 }223 167 } 168 if (selectedVisualSymbExprTreeNode == null || clonedNodes == null) return; 169 // update visual graph nodes that contain matching trees 170 MatchNodesAndRepaint(); 171 // refresh the tree chart 172 symbolicExpressionTreeChart.Repaint(); 173 } 174 175 void MatchNodesAndRepaint() { 176 genealogyGraphChart.Chart.UpdateEnabled = false; 177 genealogyGraphChart.ClearAllNodes(); // clear node colors 178 var fragment = new Fragment(clonedNodes[selectedVisualSymbExprTreeNode.SymbolicExpressionTreeNode]); 179 var fragmentLength = fragment.Length; 180 genealogyGraphChart.HighlightNodes(from node in genealogyGraphChart.Graph.Nodes 181 let tree = node.SymbolicExpressionTree 182 where tree.Length >= fragmentLength 183 where tree.Root.ContainsFragment(fragment, comparer) 184 select tree, Color.DodgerBlue); 224 185 genealogyGraphChart.Chart.UpdateEnabled = true; 225 186 genealogyGraphChart.Chart.EnforceUpdate(); 226 // refresh the tree chart227 symbolicExpressionTreeChart.Repaint();228 187 } 229 188 230 189 private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) { 231 190 } 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 nodes241 genealogyGraphChart.HighlightNodes(owners, Color.LightSkyBlue);242 // highlight matching individuals from the genealogy243 genealogyGraphChart.Chart.UpdateEnabled = true;244 }245 genealogyGraphChart.Chart.EnforceUpdate();246 // highlight subtree nodes in the tree chart247 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 191 #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(); 192 private void matchConstantsCheckBox_CheckedChanged(object sender, EventArgs e) { 193 comparer.MatchConstantValues = matchConstantsCheckBox.Checked; 194 if (selectedVisualSymbExprTreeNode != null) 195 MatchNodesAndRepaint(); 196 } 197 198 private void matchVariableWeightsCheckBox_CheckedChanged(object sender, EventArgs e) { 199 comparer.MatchVariableWeights = matchVariableWeightsCheckBox.Checked; 200 if (selectedVisualSymbExprTreeNode != null) 201 MatchNodesAndRepaint(); 202 } 203 204 private void matchVariableNamesCheckBox_CheckedChanged(object sender, EventArgs e) { 205 comparer.MatchVariableNames = matchVariableNamesCheckBox.Checked; 206 if (selectedVisualSymbExprTreeNode != null) 207 MatchNodesAndRepaint(); 264 208 } 265 209 } -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphArc.cs
r8213 r9084 49 49 50 50 internal void UpdatePosition() { 51 if (Source.Equals(Target)) return; 51 52 // calculate the positions of the arc ends so that virtually the line will go through the centers of the two elliptical node shapes 52 53 PointD c1 = Source.Center; … … 74 75 p2Y = c2.Y - p1.Y; 75 76 } 77 if (double.IsNaN(p1X) || double.IsNaN(p1Y) || double.IsNaN(p2X) || double.IsNaN(p2Y)) 78 throw new Exception("Error calculating arc position."); 76 79 p1.X = p1X; 77 80 p1.Y = p1Y; -
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.EvolutionaryTracking.Views/3.4/VisualGenealogyGraphNode.cs
r8556 r9084 27 27 namespace HeuristicLab.EvolutionaryTracking.Views { 28 28 public class VisualGenealogyGraphNode : Ellipse { 29 public IGenealogyGraphNode Data { get; internal set; }30 private List<VisualGenealogyGraphArc> _incomingArcs = new List<VisualGenealogyGraphArc>();31 private List<VisualGenealogyGraphArc> _outgoingArgs = new List<VisualGenealogyGraphArc>();29 public SymbolicExpressionGenealogyGraphNode Data { get; internal set; } 30 private List<VisualGenealogyGraphArc> incomingArcs = new List<VisualGenealogyGraphArc>(); 31 private List<VisualGenealogyGraphArc> outgoingArcs = new List<VisualGenealogyGraphArc>(); 32 32 33 33 public List<VisualGenealogyGraphArc> IncomingArcs { 34 get { return _incomingArcs; }35 set { _incomingArcs = value; }34 get { return incomingArcs; } 35 set { incomingArcs = value; } 36 36 } 37 37 public List<VisualGenealogyGraphArc> OutgoingArcs { 38 get { return _outgoingArgs; }39 set { _outgoingArgs = value; }38 get { return outgoingArcs; } 39 set { outgoingArcs = value; } 40 40 } 41 41 … … 81 81 graphics.FillEllipse(Brush, p.X, p.Y, s.Width, s.Height); 82 82 graphics.DrawEllipse(Pen, p.X, p.Y, s.Width, s.Height); 83 if ( ((SymbolicExpressionGenealogyGraphNode)Data).IsElite) {83 if (Data.IsElite) { 84 84 graphics.DrawEllipse(Pen, p.X + 2, p.Y + 2, s.Width - 4, s.Height - 4); 85 85 }
Note: See TracChangeset
for help on using the changeset viewer.