Free cookie consent management tool by TermsFeed Policy Generator

Changeset 1182


Ignore:
Timestamp:
01/27/09 23:50:10 (16 years ago)
Author:
mstoeger
Message:

Implemented X/Y-Axes and a Grid. (#433)

Location:
trunk/sources/HeuristicLab.Visualization
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Visualization/ChartDataRowsModel.cs

    r1061 r1182  
    1212
    1313  public class ChartDataRowsModel : ChartDataModelBase, IChartDataRowsModel{
    14     private string title;
     14    private string title = "Title";
    1515    private string xAxisLabel;
    1616
  • trunk/sources/HeuristicLab.Visualization/HeuristicLab.Visualization.csproj

    r1055 r1182  
    8181    <Compile Include="CompositeShape.cs" />
    8282    <Compile Include="ChartDataRowsModelDataCollector.cs" />
     83    <Compile Include="DefaultLabelProvider.cs" />
     84    <Compile Include="Grid.cs" />
     85    <Compile Include="ILabelProvider.cs" />
    8386    <Compile Include="IMouseEventListener.cs" />
    8487    <Compile Include="PanListener.cs" />
     
    109112    <Compile Include="WorldShape.cs" />
    110113    <Compile Include="XAxis.cs" />
     114    <Compile Include="YAxis.cs" />
    111115    <Compile Include="ZoomListener.cs" />
    112116  </ItemGroup>
  • trunk/sources/HeuristicLab.Visualization/LineChart.cs

    r1059 r1182  
    66
    77namespace HeuristicLab.Visualization {
    8   public class LinesShape : WorldShape {
    9     private readonly RectangleShape background = new RectangleShape(0, 0, 1, 1, Color.FromArgb(240, 240, 240));
    10 
    11     public LinesShape(RectangleD clippingArea, RectangleD boundingBox)
    12       : base(clippingArea, boundingBox) {
    13       AddShape(background);
    14     }
    15 
    16     public override void Draw(Graphics graphics, Rectangle viewport, RectangleD clippingArea) {
    17       UpdateLayout();
    18       base.Draw(graphics, viewport, clippingArea);
    19     }
    20 
    21     private void UpdateLayout() {
    22       background.Rectangle = ClippingArea;
    23     }
    24   }
     8  public class LinesShape : WorldShape { }
    259
    2610  public partial class LineChart : ViewBase {
     
    3721
    3822    private readonly XAxis xAxis;
     23    private readonly YAxis yAxis;
     24    private readonly Grid grid;
    3925
    4026    /// <summary>
     
    5642      //TODO: correct Rectangle to fit
    5743
    58       RectangleD dummy = new RectangleD(0, 0, 1, 1);
    59 
    60       root = new WorldShape(dummy, dummy);
    61 
    62       linesShape = new LinesShape(dummy, dummy);
     44      root = new WorldShape();
     45
     46      grid = new Grid();
     47      root.AddShape(grid);
     48
     49      linesShape = new LinesShape();
    6350      root.AddShape(linesShape);
    6451
     
    6956      root.AddShape(legendShape);
    7057
    71       xAxis = new XAxis(dummy, dummy);
     58      xAxis = new XAxis();
    7259      root.AddShape(xAxis);
    7360
    74       titleShape = new TextShape(0, 0, "Title", 15);
     61      yAxis = new YAxis();
     62      root.AddShape(yAxis);
     63
     64      titleShape = new TextShape(0, 0, model.Title, 15);
    7565      root.AddShape(titleShape);
    7666
     
    10090      titleShape.Y = canvas.Height - 10;
    10191
    102       linesShape.BoundingBox = new RectangleD(0, 20, canvas.Width, canvas.Height);
     92      const int yAxisWidth = 100;
     93      const int xAxisHeight = 20;
     94
     95      linesShape.BoundingBox = new RectangleD(yAxisWidth,
     96                                              xAxisHeight,
     97                                              canvas.Width,
     98                                              canvas.Height);
     99     
     100      grid.BoundingBox = linesShape.BoundingBox;
     101
     102      yAxis.BoundingBox = new RectangleD(0,
     103                                         linesShape.BoundingBox.Y1,
     104                                         linesShape.BoundingBox.X1,
     105                                         linesShape.BoundingBox.Y2);
    103106
    104107      xAxis.BoundingBox = new RectangleD(linesShape.BoundingBox.X1,
     
    170173    private void SetLineClippingArea(RectangleD clippingArea) {
    171174      linesShape.ClippingArea = clippingArea;
     175     
     176      grid.ClippingArea = linesShape.ClippingArea;
     177
    172178      xAxis.ClippingArea = new RectangleD(linesShape.ClippingArea.X1,
    173179                                          xAxis.BoundingBox.Y1,
    174180                                          linesShape.ClippingArea.X2,
    175181                                          xAxis.BoundingBox.Y2);
     182     
     183      yAxis.ClippingArea = new RectangleD(yAxis.BoundingBox.X1,
     184                                          linesShape.ClippingArea.Y1,
     185                                          yAxis.BoundingBox.X2,
     186                                          linesShape.ClippingArea.Y2);
    176187    }
    177188
     
    206217    // TODO use action parameter
    207218    private void OnRowValueChanged(IDataRow row, double value, int index, Action action) {
    208       xAxis.SetLabel(index, index.ToString());
    209 
    210219      List<LineShape> lineShapes = rowToLineShapes[row];
    211220      maxDataValue = Math.Max(value, maxDataValue);
     
    248257    }
    249258
    250     private void OnModelChanged() {}
     259    private void OnModelChanged() {
     260      titleShape.Text = model.Title;
     261
     262      Invalidate();
     263    }
    251264
    252265    #endregion
  • trunk/sources/HeuristicLab.Visualization/TextShape.cs

    r1046 r1182  
    1 using System.Drawing;
     1using System;
     2using System.Drawing;
    23
    34namespace HeuristicLab.Visualization {
     5  public enum AnchorPositionX {
     6    Left, Middle, Right
     7  }
     8
     9  public enum AnchorPositionY {
     10    Bottom, Middle, Top
     11  }
     12
    413  public class TextShape : IShape {
    514    private Font font;
     
    918    private double x;
    1019    private double y;
     20
     21    private AnchorPositionX anchorPositionX = AnchorPositionX.Left;
     22    private AnchorPositionY anchorPositionY = AnchorPositionY.Top;
    1123
    1224    public TextShape(double x, double y, string text) : this(x, y, text, 8) {}
     
    4456    }
    4557
     58    public AnchorPositionX AnchorPositionX {
     59      get { return anchorPositionX; }
     60      set { anchorPositionX = value; }
     61    }
     62
     63    public AnchorPositionY AnchorPositionY {
     64      get { return anchorPositionY; }
     65      set { anchorPositionY = value; }
     66    }
     67
    4668    #region IShape Members
    4769
     
    4971      int screenX = Transform.ToScreenX(x, viewport, clippingArea);
    5072      int screenY = Transform.ToScreenY(y, viewport, clippingArea);
     73
     74      SizeF size = graphics.MeasureString(text, font);
     75
     76      switch (AnchorPositionX) {
     77        case AnchorPositionX.Left:
     78          break;
     79        case AnchorPositionX.Middle:
     80          screenX -= (int)(size.Width/2);
     81          break;
     82        case AnchorPositionX.Right:
     83          screenX -= (int)size.Width;
     84          break;
     85        default:
     86          throw new NotSupportedException("Unknown anchor position: " + AnchorPositionX);
     87      }
     88
     89      switch (AnchorPositionY) {
     90        case AnchorPositionY.Top:
     91          break;
     92        case AnchorPositionY.Middle:
     93          screenY -= (int)(size.Height/2);
     94          break;
     95        case AnchorPositionY.Bottom:
     96          screenY -= (int)size.Height;
     97          break;
     98        default:
     99          throw new NotSupportedException("Unknown anchor position: " + AnchorPositionX);
     100      }
    51101
    52102      graphics.DrawString(text, font, brush, screenX, screenY);
  • trunk/sources/HeuristicLab.Visualization/WorldShape.cs

    r1038 r1182  
    99
    1010    protected readonly List<IShape> shapes = new List<IShape>();
     11
     12    public WorldShape()
     13      : this(new RectangleD(0, 0, 1, 1), new RectangleD(0, 0, 1, 1)) {}
    1114
    1215    public WorldShape(RectangleD clippingArea, RectangleD boundingBox) {
  • trunk/sources/HeuristicLab.Visualization/XAxis.cs

    r1046 r1182  
     1using System;
    12using System.Collections.Generic;
    23using System.Drawing;
    34
    45namespace HeuristicLab.Visualization {
     6  public class XAxis : WorldShape {
     7    public const int PixelsPerInterval = 100;
     8    private ILabelProvider labelProvider = new DefaultLabelProvider("0.##");
    59
    6   public class XAxis : WorldShape {
    7     private readonly IDictionary<int, TextShape> labels = new Dictionary<int, TextShape>();
    8 
    9     public XAxis(RectangleD clippingArea, RectangleD boundingBox)
    10       : base(clippingArea, boundingBox) {}
    11 
    12     public void ClearLabels() {
    13       labels.Clear();
     10    public ILabelProvider LabelProvider {
     11      get { return labelProvider; }
     12      set { labelProvider = value; }
    1413    }
    1514
    16     public void SetLabel(int i, string text) {
    17       labels[i] = new TextShape(i, 0, text);
     15    public static IEnumerable<double> GetTicks(int pixelsPerInterval, int screenSize, double worldSize, double worldStart) {
     16      int intervals = screenSize/pixelsPerInterval;
     17
     18      if (intervals > 0) {
     19        double step = worldSize/intervals;
     20        step = Math.Pow(10, Math.Floor(Math.Log10(step)));
     21        if (worldSize/(step*5) > intervals)
     22          step = step*5;
     23        else if (worldSize/(step*2) > intervals)
     24          step = step*2;
     25
     26        for (double x = Math.Floor(worldStart/step)*step;
     27             x <= worldStart + worldSize;
     28             x += step)
     29          yield return x;
     30      }
    1831    }
    1932
     
    2134      shapes.Clear();
    2235
    23       for (int i = (int)(ClippingArea.X1 - 1); i <= ClippingArea.X2 + 1; i++) {
    24         TextShape label;
    25 
    26         if (labels.ContainsKey(i)) {
    27           label = labels[i];
    28         } else {
    29           label = new TextShape(i, 0, i.ToString());
    30         }
    31 
    32         label.Y = ClippingArea.Height - 3;
    33 
     36      foreach (double x in GetTicks(PixelsPerInterval, viewport.Width, ClippingArea.Width, ClippingArea.X1)) {
     37        TextShape label = new TextShape(x, ClippingArea.Height - 3,
     38                                        labelProvider.GetLabel(x));
     39        label.AnchorPositionX = AnchorPositionX.Middle;
     40        label.AnchorPositionY = AnchorPositionY.Top;
    3441        shapes.Add(label);
    3542      }
Note: See TracChangeset for help on using the changeset viewer.