Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Visualization/HeuristicLab.Visualization/3.3/Primitives/Grid.cs @ 13107

Last change on this file since 13107 was 13045, checked in by jkarder, 9 years ago

#1265: merged changes from abeham

File size: 5.2 KB
Line 
1using System;
2using System.Drawing;
3
4namespace HeuristicLab.Visualization {
5  public class Grid : PrimitiveBase, IGrid {
6    protected const int CellSpacing = 10;
7
8    public virtual PointD Origin { get; set; }
9    public virtual PointD Offset { get; set; }
10    public virtual SizeD Size { get; set; }
11
12    public virtual double XPrecision { get; set; }
13    public virtual double YPrecision { get; set; }
14
15    public virtual PointD GetBottomLeftGridPoint(PointD point) {
16      var nx = (int)Math.Floor((point.X - Origin.X) / XPrecision);
17      var ny = (int)Math.Floor((point.Y - Origin.Y) / YPrecision);
18      return new PointD(Origin.X + nx * XPrecision, Origin.Y + ny * YPrecision);
19    }
20
21    public virtual PointD GetUpperRightGridPoint(PointD point) {
22      var nx = (int)Math.Ceiling((point.X - Origin.X) / XPrecision);
23      var ny = (int)Math.Ceiling((point.Y - Origin.Y) / YPrecision);
24      return new PointD(Origin.X + nx * XPrecision, Origin.Y + ny * YPrecision);
25    }
26
27    public virtual PointD GetNearestGridPoint(PointD point) {
28      var bl = GetBottomLeftGridPoint(point);
29      var ur = GetUpperRightGridPoint(point);
30      return new PointD(
31        Math.Abs(bl.X - point.X) <= Math.Abs(ur.X - point.X) ? bl.X : ur.X,
32        Math.Abs(bl.Y - point.Y) <= Math.Abs(ur.Y - point.Y) ? bl.Y : ur.Y);
33    }
34
35    public Grid(IChart chart, PointD offset, SizeD size)
36      : this(chart, offset, size, 1) { }
37    public Grid(IChart chart, PointD offset, SizeD size, double precision)
38      : base(chart) {
39      Origin = new PointD(0, 0);
40      Offset = offset;
41      Size = size;
42      XPrecision = precision;
43      YPrecision = precision;
44    }
45
46    public override bool ContainsPoint(PointD point) {
47      return false;
48    }
49
50    public override void Move(Offset delta) {
51      Offset += delta;
52    }
53
54    public override void Move(PointD point, Offset delta) {
55      Move(delta);
56    }
57
58    public override void SnapToGrid(IGrid grid) { }
59
60    public override void SnapToGrid(PointD point, IGrid grid) { }
61
62    public override void Draw(Graphics graphics) {
63      if (!(Size.Width > 0) || !(Size.Height > 0)) return;
64      graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
65      var pen = new Pen(Color.LightGray, 1.0f);
66      var pixelSize = Chart.TransformWorldToPixel(Size); // size of the drawing area in pixel coordinates
67
68      var numberOfXParallelLines = (int)Math.Floor(pixelSize.Height / (double)CellSpacing); // how many x parallel lines can be drawn
69      var numberOfYParallelLines = (int)Math.Floor(pixelSize.Width / (double)CellSpacing); // how many y parallel lines can be drawn
70      if (numberOfXParallelLines <= 0 || numberOfYParallelLines <= 0) return;
71      var cellWorldSize = new SizeD(Size.Width / numberOfYParallelLines, Size.Height / numberOfXParallelLines); // the cellSize in world coordinates
72      cellWorldSize.Width = Math.Pow(10, Math.Floor(Math.Log10(cellWorldSize.Width)));
73      cellWorldSize.Height = Math.Pow(10, Math.Floor(Math.Log10(cellWorldSize.Width)));
74      var cellPixelSize = Chart.TransformWorldToPixel(cellWorldSize);
75      while (cellPixelSize.Width < 25 || cellPixelSize.Height < 25) {
76        if (cellPixelSize.Width < 25) cellWorldSize.Width *= 2;
77        if (cellPixelSize.Height < 25) cellWorldSize.Height *= 2;
78        cellPixelSize = Chart.TransformWorldToPixel(cellWorldSize);
79        if (cellPixelSize.Width < 25) cellWorldSize.Width *= 2.5;
80        if (cellPixelSize.Height < 25) cellWorldSize.Height *= 2.5;
81        cellPixelSize = Chart.TransformWorldToPixel(cellWorldSize);
82      }
83      var firstX = Math.Floor(Offset.X / cellWorldSize.Width) * cellWorldSize.Width;
84      var firstY = Math.Floor(Offset.Y / cellWorldSize.Height) * cellWorldSize.Height;
85      double x = firstX, y = firstY;
86      var axisyLabel = new Font(FontFamily.GenericMonospace, 7.0f, FontStyle.Regular, GraphicsUnit.Point, 0);
87      var axisxLabel = new Font(FontFamily.GenericMonospace, 7.0f, FontStyle.Regular, GraphicsUnit.Point, 0, true);
88      var axisDrawing = new SolidBrush(Color.DarkGray);
89      try {
90        var bottom = Chart.TransformWorldToPixel(Size).Height;
91        while (x <= Offset.X + Size.Width) {
92          var start = Chart.TransformWorldToPixel(new PointD(x, firstY));
93          var end = Chart.TransformWorldToPixel(new PointD(x, Offset.Y + Size.Height));
94          graphics.DrawLine(pen, start, end);
95          var axis = x.ToString("0.##");
96          double stringwidth = graphics.MeasureString(axis, axisyLabel).Width;
97          graphics.DrawString(axis, axisyLabel, axisDrawing, end.X - (int)(stringwidth / 2.0), bottom - 15);
98          x += cellWorldSize.Width;
99        }
100        while (y <= Offset.Y + Size.Height) {
101          var start = Chart.TransformWorldToPixel(new PointD(firstX, y));
102          var end = Chart.TransformWorldToPixel(new PointD(Offset.X + Size.Width, y));
103          graphics.DrawLine(pen, start, end);
104          graphics.DrawString(y.ToString("0.##"), axisxLabel, axisDrawing, 0, start.Y);
105          y += cellWorldSize.Height;
106        }
107      } finally {
108        axisDrawing.Dispose();
109        axisxLabel.Dispose();
110        axisyLabel.Dispose();
111      }
112    }
113  }
114}
Note: See TracBrowser for help on using the repository browser.