/* * NPlot - A charting library for .NET * * PointPlot.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; using System.Drawing; namespace NPlot { /// /// Encapsulates functionality for drawing data as a series of points. /// public class PointPlot : BaseSequencePlot, ISequencePlot, IPlot { private Marker marker_; /// /// Default Constructor /// public PointPlot() { marker_ = new Marker(); } /// /// Constructor for the marker plot. /// /// The marker to use. public PointPlot(Marker marker) { marker_ = marker; } /// /// The Marker object used for the plot. /// public Marker Marker { set { marker_ = value; } get { return marker_; } } /// /// Draws the point plot on a GDI+ surface against the provided x and y axes. /// /// The GDI+ surface on which to draw. /// The X-Axis to draw against. /// The Y-Axis to draw against. public virtual void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { SequenceAdapter data_ = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); float leftCutoff_ = xAxis.PhysicalMin.X - marker_.Size; float rightCutoff_ = xAxis.PhysicalMax.X + marker_.Size; for (int i = 0; i < data_.Count; ++i) { if (!Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y)) { PointF xPos = xAxis.WorldToPhysical(data_[i].X, false); if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X) continue; PointF yPos = yAxis.WorldToPhysical(data_[i].Y, false); marker_.Draw(g, (int) xPos.X, (int) yPos.Y); if (marker_.DropLine) { PointD yMin = new PointD(data_[i].X, Math.Max(0.0f, yAxis.Axis.WorldMin)); PointF yStart = yAxis.WorldToPhysical(yMin.Y, false); g.DrawLine(marker_.Pen, new Point((int) xPos.X, (int) yStart.Y), new Point((int) xPos.X, (int) yPos.Y)); } } } } /// /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { SequenceAdapter data_ = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); return data_.SuggestXAxis(); } /// /// Returns a y-axis that is suitable for drawing this plot. /// /// A suitable y-axis. public Axis SuggestYAxis() { SequenceAdapter data_ = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); return data_.SuggestYAxis(); } /// /// Draws a representation of this plot in the legend. /// /// The graphics surface on which to draw. /// A rectangle specifying the bounds of the area in the legend set aside for drawing. public void DrawInLegend(Graphics g, Rectangle startEnd) { if (marker_.Size > 0) { marker_.Draw(g, (startEnd.Left + startEnd.Right)/2, (startEnd.Top + startEnd.Bottom)/2); } else if (marker_.Pen.Width > 0) { g.DrawLine(marker_.Pen, (startEnd.Left + startEnd.Right)/2, (startEnd.Top + startEnd.Bottom - marker_.Pen.Width)/2, (startEnd.Left + startEnd.Right)/2, (startEnd.Top + startEnd.Bottom + marker_.Pen.Width)/2); } } } }