/* * NPlot - A charting library for .NET * * Grid.cs * Copyright (C) 2003-2006 Matt Howlett and others. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of NPlot nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ using System.Collections; using System.Drawing; namespace NPlot { /// /// Encapsulates a Grid IDrawable object. Instances of this to a PlotSurface2D /// instance to produce a grid. /// public class Grid : IDrawable { /// /// public enum GridType { /// /// No grid. /// None = 0, /// /// Coarse grid. Lines at large tick positions only. /// Coarse = 1, /// /// Fine grid. Lines at both large and small tick positions. /// Fine = 2 } private GridType horizontalGridType_; private Pen minorGridPen_; private GridType verticalGridType_; /// /// Default constructor /// public Grid() { minorGridPen_ = new Pen(Color.LightGray); float[] pattern = {1.0f, 2.0f}; minorGridPen_.DashPattern = pattern; MajorGridPen = new Pen(Color.LightGray); horizontalGridType_ = GridType.Coarse; verticalGridType_ = GridType.Coarse; } /// /// Specifies the horizontal grid type (none, coarse or fine). /// public GridType HorizontalGridType { get { return horizontalGridType_; } set { horizontalGridType_ = value; } } /// /// Specifies the vertical grid type (none, coarse, or fine). /// public GridType VerticalGridType { get { return verticalGridType_; } set { verticalGridType_ = value; } } /// /// The pen used to draw major (coarse) grid lines. /// public Pen MajorGridPen { get; set; } /// /// The pen used to draw minor (fine) grid lines. /// public Pen MinorGridPen { get { return minorGridPen_; } set { minorGridPen_ = value; } } /// /// Draws the grid /// /// The graphics surface on which to draw /// The physical x axis to draw horizontal lines parallel to. /// The physical y axis to draw vertical lines parallel to. public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { ArrayList xLargePositions = null; ArrayList yLargePositions = null; ArrayList xSmallPositions = null; ArrayList ySmallPositions = null; if (horizontalGridType_ != GridType.None) { xAxis.Axis.WorldTickPositions_FirstPass(xAxis.PhysicalMin, xAxis.PhysicalMax, out xLargePositions, out xSmallPositions); DrawGridLines(g, xAxis, yAxis, xLargePositions, true, MajorGridPen); } if (verticalGridType_ != GridType.None) { yAxis.Axis.WorldTickPositions_FirstPass(yAxis.PhysicalMin, yAxis.PhysicalMax, out yLargePositions, out ySmallPositions); DrawGridLines(g, yAxis, xAxis, yLargePositions, false, MajorGridPen); } if (horizontalGridType_ == GridType.Fine) { xAxis.Axis.WorldTickPositions_SecondPass(xAxis.PhysicalMin, xAxis.PhysicalMax, xLargePositions, ref xSmallPositions); DrawGridLines(g, xAxis, yAxis, xSmallPositions, true, MinorGridPen); } if (verticalGridType_ == GridType.Fine) { yAxis.Axis.WorldTickPositions_SecondPass(yAxis.PhysicalMin, yAxis.PhysicalMax, yLargePositions, ref ySmallPositions); DrawGridLines(g, yAxis, xAxis, ySmallPositions, false, MinorGridPen); } } /// /// Does all the work in drawing grid lines. /// /// The graphics surface on which to render. /// TODO /// TODO /// the list of world values to draw grid lines at. /// true if want horizontal lines, false otherwise. /// the pen to use to draw the grid lines. private void DrawGridLines( Graphics g, PhysicalAxis axis, PhysicalAxis orthogonalAxis, ArrayList a, bool horizontal, Pen p) { for (int i = 0; i < a.Count; ++i) { PointF p1 = axis.WorldToPhysical((double) a[i], true); PointF p2 = p1; PointF p3 = orthogonalAxis.PhysicalMax; PointF p4 = orthogonalAxis.PhysicalMin; if (horizontal) { p1.Y = p4.Y; p2.Y = p3.Y; } else { p1.X = p4.X; p2.X = p3.X; } // note: casting all drawing was necessary for sane display. why? g.DrawLine(p, (int) p1.X, (int) p1.Y, (int) p2.X, (int) p2.Y); } } } }