/// <summary> /// Plots grid lines onto the graph. /// </summary> /// <param name="graphics">The GDI+ drawing surface to use for plotting this IPlottable.</param> /// <param name="graphSize">The size of the Graph on the screen. This is a property of the display rather than the /// graph and is thus not included in the graph's parameters.</param> /// <param name="plotParams">The parameters used to plot this IPlottable.</param> /// <param name="originX">The X position of the origin on the screen.</param> /// <param name="originY">The Y position of the origin on the screen.</param> private void PlotGridLinesOnto(Graph graph, Graphics graphics, Size graphSize, PlottableParameters plotParams, int originX, int originY) { using (Pen majorPen = new Pen(plotParams.PlotColor.ColorAlpha(0.25))) using (Pen minorPen = new Pen(plotParams.PlotColor.ColorAlpha(0.15))) using (Brush valueBrush = new SolidBrush(plotParams.PlotColor.ColorAlpha(0.5))) { // the increment, in pixels, of each grid space double incrementX = HorizontalType.AxisTypeGridScale() * GridSize / graph.Parameters.HorizontalPixelScale, incrementY = VerticalType.AxisTypeGridScale() * GridSize / graph.Parameters.VerticalPixelScale; // draw the variable names onto the axis graphics.DrawString(graph.Parameters.VerticalAxis.ToString(), SystemFonts.DefaultFont, valueBrush, (int)originX, 2); graphics.DrawString(graph.Parameters.HorizontalAxis.ToString(), SystemFonts.DefaultFont, valueBrush, (int)graphSize.Width - 16, (int)originY); // the unit suffix of the grid labels, for example the little circle for degrees string horizontalAxisSuffix = HorizontalType.AxisTypeExtension(); string verticalAxisSuffix = VerticalType.AxisTypeExtension(); // the axis label scale for the numbers along each axis // for example, axes plotted in degree mode are scaled such that 2*pi is displayed // as 360 degrees instead double horizontalAxisScale = GridSize * HorizontalType.AxisTypeLabelScale() * HorizontalType.AxisTypeGridScale(); double verticalAxisScale = GridSize * VerticalType.AxisTypeLabelScale() * VerticalType.AxisTypeGridScale(); // the remainder of the code in this method plots the gridlines from the origin outward. // this is potentially not the most efficient method of doing it, but it avoids floating- // point rounding errors resulting in axis labels like 2.00000000000017 without adding in // even more horrible code. // some of this code looks redundant, and it is. However as drawing the grid lines is a // (surprisingly) CPU intensive operation this method needs to be as fast as possible as // the grid is drawn every time the graph is double value = originX; int index = 0; // plot horizontal grid lines from the origin to the right of the page while (value < graphSize.Width) { bool major = index % MajorInterval == 0; if (major) { graphics.DrawLine(majorPen, (int)value, 0, (int)value, graphSize.Height); graphics.DrawString( String.Format("{0:0.####}{1}", index * horizontalAxisScale, horizontalAxisSuffix), SystemFonts.DefaultFont, valueBrush, (int)value, (int)originY); } else { graphics.DrawLine(minorPen, (int)value, 0, (int)value, graphSize.Height); } value += incrementX; index++; } value = originX; index = 0; // plot hoz grid from origin to left of page while (value >= 0) { bool major = index % MajorInterval == 0; if (major) { graphics.DrawLine(majorPen, (int)value, 0, (int)value, graphSize.Height); graphics.DrawString( String.Format("{0:0.####}{1}", index * horizontalAxisScale, horizontalAxisSuffix), SystemFonts.DefaultFont, valueBrush, (int)value, (int)originY); } else { graphics.DrawLine(minorPen, (int)value, 0, (int)value, graphSize.Height); } value -= incrementX; index++; } value = originY; index = 0; // plot vertical grid lines from origin to bottom of page while (value < graphSize.Height) { bool major = index % MajorInterval == 0; if (major) { graphics.DrawLine(majorPen, 0, (int)value, graphSize.Width, (int)value); graphics.DrawString( String.Format("{0:0.####}{1}", index * verticalAxisScale, verticalAxisSuffix), SystemFonts.DefaultFont, valueBrush, (int)originX, (int)value); } else { graphics.DrawLine(minorPen, 0, (int)value, graphSize.Width, (int)value); } value += incrementY; index++; } value = originY; index = 0; // plot vert grid from origin to top of page while (value >= 0) { bool major = index % MajorInterval == 0; if (major) { graphics.DrawLine(majorPen, 0, (int)value, graphSize.Width, (int)value); double vertical = graph.Parameters.VerticalPixelScale * index; graphics.DrawString( String.Format("{0:0.####}{1}", index * verticalAxisScale, verticalAxisSuffix), SystemFonts.DefaultFont, valueBrush, (int)originX, (int)value); } else { graphics.DrawLine(minorPen, 0, (int)value, graphSize.Width, (int)value); } value -= incrementY; index++; } } }