Changeset 11009 for branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4
- Timestamp:
- 06/12/14 13:26:18 (10 years ago)
- Location:
- branches/DataPreprocessing
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/DataPreprocessing
- Property svn:ignore
-
old new 8 8 FxCopResults.txt 9 9 Google.ProtocolBuffers-0.9.1.dll 10 Google.ProtocolBuffers-2.4.1.473.dll 10 11 HeuristicLab 3.3.5.1.ReSharper.user 11 12 HeuristicLab 3.3.6.0.ReSharper.user 12 13 HeuristicLab.4.5.resharper.user 13 14 HeuristicLab.ExtLibs.6.0.ReSharper.user 15 HeuristicLab.Scripting.Development 14 16 HeuristicLab.resharper.user 15 17 ProtoGen.exe … … 17 19 _ReSharper.HeuristicLab 18 20 _ReSharper.HeuristicLab 3.3 21 _ReSharper.HeuristicLab 3.3 Tests 19 22 _ReSharper.HeuristicLab.ExtLibs 20 23 bin 21 24 protoc.exe 22 _ReSharper.HeuristicLab 3.3 Tests23 Google.ProtocolBuffers-2.4.1.473.dll
-
- Property svn:mergeinfo changed
- Property svn:ignore
-
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views
- Property svn:mergeinfo changed
/trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views merged: 10561,10565,10793,10799-10800,10862,10885,10953
- Property svn:mergeinfo changed
-
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/Formatters/SymbolicExpressionTreeLatexFormatter.cs
r10520 r11009 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Drawing; 24 25 using System.Globalization; 25 26 using System.Linq; … … 36 37 {"StartSymbol","RPB"} 37 38 }; 38 private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(); 39 40 private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> layoutEngine; 39 41 40 42 public SymbolicExpressionTreeLatexFormatter() 41 43 : base("LaTeX/PDF Formatter", "Formatter for symbolic expression trees for use with latex package tikz.") { 42 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> {44 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) { 43 45 HorizontalSpacing = 2, 44 46 VerticalSpacing = 2, … … 57 59 58 60 public string Format(ISymbolicExpressionTree symbolicExpressionTree) { 59 layoutEngine.Reset();60 61 var root = symbolicExpressionTree.Root; 61 62 var actualRoot = root.SubtreeCount == 0 ? root.GetSubtree(0) : root; 62 layoutEngine.Initialize(actualRoot, x => x.Subtrees); 63 layoutEngine.CalculateLayout(); 64 var nodeCoordinates = layoutEngine.GetCoordinates(); 63 var nodeCoordinates = layoutEngine.CalculateLayout(actualRoot).ToDictionary(n => n.Content, n => new PointF(n.X, n.Y)); 65 64 var sb = new StringBuilder(); 66 65 var nl = Environment.NewLine; -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj
r10538 r11009 272 272 </BootstrapperPackage> 273 273 </ItemGroup> 274 <ItemGroup />275 274 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 276 275 <!-- To modify your build process, add your task inside one of the targets below and uncomment it. -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/LayoutEngines/BoxesLayoutEngine.cs
r10520 r11009 1 1 #region License Information 2 3 /* HeuristicLab 4 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 5 * 6 * This file is part of HeuristicLab. 7 * 8 * HeuristicLab is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * HeuristicLab is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #endregion 23 2 24 using System; 3 25 using System.Collections.Generic; 4 using System.Drawing;5 26 using System.Linq; 6 27 7 28 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views { 8 29 public class BoxesLayoutEngine<T> : ILayoutEngine<T> where T : class { 9 private readonly Dictionary<T, VisualTreeNode<T>> nodeMap;10 11 30 public int NodeWidth { get; set; } 12 31 public int NodeHeight { get; set; } 13 32 public int HorizontalSpacing { get; set; } 14 33 public int VerticalSpacing { get; set; } 15 private VisualTreeNode<T> layoutRoot;16 34 17 public int Width { get; private set; } 18 public int Height { get; private set; } 35 private readonly Func<T, IEnumerable<T>> GetChildren; 36 private readonly Func<T, int> GetLength; 37 private readonly Func<T, int> GetDepth; 19 38 20 public Func<T, IEnumerable<T>> GetChildren { get; set; } 21 public Func<T, int> GetLength { get; set; } 22 public Func<T, int> GetDepth { get; set; } 39 public BoxesLayoutEngine(Func<T, IEnumerable<T>> GetChildren, Func<T, int> GetLength, Func<T, int> GetDepth) { 40 if (GetChildren == null) throw new ArgumentNullException("GetChildren"); 41 if (GetLength == null) throw new ArgumentNullException("GetLength"); 42 if (GetDepth == null) throw new ArgumentNullException("GetDepth"); 23 43 24 public BoxesLayoutEngine() { 25 nodeMap = new Dictionary<T, VisualTreeNode<T>>(); 44 this.GetChildren = GetChildren; 45 this.GetLength = GetLength; 46 this.GetDepth = GetDepth; 26 47 } 27 48 28 public void CalculateLayout() { 29 throw new Exception("The BoxesLayoutEngine does not support arbitrary bounds. Please use method CalculateLayout(Width, Height)"); 49 50 public IEnumerable<VisualTreeNode<T>> CalculateLayout(T root, float width, float height) { 51 var nodeMap = new Dictionary<T, VisualTreeNode<T>>(); 52 CreateVisualNodes(root, nodeMap); 53 RecursiveLayout(nodeMap, nodeMap[root], 0, 0, (int)Math.Round(width), (int)Math.Round(height) / GetDepth(root)); 54 return nodeMap.Values; 30 55 } 31 56 32 public void CalculateLayout(float width, float height) { 33 Width = (int)Math.Round(width); 34 Height = (int)Math.Round(height); 35 Reset(); 36 RecursiveLayout(layoutRoot, 0, 0, Width, Height / GetDepth(layoutRoot.Content)); 37 } 38 39 public void Initialize(T root, Func<T, IEnumerable<T>> getChildren, Func<T, int> getLength, Func<T, int> getDepth) { 40 if (getChildren == null || getLength == null || getDepth == null) 41 throw new ArgumentNullException("The BoxesLayoutEngine requires all of the lambdas: (getChildren, getLength and getDepth) to be defined."); 42 GetChildren = getChildren; 43 GetLength = getLength; 44 GetDepth = getDepth; 45 Clear(); 46 Expand(root); // produce the nodeMap 47 layoutRoot = nodeMap[root]; 48 } 49 50 private void Expand(T root) { 57 private void CreateVisualNodes(T root, Dictionary<T, VisualTreeNode<T>> map) { 51 58 var node = new VisualTreeNode<T>(root) { 52 59 PreferredWidth = NodeWidth, 53 60 PreferredHeight = NodeHeight 54 61 }; 55 nodeMap.Add(root, node); 62 63 map.Add(root, node); 56 64 var children = GetChildren(root).ToList(); 57 65 if (children.Any()) { 58 66 foreach (var child in children) { 59 Expand(child);67 CreateVisualNodes(child, map); 60 68 } 61 69 } 62 70 } 63 71 64 public void Center(float width, float height) { 65 // does nothing because the BoxesLayout centers the tree by default 66 } 67 68 public void Clear() { 69 nodeMap.Clear(); 70 layoutRoot = null; 71 } 72 73 public void Reset() { 74 foreach (var node in nodeMap.Values) { 75 node.X = 0; 76 node.Y = 0; 77 } 78 } 79 80 public Dictionary<T, PointF> GetCoordinates() { 81 return nodeMap.ToDictionary(x => x.Key, x => new PointF(x.Value.X, x.Value.Y)); 82 } 83 84 public void FitToBounds(float width, float height) { 85 // does nothing because the BoxesLayout is by default stretched on the whole drawing area 86 } 87 88 private void RecursiveLayout(VisualTreeNode<T> visualTreeNode, int x, int y, int width, int height) { 72 private void RecursiveLayout(Dictionary<T, VisualTreeNode<T>> nodeMap, VisualTreeNode<T> visualTreeNode, int x, int y, int width, int height) { 89 73 float center_x = x + width / 2; 90 74 float center_y = y + height / 2; 91 int actualWidth = width - VerticalSpacing;75 int actualWidth = width - HorizontalSpacing; 92 76 int actualHeight = height - VerticalSpacing; 93 77 … … 127 111 for (int i = 0; i < children.Count; i++) { 128 112 xBoundaries[i + 1] = (int)(xBoundaries[i] + (width * (double)GetLength(children[i])) / (GetLength(node) - 1)); 129 RecursiveLayout(nodeMap [children[i]], xBoundaries[i], y + height, xBoundaries[i + 1] - xBoundaries[i], height);113 RecursiveLayout(nodeMap, nodeMap[children[i]], xBoundaries[i], y + height, xBoundaries[i + 1] - xBoundaries[i], height); 130 114 } 131 }132 133 public IEnumerable<VisualTreeNode<T>> GetVisualNodes() {134 return nodeMap.Values;135 115 } 136 116 } -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/LayoutEngines/ILayoutEngine.cs
r10520 r11009 1 2 using System; 1 #region License Information 2 3 /* HeuristicLab 4 * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 5 * 6 * This file is part of HeuristicLab. 7 * 8 * HeuristicLab is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * HeuristicLab is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #endregion 23 3 24 using System.Collections.Generic; 4 using System.Drawing;5 25 6 26 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views { … … 11 31 int VerticalSpacing { get; set; } 12 32 13 void CalculateLayout(); 14 void CalculateLayout(float width, float height); 15 void Initialize(T root, Func<T, IEnumerable<T>> getChildren, Func<T, int> getLength = null, Func<T, int> getDepth = null); 16 void Clear(); 17 void Reset(); 18 19 // function members necessary to navigate the tree structure 20 Func<T, IEnumerable<T>> GetChildren { get; set; } 21 Func<T, int> GetLength { get; set; } 22 Func<T, int> GetDepth { get; set; } 23 24 IEnumerable<VisualTreeNode<T>> GetVisualNodes(); 25 Dictionary<T, PointF> GetCoordinates(); 33 IEnumerable<VisualTreeNode<T>> CalculateLayout(T root, float width, float height); 26 34 } 27 35 } -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/LayoutEngines/LayoutNode.cs
r10520 r11009 25 25 26 26 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views { 27 publicclass LayoutNode<T> : object where T : class {27 internal class LayoutNode<T> : object where T : class { 28 28 public float Width { get; set; } 29 29 public float Height { get; set; } -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/LayoutEngines/ReingoldTilfordLayoutEngine.cs
r10531 r11009 7 7 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views { 8 8 public class ReingoldTilfordLayoutEngine<T> : ILayoutEngine<T> where T : class { 9 private readonly Dictionary<T, LayoutNode<T>> nodeMap; // provides a reverse mapping T => LayoutNode10 9 public int NodeWidth { get; set; } 11 10 public int NodeHeight { get; set; } … … 22 21 } 23 22 24 public Func<T, IEnumerable<T>> GetChildren { get; set; } 25 public Func<T, int> GetLength { get; set; } 26 public Func<T, int> GetDepth { get; set; } 27 private LayoutNode<T> layoutRoot; 28 29 public ReingoldTilfordLayoutEngine() { 30 nodeMap = new Dictionary<T, LayoutNode<T>>(); 31 } 32 33 public ReingoldTilfordLayoutEngine(T root, Func<T, IEnumerable<T>> childrenFunc) 34 : this() { 35 Initialize(root, childrenFunc); 36 } 37 38 public void Initialize(T root, Func<T, IEnumerable<T>> getChildren, Func<T, int> getLength = null, Func<T, int> getDepth = null) { 39 GetChildren = getChildren; 40 Clear(); 41 var node = new LayoutNode<T> { Content = root, Width = NodeWidth, Height = NodeHeight }; 42 node.Ancestor = node; 43 layoutRoot = node; 44 Expand(node); 45 } 46 47 private void Expand(LayoutNode<T> lRoot) { 48 nodeMap.Add(lRoot.Content, lRoot); 23 private readonly Func<T, IEnumerable<T>> GetChildren; 24 25 public ReingoldTilfordLayoutEngine(Func<T, IEnumerable<T>> GetChildren) { 26 this.GetChildren = GetChildren; 27 } 28 29 public IEnumerable<VisualTreeNode<T>> CalculateLayout(T root) { 30 return CalculateLayout(root, 0, 0); 31 } 32 33 public IEnumerable<VisualTreeNode<T>> CalculateLayout(T root, float width, float height) { 34 Dictionary<T, LayoutNode<T>> layoutNodeMap = new Dictionary<T, LayoutNode<T>>(); 35 var layoutRoot = new LayoutNode<T> { Content = root, Width = NodeWidth, Height = NodeHeight, }; 36 layoutRoot.Ancestor = layoutRoot; 37 Expand(layoutRoot, layoutNodeMap); 38 39 FirstWalk(layoutRoot); 40 SecondWalk(layoutRoot, -layoutRoot.Prelim); 41 NormalizeCoordinates(layoutNodeMap.Values); 42 if (height != 0 && width != 0) { 43 FitToBounds(width, height, layoutNodeMap.Values); 44 Center(width, height, layoutNodeMap.Values); 45 } 46 47 return layoutNodeMap.Values.Select(x => new VisualTreeNode<T>(x.Content) { 48 Width = (int)Math.Round(x.Width), 49 Height = (int)Math.Round(x.Height), 50 X = (int)Math.Round(x.X), 51 Y = (int)Math.Round(x.Y) 52 }); 53 } 54 55 private void Expand(LayoutNode<T> lRoot, Dictionary<T, LayoutNode<T>> map) { 56 map.Add(lRoot.Content, lRoot); 49 57 var children = GetChildren(lRoot.Content).ToList(); 50 58 if (!children.Any()) return; … … 61 69 node.Ancestor = node; 62 70 lRoot.Children.Add(node); 63 Expand(node); 64 } 65 } 66 67 public IEnumerable<VisualTreeNode<T>> GetVisualNodes() { 68 return nodeMap.Values.Select(x => new VisualTreeNode<T>(x.Content) { 69 Width = (int)Math.Round(x.Width), 70 Height = (int)Math.Round(x.Height), 71 X = (int)Math.Round(x.X), 72 Y = (int)Math.Round(x.Y) 73 }); 74 } 75 76 public IEnumerable<LayoutNode<T>> GetLayoutNodes() { 77 return nodeMap.Values; 78 } 79 80 public void AddNode(T content) { 81 if (nodeMap.ContainsKey(content)) { throw new ArgumentException("Content already present in the dictionary."); } 82 var node = new LayoutNode<T> { Content = content }; 83 nodeMap.Add(content, node); 84 } 85 86 public void AddNode(LayoutNode<T> node) { 87 var content = node.Content; 88 if (nodeMap.ContainsKey(content)) { throw new ArgumentException("Content already present in the dictionary."); } 89 nodeMap.Add(content, node); 90 } 91 92 public void AddNodes(IEnumerable<LayoutNode<T>> nodes) { 93 foreach (var node in nodes) 94 nodeMap.Add(node.Content, node); 95 } 96 97 public LayoutNode<T> GetNode(T content) { 98 LayoutNode<T> layoutNode; 99 nodeMap.TryGetValue(content, out layoutNode); 100 return layoutNode; 101 } 102 103 public void ResetCoordinates() { 104 foreach (var node in nodeMap.Values) { 105 node.ResetCoordinates(); 106 } 107 } 108 109 public Dictionary<T, PointF> GetCoordinates() { 110 return nodeMap.ToDictionary(x => x.Key, x => new PointF(x.Value.X, x.Value.Y)); 111 } 71 Expand(node, map); 72 } 73 } 74 112 75 113 76 /// <summary> 114 77 /// Transform LayoutNode coordinates so that all coordinates are positive and start from (0,0) 115 78 /// </summary> 116 private void NormalizeCoordinates() { 117 var nodes = nodeMap.Values.ToList(); 79 private static void NormalizeCoordinates(IEnumerable<LayoutNode<T>> nodes) { 118 80 float xmin = 0, ymin = 0; 119 81 foreach (var node in nodes) { … … 127 89 } 128 90 129 p ublic void Center(float width, float height) {91 private void Center(float width, float height, IEnumerable<LayoutNode<T>> nodes) { 130 92 // center layout on screen 131 var bounds = Bounds( );93 var bounds = Bounds(nodes); 132 94 float dx = 0, dy = 0; 133 95 if (width > bounds.Width) { dx = (width - bounds.Width) / 2f; } 134 96 if (height > bounds.Height) { dy = (height - bounds.Height) / 2f; } 135 foreach (var node in node Map.Values) { node.Translate(dx, dy); }136 } 137 138 p ublic void FitToBounds(float width, float height) {139 var bounds = Bounds( );97 foreach (var node in nodes) { node.Translate(dx, dy); } 98 } 99 100 private void FitToBounds(float width, float height, IEnumerable<LayoutNode<T>> nodes) { 101 var bounds = Bounds(nodes); 140 102 var myWidth = bounds.Width; 141 103 var myHeight = bounds.Height; … … 143 105 if (myWidth <= width && myHeight <= height) return; // no need to fit since we are within bounds 144 106 145 var layers = node Map.Values.GroupBy(node => node.Level, node => node).ToList();107 var layers = nodes.GroupBy(node => node.Level, node => node).ToList(); 146 108 147 109 if (myWidth > width) { … … 154 116 float spacing = minHorizontalSpacing * x; 155 117 foreach (var layer in layers) { 156 var nodes = layer.ToList();118 var nodesLayer = layer.ToList(); 157 119 float minWidth = float.MaxValue; 158 for (int i = 0; i < nodes .Count - 1; ++i) { minWidth = Math.Min(minWidth, nodes[i + 1].X - nodes[i].X); }120 for (int i = 0; i < nodesLayer.Count - 1; ++i) { minWidth = Math.Min(minWidth, nodesLayer[i + 1].X - nodesLayer[i].X); } 159 121 float w = Math.Min(NodeWidth, minWidth - spacing); 160 foreach (var node in nodes ) {122 foreach (var node in nodesLayer) { 161 123 node.X += (node.Width - w) / 2f; 162 124 node.Width = w; … … 182 144 } 183 145 184 public void Clear() {185 layoutRoot = null;186 nodeMap.Clear();187 }188 189 public void Reset() {190 foreach (var layoutNode in nodeMap.Values) {191 // reset layout-related parameters192 layoutNode.Reset();193 }194 }195 196 public void CalculateLayout() {197 if (layoutRoot == null) throw new Exception("Layout layoutRoot cannot be null.");198 Reset(); // reset node parameters like Mod, Shift etc. and set coordinates to 0199 FirstWalk(layoutRoot);200 SecondWalk(layoutRoot, -layoutRoot.Prelim);201 NormalizeCoordinates();202 }203 204 public void CalculateLayout(float width, float height) {205 CalculateLayout();206 FitToBounds(width, height);207 Center(width, height);208 }209 146 210 147 /// <summary> … … 212 149 /// </summary> 213 150 /// <returns></returns> 214 p ublic RectangleF Bounds() {151 private RectangleF Bounds(IEnumerable<LayoutNode<T>> nodes) { 215 152 float xmin = 0, xmax = 0, ymin = 0, ymax = 0; 216 var list = nodeMap.Values.ToList(); 217 foreach (LayoutNode<T> node in list) { 153 foreach (LayoutNode<T> node in nodes) { 218 154 float x = node.X, y = node.Y; 219 155 if (xmin > x) xmin = x; -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.cs
r10538 r11009 105 105 106 106 var tree = new SymbolicExpressionTree(new SymbolicExpressionTreeNode(Symbol)); 107 symbolicExpressionTreeChart.SuspendRepaint = true;108 107 if (Grammar.GetMaximumSubtreeCount(Symbol) > 0) { 109 108 for (int i = 0; i < Grammar.GetMaximumSubtreeCount(Symbol); i++) { … … 118 117 } 119 118 symbolicExpressionTreeChart.Tree = tree; 120 119 symbolicExpressionTreeChart.SuspendRepaint = true; 121 120 foreach (var subtreeNode in tree.Root.Subtrees) { 122 121 foreach (var allowedChildNode in subtreeNode.Subtrees) { … … 144 143 } 145 144 } 146 147 145 symbolicExpressionTreeChart.SuspendRepaint = false; 148 146 UpdateSelectedSymbolicExpressionTreeNodes(); … … 155 153 else visualNode.FillColor = Color.LightSteelBlue; 156 154 } 157 symbolicExpressionTreeChart.Repaint ();155 symbolicExpressionTreeChart.RepaintNodes(); 158 156 } 159 157 -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarSampleExpressionTreeView.cs
r9456 r11009 42 42 treeCreatorComboBox.Items.Add(treeCreator); 43 43 } 44 treeCreatorComboBox.SelectedI ndex = 0;44 treeCreatorComboBox.SelectedItem = treeCreatorComboBox.Items.OfType<ProbabilisticTreeCreator>().First(); 45 45 } 46 46 -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs
r10538 r11009 27 27 using System.Linq; 28 28 using System.Windows.Forms; 29 using Point = System.Drawing.Point; 29 30 30 31 31 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views { … … 39 39 private const int preferredNodeWidth = 70; 40 40 private const int preferredNodeHeight = 46; 41 private constint minHorizontalDistance = 30;42 private constint minVerticalDistance = 30;41 private int minHorizontalDistance = 30; 42 private int minVerticalDistance = 30; 43 43 44 44 public SymbolicExpressionTreeChart() { … … 50 50 this.backgroundColor = Color.White; 51 51 this.textFont = new Font(FontFamily.GenericSansSerif, 12); 52 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> { 52 53 visualTreeNodes = new Dictionary<ISymbolicExpressionTreeNode, VisualTreeNode<ISymbolicExpressionTreeNode>>(); 54 visualLines = new Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualTreeNodeConnection>(); 55 56 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) { 53 57 NodeWidth = preferredNodeWidth, 54 58 NodeHeight = preferredNodeHeight, … … 56 60 VerticalSpacing = minVerticalDistance 57 61 }; 62 reingoldTilfordToolStripMenuItem.Checked = true; 58 63 } 59 64 … … 105 110 set { 106 111 tree = value; 107 if (tree != null) { 108 //the layout engine needs to be initialized here so that the visualNodes and the visualLines dictionaries are populated 109 InitializeLayout(); 110 Repaint(); 111 } 112 Repaint(); 112 113 } 113 114 } … … 128 129 if (this.Width <= 1 || this.Height <= 1) 129 130 this.image = new Bitmap(1, 1); 130 else 131 else { 131 132 this.image = new Bitmap(Width, Height); 133 } 132 134 this.Repaint(); 135 } 136 137 public event EventHandler Repainted;//expose this event to notify the parent control that the tree was repainted 138 protected virtual void OnRepaint(object sender, EventArgs e) { 139 var repainted = Repainted; 140 if (repainted != null) { 141 repainted(sender, e); 142 } 133 143 } 134 144 … … 137 147 this.GenerateImage(); 138 148 this.Refresh(); 149 OnRepaint(this, EventArgs.Empty); 139 150 } 140 151 } … … 147 158 foreach (var visualNode in visualTreeNodes.Values) { 148 159 DrawTreeNode(graphics, visualNode); 160 if (visualNode.Content.SubtreeCount > 0) { 161 foreach (var visualSubtree in visualNode.Content.Subtrees.Select(s => visualTreeNodes[s])) { 162 DrawLine(graphics, visualNode, visualSubtree); 163 } 164 } 149 165 } 150 166 } … … 170 186 graphics.Clear(backgroundColor); 171 187 if (tree != null) { 172 DrawFunctionTree( tree,graphics, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);188 DrawFunctionTree(graphics, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance); 173 189 } 174 190 } … … 236 252 237 253 private void SymbolicExpressionTreeChart_MouseMove(object sender, MouseEventArgs e) { 238 239 254 VisualTreeNode<ISymbolicExpressionTreeNode> visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y); 240 255 if (draggedSymbolicExpressionTree != null && … … 262 277 #endregion 263 278 264 private void InitializeLayout() { 265 var actualRoot = tree.Root.SubtreeCount == 1 ? tree.Root.GetSubtree(0) : tree.Root; 266 layoutEngine.Initialize(actualRoot, n => n.Subtrees, n => n.GetLength(), n => n.GetDepth()); 267 layoutEngine.CalculateLayout(this.Width, this.Height); 268 var visualNodes = layoutEngine.GetVisualNodes().ToList(); 269 //populate the visual nodes and visual connections dictionaries 279 private void CalculateLayout(int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) { 280 layoutEngine.NodeWidth = preferredWidth; 281 layoutEngine.NodeHeight = preferredHeight; 282 layoutEngine.HorizontalSpacing = minHDistance; 283 layoutEngine.VerticalSpacing = minVDistance; 284 285 var actualRoot = tree.Root; 286 if (actualRoot.Symbol is ProgramRootSymbol && actualRoot.SubtreeCount == 1) { 287 actualRoot = tree.Root.GetSubtree(0); 288 } 289 290 var visualNodes = layoutEngine.CalculateLayout(actualRoot, Width, Height).ToList(); 270 291 visualTreeNodes = visualNodes.ToDictionary(x => x.Content, x => x); 271 292 visualLines = new Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualTreeNodeConnection>(); … … 278 299 279 300 #region methods for painting the symbolic expression tree 280 private void DrawFunctionTree(ISymbolicExpressionTree symbExprTree, Graphics graphics, int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) { 281 //we assume here that the layout has already been initialized when the symbolic expression tree was changed 282 //recalculate layout according to new node widths and spacing 283 layoutEngine.NodeWidth = preferredWidth; 284 layoutEngine.NodeHeight = preferredHeight; 285 layoutEngine.HorizontalSpacing = minHDistance; 286 layoutEngine.VerticalSpacing = minVDistance; 287 layoutEngine.CalculateLayout(Width, Height); 301 private void DrawFunctionTree(Graphics graphics, int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) { 302 CalculateLayout(preferredWidth, preferredHeight, minHDistance, minVDistance); 288 303 var visualNodes = visualTreeNodes.Values; 289 304 //draw nodes and connections 290 305 foreach (var visualNode in visualNodes) { 291 DrawTreeNode( visualNode);306 DrawTreeNode(graphics, visualNode); 292 307 var node = visualNode.Content; 293 308 foreach (var subtree in node.Subtrees) { … … 302 317 } 303 318 } 304 }305 }306 307 protected void DrawTreeNode(VisualTreeNode<ISymbolicExpressionTreeNode> visualTreeNode) {308 using (var graphics = Graphics.FromImage(image)) {309 graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;310 graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;311 DrawTreeNode(graphics, visualTreeNode);312 319 } 313 320 } … … 333 340 } 334 341 } 342 343 protected void DrawLine(Graphics graphics, VisualTreeNode<ISymbolicExpressionTreeNode> startNode, VisualTreeNode<ISymbolicExpressionTreeNode> endNode) { 344 var origin = new Point(startNode.X + startNode.Width / 2, startNode.Y + startNode.Height); 345 var target = new Point(endNode.X + endNode.Width / 2, endNode.Y); 346 graphics.Clip = new Region(new Rectangle(Math.Min(origin.X, target.X), origin.Y, Math.Max(origin.X, target.X), target.Y)); 347 var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(startNode.Content, endNode.Content); 348 using (var linePen = new Pen(visualLine.LineColor)) { 349 linePen.DashStyle = visualLine.DashStyle; 350 graphics.DrawLine(linePen, origin, target); 351 } 352 } 335 353 #endregion 336 354 #region save image … … 348 366 Image image = new Bitmap(Width, Height); 349 367 using (Graphics g = Graphics.FromImage(image)) { 350 DrawFunctionTree( tree,g, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);368 DrawFunctionTree(g, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance); 351 369 } 352 370 image.Save(filename); … … 358 376 using (Metafile file = new Metafile(filename, g.GetHdc())) { 359 377 using (Graphics emfFile = Graphics.FromImage(file)) { 360 DrawFunctionTree( tree,emfFile, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);378 DrawFunctionTree(emfFile, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance); 361 379 } 362 380 } … … 377 395 378 396 private void reingoldTilfordToolStripMenuItem_Click(object sender, EventArgs e) { 379 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> { 397 minHorizontalDistance = 30; 398 minVerticalDistance = 30; 399 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees) { 380 400 NodeWidth = preferredNodeWidth, 381 401 NodeHeight = preferredNodeHeight, … … 383 403 VerticalSpacing = minVerticalDistance 384 404 }; 385 InitializeLayout(); 405 reingoldTilfordToolStripMenuItem.Checked = true; 406 boxesToolStripMenuItem.Checked = false; 386 407 Repaint(); 387 408 } 388 409 389 410 private void boxesToolStripMenuItem_Click(object sender, EventArgs e) { 390 layoutEngine = new BoxesLayoutEngine<ISymbolicExpressionTreeNode> { 411 minHorizontalDistance = 5; 412 minVerticalDistance = 5; 413 layoutEngine = new BoxesLayoutEngine<ISymbolicExpressionTreeNode>(n => n.Subtrees, n => n.GetLength(), n => n.GetDepth()) { 391 414 NodeWidth = preferredNodeWidth, 392 415 NodeHeight = preferredNodeHeight, … … 394 417 VerticalSpacing = minVerticalDistance 395 418 }; 396 InitializeLayout(); 419 reingoldTilfordToolStripMenuItem.Checked = false; 420 boxesToolStripMenuItem.Checked = true; 397 421 Repaint(); 398 422 } -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionView.Designer.cs
r9456 r11009 52 52 // textBox 53 53 // 54 this.textBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 55 | System.Windows.Forms.AnchorStyles.Left)56 54 this.textBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 55 | System.Windows.Forms.AnchorStyles.Left) 56 | System.Windows.Forms.AnchorStyles.Right))); 57 57 this.textBox.BackColor = System.Drawing.Color.White; 58 this.textBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 58 59 this.textBox.Location = new System.Drawing.Point(3, 30); 59 60 this.textBox.Multiline = true; … … 66 67 // formattersComboBox 67 68 // 68 this.formattersComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 69 69 this.formattersComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 70 | System.Windows.Forms.AnchorStyles.Right))); 70 71 this.formattersComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 71 72 this.formattersComboBox.FormattingEnabled = true; -
branches/DataPreprocessing/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionView.cs
r9821 r11009 78 78 UpdateTextbox(); 79 79 } 80 80 81 } 81 82 }
Note: See TracChangeset
for help on using the changeset viewer.