Ignore:
Timestamp:
09/16/13 14:49:23 (6 years ago)
Author:
bburlacu
Message:

#2076: Refactored layout engine to be more generic. Svn-copied folders from trunk and readded layout files.

Location:
branches/HeuristicLab.ReingoldTilfordTreeLayout
Files:
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.ReingoldTilfordTreeLayout

    • Property svn:global-ignores set to
      bin
  • branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj

    r8600 r9970  
    4141    <DebugType>full</DebugType>
    4242    <Optimize>false</Optimize>
    43     <OutputPath>$(SolutionDir)\bin\</OutputPath>
     43    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
    4444    <DefineConstants>DEBUG;TRACE</DefineConstants>
    4545    <ErrorReport>prompt</ErrorReport>
     
    5050    <DebugType>pdbonly</DebugType>
    5151    <Optimize>true</Optimize>
    52     <OutputPath>$(SolutionDir)\bin\</OutputPath>
     52    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
    5353    <DefineConstants>TRACE</DefineConstants>
    5454    <ErrorReport>prompt</ErrorReport>
     
    9393  </PropertyGroup>
    9494  <ItemGroup>
     95    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     96      <SpecificVersion>False</SpecificVersion>
     97      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
     98    </Reference>
     99    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     100      <SpecificVersion>False</SpecificVersion>
     101      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
     102    </Reference>
     103    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     104      <SpecificVersion>False</SpecificVersion>
     105      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
     106    </Reference>
     107    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     108      <SpecificVersion>False</SpecificVersion>
     109      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
     110    </Reference>
     111    <Reference Include="HeuristicLab.Core.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     112      <SpecificVersion>False</SpecificVersion>
     113      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
     114    </Reference>
     115    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     116      <SpecificVersion>False</SpecificVersion>
     117      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
     118    </Reference>
     119    <Reference Include="HeuristicLab.Data.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     120      <SpecificVersion>False</SpecificVersion>
     121      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
     122    </Reference>
     123    <Reference Include="HeuristicLab.MainForm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     124      <SpecificVersion>False</SpecificVersion>
     125      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
     126    </Reference>
     127    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     128      <SpecificVersion>False</SpecificVersion>
     129      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
     130    </Reference>
     131    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     132      <SpecificVersion>False</SpecificVersion>
     133      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
     134    </Reference>
     135    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     136      <SpecificVersion>False</SpecificVersion>
     137      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
     138    </Reference>
     139    <Reference Include="HeuristicLab.Optimization.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     140      <SpecificVersion>False</SpecificVersion>
     141      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
     142    </Reference>
     143    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     144      <SpecificVersion>False</SpecificVersion>
     145      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     146    </Reference>
     147    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     148      <SpecificVersion>False</SpecificVersion>
     149      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
     150    </Reference>
     151    <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
     152      <SpecificVersion>False</SpecificVersion>
     153      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
     154    </Reference>
    95155    <Reference Include="System" />
    96156    <Reference Include="System.Core">
     
    164224  </ItemGroup>
    165225  <ItemGroup>
    166     <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
    167       <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
    168       <Name>HeuristicLab.Collections-3.3</Name>
    169       <Private>False</Private>
    170     </ProjectReference>
    171     <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
    172       <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
    173       <Name>HeuristicLab.Common.Resources-3.3</Name>
    174       <Private>False</Private>
    175     </ProjectReference>
    176     <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
    177       <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
    178       <Name>HeuristicLab.Common-3.3</Name>
    179       <Private>False</Private>
    180     </ProjectReference>
    181     <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
    182       <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
    183       <Name>HeuristicLab.Core.Views-3.3</Name>
    184       <Private>False</Private>
    185     </ProjectReference>
    186     <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
    187       <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
    188       <Name>HeuristicLab.Core-3.3</Name>
    189       <Private>False</Private>
    190     </ProjectReference>
    191     <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
    192       <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
    193       <Name>HeuristicLab.Data.Views-3.3</Name>
    194       <Private>False</Private>
    195     </ProjectReference>
    196     <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
    197       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
    198       <Name>HeuristicLab.Data-3.3</Name>
    199       <Private>False</Private>
    200     </ProjectReference>
    201226    <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj">
    202227      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
    203228      <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
    204       <Private>False</Private>
    205     </ProjectReference>
    206     <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
    207       <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
    208       <Name>HeuristicLab.MainForm.WindowsForms-3.3</Name>
    209       <Private>False</Private>
    210     </ProjectReference>
    211     <ProjectReference Include="..\..\HeuristicLab.MainForm\3.3\HeuristicLab.MainForm-3.3.csproj">
    212       <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
    213       <Name>HeuristicLab.MainForm-3.3</Name>
    214       <Private>False</Private>
    215     </ProjectReference>
    216     <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
    217       <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
    218       <Name>HeuristicLab.Operators-3.3</Name>
    219       <Private>False</Private>
    220     </ProjectReference>
    221     <ProjectReference Include="..\..\HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj">
    222       <Project>{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}</Project>
    223       <Name>HeuristicLab.Optimization.Views-3.3</Name>
    224       <Private>False</Private>
    225     </ProjectReference>
    226     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
    227       <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
    228       <Name>HeuristicLab.Optimization-3.3</Name>
    229       <Private>False</Private>
    230     </ProjectReference>
    231     <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
    232       <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
    233       <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
    234       <Private>False</Private>
    235     </ProjectReference>
    236     <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
    237       <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
    238       <Name>HeuristicLab.Random-3.3</Name>
    239       <Private>False</Private>
    240     </ProjectReference>
    241     <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj">
    242       <Project>{315BDA09-3F4F-49B3-9790-B37CFC1C5750}</Project>
    243       <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name>
    244229      <Private>False</Private>
    245230    </ProjectReference>
     
    276261  -->
    277262  <PropertyGroup>
    278    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
     263    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
    279264set ProjectDir=$(ProjectDir)
    280265set SolutionDir=$(SolutionDir)
     
    283268call PreBuildEvent.cmd
    284269</PreBuildEvent>
    285 <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
     270    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
    286271export ProjectDir=$(ProjectDir)
    287272export SolutionDir=$(SolutionDir)
  • branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.Designer.cs

    r9456 r9970  
    7070      //
    7171      this.saveFileDialog.Filter = "Bitmap (*.bmp)|*.bmp|EMF (*.emf)|*.emf";
    72       this.saveFileDialog.FilterIndex = 1;
     72      //
    7373      // SymbolicExpressionTreeChart
    7474      //
    75       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    7675      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
    7776      this.ContextMenuStrip = this.contextMenuStrip;
     77      this.DoubleBuffered = true;
    7878      this.Name = "SymbolicExpressionTreeChart";
    7979      this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.SymbolicExpressionTreeChart_MouseClick);
  • branches/HeuristicLab.ReingoldTilfordTreeLayout/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeChart.cs

    r9587 r9970  
    2424using System.Drawing;
    2525using System.Drawing.Imaging;
     26using System.IO;
     27using System.Linq;
    2628using System.Windows.Forms;
     29using Point = System.Drawing.Point;
    2730
    2831namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
     
    3235    private Dictionary<ISymbolicExpressionTreeNode, VisualSymbolicExpressionTreeNode> visualTreeNodes;
    3336    private Dictionary<Tuple<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>, VisualSymbolicExpressionTreeNodeConnection> visualLines;
     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;
     44
    3445
    3546    public SymbolicExpressionTreeChart() {
     
    4051      this.lineColor = Color.Black;
    4152      this.backgroundColor = Color.White;
    42       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();
    4356    }
    4457
    4558    public SymbolicExpressionTreeChart(ISymbolicExpressionTree tree)
    4659      : this() {
     60      layoutEngine = new ReingoldTilfordLayoutEngine<ISymbolicExpressionTreeNode>();
     61      layoutAdapter = new SymbolicExpressionTreeLayoutAdapter();
    4762      this.Tree = tree;
    4863    }
    4964
     65    #region Public properties
    5066    private int spacing;
    5167    public int Spacing {
     
    106122      set { suspendRepaint = value; }
    107123    }
     124    #endregion
    108125
    109126    protected override void OnPaint(PaintEventArgs e) {
     
    157174        graphics.Clear(backgroundColor);
    158175        if (tree != null) {
    159           int height = this.Height / tree.Depth;
    160           DrawFunctionTree(tree, graphics, 0, 0, this.Width, height);
     176          DrawFunctionTree(tree, graphics, preferredNodeWidth, preferredNodeHeight, minHorizontalDistance, minVerticalDistance);
    161177        }
    162178      }
     
    250266
    251267    #region methods for painting the symbolic expression tree
    252     private void DrawFunctionTree(ISymbolicExpressionTree tree, Graphics graphics, int x, int y, int width, int height) {
    253       DrawFunctionTree(tree.Root, graphics, x, y, width, height, Point.Empty);
    254     }
    255 
    256     /// <summary>
    257     ///
    258     /// </summary>
    259     /// <param name="functionTree"> function tree to draw</param>
    260     /// <param name="graphics">graphics object to draw on</param>
    261     /// <param name="x">x coordinate of drawing area</param>
    262     /// <param name="y">y coordinate of drawing area</param>
    263     /// <param name="width">width of drawing area</param>
    264     /// <param name="height">height of drawing area</param>
    265     private void DrawFunctionTree(ISymbolicExpressionTreeNode node, Graphics graphics, int x, int y, int width, int height, Point connectionPoint) {
    266       VisualSymbolicExpressionTreeNode visualTreeNode = visualTreeNodes[node];
    267       float center_x = x + width / 2;
    268       float center_y = y + height / 2;
    269       int actualWidth = width - spacing;
    270       int actualHeight = height - spacing;
    271 
    272       using (var textBrush = new SolidBrush(visualTreeNode.TextColor))
    273       using (var nodeLinePen = new Pen(visualTreeNode.LineColor))
    274       using (var nodeFillBrush = new SolidBrush(visualTreeNode.FillColor)) {
    275 
    276         //calculate size of node
    277         if (actualWidth >= visualTreeNode.PreferredWidth && actualHeight >= visualTreeNode.PreferredHeight) {
    278           visualTreeNode.Width = visualTreeNode.PreferredWidth;
    279           visualTreeNode.Height = visualTreeNode.PreferredHeight;
    280           visualTreeNode.X = (int)center_x - visualTreeNode.Width / 2;
    281           visualTreeNode.Y = (int)center_y - visualTreeNode.Height / 2;
    282         }
    283           //width too small to draw in desired sized
    284         else if (actualWidth < visualTreeNode.PreferredWidth && actualHeight >= visualTreeNode.PreferredHeight) {
    285           visualTreeNode.Width = actualWidth;
    286           visualTreeNode.Height = visualTreeNode.PreferredHeight;
    287           visualTreeNode.X = x;
    288           visualTreeNode.Y = (int)center_y - visualTreeNode.Height / 2;
    289         }
    290           //height too small to draw in desired sized
    291         else if (actualWidth >= visualTreeNode.PreferredWidth && actualHeight < visualTreeNode.PreferredHeight) {
    292           visualTreeNode.Width = visualTreeNode.PreferredWidth;
    293           visualTreeNode.Height = actualHeight;
    294           visualTreeNode.X = (int)center_x - visualTreeNode.Width / 2;
    295           visualTreeNode.Y = y;
    296         }
    297           //width and height too small to draw in desired size
    298         else {
    299           visualTreeNode.Width = actualWidth;
    300           visualTreeNode.Height = actualHeight;
    301           visualTreeNode.X = x;
    302           visualTreeNode.Y = y;
    303         }
    304 
    305         //draw terminal node
    306         if (node.SubtreeCount == 0) {
    307           graphics.FillRectangle(nodeFillBrush, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    308           graphics.DrawRectangle(nodeLinePen, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    309         } else {
    310           graphics.FillEllipse(nodeFillBrush, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    311           graphics.DrawEllipse(nodeLinePen, visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height);
    312         }
    313 
    314         //draw name of symbol
    315         var text = node.ToString();
    316         graphics.DrawString(text, textFont, textBrush, new RectangleF(visualTreeNode.X, visualTreeNode.Y, visualTreeNode.Width, visualTreeNode.Height), stringFormat);
    317 
    318         //draw connection line to parent node
    319         if (!connectionPoint.IsEmpty && node.Parent != null) {
    320           var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node.Parent, node);
    321           using (Pen linePen = new Pen(visualLine.LineColor)) {
     268
     269    private void DrawFunctionTree(ISymbolicExpressionTree tree, Graphics graphics, int preferredWidth, int preferredHeight, int minHDistance, int minVDistance) {
     270      var layoutNodes = layoutAdapter.Convert(tree).ToList();
     271      layoutEngine.Reset();
     272      layoutEngine.Root = layoutNodes[0];
     273      foreach (var ln in layoutNodes)
     274        layoutEngine.AddNode(ln.Content, ln);
     275      layoutEngine.MinHorizontalSpacing = (preferredNodeWidth + minHDistance);
     276      layoutEngine.MinVerticalSpacing = (preferredNodeHeight + minVDistance);
     277      layoutEngine.CalculateLayout();
     278      var bounds = layoutEngine.Bounds();
     279      double sx = this.Width / bounds.Width;
     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      var levels = layoutEngine.Nodes.GroupBy(n => n.Value.Level, n => n.Value);
     288
     289      foreach (var level in levels) {
     290        double width = (level.Max(n => n.X) - level.Min(n => n.X) + preferredWidth);
     291        double ssx = this.Width / width;
     292        if (ssx > 1) ssx = 1;
     293        foreach (var layoutNode in level) {
     294          var node = layoutNode.Content;
     295          var visualNode = visualTreeNodes[node];
     296          visualNode.Width = (int)Math.Round(preferredWidth * ssx);
     297          visualNode.Height = (int)Math.Round(preferredHeight * sy);
     298          visualNode.X = (int)(Math.Round(layoutNode.X * sx + dx));
     299          visualNode.Y = (int)(Math.Round(layoutNode.Y * sy + dy));
     300          DrawTreeNode(graphics, visualNode);
     301        }
     302      }
     303      graphics.ResetClip(); // reset clip region
     304      foreach (var visualNode in visualTreeNodes.Values) {
     305        var node = visualNode.SymbolicExpressionTreeNode;
     306        foreach (var subtree in node.Subtrees) {
     307          var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node, subtree);
     308          var visualSubtree = visualTreeNodes[subtree];
     309          var origin = new Point(visualNode.X + visualNode.Width / 2, visualNode.Y + visualNode.Height);
     310          var target = new Point(visualSubtree.X + visualSubtree.Width / 2, visualSubtree.Y);
     311          using (var linePen = new Pen(visualLine.LineColor)) {
    322312            linePen.DashStyle = visualLine.DashStyle;
    323             graphics.DrawLine(linePen, connectionPoint, new Point(visualTreeNode.X + visualTreeNode.Width / 2, visualTreeNode.Y));
     313            graphics.DrawLine(linePen, origin, target);
    324314          }
    325         }
    326 
    327         //calculate areas for the subtrees according to their tree size and call drawFunctionTree
    328         Point connectFrom = new Point(visualTreeNode.X + visualTreeNode.Width / 2, visualTreeNode.Y + visualTreeNode.Height);
    329         int[] xBoundaries = new int[node.SubtreeCount + 1];
    330         xBoundaries[0] = x;
    331         for (int i = 0; i < node.SubtreeCount; i++) {
    332           xBoundaries[i + 1] = (int)(xBoundaries[i] + (width * (double)node.GetSubtree(i).GetLength()) / (node.GetLength() - 1));
    333           DrawFunctionTree(node.GetSubtree(i), graphics, xBoundaries[i], y + height, xBoundaries[i + 1] - xBoundaries[i], height, connectFrom);
    334315        }
    335316      }
     
    365346    }
    366347    #endregion
    367 
    368348    #region save image
    369349    private void saveImageToolStripMenuItem_Click(object sender, EventArgs e) {
     
    399379    }
    400380    #endregion
     381    #region export pgf/tikz
     382    private void exportLatexToolStripMenuItem_Click(object sender, EventArgs e) {
     383      using (var dialog = new SaveFileDialog { Filter = "Tex (*.tex)|*.tex" }) {
     384        if (dialog.ShowDialog() != DialogResult.OK) return;
     385        string filename = dialog.FileName.ToLower();
     386        var formatter = new SymbolicExpressionTreeLatexFormatter();
     387        File.WriteAllText(filename, formatter.Format(Tree));
     388      }
     389    }
     390    #endregion
    401391  }
    402392}
Note: See TracChangeset for help on using the changeset viewer.