Changeset 9996 for branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4
- Timestamp:
- 09/20/13 10:10:41 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs
r9963 r9996 35 35 private Dictionary<ISymbolicExpressionTreeNode, VisualSymbolicExpressionTreeNode> visualTreeNodes; 36 36 private Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualSymbolicExpressionTreeNodeConnection> visualLines; 37 private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> { MinHorizontalSpacing = 5, MinVerticalSpacing = 5 }; 38 private readonly SymbolicExpressionTreeLayoutAdapter layoutAdapter = new SymbolicExpressionTreeLayoutAdapter(); 37 private readonly ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode> layoutEngine; 38 private readonly SymbolicExpressionTreeLayoutAdapter layoutAdapter; 39 40 private const int preferredNodeWidth = 70; 41 private const int preferredNodeHeight = 46; 42 private const int minHorizontalDistance = 20; 43 private const int minVerticalDistance = 20; 39 44 40 45 … … 46 51 this.lineColor = Color.Black; 47 52 this.backgroundColor = Color.White; 48 this.textFont = new Font("Times New Roman", 8); 53 this.textFont = new Font("Times New Roman", 12); 54 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(); 55 layoutAdapter = new SymbolicExpressionTreeLayoutAdapter(); 49 56 } 50 57 51 58 public SymbolicExpressionTreeChart(ISymbolicExpressionTree tree) 52 59 : this() { 60 layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>(); 61 layoutAdapter = new SymbolicExpressionTreeLayoutAdapter(); 53 62 this.Tree = tree; 54 63 } … … 165 174 graphics.Clear(backgroundColor); 166 175 if (tree != null) { 167 DrawFunctionTree(tree, graphics, 70, 46, 20, 50);176 DrawFunctionTree(tree, graphics, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance); 168 177 } 169 178 } … … 258 267 #region methods for painting the symbolic expression tree 259 268 260 private void DrawFunctionTree(ISymbolicExpressionTree tree, Graphics graphics, int preferredWidth, int preferredHeight, int min Distance, int maxDistance) {269 private void DrawFunctionTree(ISymbolicExpressionTree tree, Graphics graphics, int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) { 261 270 var layoutNodes = layoutAdapter.Convert(tree).ToList(); 262 271 layoutEngine.Reset(); … … 264 273 foreach (var ln in layoutNodes) 265 274 layoutEngine.AddNode(ln.Content, ln); 275 layoutEngine.MinHorizontalSpacing = (preferredNodeWidth + minHDistance); 276 layoutEngine.MinVerticalSpacing = (preferredNodeHeight + minVDistance); 266 277 layoutEngine.CalculateLayout(); 267 var nodePositions = layoutEngine.GetNodeCoordinates();268 278 var bounds = layoutEngine.Bounds(); 269 270 double sx = Width / bounds.Width; 271 double sy = Height / bounds.Height; 272 273 double dx = layoutEngine.MinHorizontalSpacing * sx; // scaled horizontal distance 274 double dy = layoutEngine.MinVerticalSpacing * sy; // scaled vertical distance 275 276 int maxWidth = (int)Math.Round(dx); 277 int maxHeight = (int)Math.Round(dy); 278 279 // instead of using the preferred with/height of each node inside the foreach loop below, 280 // we assume the same width/height for all nodes 281 int w = Math.Min(preferredWidth, maxWidth - minDistance / 2); 282 int h = Math.Min(preferredHeight, maxHeight - minDistance / 2); 283 // adjust scaling factor so that nodes will be at most maxDistance far from each other on the horizontal axis 284 double offset = 0; 285 if (maxDistance + w < maxWidth) { 286 sx *= (double)(maxDistance + w) / maxWidth; 287 offset = (Width - (sx * bounds.Width)) / 2; 288 } 289 foreach (var node in visualTreeNodes.Keys) { 290 var visualNode = visualTreeNodes[node]; 291 var pos = nodePositions[node]; 292 visualNode.Width = w; 293 visualNode.Height = h; 294 visualNode.X = (int)Math.Round(pos.X * sx + offset); ; 295 visualNode.Y = (int)Math.Round(pos.Y * sy); 296 DrawTreeNode(graphics, visualNode); 297 } 279 double sx = this.Width / (bounds.Width + preferredWidth); 280 if (sx > 1) sx = 1; 281 double sy = this.Height / bounds.Height; 282 if (sy > 1) sy = 1; 283 double dx = (this.Width - bounds.Width) / 2; 284 if (dx < 0) dx = 0; 285 double dy = (this.Height - bounds.Height) / 2; 286 if (dy < 0) dy = 0; 287 288 var levels = layoutNodes.GroupBy(n => n.Level, n => n); 289 290 foreach (var level in levels) { 291 var nodes = level.ToList(); 292 double min = 0; 293 for (int i = 0; i < nodes.Count - 1; ++i) { 294 var w = (nodes[i + 1].X - nodes[i].X) * sx - preferredWidth; 295 if (w < min) min = w; 296 } 297 if (min > 0) min = 0; 298 299 foreach (var layoutNode in level) { 300 var visualNode = visualTreeNodes[layoutNode.Content]; 301 visualNode.Width = (int)Math.Round(preferredWidth + min) - 2; // -2 to allow enough padding (1px on each side) for the node contour to be drawn 302 visualNode.Height = (int)Math.Round(preferredHeight * sy); 303 visualNode.X = (int)(Math.Round(layoutNode.X * sx + dx)); 304 visualNode.Y = (int)(Math.Round(layoutNode.Y * sy + dy)); 305 DrawTreeNode(graphics, visualNode); 306 } 307 } 308 298 309 graphics.ResetClip(); // reset clip region 310 // draw node connections 299 311 foreach (var visualNode in visualTreeNodes.Values) { 300 312 var node = visualNode.SymbolicExpressionTreeNode;
Note: See TracChangeset
for help on using the changeset viewer.