nplot-gtk-0.9.9.2/0000755000175000017500000000000010512404466014310 5ustar carlosblecarlosblenplot-gtk-0.9.9.2/README0000644000175000017500000000077410512404466015200 0ustar carlosblecarlosbleThe first version of NPlot-Gtk was made by Miguel de Icaza, and was a NPlot 0.9.8.5 wrapper. Now the version 0.9.9.2 wrapper is just an upgrade and a few hacks over the work of Miguel (Carlos Ble) ------------------------ This version of NPlot has been extended to support Gtk# on Linux. The version is based on NPlot 0.9.9.2 To build, type `make' The Gtk# demo is in lib/mf.exe and lib/test.exe Notice that you must include in your distirbution not only the .dll files, but also the .config files. nplot-gtk-0.9.9.2/lib/0000755000175000017500000000000010512404335015051 5ustar carlosblecarlosblenplot-gtk-0.9.9.2/lib/ArrowItem.cs0000644000175000017500000002662510512404106017320 0ustar carlosblecarlosble/* NPlot - A charting library for .NET ArrowItem.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// An Arrow IDrawable, with a text label that is automatically /// nicely positioned at the non-pointy end of the arrow. Future /// feature idea: have constructor that takes a dataset, and have /// the arrow know how to automatically set it's angle to avoid /// the data. /// public class ArrowItem : IDrawable { private void Init() { FontFamily fontFamily = new FontFamily("Arial"); font_ = new Font(fontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel); } /// /// Default constructor : /// text = "" /// angle = 45 degrees anticlockwise from horizontal. /// /// The position the arrow points to. public ArrowItem( PointD position ) { to_ = position; Init(); } /// /// Constructor /// /// The position the arrow points to. /// angle of arrow with respect to x axis. public ArrowItem( PointD position, double angle ) { to_ = position; angle_ = -angle; Init(); } /// /// Constructor /// /// The position the arrow points to. /// angle of arrow with respect to x axis. /// The text associated with the arrow. public ArrowItem( PointD position, double angle, string text ) { to_ = position; angle_ = -angle; text_ = text; Init(); } /// /// Text associated with the arrow. /// public string Text { get { return text_; } set { text_ = value; } } private string text_ = ""; /// /// Angle of arrow anti-clockwise to right horizontal in degrees. /// /// The code relating to this property in the Draw method is /// a bit weird. Internally, all rotations are clockwise [this is by /// accient, I wasn't concentrating when I was doing it and was half /// done before I realised]. The simplest way to make angle represent /// anti-clockwise rotation (as it is normal to do) is to make the /// get and set methods negate the provided value. public double Angle { get { return -angle_; } set { angle_ = -value; } } private double angle_ = -45.0; /// /// Physical length of the arrow. /// public float PhysicalLength { get { return physicalLength_; } set { physicalLength_ = value; } } private float physicalLength_ = 40.0f; /// /// The point the arrow points to. /// public PointD To { get { return to_; } set { to_ = value; } } private PointD to_; /// /// Size of the arrow head sides in pixels. /// public float HeadSize { get { return headSize_; } set { headSize_ = value; } } private float headSize_ = 10.0f; /// /// angle between sides of arrow head in degrees /// public float HeadAngle { get { return headAngle_; } set { headAngle_ = value; } } private float headAngle_ = 40.0f; /// /// Draws the arrow on a plot surface. /// /// graphics surface on which to draw /// The X-Axis to draw against. /// The Y-Axis to draw against. public void Draw( System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { if (this.To.X > xAxis.Axis.WorldMax || this.To.X < xAxis.Axis.WorldMin) return; if (this.To.Y > yAxis.Axis.WorldMax || this.To.Y < yAxis.Axis.WorldMin) return; double angle = this.angle_; if (this.angle_ < 0.0) { int mul = -(int)(this.angle_ / 360.0) + 2; angle = angle_ + 360.0 * (double)mul; } double normAngle = (double)angle % 360.0; // angle in range 0 -> 360. Point toPoint = new Point( (int)xAxis.WorldToPhysical( to_.X, true ).X, (int)yAxis.WorldToPhysical( to_.Y, true ).Y ); float xDir = (float)Math.Cos( normAngle * 2.0 * Math.PI / 360.0 ); float yDir = (float)Math.Sin( normAngle * 2.0 * Math.PI / 360.0 ); toPoint.X += (int)(xDir*headOffset_); toPoint.Y += (int)(yDir*headOffset_); float xOff = physicalLength_ * xDir; float yOff = physicalLength_ * yDir; Point fromPoint = new Point( (int)(toPoint.X + xOff), (int)(toPoint.Y + yOff) ); g.DrawLine( pen_, toPoint, fromPoint ); Point[] head = new Point[3]; head[0] = toPoint; xOff = headSize_ * (float)Math.Cos( (normAngle-headAngle_/2.0f) * 2.0 * Math.PI / 360.0 ); yOff = headSize_ * (float)Math.Sin( (normAngle-headAngle_/2.0f) * 2.0 * Math.PI / 360.0 ); head[1] = new Point( (int)(toPoint.X + xOff), (int)(toPoint.Y + yOff) ); float xOff2 = headSize_ * (float)Math.Cos( (normAngle+headAngle_/2.0f) * 2.0 * Math.PI / 360.0 ); float yOff2 = headSize_ * (float)Math.Sin( (normAngle+headAngle_/2.0f) * 2.0 * Math.PI / 360.0 ); head[2] = new Point( (int)(toPoint.X + xOff2), (int)(toPoint.Y + yOff2) ); g.FillPolygon( arrowBrush_, head ); SizeF textSize = g.MeasureString( text_, font_ ); SizeF halfSize = new SizeF( textSize.Width / 2.0f, textSize.Height / 2.0f ); float quadrantSlideLength = halfSize.Width + halfSize.Height; float quadrantF = (float)normAngle / 90.0f; // integer part gives quadrant. int quadrant = (int)quadrantF; // quadrant in. float prop = quadrantF - (float)quadrant; // proportion of way through this qadrant. float dist = prop * quadrantSlideLength; // distance along quarter of bounds rectangle. // now find the offset from the middle of the text box that the // rear end of the arrow should end at (reverse this to get position // of text box with respect to rear end of arrow). // // There is almost certainly an elgant way of doing this involving // trig functions to get all the signs right, but I'm about ready to // drop off to sleep at the moment, so this blatent method will have // to do. PointF offsetFromMiddle = new PointF( 0.0f, 0.0f ); switch (quadrant) { case 0: if (dist > halfSize.Height) { dist -= halfSize.Height; offsetFromMiddle = new PointF( -halfSize.Width + dist, halfSize.Height ); } else { offsetFromMiddle = new PointF( -halfSize.Width, - dist ); } break; case 1: if (dist > halfSize.Width) { dist -= halfSize.Width; offsetFromMiddle = new PointF( halfSize.Width, halfSize.Height - dist ); } else { offsetFromMiddle = new PointF( dist, halfSize.Height ); } break; case 2: if (dist > halfSize.Height) { dist -= halfSize.Height; offsetFromMiddle = new PointF( halfSize.Width - dist, -halfSize.Height ); } else { offsetFromMiddle = new PointF( halfSize.Width, -dist ); } break; case 3: if (dist > halfSize.Width) { dist -= halfSize.Width; offsetFromMiddle = new PointF( -halfSize.Width, -halfSize.Height + dist ); } else { offsetFromMiddle = new PointF( -dist, -halfSize.Height ); } break; default: throw new NPlotException( "Programmer error." ); } g.DrawString( text_, font_, textBrush_, (int)(fromPoint.X - halfSize.Width - offsetFromMiddle.X), (int)(fromPoint.Y - halfSize.Height + offsetFromMiddle.Y) ); } /// /// The brush used to draw the text associated with the arrow. /// public Brush TextBrush { get { return textBrush_; } set { textBrush_ = value; } } /// /// Set the text to be drawn with a solid brush of this color. /// public Color TextColor { set { textBrush_ = new SolidBrush( value ); } } /// /// The color of the pen used to draw the arrow. /// public Color ArrowColor { get { return pen_.Color; } set { pen_.Color = value; arrowBrush_ = new SolidBrush( value ); } } /// /// The font used to draw the text associated with the arrow. /// public Font TextFont { get { return this.font_; } set { this.font_ = value; } } /// /// Offset the whole arrow back in the arrow direction this many pixels from the point it's pointing to. /// public int HeadOffset { get { return headOffset_; } set { headOffset_ = value; } } private int headOffset_ = 2; private Brush arrowBrush_ = new SolidBrush( Color.Black ); private Brush textBrush_ = new SolidBrush( Color.Black ); private Pen pen_ = new Pen( Color.Black ); private Font font_; } } nplot-gtk-0.9.9.2/lib/AssemblyInfo.cs0000644000175000017500000000521010512404106017765 0ustar carlosblecarlosble/* NPlot - A charting library for .NET AssemblyInfo.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("NPlot")] [assembly: AssemblyDescription("NPlot Charting Library")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("netcontrols")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("0.9.9.2")] [assembly: CLSCompliant(true)] [assembly: AssemblyKeyFile("StrongName.snk")] nplot-gtk-0.9.9.2/lib/AxesConstraint.cs0000644000175000017500000004570010512404106020347 0ustar carlosblecarlosble/* NPlot - A charting library for .NET AxesConstraint.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; namespace NPlot { /// /// Classes derived from this abstract base class define and can apply /// some form of constraint to the positioning and length of one or more /// of the four axes of a PlotSurface2D. /// public abstract class AxesConstraint { /// /// Defines an AxisConstraint that forces the world length corresponding /// to one pixel on the bottom x-axis to be a certain value. /// /// TODO: Allow the pixel world length to be set for the top axis. /// public class XPixelWorldLength : AxesConstraint { private double pWorldLength_ = 0.0f; private object holdFixedY_ = null; /// /// Constructor, which defines the world pixel length only. Both /// y-axes will be moved by equal amounts in order to force this /// constraint. /// /// The world pixel length public XPixelWorldLength( double p ) { this.pWorldLength_ = p; } /// /// Constructor, which defines the world pixel length together with /// the y-axis that should be held constant when forcing this /// constraint [the other y-axis only will be moved]. /// /// The world pixel length /// The position of this y-axis will be /// held constant. The other y-axis will be moved in order to /// force the constraint. public XPixelWorldLength( double p, PlotSurface2D.YAxisPosition holdFixedY ) { this.pWorldLength_ = p; this.holdFixedY_ = holdFixedY; } /// /// Applies the constraint to the axes. /// /// The bottom x-axis. /// The left y-axis. /// The top x-axis. /// The right y-axis. public override void ApplyConstraint( PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2 ) { int desiredLength = (int)(pXAxis1.Axis.WorldLength / (double)this.pWorldLength_); int currentLength = pXAxis1.PhysicalLength; int delta = currentLength - desiredLength; int changeLeft = delta / 2; int changeRight = delta / 2; if (this.holdFixedY_ != null) { if ( (PlotSurface2D.YAxisPosition)this.holdFixedY_ == PlotSurface2D.YAxisPosition.Left ) { changeLeft = 0; changeRight = delta; } else { changeLeft = delta; changeRight = 0; } } pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X+changeLeft, pXAxis1.PhysicalMin.Y ); pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X-changeRight, pXAxis1.PhysicalMax.Y ); pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X+changeLeft, pXAxis2.PhysicalMin.Y ); pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X-changeRight, pXAxis2.PhysicalMax.Y ); pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X+changeLeft, pYAxis1.PhysicalMin.Y ); pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X+changeLeft, pYAxis1.PhysicalMax.Y ); pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X-changeRight, pYAxis2.PhysicalMin.Y ); pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X-changeRight, pYAxis2.PhysicalMax.Y ); } } /// /// Defines an AxisConstraint that forces the world length corresponding /// to one pixel on the left y-axis to be a certain value. /// /// TODO: Allow the pixel world length to be set for the right axis. /// public class YPixelWorldLength : AxesConstraint { private double pWorldLength_ = 0.0; private object holdFixedX_ = null; /// /// Constructor, which defines the world pixel length only. Both /// x-axes will be moved by equal amounts in order to force this /// constraint. /// /// The world pixel length public YPixelWorldLength( double p ) { this.pWorldLength_ = p; } /// /// Constructor, which defines the world pixel length together with /// the x-axis that should be held constant when forcing this /// constraint [the other x-axis only will be moved]. /// /// The world pixel length /// The position of this x-axis will be held constant. The other x-axis will be moved in order to force the constraint. public YPixelWorldLength( double p, PlotSurface2D.XAxisPosition holdFixedX ) { this.pWorldLength_ = p; this.holdFixedX_ = holdFixedX; } /// /// Applies the constraint to the axes. /// /// The bottom x-axis. /// The left y-axis. /// The top x-axis. /// The right y-axis. public override void ApplyConstraint( PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2 ) { int desiredLength = (int)(pYAxis1.Axis.WorldLength / this.pWorldLength_); int currentLength = pYAxis1.PhysicalLength; int delta = currentLength - desiredLength; int changeBottom = -delta / 2; int changeTop = -delta / 2; if (this.holdFixedX_ != null) { if ( (PlotSurface2D.XAxisPosition)this.holdFixedX_ == PlotSurface2D.XAxisPosition.Bottom ) { changeBottom = 0; changeTop = -delta; } else { changeBottom = -delta; changeTop = 0; } } pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X, pYAxis1.PhysicalMin.Y+changeBottom ); pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X, pYAxis1.PhysicalMax.Y-changeTop ); pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X, pYAxis2.PhysicalMin.Y+changeBottom ); pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X, pYAxis2.PhysicalMax.Y-changeTop ); pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMin.Y+changeBottom ); pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X, pXAxis1.PhysicalMax.Y+changeBottom ); pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X, pXAxis2.PhysicalMin.Y-changeTop ); pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X, pXAxis2.PhysicalMax.Y-changeTop ); } } /// /// Defines an AxisConstraint that forces the specified axis to be placed at a /// specific physical position. The position of the axis opposite is held /// constant. /// public class AxisPosition : AxesConstraint { private object xAxisPosition_; private object yAxisPosition_; private int position_; /// /// Constructor, which defines an horizontal axis and the physical /// y position it should be drawn at. /// /// The x-axis for which the y position is to be specified. /// The [physical] y position of the axis. public AxisPosition( PlotSurface2D.XAxisPosition axis, int yPosition ) { position_ = yPosition; xAxisPosition_ = axis; } /// /// Constructor, which defines a vertical axis and the physical /// x position it should be drawn at. /// /// The y-axis for which the x position is to be specified. /// The [physical] x position of the axis. public AxisPosition( PlotSurface2D.YAxisPosition axis, int xPosition ) { position_ = xPosition; yAxisPosition_ = axis; } /// /// Applies the constraint to the axes. /// /// The bottom x-axis. /// The left y-axis. /// The top x-axis. /// The right y-axis. public override void ApplyConstraint( PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2 ) { if ( xAxisPosition_ != null ) { if ((PlotSurface2D.XAxisPosition)xAxisPosition_ == PlotSurface2D.XAxisPosition.Bottom) { pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X, position_ ); pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X, position_ ); pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X, position_ ); pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X, position_ ); } else { pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X, position_ ); pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X, position_ ); pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X, position_ ); pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X, position_ ); } } else if (yAxisPosition_ != null ) { if ((PlotSurface2D.YAxisPosition)yAxisPosition_ == PlotSurface2D.YAxisPosition.Left) { pYAxis1.PhysicalMin = new Point( position_, pYAxis1.PhysicalMin.Y ); pYAxis1.PhysicalMax = new Point( position_, pYAxis1.PhysicalMax.Y ); pXAxis1.PhysicalMin = new Point( position_, pXAxis1.PhysicalMin.Y ); pXAxis2.PhysicalMin = new Point( position_, pXAxis2.PhysicalMin.Y ); } else { pYAxis2.PhysicalMin = new Point( position_, pYAxis2.PhysicalMin.Y ); pYAxis2.PhysicalMax = new Point( position_, pYAxis2.PhysicalMax.Y ); pXAxis1.PhysicalMax = new Point( position_, pXAxis1.PhysicalMax.Y ); pXAxis2.PhysicalMax = new Point( position_, pXAxis2.PhysicalMax.Y ); } } } } /// /// Defines an axes constraint that forces the world width and height pixel lengths /// to be at the provided ratio. For example, an aspect ratio of 3:2 or /// 1.5 indicates that there should be 1.5 times as many pixels per fixed /// world length along the x direction than for the same world length along /// the y direction. In other words, the world length of one pixel along /// the x direction is 2/3rds that of the world length of one pixel height /// in the y direction. /// /// /// This class will never increase the size of the plot bounding box. It /// will always be made smaller. /// public class AspectRatio : AxesConstraint { private double a_; private object holdFixedX_ = null; private object holdFixedY_ = null; /// /// Constructor. /// /// Aspect Ratio public AspectRatio( double a ) { this.a_ = a; } /// /// Constructor /// /// Aspect Ratio /// /// When adjusting the position of axes, the specified axis will never /// be moved. /// public AspectRatio( double a, PlotSurface2D.XAxisPosition holdFixedX ) { this.a_ = a; this.holdFixedX_ = holdFixedX; } /// /// Constructor /// /// Aspect Ratio /// /// When adjusting the position of axes, the /// specified axis will never be moved. /// public AspectRatio( double a, PlotSurface2D.YAxisPosition holdFixedY ) { this.a_ = a; this.holdFixedY_ = holdFixedY; } /// /// Constructor /// /// Aspect Ratio /// When adjusting the position of axes, the specified axis will never be moved. /// When adjusting the position of axes, the specified axis will never be moved. public AspectRatio( double a, PlotSurface2D.XAxisPosition holdFixedX, PlotSurface2D.YAxisPosition holdFixedY ) { this.a_ = a; this.holdFixedX_ = holdFixedX; this.holdFixedY_ = holdFixedY; } /// /// Applies the constraint to the axes. /// /// The bottom x-axis. /// The left y-axis. /// The top x-axis. /// The right y-axis. public override void ApplyConstraint( PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2 ) { double xWorldRange = Math.Abs( pXAxis1.Axis.WorldMax - pXAxis1.Axis.WorldMin ); double xPhysicalRange = Math.Abs( pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X ); double xDirPixelSize = xWorldRange / xPhysicalRange; double yWorldRange = Math.Abs( pYAxis1.Axis.WorldMax - pYAxis1.Axis.WorldMin ); double yPhysicalRange = Math.Abs( pYAxis1.PhysicalMax.Y - pYAxis1.PhysicalMin.Y ); double yDirPixelSize = yWorldRange / yPhysicalRange; double currentAspectRatio = yDirPixelSize / xDirPixelSize; // we want to change the current aspect ratio to be the desired. // to do this, we may only add the world pixel lengths. if ( this.a_ > currentAspectRatio ) { // want to increase aspect ratio. Therefore, want to add some amount // to yDirPixelSize (numerator). double toAdd = ( this.a_ - currentAspectRatio ) * xDirPixelSize; int newHeight = (int)( Math.Abs(pYAxis1.Axis.WorldMax - pYAxis1.Axis.WorldMin) / (yDirPixelSize + toAdd) ); int changeInHeight = (int)yPhysicalRange - newHeight; int changeBottom = changeInHeight/2; int changeTop = changeInHeight/2; if (this.holdFixedX_ != null) { if ( (PlotSurface2D.XAxisPosition)this.holdFixedX_ == PlotSurface2D.XAxisPosition.Bottom ) { changeBottom = 0; changeTop = changeInHeight; } else { changeBottom = changeInHeight; changeTop = 0; } } pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X, pYAxis1.PhysicalMin.Y-changeBottom ); pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X, pYAxis1.PhysicalMax.Y+changeTop ); pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X, pYAxis2.PhysicalMin.Y-changeBottom ); pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X, pYAxis2.PhysicalMax.Y+changeTop ); pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMin.Y-changeBottom ); pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X, pXAxis1.PhysicalMax.Y-changeBottom ); pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X, pXAxis2.PhysicalMin.Y+changeTop ); pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X, pXAxis2.PhysicalMax.Y+changeTop ); } else { // want to decrease aspect ratio. Therefore, want to add some amount // to xDirPixelSize (denominator). double toAdd = yDirPixelSize / this.a_ - xDirPixelSize; int newWidth = (int)( Math.Abs(pXAxis1.Axis.WorldMax - pXAxis1.Axis.WorldMin) / (xDirPixelSize + toAdd) ); int changeInWidth = (int)xPhysicalRange - newWidth; int changeLeft = changeInWidth / 2; int changeRight = changeInWidth / 2; if (this.holdFixedY_ != null) { if ( (PlotSurface2D.YAxisPosition)this.holdFixedY_ == PlotSurface2D.YAxisPosition.Left ) { changeLeft = 0; changeRight = changeInWidth; } else { changeLeft = changeInWidth; changeRight = 0; } } pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X+changeLeft, pXAxis1.PhysicalMin.Y ); pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X-changeRight, pXAxis1.PhysicalMax.Y ); pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X+changeLeft, pXAxis2.PhysicalMin.Y ); pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X-changeRight, pXAxis2.PhysicalMax.Y ); pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X+changeLeft, pYAxis1.PhysicalMin.Y ); pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X+changeLeft, pYAxis1.PhysicalMax.Y ); pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X-changeRight, pYAxis2.PhysicalMin.Y ); pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X-changeRight, pYAxis2.PhysicalMax.Y ); } } } /// /// Applies the constraint to the axes. Must be overriden. /// /// The bottom x-axis. /// The left y-axis. /// The top x-axis. /// The right y-axis. public abstract void ApplyConstraint( PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2 ); } } nplot-gtk-0.9.9.2/lib/Axis.cs0000644000175000017500000013425410512404106016311 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Axis.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Drawing.Drawing2D; using System.Drawing; using System; using System.Collections; namespace NPlot { /// /// Encapsulates functionality common to all axis classes. All specific /// axis classes derive from Axis. Axis can be used as a concrete class /// itself - it is an Axis without any embilishments [tick marks or tick /// mark labels].



/// This class encapsulates no physical information about where the axes /// are drawn. ///
public class Axis : System.ICloneable { /// /// If true, tick marks will cross the axis, with their centre on the axis line. /// If false, tick marks will be drawn as a line with origin starting on the axis line. /// public bool TicksCrossAxis { get { return ticksCrossAxis_; } set { ticksCrossAxis_ = value; } } bool ticksCrossAxis_ = false; /// /// The maximum world extent of the axis. Note that it is sensical if /// WorldMax is less than WorldMin - the axis would just be descending /// not ascending. Currently Axes won't display properly if you do /// this - use the Axis.Reversed property instead to achieve the same /// result. /// /// Setting this raises the WorldMinChanged event and the WorldExtentsChanged event. /// public virtual double WorldMax { get { return worldMax_; } set { this.worldMax_ = value; /* if (this.WorldExtentsChanged != null) this.WorldExtentsChanged(this, new WorldValueChangedArgs(worldMax_, WorldValueChangedArgs.MinMaxType.Max)); if (this.WorldMaxChanged != null) this.WorldMaxChanged(this, new WorldValueChangedArgs(worldMax_, WorldValueChangedArgs.MinMaxType.Max)); */ } } private double worldMax_; /// /// The minumum world extent of the axis. Note that it is sensical if /// WorldMax is less than WorldMin - the axis would just be descending /// not ascending. Currently Axes won't display properly if you do /// this - use the Axis.Reversed property instead to achieve the same /// result. /// /// Setting this raises the WorldMinChanged event and the WorldExtentsChanged event. /// public virtual double WorldMin { get { return this.worldMin_; } set { this.worldMin_ = value; /* if (this.WorldExtentsChanged != null) this.WorldExtentsChanged( this, new WorldValueChangedArgs( worldMin_, WorldValueChangedArgs.MinMaxType.Min) ); if (this.WorldMinChanged != null) this.WorldMinChanged( this, new WorldValueChangedArgs(worldMin_, WorldValueChangedArgs.MinMaxType.Min) ); */ } } private double worldMin_; /// /// Length (in pixels) of a large tick. Not the distance /// between large ticks. The length of the tick itself. /// public int LargeTickSize { get { return largeTickSize_; } set { largeTickSize_ = value; } } private int largeTickSize_; /// /// Length (in pixels) of the small ticks. /// public int SmallTickSize { get { return smallTickSize_; } set { smallTickSize_ = value; } } private int smallTickSize_; /// /// The Axis Label /// public string Label { get { return label_; } set { label_ = value; } } private string label_; /// /// If true, text associated with tick marks will be drawn on the other side of the /// axis line [next to the axis]. If false, tick mark text will be drawn at the end /// of the tick mark [on the same of the axis line as the tick]. /// public bool TickTextNextToAxis { get { return tickTextNextToAxis_; } set { tickTextNextToAxis_ = value; } } bool tickTextNextToAxis_; /// /// If set to true, the axis is hidden. That is, the axis line, ticks, tick /// labels and axis label will not be drawn. /// public bool Hidden { get { return hidden_; } set { hidden_ = value; } } private bool hidden_; /// /// If set true, the axis will behave as though the WorldMin and WorldMax values /// have been swapped. /// public bool Reversed { get { return reversed_; } set { reversed_ = value; } } private bool reversed_; /// /// If true, no text will be drawn next to any axis tick marks. /// public bool HideTickText { get { return hideTickText_; } set { hideTickText_ = value; } } private bool hideTickText_; /// /// This font is used for the drawing of text next to the axis tick marks. /// public Font TickTextFont { get { return this.tickTextFont_; } set { this.tickTextFont_ = value; UpdateScale(); } } private Font tickTextFont_; private Font tickTextFontScaled_; /// /// This font is used to draw the axis label. /// public Font LabelFont { get { return labelFont_; } set { labelFont_ = value; UpdateScale(); } } private Font labelFont_; private Font labelFontScaled_; /// /// Specifies the format used for drawing tick labels. See /// StringBuilder.AppendFormat for a description of this /// string. /// public string NumberFormat { get { return numberFormat_; } set { numberFormat_ = value; } } private string numberFormat_; /// /// If LargeTickStep isn't specified, then this will be calculated /// automatically. The calculated value will not be less than this /// amount. /// public int MinPhysicalLargeTickStep { get { return minPhysicalLargeTickStep_; } set { minPhysicalLargeTickStep_ = value; } } private int minPhysicalLargeTickStep_ = 30; /// /// The color of the pen used to draw the ticks and the axis line. /// public System.Drawing.Color AxisColor { get { return linePen_.Color; } set { linePen_ = new Pen( (Color)value ); } } /// /// The pen used to draw the ticks and the axis line. /// public System.Drawing.Pen AxisPen { get { return linePen_; } set { linePen_ = value; } } private System.Drawing.Pen linePen_; /// /// If true, automated tick placement will be independent of the physical /// extent of the axis. Tick placement will look good for charts of typical /// size (say physical dimensions of 640x480). If you want to produce the /// same chart on two graphics surfaces of different sizes [eg Windows.Forms /// control and printer], then you will want to set this property to true. /// If false [default], the number of ticks and their placement will be /// optimally calculated to look the best for the given axis extent. This /// is very useful if you are creating a cart with particularly small or /// large physical dimensions. /// public bool TicksIndependentOfPhysicalExtent { get { return ticksIndependentOfPhysicalExtent_; } set { ticksIndependentOfPhysicalExtent_ = value; } } private bool ticksIndependentOfPhysicalExtent_ = false; /// /// If true label is flipped about the text center line parallel to the text. /// public bool FlipTicksLabel { get { return flipTicksLabel_; } set { flipTicksLabel_ = value; } } private bool flipTicksLabel_ = false; /// /// Angle to draw ticks at (measured anti-clockwise from axis direction). /// public float TicksAngle { get { return ticksAngle_; } set { ticksAngle_ = value; } } private float ticksAngle_ = (float)Math.PI / 2.0f; /// /// Angle to draw large tick labels at (clockwise from horizontal). Note: /// this is currently only implemented well for the lower x-axis. /// public float TicksLabelAngle { get { return ticksLabelAngle_; } set { ticksLabelAngle_ = value; } } private float ticksLabelAngle_ = 0.0f; /// /// The color of the brush used to draw the axis label. /// public Color LabelColor { set { labelBrush_ = new SolidBrush( value ); } } /// /// The brush used to draw the axis label. /// public Brush LabelBrush { get { return labelBrush_; } set { labelBrush_ = value; } } private Brush labelBrush_; /// /// The color of the brush used to draw the axis tick labels. /// public Color TickTextColor { set { tickTextBrush_ = new SolidBrush( value ); } } /// /// The brush used to draw the tick text. /// public Brush TickTextBrush { get { return tickTextBrush_; } set { tickTextBrush_ = value; } } private Brush tickTextBrush_; /// /// If true, label and tick text will be scaled to match size /// of PlotSurface2D. If false, they won't be. /// /// Could also be argued this belongs in PlotSurface2D public bool AutoScaleText { get { return autoScaleText_; } set { autoScaleText_ = value; } } private bool autoScaleText_; /// /// If true, tick lengths will be scaled to match size /// of PlotSurface2D. If false, they won't be. /// /// Could also be argued this belongs in PlotSurface2D public bool AutoScaleTicks { get { return autoScaleTicks_; } set { autoScaleTicks_ = value; } } private bool autoScaleTicks_; /// /// Deep copy of Axis. /// /// /// This method includes a check that guards against derived classes forgetting /// to implement their own Clone method. If Clone is called on a object derived /// from Axis, and the Clone method hasn't been overridden by that object, then /// the test this.GetType == typeof(Axis) will fail. /// /// A copy of the Axis Class public virtual object Clone() { // ensure that this isn't being called on a derived type. If that is the case // then the derived type didn't override this method as it should have. if (this.GetType() != typeof(Axis)) { throw new NPlotException( "Clone not defined in derived type." ); } Axis a = new Axis(); DoClone( this, a ); return a; } /// /// Helper method for Clone. Does all the copying - can be called by derived /// types so they don't need to implement this part of the copying themselves. /// also useful in constructor of derived types that takes Axis class. /// protected static void DoClone( Axis b, Axis a ) { // value items a.autoScaleText_ = b.autoScaleText_; a.autoScaleTicks_ = b.autoScaleTicks_; a.worldMax_ = b.worldMax_; a.worldMin_ = b.worldMin_; a.tickTextNextToAxis_ = b.tickTextNextToAxis_; a.hidden_ = b.hidden_; a.hideTickText_ = b.hideTickText_; a.reversed_ = b.reversed_; a.ticksAngle_ = b.ticksAngle_; a.ticksLabelAngle_ = b.ticksLabelAngle_; a.minPhysicalLargeTickStep_ = b.minPhysicalLargeTickStep_; a.ticksIndependentOfPhysicalExtent_ = b.ticksIndependentOfPhysicalExtent_; a.largeTickSize_ = b.largeTickSize_; a.smallTickSize_ = b.smallTickSize_; a.ticksCrossAxis_ = b.ticksCrossAxis_; a.labelOffset_ = b.labelOffset_; a.labelOffsetAbsolute_ = b.labelOffsetAbsolute_; a.labelOffsetScaled_ = b.labelOffsetScaled_; // reference items. a.tickTextFont_ = (Font)b.tickTextFont_.Clone(); a.label_ = (string)b.label_.Clone(); if (b.numberFormat_ != null) { a.numberFormat_ = (string)b.numberFormat_.Clone(); } else { a.numberFormat_ = null; } a.labelFont_ = (Font)b.labelFont_.Clone(); a.linePen_ = (Pen)b.linePen_.Clone(); a.tickTextBrush_ = (Brush)b.tickTextBrush_.Clone(); a.labelBrush_ = (Brush)b.labelBrush_.Clone(); a.FontScale = b.FontScale; a.TickScale = b.TickScale; } /// /// Helper function for constructors. /// Do initialization here so that Clear() method is handled properly /// private void Init() { this.worldMax_ = double.NaN; this.worldMin_ = double.NaN; this.Hidden = false; this.SmallTickSize = 2; this.LargeTickSize = 6; this.FontScale = 1.0f; this.TickScale = 1.0f; this.AutoScaleTicks = false; this.AutoScaleText = false; this.TickTextNextToAxis = true; this.HideTickText = false; this.TicksCrossAxis = false; this.LabelOffset = 0.0f; this.LabelOffsetAbsolute = false; this.LabelOffsetScaled = true; this.Label = "" ; this.NumberFormat = null; this.Reversed = false; FontFamily fontFamily = new FontFamily( "Arial" ); this.TickTextFont = new Font( fontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel ); this.LabelFont = new Font( fontFamily, 12, FontStyle.Regular, GraphicsUnit.Pixel ); this.LabelColor = System.Drawing.Color.Black; this.TickTextColor = System.Drawing.Color.Black; this.linePen_ = new Pen( System.Drawing.Color.Black ); this.linePen_.Width = 1.0f; this.FontScale = 1.0f; // saves constructing these in draw method. drawFormat_ = new StringFormat(); drawFormat_.Alignment = StringAlignment.Center; } StringFormat drawFormat_; /// /// Default constructor /// public Axis( ) { this.Init(); } /// /// Constructor that takes only world min and max values. /// /// The minimum world coordinate. /// The maximum world coordinate. public Axis( double worldMin, double worldMax ) { this.Init(); this.WorldMin = worldMin; this.WorldMax = worldMax; } /// /// Copy constructor. /// /// The Axis to clone. public Axis( Axis a ) { Axis.DoClone( a, this ); } /// /// Determines whether a world value is outside range WorldMin -> WorldMax /// /// the world value to test /// true if outside limits, false otherwise public bool OutOfRange( double coord ) { if (double.IsNaN(WorldMin) || double.IsNaN(WorldMax)) { throw new NPlotException( "world min / max not set" ); } if (coord > this.WorldMax || coord < this.WorldMin) { return true; } else { return false; } } /// /// Sets the world extent of the current axis to be just large enough /// to encompas the current world extent of the axis, and the world /// extent of the passed in axis /// /// The other Axis instance. public void LUB( Axis a ) { if (a == null) { return; } // mins if (!double.IsNaN(a.worldMin_)) { if (double.IsNaN(worldMin_)) { WorldMin = a.WorldMin; } else { if (a.WorldMin < WorldMin) { WorldMin = a.WorldMin; } } } // maxs. if (!double.IsNaN(a.worldMax_)) { if (double.IsNaN(worldMax_)) { WorldMax = a.WorldMax; } else { if (a.WorldMax > WorldMax) { WorldMax = a.WorldMax; } } } } /// /// World to physical coordinate transform. /// /// The coordinate value to transform. /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// if false, then physical value may extend outside worldMin / worldMax. If true, the physical value returned will be clipped to physicalMin or physicalMax if it lies outside this range. /// The transformed coordinates. /// Not sure how much time is spent in this often called function. If it's lots, then /// worth optimizing (there is scope to do so). public virtual PointF WorldToPhysical( double coord, PointF physicalMin, PointF physicalMax, bool clip ) { // (1) account for reversed axis. Could be tricky and move // this out, but would be a little messy. PointF _physicalMin; PointF _physicalMax; if ( this.Reversed ) { _physicalMin = physicalMax; _physicalMax = physicalMin; } else { _physicalMin = physicalMin; _physicalMax = physicalMax; } // (2) if want clipped value, return extrema if outside range. if ( clip ) { if ( WorldMin < WorldMax ) { if ( coord > WorldMax ) { return _physicalMax; } if ( coord < WorldMin ) { return _physicalMin; } } else { if ( coord < WorldMax ) { return _physicalMax; } if ( coord > WorldMin ) { return _physicalMin; } } } // (3) we are inside range or don't want to clip. double range = WorldMax - WorldMin; double prop = (double)((coord - WorldMin) / range); // Force clipping at bounding box largeClip times that of real bounding box // anyway. This is effectively at infinity. const double largeClip = 100.0; if (prop > largeClip && clip) prop = largeClip; if (prop < -largeClip && clip) prop = -largeClip; if (range == 0) { if (coord >= WorldMin) prop = largeClip; if (coord < WorldMin) prop = -largeClip; } // calculate the physical coordinate. PointF offset = new PointF( (float)(prop * (_physicalMax.X - _physicalMin.X)), (float)(prop * (_physicalMax.Y - _physicalMin.Y)) ); return new PointF( (int)(_physicalMin.X + offset.X), (int)(_physicalMin.Y + offset.Y) ); } /// /// Return the world coordinate of the projection of the point p onto /// the axis. /// /// The point to project onto the axis /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// If true, the world value will be clipped to WorldMin or WorldMax as appropriate if it lies outside this range. /// The world value corresponding to the projection of the point p onto the axis. public virtual double PhysicalToWorld( PointF p, PointF physicalMin, PointF physicalMax, bool clip ) { // (1) account for reversed axis. Could be tricky and move // this out, but would be a little messy. PointF _physicalMin; PointF _physicalMax; if ( this.Reversed ) { _physicalMin = physicalMax; _physicalMax = physicalMin; } else { _physicalMin = physicalMin; _physicalMax = physicalMax; } // normalised axis dir vector float axis_X = _physicalMax.X - _physicalMin.X; float axis_Y = _physicalMax.Y - _physicalMin.Y; float len = (float)Math.Sqrt( axis_X * axis_X + axis_Y * axis_Y ); axis_X /= len; axis_Y /= len; // point relative to axis physical minimum. PointF posRel = new PointF( p.X - _physicalMin.X, p.Y - _physicalMin.Y ); // dist of point projection on axis, normalised. float prop = ( axis_X * posRel.X + axis_Y * posRel.Y ) / len; double world = prop * (this.WorldMax - this.WorldMin) + this.WorldMin; // if want clipped value, return extrema if outside range. if (clip) { world = Math.Max( world, this.WorldMin ); world = Math.Min( world, this.WorldMax ); } return world; } /// /// Draw the Axis Label /// /// The GDI+ drawing surface on which to draw. /// offset from axis. Should be calculated so as to make sure axis label misses tick labels. /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// boxed Rectangle indicating bounding box of label. null if no label printed. public object DrawLabel( Graphics g, Point offset, Point axisPhysicalMin, Point axisPhysicalMax ) { if ( Label != "" ) { // first calculate any extra offset for axis label spacing. float extraOffsetAmount = this.LabelOffset; extraOffsetAmount += 2.0f; // empirically determed - text was too close to axis before this. if (this.AutoScaleText) { if (this.LabelOffsetScaled) { extraOffsetAmount *= this.FontScale; } } // now extend offset. float offsetLength = (float)Math.Sqrt( offset.X*offset.X + offset.Y*offset.Y ); if (offsetLength > 0.01) { float x_component = offset.X / offsetLength; float y_component = offset.Y / offsetLength; x_component *= extraOffsetAmount; y_component *= extraOffsetAmount; if (this.LabelOffsetAbsolute) { offset.X = (int)x_component; offset.Y = (int)y_component; } else { offset.X += (int)x_component; offset.Y += (int)y_component; } } // determine angle of axis in degrees double theta = Math.Atan2( axisPhysicalMax.Y - axisPhysicalMin.Y, axisPhysicalMax.X - axisPhysicalMin.X ); theta = theta * 180.0f / Math.PI; PointF average = new PointF( (axisPhysicalMax.X + axisPhysicalMin.X)/2.0f, (axisPhysicalMax.Y + axisPhysicalMin.Y)/2.0f ); g.TranslateTransform( offset.X , offset.Y ); // this is done last. g.TranslateTransform( average.X, average.Y ); g.RotateTransform( (float)theta ); // this is done first. SizeF labelSize = g.MeasureString( Label, labelFontScaled_); //bounding box for label centered around zero. RectangleF drawRect = new RectangleF( -labelSize.Width/2.0f, -labelSize.Height/2.0f, labelSize.Width, labelSize.Height ); g.DrawString( Label, labelFontScaled_, labelBrush_, drawRect, drawFormat_ ); // now work out physical bounds of label. Matrix m = g.Transform; PointF[] recPoints = new PointF[2]; recPoints[0] = new PointF( -labelSize.Width/2.0f, -labelSize.Height/2.0f ); recPoints[1] = new PointF( labelSize.Width/2.0f, labelSize.Height/2.0f ); m.TransformPoints( recPoints ); int x1 = (int)Math.Min( recPoints[0].X, recPoints[1].X ); int x2 = (int)Math.Max( recPoints[0].X, recPoints[1].X ); int y1 = (int)Math.Min( recPoints[0].Y, recPoints[1].Y ); int y2 = (int)Math.Max( recPoints[0].Y, recPoints[1].Y ); g.ResetTransform(); // and return label bounding box. return new Rectangle( x1, y1, (x2-x1), (y2-y1) ); } return null; } /// /// Draw a tick on the axis. /// /// The graphics surface on which to draw. /// The tick position in world coordinates. /// The size of the tick (in pixels) /// The text associated with the tick /// The Offset to draw from the auto calculated position /// The minimum physical extent of the axis /// The maximum physical extent of the axis /// out: The bounding rectangle for the tick and tickLabel drawn /// out: offset from the axies required for axis label public virtual void DrawTick( Graphics g, double w, float size, string text, Point textOffset, Point axisPhysMin, Point axisPhysMax, out Point labelOffset, out Rectangle boundingBox ) { // determine physical location where tick touches axis. PointF tickStart = WorldToPhysical( w, axisPhysMin, axisPhysMax, true ); // determine offset from start point. PointF axisDir = Utils.UnitVector( axisPhysMin, axisPhysMax ); // rotate axis dir clockwise by angle radians to get tick direction. float x1 = (float)(Math.Cos( -this.TicksAngle ) * axisDir.X + Math.Sin( -this.TicksAngle ) * axisDir.Y); float y1 = (float)(-Math.Sin( -this.TicksAngle ) * axisDir.X + Math.Cos( -this.TicksAngle ) * axisDir.Y); // now get the scaled tick vector. PointF tickVector = new PointF( this.TickScale * size * x1, this.TickScale * size * y1 ); if (this.TicksCrossAxis) { tickStart = new PointF( tickStart.X - tickVector.X / 2.0f, tickStart.Y - tickVector.Y / 2.0f ); } // and the end point [point off axis] of tick mark. PointF tickEnd = new PointF( tickStart.X + tickVector.X, tickStart.Y + tickVector.Y ); // and draw it! if (g != null) g.DrawLine( this.linePen_, (int)tickStart.X, (int)tickStart.Y, (int)tickEnd.X, (int)tickEnd.Y ); // note: casting to int for tick positions was necessary to ensure ticks drawn where we wanted // them. Not sure of the reason. // calculate bounds of tick. int minX = (int)Math.Min( tickStart.X, tickEnd.X ); int minY = (int)Math.Min( tickStart.Y, tickEnd.Y ); int maxX = (int)Math.Max( tickStart.X, tickEnd.X ); int maxY = (int)Math.Max( tickStart.Y, tickEnd.Y ); boundingBox = new Rectangle( minX, minY, maxX-minX, maxY-minY ); // by default, label offset from axis is 0. TODO: revise this. labelOffset = new Point( -(int)tickVector.X, -(int)tickVector.Y ); // ------------------------ // now draw associated text. // **** TODO **** // The following code needs revising. A few things are hard coded when // they should not be. Also, angled tick text currently just works for // the bottom x-axis. Also, it's a bit hacky. if (text != "" && !HideTickText && g != null ) { SizeF textSize = g.MeasureString( text, tickTextFontScaled_ ); // determine the center point of the tick text. float textCenterX; float textCenterY; // if text is at pointy end of tick. if (!this.TickTextNextToAxis) { // offset due to tick. textCenterX = tickStart.X + tickVector.X*1.2f; textCenterY = tickStart.Y + tickVector.Y*1.2f; // offset due to text box size. textCenterX += 0.5f * x1 * textSize.Width; textCenterY += 0.5f * y1 * textSize.Height; } // else it's next to the axis. else { // start location. textCenterX = tickStart.X; textCenterY = tickStart.Y; // offset due to text box size. textCenterX -= 0.5f * x1 * textSize.Width; textCenterY -= 0.5f * y1 * textSize.Height; // bring text away from the axis a little bit. textCenterX -= x1*(2.0f+FontScale); textCenterY -= y1*(2.0f+FontScale); } // If tick text is angled.. if (this.TicksLabelAngle != 0.0f) { // determine the point we want to rotate text about. PointF textScaledTickVector = new PointF( this.TickScale * x1 * (textSize.Height/2.0f), this.TickScale * y1 * (textSize.Height/2.0f) ); PointF rotatePoint; if (this.TickTextNextToAxis) { rotatePoint = new PointF( tickStart.X - textScaledTickVector.X, tickStart.Y - textScaledTickVector.Y ); } else { rotatePoint = new PointF( tickEnd.X + textScaledTickVector.X, tickEnd.Y + textScaledTickVector.Y ); } float actualAngle; if (flipTicksLabel_) { double radAngle = (Math.PI / 180) * this.TicksLabelAngle; rotatePoint.X += textSize.Width * (float)Math.Cos(radAngle); rotatePoint.Y += textSize.Width * (float)Math.Sin(radAngle); actualAngle = this.TicksLabelAngle + 180; } else { actualAngle = this.TicksLabelAngle; } g.TranslateTransform( rotatePoint.X, rotatePoint.Y ); g.RotateTransform( actualAngle ); Matrix m = g.Transform; PointF[] recPoints = new PointF[2]; recPoints[0] = new PointF( 0.0f, -(textSize.Height / 2) ); recPoints[1] = new PointF( textSize.Width, textSize.Height ); m.TransformPoints( recPoints ); float t_x1 = Math.Min( recPoints[0].X, recPoints[1].X ); float t_x2 = Math.Max( recPoints[0].X, recPoints[1].X ); float t_y1 = Math.Min( recPoints[0].Y, recPoints[1].Y ); float t_y2 = Math.Max( recPoints[0].Y, recPoints[1].Y ); boundingBox = Rectangle.Union(boundingBox, new Rectangle( (int)t_x1, (int)t_y1, (int)(t_x2-t_x1), (int)(t_y2-t_y1) ) ); RectangleF drawRect = new RectangleF( 0.0f, -(textSize.Height / 2), textSize.Width, textSize.Height ); g.DrawString( text, tickTextFontScaled_, tickTextBrush_, drawRect, drawFormat_ ); t_x2 -= tickStart.X; t_y2 -= tickStart.Y; t_x2 *= 1.25f; t_y2 *= 1.25f; labelOffset = new Point( (int)t_x2, (int)t_y2 ); g.ResetTransform(); //g.DrawRectangle( new Pen(Color.Purple), boundingBox.X, boundingBox.Y, boundingBox.Width, boundingBox.Height ); } else { float bx1 = (textCenterX - textSize.Width/2.0f); float by1 = (textCenterY - textSize.Height/2.0f); float bx2 = textSize.Width; float by2 = textSize.Height; RectangleF drawRect = new RectangleF( bx1, by1, bx2, by2 ); Rectangle drawRect_int = new Rectangle( (int)bx1, (int)by1, (int)bx2, (int)by2 ); // g.DrawRectangle( new Pen(Color.Green), bx1, by1, bx2, by2 ); boundingBox = Rectangle.Union( boundingBox, drawRect_int ); // g.DrawRectangle( new Pen(Color.Purple), boundingBox.X, boundingBox.Y, boundingBox.Width, boundingBox.Height ); g.DrawString( text, tickTextFontScaled_, tickTextBrush_, drawRect, drawFormat_ ); textCenterX -= tickStart.X; textCenterY -= tickStart.Y; textCenterX *= 2.3f; textCenterY *= 2.3f; labelOffset = new Point( (int)textCenterX, (int)textCenterY ); } } } /// /// Draw the axis. This involves three steps: /// (1) Draw the axis line. /// (2) Draw the tick marks. /// (3) Draw the label. /// /// The drawing surface on which to draw. /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// out The bounding rectangle of the axis including axis line, label, tick marks and tick mark labels public virtual void Draw( System.Drawing.Graphics g, Point physicalMin, Point physicalMax, out Rectangle boundingBox ) { // calculate the bounds of the axis line only. int x1 = Math.Min( physicalMin.X, physicalMax.X ); int x2 = Math.Max( physicalMin.X, physicalMax.X ); int y1 = Math.Min( physicalMin.Y, physicalMax.Y ); int y2 = Math.Max( physicalMin.Y, physicalMax.Y ); Rectangle bounds = new Rectangle( x1, y1, x2-x1, y2-y1 ); if (!Hidden) { // (1) Draw the axis line. g.DrawLine( this.linePen_, physicalMin.X, physicalMin.Y, physicalMax.X, physicalMax.Y ); // (2) draw tick marks (subclass responsibility). object labelOffset; object tickBounds; this.DrawTicks( g, physicalMin, physicalMax, out labelOffset, out tickBounds ); // (3) draw the axis label object labelBounds = null; if (!this.HideTickText) { labelBounds = this.DrawLabel( g, (Point)labelOffset, physicalMin, physicalMax ); } // (4) merge bounds and return. if (labelBounds != null) bounds = Rectangle.Union( bounds, (Rectangle)labelBounds ); if (tickBounds != null) bounds = Rectangle.Union( bounds, (Rectangle)tickBounds ); } boundingBox = bounds; } /// /// Update the bounding box and label offset associated with an axis /// to encompass the additionally specified mergeBoundingBox and /// mergeLabelOffset respectively. /// /// Current axis label offset. /// Current axis bounding box. /// the label offset to merge. The current label offset will be replaced by this if it's norm is larger. /// the bounding box to merge. The current bounding box will be replaced by this if null, or by the least upper bound of bother bounding boxes otherwise. protected static void UpdateOffsetAndBounds( ref object labelOffset, ref object boundingBox, Point mergeLabelOffset, Rectangle mergeBoundingBox ) { // determining largest label offset and use it. Point lo = (Point)labelOffset; double norm1 = Math.Sqrt( lo.X*lo.X + lo.Y*lo.Y ); double norm2 = Math.Sqrt( mergeLabelOffset.X*mergeLabelOffset.X + mergeLabelOffset.Y*mergeLabelOffset.Y ); if (norm1 < norm2) { labelOffset = mergeLabelOffset; } // determining bounding box. Rectangle b = mergeBoundingBox; if (boundingBox == null) { boundingBox = b; } else { boundingBox = Rectangle.Union( (Rectangle)boundingBox, b ); } } /// /// DrawTicks method. In base axis class this does nothing. /// /// The graphics surface on which to draw /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// is set to a suitable offset from the axis to draw the axis label. In this base method, set to null. /// is set to the smallest box that bounds the ticks and the tick text. In this base method, set to null. protected virtual void DrawTicks( Graphics g, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { labelOffset = null; boundingBox = null; // do nothing. This class is not abstract because a subclass may // want to override the Axis.Draw method to one that doesn't // require DrawTicks. } /// /// World extent of the axis. /// public double WorldLength { get { return Math.Abs( worldMax_ - worldMin_ ); } } /// /// Determines the positions, in world coordinates, of the large ticks. /// When the physical extent of the axis is small, some of the positions /// that were generated in this pass may be converted to small tick /// positions and returned as well. /// /// This default implementation returns empty large ticks list and null /// small tick list. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// ArrayList containing the positions of the small ticks if calculated, null otherwise. internal virtual void WorldTickPositions_FirstPass( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { largeTickPositions = new ArrayList(); smallTickPositions = null; } /// /// Determines the positions, in world coordinates, of the small ticks /// if they have not already been generated. /// /// This default implementation creates an empty smallTickPositions list /// if it doesn't already exist. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// The positions of the large ticks. /// If null, small tick positions are returned via this parameter. Otherwise this function does nothing. internal virtual void WorldTickPositions_SecondPass( Point physicalMin, Point physicalMax, ArrayList largeTickPositions, ref ArrayList smallTickPositions ) { if (smallTickPositions == null) smallTickPositions = new ArrayList(); } /// /// Determines the positions of all Large and Small ticks. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// ArrayList containing the positions of the small ticks. public void WorldTickPositions( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { WorldTickPositions_FirstPass( physicalMin, physicalMax, out largeTickPositions, out smallTickPositions ); WorldTickPositions_SecondPass( physicalMin, physicalMax, largeTickPositions, ref smallTickPositions ); } /// /// Moves the world min and max values so that the world axis /// length is [percent] bigger. If the current world /// max and min values are the same, they are moved appart /// an arbitrary amount. This arbitrary amount is currently /// 0.01, and will probably be configurable in the future. /// /// Percentage to increase world length by. /// Works for the case WorldMax is less than WorldMin. public void IncreaseRange( double percent ) { double range = WorldMax - WorldMin; if ( !Utils.DoubleEqual( range, 0.0 ) ) { range *= percent; } else { // arbitrary number. // TODO make this configurable. range = 0.01; } WorldMax += range; WorldMin -= range; } /// /// Scale label and tick fonts by this factor. Set by PlotSurface2D /// Draw method. /// internal float FontScale { get { return fontScale_; } set { fontScale_ = value; UpdateScale(); } } private float fontScale_; /// /// Scale tick mark lengths by this factor. Set by PlotSurface2D /// Draw method. /// internal float TickScale { get { return tickScale_; } set { tickScale_ = value; } } private float tickScale_; private void UpdateScale() { if (labelFont_ != null) this.labelFontScaled_ = Utils.ScaleFont( labelFont_, FontScale ); if (tickTextFont_ != null) this.tickTextFontScaled_ = Utils.ScaleFont( tickTextFont_, FontScale ); } /// /// Get whether or not this axis is linear. /// public virtual bool IsLinear { get { return true; } } private float labelOffset_ = 0; /// /// If LabelOffsetAbsolute is false (default) then this is the offset /// added to default axis label position. If LabelOffsetAbsolute is /// true, then this is the absolute offset of the label from the axis. /// /// If positive, offset is further away from axis, if negative, towards /// the axis. /// public float LabelOffset { get { return labelOffset_; } set { labelOffset_ = value; } } private bool labelOffsetAbsolute_ = false; /// /// If true, the value specified by LabelOffset is the absolute distance /// away from the axis that the label is drawn. If false, the value /// specified by LabelOffset is added to the pre-calculated value to /// determine the axis label position. /// /// public bool LabelOffsetAbsolute { get { return labelOffsetAbsolute_; } set { labelOffsetAbsolute_ = value; } } private bool labelOffsetScaled_ = true; /// /// Whether or not the supplied LabelOffset should be scaled by /// a factor as specified by FontScale. /// public bool LabelOffsetScaled { get { return labelOffsetScaled_; } set { labelOffsetScaled_ = value; } } /// /// returns a suitable offset for the axis label in the case that there are no /// ticks or tick text in the way. /// /// physical point corresponding to the axis world maximum. /// physical point corresponding to the axis world minimum. /// axis label offset protected Point getDefaultLabelOffset( Point physicalMin, Point physicalMax ) { System.Drawing.Rectangle tBoundingBox; System.Drawing.Point tLabelOffset; this.DrawTick( null, this.WorldMax, this.LargeTickSize, "", new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); return tLabelOffset; } /// /// Set the Axis color (sets all of axis line color, Tick text color, and label color). /// public Color Color { set { this.AxisColor = value; this.TickTextColor = value; this.LabelColor = value; } } /* // finish implementation of this at some point. public class WorldValueChangedArgs { public WorldValueChangedArgs( double value, MinMaxType minOrMax ) { Value = value; MinOrMax = minOrMax; } public double Value; public enum MinMaxType { Min = 0, Max = 1 } public MinMaxType MinOrMax; } public delegate void WorldValueChangedHandler( object sender, WorldValueChangedArgs e ); public event WorldValueChangedHandler WorldMinChanged; public event WorldValueChangedHandler WorldMaxChanged; public event WorldValueChangedHandler WorldExtentsChanged; */ } } nplot-gtk-0.9.9.2/lib/BasePlot.cs0000644000175000017500000000721010512404106017105 0ustar carlosblecarlosble/* NPlot - A charting library for .NET BasePlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// Supplies implementation of basic legend handling properties, and /// basic data specifying properties which are used by all plots. /// /// If C# had multiple inheritance, the heirachy would be different. public abstract class BasePlot { /// /// A label to associate with the plot - used in the legend. /// public string Label { get { return label_; } set { this.label_ = value; } } private string label_ = ""; /// /// Whether or not to include an entry for this plot in the legend if it exists. /// public bool ShowInLegend { get { return showInLegend_; } set { this.showInLegend_ = value; } } private bool showInLegend_ = true; /// /// Gets or sets the source containing a list of values used to populate the plot object. /// public object DataSource { get { return this.dataSource_; } set { this.dataSource_ = value; } } private object dataSource_ = null; /// /// Gets or sets the specific data member in a multimember data source to get data from. /// public string DataMember { get { return this.dataMember_; } set { this.dataMember_ = value; } } private string dataMember_ = null; } } nplot-gtk-0.9.9.2/lib/BasePlot3D.cs0000644000175000017500000000244310512404106017277 0ustar carlosblecarlosble// ******** experimental ******** /* using System; namespace NPlot { /// /// Functionality shared amoungst all 3D plots. TODO: Not implemented. /// public class BasePlot3D { /// /// Constructor. /// public BasePlot3D() { } // DATA SPECIFIERS // in first instance I think just have a DataSource, with // the only way of specifying points as an ArrayList of // point3s /// /// Gets or sets the source containing a list of values used to populate the plot object. /// public object DataSource { get { return dataSource_; } set { dataSource_ = value; } } object dataSource_ = null; need a SequenceAdapter3D to interpret all this crap - probably build on SequenceAdapter. public string DataMember { get { return dataMember_; } set { dataMember_ = value; } } string dataMember_ = null; // these are needed for access to table columns. public object XData { get { } set { } } public object YData { get { } set { } } public object ZData { get { } set { } } } } */nplot-gtk-0.9.9.2/lib/BaseSequenceLinePlot.cs0000644000175000017500000000274410512404106021415 0ustar carlosblecarlosbleusing System; using System.Drawing; namespace NPlot { /// /// supplies implementation of basic functionality for plots based on drawing /// lines [line, step and histogram]. /// /// If C# had multiple inheritance, the heirachy would be different. The way it is isn't very nice. public class BaseSequenceLinePlot : BaseSequencePlot, ISequencePlot { /// /// 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 virtual void DrawInLegend( Graphics g, Rectangle startEnd ) { g.DrawLine( pen_, startEnd.Left, (startEnd.Top + startEnd.Bottom)/2, startEnd.Right, (startEnd.Top + startEnd.Bottom)/2 ); } /// /// The pen used to draw the plot /// public System.Drawing.Pen Pen { get { return pen_; } set { pen_ = value; } } private System.Drawing.Pen pen_ = new Pen( Color.Black ); /// /// The color of the pen used to draw lines in this plot. /// public System.Drawing.Color Color { set { if (pen_ != null) { pen_.Color = value; } else { pen_ = new Pen( value ); } } get { return pen_.Color; } } } } nplot-gtk-0.9.9.2/lib/BaseSequencePlot.cs0000644000175000017500000000761610512404106020610 0ustar carlosblecarlosble/* NPlot - A charting library for .NET BaseSequencePlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; namespace NPlot { /// /// Adds additional basic functionality to BasePlot that is common to all /// plots that implement the ISequencePlot interface. /// /// If C# had multiple inheritance, the heirachy would be different. The way it is isn't very nice. public class BaseSequencePlot : BasePlot, ISequencePlot { /// /// Gets or sets the data, or column name for the ordinate [y] axis. /// public object OrdinateData { get { return this.ordinateData_; } set { this.ordinateData_ = value; } } private object ordinateData_ = null; /// /// Gets or sets the data, or column name for the abscissa [x] axis. /// public object AbscissaData { get { return this.abscissaData_; } set { this.abscissaData_ = value; } } private object abscissaData_ = null; /// /// Writes text data of the plot object to the supplied string builder. It is /// possible to specify that only data in the specified range be written. /// /// the StringBuilder object to write to. /// a region used if onlyInRegion is true. /// If true, only data enclosed in the provided region will be written. public void WriteData( System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion ) { SequenceAdapter data_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); sb.Append( "Label: " ); sb.Append( this.Label ); sb.Append( "\r\n" ); data_.WriteData( sb, region, onlyInRegion ); } } } nplot-gtk-0.9.9.2/lib/Bitmap.PlotSurface2D.cs0000644000175000017500000003111110512404106021221 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Bitmap.PlotSurface2D.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; using System.Collections; namespace NPlot { namespace Bitmap { /// /// Wrapper around NPlot.PlotSurface2D that provides extra functionality /// specific to drawing to Bitmaps. /// public class PlotSurface2D: IPlotSurface2D { /// /// Constructor. /// /// width of the bitmap. /// height of the bitmap. public PlotSurface2D( int width, int height ) { b_ = new System.Drawing.Bitmap( width, height ); ps_ = new NPlot.PlotSurface2D(); } /// /// Constructor. /// /// The Bitmap where the plot is to be rendered. public PlotSurface2D( System.Drawing.Bitmap b ) { b_ = b; ps_ = new NPlot.PlotSurface2D(); } /// /// Renders the plot. /// /// The graphics surface. /// The rectangle storing the bounds for rendering. public void Draw( Graphics g, Rectangle bounds ) { ps_.Draw( g, bounds ); } /// /// Clears the plot. /// public void Clear() { ps_.Clear(); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. public void Add( IDrawable p ) { ps_.Add( p ); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp ) { ps_.Add( p, xp, yp ); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, int zOrder ) { ps_.Add( p, zOrder ); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp, int zOrder ) { ps_.Add( p, xp, yp , zOrder); } /// /// The plot surface title. /// public string Title { get { return ps_.Title; } set { ps_.Title = value; } } /// /// The plot title font. /// public Font TitleFont { get { return ps_.TitleFont; } set { ps_.TitleFont = value; } } /// /// The distance in pixels to leave between of the edge of the bounding rectangle /// supplied to the Draw method, and the markings that make up the plot. /// public int Padding { get { return ps_.Padding; } set { ps_.Padding = value; } } /// /// The bottom abscissa axis. /// public Axis XAxis1 { get { return ps_.XAxis1; } set { ps_.XAxis1 = value; } } /// /// The left ordinate axis. /// public Axis YAxis1 { get { return ps_.YAxis1; } set { ps_.YAxis1 = value; } } /// /// The top abscissa axis. /// public Axis XAxis2 { get { return ps_.XAxis2; } set { ps_.XAxis2 = value; } } /// /// The right ordinate axis. /// public Axis YAxis2 { get { return ps_.YAxis2; } set { ps_.YAxis2 = value; } } /// /// Gets or Sets the legend to use with this plot surface. /// public NPlot.Legend Legend { get { return ps_.Legend; } set { ps_.Legend = value; } } /// /// Gets or Sets the legend z-order. /// public int LegendZOrder { get { return ps_.LegendZOrder; } set { ps_.LegendZOrder = value; } } /// /// A color used to paint the plot background. Mutually exclusive with PlotBackImage and PlotBackBrush /// public System.Drawing.Color PlotBackColor { set { ps_.PlotBackColor = value; } } /// /// An imaged used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// public System.Drawing.Bitmap PlotBackImage { set { ps_.PlotBackImage = value; } } /// /// A Rectangle brush used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// public IRectangleBrush PlotBackBrush { set { ps_.PlotBackBrush = value; } } /// /// Smoothing mode to use when drawing plots. /// public System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get { return ps_.SmoothingMode; } set { ps_.SmoothingMode = value; } } /// /// The bitmap width /// public int Width { get { return b_.Width; } } /// /// The bitmap height /// public int Height { get { return b_.Height; } } /// /// Renders the bitmap to a MemoryStream. Useful for returning the bitmap from /// an ASP.NET page. /// /// The MemoryStream object. public System.IO.MemoryStream ToStream( System.Drawing.Imaging.ImageFormat imageFormat ) { System.IO.MemoryStream stream = new System.IO.MemoryStream(); ps_.Draw(Graphics.FromImage(this.Bitmap),new System.Drawing.Rectangle(0,0,b_.Width,b_.Height)); this.Bitmap.Save(stream, imageFormat); return stream; } /// /// The bitmap to use as the drawing surface. /// public System.Drawing.Bitmap Bitmap { get { return b_; } set { b_ = value; } } /// /// The bitmap background color outside the bounds of the plot surface. /// public Color BackColor { set { backColor_ = value; } } object backColor_ = null; /// /// Refreshes (draws) the plot. /// public void Refresh() { if (this.backColor_!=null) { Graphics g = Graphics.FromImage( b_ ); g.FillRectangle( (new Pen( (Color)this.backColor_)).Brush,0,0,b_.Width,b_.Height ); } ps_.Draw( Graphics.FromImage(b_), new System.Drawing.Rectangle(0,0,b_.Width,b_.Height) ); } private NPlot.PlotSurface2D ps_; private System.Drawing.Bitmap b_; /// /// Add an axis constraint to the plot surface. Axis constraints can /// specify relative world-pixel scalings, absolute axis positions etc. /// /// The axis constraint to add. public void AddAxesConstraint( AxesConstraint c ) { ps_.AddAxesConstraint( c ); } /// /// Whether or not the title will be scaled according to size of the plot /// surface. /// public bool AutoScaleTitle { get { return ps_.AutoScaleTitle; } set { ps_.AutoScaleTitle = value; } } /// /// When plots are added to the plot surface, the axes they are attached to /// are immediately modified to reflect data of the plot. If /// AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will /// be turned in to auto scaling ones if they are not already [tick marks, /// tick text and label size scaled to size of plot surface]. If false, /// axes will not be autoscaling. /// public bool AutoScaleAutoGeneratedAxes { get { return ps_.AutoScaleAutoGeneratedAxes; } set { ps_.AutoScaleAutoGeneratedAxes = value; } } /// /// Sets the title to be drawn using a solid brush of this color. /// public Color TitleColor { set { ps_.TitleColor = value; } } /// /// The brush used for drawing the title. /// public Brush TitleBrush { get { return ps_.TitleBrush; } set { ps_.TitleBrush = value; } } /// /// Remove a drawable object from the plot surface. /// /// the drawable to remove /// whether or not to update the axes after removing the idrawable. public void Remove(IDrawable p, bool updateAxes) { ps_.Remove(p, updateAxes); } /// /// Gets an array list containing all drawables currently added to the PlotSurface2D. /// public ArrayList Drawables { get { return ps_.Drawables; } } } } } nplot-gtk-0.9.9.2/lib/BubblePlot.cs0000644000175000017500000000233710512404106017433 0ustar carlosblecarlosbleusing System; /* namespace NPlot { /// /// Summary description for BubblePlot. /// public class BubblePlot : BasePlot, IPlot { /// /// Constructor /// public BubblePlot() { } public void DrawInLegend(System.Drawing.Graphics g, System.Drawing.Rectangle startEnd) { // TODO: Add BubblePlot.DrawInLegend implementation } public string Label { get { // TODO: Add BubblePlot.Label getter implementation return null; } set { // TODO: Add BubblePlot.Label setter implementation } } public bool ShowInLegend { get { // TODO: Add BubblePlot.ShowInLegend getter implementation return false; } set { // TODO: Add BubblePlot.ShowInLegend setter implementation } } public Axis SuggestXAxis() { // TODO: Add BubblePlot.SuggestXAxis implementation return null; } public Axis SuggestYAxis() { // TODO: Add BubblePlot.SuggestYAxis implementation return null; } public void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { // TODO: Add BubblePlot.Draw implementation } } } */nplot-gtk-0.9.9.2/lib/CandlePlot.cs0000644000175000017500000006250310512404106017427 0ustar carlosblecarlosble/* NPlot - A charting library for .NET CandlePlot.cs Copyright (C) 2003 Matt Howlett Pawel Konieczny Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Data; namespace NPlot { /// /// Encapsulates open, low, high and close values useful for specifying financial data /// over a time period, together with a [single] x-value indicating the time [period] the /// data corresponds to. /// public class PointOLHC { /// /// Constructor /// /// value representing the time period that the financial values refer to /// The value at open of time period. /// The low value over the time period /// The high value over the time period. /// The value at close of time period. public PointOLHC( double x, double open, double low, double high, double close ) { this.x_ = x; this.open_ = open; this.close_ = close; this.low_ = low; this.high_ = high; } /// /// value representing the time period that the financial values apply to. /// public double X { get { return x_; } set { this.x_ = value; } } private double x_; /// /// The value at open of time period. /// public double Open { get { return open_; } set { open_ = value; } } private double open_; /// /// The value at close of time period. /// public double Close { get { return close_; } set { close_ = value; } } private double close_; /// /// Low value of the time period. /// public double Low { get { return low_; } set { low_ = value; } } private double low_; /// /// High value of the time period. /// public double High { get { return high_; } set { high_ = value; } } private double high_; } /// /// Encapsulates functionality for drawing finacial candle charts. /// public class CandlePlot : BasePlot, IPlot { /// /// /// public abstract class CandleStyle { /// /// /// /// /// public abstract CandleStyle Create(CandleDataAdapter d); } /// /// /// public class Stick : CandleStyle { private Stick() { } /// /// /// /// /// public override CandleStyle Create(CandleDataAdapter d) { return new Stick(); } } /// /// This class is responsible for interpreting the various ways you can /// specify data to CandlePlot objects /// public class CandleDataAdapter { private object openData_; private object lowData_; private object highData_; private object closeData_; private object abscissaData_; private object dataSource_; private string dataMember_; DataRowCollection rows_ = null; // speed optimizations if data is double. private double[] openDataArray_; private double[] lowDataArray_; private double[] highDataArray_; private double[] closeDataArray_; private double[] abscissaDataArray_; private bool useDoublesArrays_; /// /// Constructor /// /// /// /// /// /// /// /// public CandleDataAdapter( object dataSource, string dataMember, object abscissaData, object openData, object lowData, object highData, object closeData ) { this.openData_ = openData; this.lowData_ = lowData; this.highData_ = highData; this.closeData_ = closeData; this.abscissaData_ = abscissaData; this.dataSource_ = dataSource; this.dataMember_ = dataMember; if (dataSource_ != null) { if ( dataSource_ is DataSet ) { if (dataMember_ != null) { rows_ = ((DataTable)((DataSet)dataSource_).Tables[dataMember_]).Rows; } else { rows_ = ((DataTable)((DataSet)dataSource_).Tables[0]).Rows; } } else if (dataSource_ is DataTable ) { rows_ = ((DataTable)dataSource_).Rows; } else { throw new NPlotException ( "not implemented yet" ); } } openDataArray_ = openData_ as System.Double[]; lowDataArray_ = lowData_ as System.Double[]; highDataArray_ = highData_ as System.Double[]; closeDataArray_ = closeData_ as System.Double[]; abscissaDataArray_ = abscissaData_ as System.Double[]; useDoublesArrays_ = ( openDataArray_ != null && lowDataArray_ != null && highDataArray_ != null && lowDataArray_ != null && abscissaDataArray_ != null ); } /// /// Gets the ith point in the candle adapter /// /// index of datapoint to get /// the datapoint. public PointOLHC this[int i] { get { // try a fast track first if (useDoublesArrays_) { return new PointOLHC( abscissaDataArray_[i], openDataArray_[i], lowDataArray_[i], highDataArray_[i], closeDataArray_[i]); } // is the data coming from a data source? else if (rows_ != null) { double x = Utils.ToDouble(((DataRow)(rows_[i]))[(string)abscissaData_]); double open = Utils.ToDouble(((DataRow)(rows_[i]))[(string)openData_]); double low = Utils.ToDouble(((DataRow)(rows_[i]))[(string)lowData_]); double high = Utils.ToDouble(((DataRow)(rows_[i]))[(string)highData_]); double close = Utils.ToDouble(((DataRow)(rows_[i]))[(string)closeData_]); return new PointOLHC(x, open, low, high, close); } // the data is coming from individual arrays. else if (abscissaData_ is Array && openData_ is Array && lowData_ is Array && highData_ is Array && closeData_ is Array) { double x = Utils.ToDouble(((Array)abscissaData_).GetValue(i)); double open = Utils.ToDouble(((Array)openData_).GetValue(i)); double low = Utils.ToDouble(((Array)lowData_).GetValue(i)); double high = Utils.ToDouble(((Array)highData_).GetValue(i)); double close = Utils.ToDouble(((Array)closeData_).GetValue(i)); return new PointOLHC(x, open, low, high, close); } else { throw new NPlotException("not implemented yet"); } } } /// /// The number of datapoints available via the candle adapter. /// /// the number of datapoints available. public int Count { get { // this is inefficient [could set up delegates in constructor]. if (useDoublesArrays_) { return openDataArray_.Length; } if (openData_ == null) { return 0; } if (rows_ != null) { return rows_.Count; } if (openData_ is Array) { int size = ((Array)openData_).Length; if (size != ((Array)closeData_).Length) throw new NPlotException("open and close arrays are not of same length"); if (size != ((Array)lowData_).Length) throw new NPlotException("open and close arrays are not of same length"); if (size != ((Array)highData_).Length) throw new NPlotException("open and close arrays are not of same length"); return size; } throw new NPlotException( "data not in correct format" ); } } /// /// Returns an x-axis that is suitable for drawing the data. /// /// A suitable x-axis. public Axis SuggestXAxis() { double min; double max; double minStep = 0.0; if (this.rows_ == null) { Utils.ArrayMinMax((System.Collections.IList)this.abscissaData_, out min, out max); if (((System.Collections.IList)abscissaData_).Count > 1) { double first = Utils.ToDouble(((Array)abscissaData_).GetValue(0)); double second = Utils.ToDouble(((Array)abscissaData_).GetValue(1)); minStep = Math.Abs(second - first); } if (((System.Collections.IList)abscissaData_).Count > 2) { double first = Utils.ToDouble(((Array)abscissaData_).GetValue(1)); double second = Utils.ToDouble(((Array)abscissaData_).GetValue(2)); if (Math.Abs(second - first) < minStep) minStep = Math.Abs(second - first); } if (((System.Collections.IList)abscissaData_)[0] is DateTime) { return new DateTimeAxis(min - minStep / 2.0, max + minStep / 2.0); } else { return new LinearAxis(min - minStep / 2.0, max + minStep / 2.0); } } else { Utils.RowArrayMinMax(this.rows_, out min, out max, (string)this.abscissaData_); if (rows_.Count > 1) { double first = Utils.ToDouble(rows_[0][(string)abscissaData_]); double second = Utils.ToDouble(rows_[1][(string)abscissaData_]); minStep = Math.Abs(second - first); } if (rows_.Count > 2) { double first = Utils.ToDouble(rows_[1][(string)abscissaData_]); double second = Utils.ToDouble(rows_[2][(string)abscissaData_]); if (Math.Abs(second - first) < minStep) minStep = Math.Abs(second - first); } if ((rows_[0])[(string)abscissaData_] is DateTime) { return new DateTimeAxis(min - minStep / 2.0, max + minStep / 2.0); } else { return new LinearAxis(min - minStep / 2.0, max + minStep / 2.0); } } } /// /// Returns a y-axis that is suitable for drawing the data. /// /// A suitable y-axis. public Axis SuggestYAxis() { double min_l; double max_l; double min_h; double max_h; if (this.rows_ == null) { Utils.ArrayMinMax((System.Collections.IList)lowData_, out min_l, out max_l); Utils.ArrayMinMax((System.Collections.IList)highData_, out min_h, out max_h); } else { Utils.RowArrayMinMax(this.rows_, out min_l, out max_l, (string)this.lowData_); Utils.RowArrayMinMax(this.rows_, out min_h, out max_h, (string)this.highData_); } Axis a = new LinearAxis( min_l, max_h ); a.IncreaseRange( 0.08 ); return a; } } /// /// Default constructor. /// public CandlePlot() { } /// /// Calculates the physical (not world) separation between abscissa values. /// /// Candle adapter containing data /// Physical x axis the data is plotted against. /// physical separation between abscissa values. private static float CalculatePhysicalSeparation( CandleDataAdapter cd, PhysicalAxis xAxis ) { if (cd.Count > 1) { int xPos1 = (int)(xAxis.WorldToPhysical( ((PointOLHC)cd[0]).X, false )).X; int xPos2 = (int)(xAxis.WorldToPhysical( ((PointOLHC)cd[1]).X, false )).X; int minDist = xPos2 - xPos1; if (cd.Count > 2) { // to be pretty sure we get the smallest gap. int xPos3 = (int)(xAxis.WorldToPhysical(((PointOLHC)cd[2]).X, false)).X; if (xPos3 - xPos2 < minDist) minDist = xPos3 - xPos2; if (cd.Count > 3) { int xPos4 = (int)(xAxis.WorldToPhysical(((PointOLHC)cd[3]).X, false)).X; if (xPos4 - xPos3 < minDist) minDist = xPos4 - xPos3; } } return minDist; } return 0.0f; } /// /// Draws the candle plot on a GDI+ surface agains 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 void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { CandleDataAdapter cd = new CandleDataAdapter( this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData ); Brush bearishBrush = new SolidBrush( BearishColor ); Brush bullishBrush = new SolidBrush( BullishColor ); uint offset = 0; if (this.centered_) { offset = (uint)(CalculatePhysicalSeparation(cd,xAxis) / 2.0f); } uint addAmount = (uint)StickWidth/2; uint stickWidth = (uint)StickWidth; if (StickWidth == AutoScaleStickWidth) { // default addAmount = 2; stickWidth = 4; float minDist = CalculatePhysicalSeparation( cd, xAxis ); addAmount = (uint)(minDist / 3); stickWidth = addAmount * 2; } Pen p = new Pen(this.color_); /* // brant hyatt proposed. if (this.Style == Styles.Stick) { p.Width = stickWidth; addAmount = stickWidth + 2; } */ for (int i=0; i 0) { if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close) { p.Color = BullishColor; } else { p.Color = BearishColor; } } */ g.DrawLine( p, xPos+offset, yPos1, xPos+offset, yPos2 ); g.DrawLine( p, xPos-addAmount+offset, yPos3, xPos+offset, yPos3 ); g.DrawLine( p, xPos+offset, yPos4, xPos+addAmount+offset, yPos4 ); } else if (this.Style == Styles.Filled) { g.DrawLine( p, xPos+offset, yPos1, xPos+offset, yPos2 ); if (yPos3 > yPos4) { g.FillRectangle( bullishBrush, xPos-addAmount+offset, yPos4, stickWidth, yPos3 - yPos4 ); g.DrawRectangle( p, xPos-addAmount+offset, yPos4, stickWidth, yPos3 - yPos4 ); } else if (yPos3 < yPos4) { g.FillRectangle( bearishBrush, xPos-addAmount+offset, yPos3, stickWidth, yPos4 - yPos3 ); g.DrawRectangle( p, xPos-addAmount+offset, yPos3, stickWidth, yPos4 - yPos3 ); } else { g.DrawLine( p, xPos-addAmount+offset, yPos3, xPos-addAmount+stickWidth+offset, yPos3 ); } } } } } /// /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { CandleDataAdapter candleData = new CandleDataAdapter( this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData ); return candleData.SuggestXAxis(); } /// /// Returns a y-axis that is suitable for drawing this plot. /// /// A suitable y-axis. public Axis SuggestYAxis() { CandleDataAdapter candleData = new CandleDataAdapter( this.DataSource, this.DataMember, this.AbscissaData, this.OpenData, this.LowData, this.HighData, this.CloseData ); return candleData.SuggestYAxis(); } /// /// Gets or sets the data, or column name for the open values. /// public object OpenData { get { return openData_; } set { openData_ = value; } } private object openData_ = null; /// /// Gets or sets the data, or column name for the interval low values. /// public object LowData { get { return lowData_; } set { lowData_ = value; } } private object lowData_ = null; /// /// Gets or sets the data, or column name for the interval high values. /// public object HighData { get { return highData_; } set { highData_ = value; } } private object highData_ = null; /// /// Gets or sets the data, or column name for the close values. /// public object CloseData { get { return closeData_; } set { closeData_ = value; } } private object closeData_ = null; /// /// Gets or sets the data, or column name for the abscissa [x] axis. /// public object AbscissaData { get { return abscissaData_; } set { abscissaData_ = value; } } private object abscissaData_ = null; /// /// 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 virtual void DrawInLegend( Graphics g, Rectangle startEnd ) { Pen p = new Pen(this.color_); g.DrawLine( p, startEnd.Left, (startEnd.Top + startEnd.Bottom)/2, startEnd.Right, (startEnd.Top + startEnd.Bottom)/2 ); } /// /// Color of this plot [excluding interior of filled boxes if Style is fill]. To /// change the Bullish and Bearish colours in Filled mode, use the BullishColor /// and BearishColor properties. /// public System.Drawing.Color Color { get { return color_; } set { color_ = value; } } Color color_ = Color.Black; /// /// Possible CandleStick styles. /// public enum Styles { /// /// Draw vertical line between low and high, tick on left for open and tick on right for close. /// Stick, /// /// Draw vertical line between low and high and place on top of this a box with bottom /// and top determined by open and high values. The box is filled using the colors specified /// in BullishColor and BearishColor properties. /// Filled } /// /// Specifies the CandleStick style to use. /// public Styles Style = Styles.Filled; /// /// If CandlePlot.Style is Filled, then bullish open-close moves are displayed in this color. /// public Color BullishColor = Color.White; /// /// If CandlePlot.Style is Filled, then bearish moves are displayed in this color. /// public Color BearishColor = Color.Black; /// /// Width of each stick in pixels. It is best if this is an odd number. /// public int StickWidth { get { return stickWidth_; } set { if (value < 1) { throw new NPlotException( "Stick width must be greater than 0." ); } stickWidth_ = value; } } private int stickWidth_ = AutoScaleStickWidth; /// /// If stick width is set equal to this value, the width will be /// automatically scaled dependant on the space between sticks. /// public const int AutoScaleStickWidth = 0; /// /// If true (default), bars will be centered on the abscissa times. /// If false, bars will be drawn between the corresponding abscissa time /// and the next abscissa time. /// /// public bool Centered { get { return centered_; } set { centered_ = value; } } private bool centered_ = true; /// /// Write data associated with the plot as text. /// /// the string builder to write to. /// Only write out data in this region if onlyInRegion is true. /// If true, only data in region is written, else all data is written. /// TODO: not implemented. public void WriteData( System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion ) { } } } nplot-gtk-0.9.9.2/lib/changelog.txt0000644000175000017500000003710310512404106017541 0ustar carlosblecarlosble0.9.9.2 28 Feb 2006 Fixed bug in DateTimeAxis.WorldTickPositions_FirstPass reported by Pawel Konieczny. Fixed a bug in WorldTickPositions_SecondPass - thanks to Pawel Konieczny. Fixed a problem in Axis.WorldToPhysical - Thanks to Pawel Konieczny again for this one. Adding TradingDateTimeAxis contributed by Pawel Konieczny. Made changes to DateTimeAxis to allow TradingDateTimeAxis to work. Added Line in legend for point plot in appropriate case (thanks to Pawel Konieczny). Pawel Konieczny: Fixing suggested axes in BarPlot, which did not take into account all Y points originally. Made bar width configurable Pawel Konieczny: A small fix for vertical and horizontal guidelines, to remove their remnants from the plot. The remnants can be left over when the mouse move is fast such that the interaction does not get enough move even to remove itself. This fix does not really solve all problems with guidelines; for instance, try the following: run a demo application with a plot with a guideline, cover part of the plot by a window of another program, then hover the mouse over the not obscured area of the plot. Pawel Konieczny: A fix in CandlePlot.CalculatePhysicalSeparation(). The original code bombs with a null pointer exception when there are exactly three points. Pawel Konieczny: fixed bugs in horizontal and vertical drag interactions when the axis is non-linear. It fixes also a small bug for a linear axes, which led to a slight and steady zoom-in process when dragging the plot somewhat longer. Pawel Konieczny: fixed bugs in axis drag interaction for non-linear axes. Pawel Konieczny: MouseWheelZoom (which actually does scroll) adapted to non-linear axes. Additionally, Interaction.MouseWheelZoom improved to do zoom and handle Y axis too. Pawel Konieczny: Performance enhancements to CandlePlot Pawel Konieczny: Performance enhancements to LinePlot Pawel Konieczny: Performance enhancements to Transform2D Pawel Konieczny: Performance enhancements to SequenceAdapter Pawel Konieczny: Performance enhancements to PointPlot Pawel Konieczny: DataGetter_DoublesArray added to AdapeterUtils Pawel Konieczny: Performance enhancements to Windows.PlotSurface2D and contained classes. Added comments to uncommented public methods. Pawel Konieczny: This one makes HorizontalRangeSelection forgiving accidental clicks. Originally, a single click on a plot area with HorizontalRangeSelection active would immediately zoom into an indefinitely small zoom window. The change makes the interaction to ignore very small selections, that may be made accidentally (I suppose nobody would try to make deliberately such small selections, simply because it is very hard to make them accurately with a mouse). Matt: Added a property to set minimum select width in pixels in HorizontalRangeSelection. Pawel Konieczny: This one allows changing list of interactions on MouseUp. Originally, on MouseUp, the list of the registered interactions is looped through to dispatch the event. However, since the list is being looped, it cannot be modified during that process (otherwise an exception occurs). Pawel Konieczny: I have added handling of "MouseLeave" to the list of events that interaction may react to. This fine tunes the problem of "cleaning up" the guidelines (not unconditionally anymore), and is used in some new interactions I will send you later. Pawel Konieczny: I have disable the check whether the candle width is not zero. The effect was that when the amount of data displayed increases (e.g. zoom out) and the candles got thinner and thinner, suddenly they become thick again, overlapping each other. It may be even so, that by scrolling left or right, due to different rounding errors, they become thin again, and then again thick. I don't think it is useful to prohibit candles of zero width (there always will be the vertical line visible), since in such cases the distance between them is so small that they form an almost contiguous fill region. Pawel Konieczny: A few changes to ImagePlot. The point here is that the ImagePlot by default uses the gradient to span from the minimum value to maximum value. This is sometimes useful, but sometimes not. For instance, when the image plot is used to show a sort of a topographic map, where each color should correspond to some absolute value. The changes here allow to explicitly set the values corresponding to the gradient boundaries. Values outside the boundaries are mapped to the boundary colors (that functionality was already present in the gradient code, except that some debug check was throwing an exception when it happened - I had to remove that too). For instance, values of 0.0 and all negatives could be mapped to black. I have also added a possibility of a "void" color, which is used for NaN values. I use NaN values to indicate that no data is present for a given point. Pawel Konieczny: A small patch in drawing a shadow of the legend box. In the original NPlot, the shadow is not really a shadow - it is a light gray opaque rectangle box. Small fix from Rosco to allow zero height bars in BarPlot. Added data clipping speed up code to StepPlot (similar to code in Line, Point and CandlePlot). Added SmallestAllowedRange property to HorizontalRangeSelection interaction. 0.9.9.1 20 Feb 2006 (not released). Fixed bug with Linear Axis Offset and Scale properties which caused incorrect display. 0.9.9 22 July 2005 Added LegendZOrder to PlotSurface2D. Added PhysicalSpacingMin to LabelAxis Added RemoveInteraction method to Windows.PlotSurface2D. Thanks to Mns Erlandson. Fixed bug in Windows.PlotSurface2D.DoMouseMove reported by Mns Erlandson. Added StepGradient with RGB and Rainbow types. Ivan Ivanov fixed a bug in the Web Control when url contains params. Image stored in session variable is now explicitly deleted (known issue, but thanks to Ivan Ivanov for pointing this out also). Fixed up designer attributes in web control. Other (substantial) tweaking of web control. Note that this will eventually use the DynamicImage control in ASP.NET 2.0, this control will be much more efficient. Revised attributes (Bindable, Browsable, Description, Category) on relevant public properties on Windows.PlotSurface2D. Rosco Hill pointed out a bug in RefreshZOrdering. Spent quite a lot of time designing MultiLinePlot and MultiSequenceAdapter classes and supporting functions in AdapterUtils. There are issues remaining. I have left this out of pre 1.0 releases. Now prints title in centre of plot if there is no data. Took StringFormat construction out of PlotSurface2D.Draw method and put in constructor (to avoid unnecessarily creating this many times). Removed PlotSurface3D and all related. Removed PlotSurface2Dnew and all related. Removed BubblePlot.cs Removed PLotSurface and all related. Removed StartStep and all related. Removed MathExtra from Utils (3D calculations) Finished commenting AdapterUtils Filled in missing comments from other classes as well. Deleted ErrorHandler class (wasn't a good move that one...). Added NPlotException class - all NPlot exceptions throw of this type. Added quick fix from Rosco Hill for fixing weird behaviour when Legend is wider than plotting surface. Changed ToBrowser method in Bitmap.PlotSurface2D to ToStream and to take image format parameter. 0.9.8.9 [21 May 2005] Gareth Hayter found the bug introduced in 0.9.8.8 whereby LinePlots are sometimes not drawn. Added LengthScale and PixelIndent properties to VerticalLine and HorizontalLine Added ability to have multiple lines of text in the title. Added HideVerticalLines property to StepPlot Added HideHorizontalLines property to StepPlot. Added ScaleWidth property to StepPlot. Added zOffset to Windows.PlotSurface2D Web.PlotSurface2D and Bitmap.PlotSurface2D classes. Legends can now have items placed in a grid (not just vertically). Added BarPlot for charting a series of two ordinate values as bars. This still has work to go - the horizontal spacing is just a hack at the moment. Added ability of legend to grow horizontally or vertically, and to specify the maximum in the other direction. Ticks can be placed between labels in the label axis. 0.9.8.8 [15 May 2005] Added functionality to Filled region such that VerticalLine or Horizontal lines can be specified in the bounds. Added functionality that allows data to be obtained from arrays in CandleAdapter class. Code implemented was a more general version of that contributed Gareth Hayter. Added new demo plot to demonstrate this. Fixed problem with PlotSurface2D.Remove reported by Jonne van Wijngaarden. Added patch from Jonne van Wijngaarden that makes axes drag expand from the point clicked rather than the center. Bug fix by Rosco Hill in line plot when zoomed right in. Rosco Hill added code to draw small ticks in DateTime axis when in year mode. Anton fixed a bug in Web.PlotSurface2D. Change by Mike Miller for drawing Large Tickes on DateTime axes for time-spans greater than 30 years. Fix by Mike Miller in WorldToPhysical. Great work traking this one down. Implemented z-ordering in PlotSurface2D Add methods after suggestion by Gareth Hayter. Revised default positioning of candle bars based on justification by Mike Miller. Added Centered property to CandlePlot to chose between old default and new default positioning of bars. Converted back to VS2003 solution file. Ren van Kleef fixed a bug in linear axis on large zooms. Fixed Reversed flag not working anymore bug reported by "Steven". Thanks to Ren van Kleef for finding the problem. Fixed error found by Ren van Kleef in MarkerItem - incorrectly derived from Marker Added Constructors to MarkerItem as suggested by Ren van Kleef. Added TextItem implementation submitted by Ren van Kleef. 0.9.8.7 [] DateTimeAxis now scales down to second resolution. Added strong name key. Windows.Plotsurface2D.Draw no longer catches exceptions. Implemented interactions (lots of additions here). Large Chunk of 3D Plotsurface and related classes implemented. Changed axisCache variables in Windows.PlotSurface2D to zoomAxisCache. Changed "Zoom Back" to "Original Dimensions". Changed AllowSelection to EnableSelection. Added EnableDrag property and implementation. Arrow is not displayed if outside area of chart. Made threads created in demo STA. Made CopyToClipboard copy = true. Changed DateTimeAxis such that if scaled such that tick spacings every 2, 7, or 14 days, ticks are always placed in the same spot regardless of WorldMin / WorldMax. Changed Axis.Length property name to Axis.WorldLength. Added LabelOffsetAbsolute property to Axis class. 0.9.8.5 [15 February 2005] Przemyslaw Grodzki pointed out a Windows bug which caused "copy data to clipboard" to crash, and provided a solution. Added check for null in RightMenu property of Windows.PlotSurface2D. Made NumberFormat null on DateTimeAxis Axis copy constructor to avoid formatting problems when constrructing from non DateTime axes. Changed the space between values in "copy data to clipboard" to a tab. This makes it easier to insert values into Microsoft Excel and other programs. Removed redundent WorldMin and WorldMax properties from DateTimeAxis. 0.9.8.4 [13 February 2005] Removed context menu from Windows.PlotSurface2D and provided public methods for all functions previously only available through the ContextMenu in Windows.PlotSurface2D. Created PlotContextMenu class and associated classes which allow the right context menu to be completely customized and extended. Created the PlotSurface class and rearranged PlotSurface2D such that this is possible. PlotSurface is not working completely yet, but the concept is proved. This is going to be an all encompasing class for all types of plot surfaces (PiePlotSurface, RadialPlotSurface PlotSurface3D etc). Thanks to Roberto Pea for useful discussions on this topic. Added Drawables property to PlotSurface2D Added CopyDataToClipboard functionality. This needs modifying now so that values reflect axis types. Minor changes to LogAxis (object->double). Added LabelOffset and LabelOffsetScaled to Axis class. Changed the default Axis Label offset so it looks better. Added HorizontalLine class to make drawing horizontal lines easy (it takes a bit of effort to set up a LinePlot to do this). Added VerticalLine class as well. Added PiAxis class. Currently this can only print labels at integral values of Pi. Added placeholder for TextItem. This IDrawable is needed. Added RectangleD. This is used for CopyDataToClipboard When no tick marks are shown, the Axis label position is now shown in a more reasonable position. Rearranged the demo. Bug when O/L/C/H value is NaN fixed in CandlePlot by Florian Hoertlehner. Roberto Pea fixed a bug in LegendBase in the case that there are no lines. 0.9.8.3 [23 January 2005] Florian Hoertlehner provided better NaN handling ability in Utils.RowArrayMinMax. NPlot now is, and is marked CLSCompliant. Thanks to Roberto Pea for point this out. Added lots of pre-defined Solid RectangleBrushes. Still need to add lots of predefined other style brushes. Fixed bug whereby sometimes on Windows.Forms resize, the world bounds were randomly changing. The problem turned out to be in OnMouseUp function [proved v. hard to track down!]. Cleaned up the demo code a bit. Removed PropertyGrid from Windows.PlotSurface2D. I've left all the object selection code in there as it will be useful in the future, but I don't wan't ProperyGrid to be on the control itself. 0.9.8.2 [12 January 2005] Added patch by Rosco Hill for removing drawables from PlotSurfaces. Fixed bug introduced in 0.9.8.1 that prevented LogAxes from working correctly. This involved improvements to Transform2D and related classes. 0.9.8.1 [3 December 2004] Przemyslaw Grodzki fixed a small internationalization bug in the demo. PlotSurface gradient backgrounds. PlotSurface Bitmap backgrounds. Added some ready to go RectangleBrushes. Improved efficiency of Line drawing - using optimized transform class. Added shadow property for line class. Juraj Skripsky fixed a bug in the SuggestYAxis method in HistogramPlot for stacked histograms. Fixed "shakey lines" bug due to sub-optimal rounding. Thanks to Ren van Kleef for pointing this out. Made Physical Axis Caches public in Windows.PlotSurface2D. Thanks to Stephan Puchegger for pointing this out. 0.9.8 [17 November 2004] SequenceAdapter can now handle DataViews. Revised implementation and interaction of Color, Pen and Brush properties in appropriate classes. Added ArrowItem Drawable object. Added skeleton code for 3D plots. No implementation yet. Added Miguel's patch that reduces excessive memory allocations due to font scaling. Applied many other similar optimizations. In process of rethinking license. ScreenAlignedPhysicalAxis (not in use yet). Transform2D class skeleton (not in use yet). Cleaned up Marker.cs. Removed creation of Brush object in every call to Draw. Added MarkerItem IDrawable. Made RectangleBrush classes [moving out of HistogramPlot]. Changed lots of floats to ints - convention: * double in world domain. * in physical domain: float only where need for accurate calculations, otherwise int. * float for angles (not doubles) - as with .net Graphics class. made candle widths depend on distance between successive points. Added patches by Alexander Kucheravy relating to angled tick labels and large tick spacing for DateTime Axes. 0.9.7 [4 November 2004] change log started. nplot-gtk-0.9.9.2/lib/DateTimeAxis.cs0000644000175000017500000005231610512404106017724 0ustar carlosblecarlosble/* NPlot - A charting library for .NET DateTimeAxis.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Collections; using System.Globalization; // TODO: More control over how labels are displayed. // TODO: SkipWeekends property. // TODO: Make a relative (as opposed to absolute) TimeAxis. namespace NPlot { /// /// The DateTimeAxis class /// public class DateTimeAxis : Axis { #region Clone implementation /// /// Deep copy of DateTimeAxis. /// /// A copy of the DateTimeAxis Class. public override object Clone() { DateTimeAxis a = new DateTimeAxis(); // ensure that this isn't being called on a derived type. If it is, then oh no! if (this.GetType() != a.GetType()) { throw new NPlotException( "Clone not defined in derived type. Help!" ); } DoClone( this, a ); return a; } /// /// Helper method for Clone. /// /// The original object to clone. /// The cloned object. protected static void DoClone( DateTimeAxis b, DateTimeAxis a ) { Axis.DoClone( b, a ); } #endregion private void Init() { } /// /// Constructor /// /// Axis to construct from public DateTimeAxis( Axis a ) : base( a ) { this.Init(); this.NumberFormat = null; } /// /// Default Constructor /// public DateTimeAxis() : base() { this.Init(); } /// /// Constructor /// /// World min of axis /// World max of axis public DateTimeAxis( double worldMin, double worldMax ) : base( worldMin, worldMax ) { this.Init(); } /// /// Constructor /// /// World min of axis /// World max of axis public DateTimeAxis( long worldMin, long worldMax ) : base( (double)worldMin, (double)worldMax ) { this.Init(); } /// /// Constructor /// /// World min of axis /// World max of axis public DateTimeAxis( DateTime worldMin, DateTime worldMax ) : base( (double)worldMin.Ticks, (double)worldMax.Ticks ) { this.Init(); } /// /// Draw the ticks. /// /// The drawing surface on which to draw. /// The minimum physical extent of the axis. /// The maximum physical extent of the axis. /// out: smallest box that completely encompasses all of the ticks and tick labels. /// out: a suitable offset from the axis to draw the axis label. protected override void DrawTicks( Graphics g, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { // TODO: Look at offset and bounding box logic again here. why temp and other vars? Point tLabelOffset; Rectangle tBoundingBox; labelOffset = this.getDefaultLabelOffset( physicalMin, physicalMax ); boundingBox = null; ArrayList largeTicks; ArrayList smallTicks; this.WorldTickPositions( physicalMin, physicalMax, out largeTicks, out smallTicks ); // draw small ticks. for (int i=0; i /// Get the label corresponding to the provided date time /// /// the date time to get the label for /// label for the provided DateTime protected virtual string LargeTickLabel(DateTime tickDate) { string label = ""; if(this.NumberFormat == null || this.NumberFormat == String.Empty) { if ( this.LargeTickLabelType_ == LargeTickLabelType.year ) { label = tickDate.Year.ToString(); } else if ( this.LargeTickLabelType_ == LargeTickLabelType.month ) { label = tickDate.ToString("MMM"); label += " "; label += tickDate.Year.ToString().Substring(2,2); } else if ( this.LargeTickLabelType_ == LargeTickLabelType.day ) { label = (tickDate.Day).ToString(); label += " "; label += tickDate.ToString("MMM"); } else if ( this.LargeTickLabelType_ == LargeTickLabelType.hourMinute ) { string minutes = tickDate.Minute.ToString(); if (minutes.Length == 1) { minutes = "0" + minutes; } label = tickDate.Hour.ToString() + ":" + minutes; } else if ( this.LargeTickLabelType_ == LargeTickLabelType.hourMinuteSeconds ) { string minutes = tickDate.Minute.ToString(); string seconds = tickDate.Second.ToString(); if (seconds.Length == 1) { seconds = "0" + seconds; } if (minutes.Length == 1) { minutes = "0" + minutes; } label = tickDate.Hour.ToString() + ":" + minutes + "." + seconds; } } else { label = tickDate.ToString(NumberFormat); } return label; } /// /// Enumerates the different types of tick label possible. /// protected enum LargeTickLabelType { /// /// default - no tick labels. /// none = 0, /// /// tick labels should be years /// year = 1, /// /// Tick labels should be month names /// month = 2, /// /// Tick labels should be day names /// day = 3, /// /// Tick labels should be hour / minutes. /// hourMinute = 4, /// /// tick labels should be hour / minute / second. /// hourMinuteSeconds = 5 } /// /// this gets set after a get LargeTickPositions. /// protected LargeTickLabelType LargeTickLabelType_; /// /// Determines the positions, in world coordinates, of the large ticks. No /// small tick marks are currently calculated by this method. /// /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// null internal override void WorldTickPositions_FirstPass( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { smallTickPositions = null; largeTickPositions = new ArrayList(); const int daysInMonth = 30; TimeSpan timeLength = new TimeSpan( (long)(WorldMax-WorldMin)); DateTime worldMinDate = new DateTime( (long)this.WorldMin ); DateTime worldMaxDate = new DateTime( (long)this.WorldMax ); if(largeTickStep_ == TimeSpan.Zero) { // if less than 10 minutes, then large ticks on second spacings. if ( timeLength < new TimeSpan(0,0,2,0,0) ) { this.LargeTickLabelType_ = LargeTickLabelType.hourMinuteSeconds; double secondsSkip; if (timeLength < new TimeSpan( 0,0,0,10,0 ) ) secondsSkip = 1.0; else if ( timeLength < new TimeSpan(0,0,0,20,0) ) secondsSkip = 2.0; else if ( timeLength < new TimeSpan(0,0,0,50,0) ) secondsSkip = 5.0; else if ( timeLength < new TimeSpan(0,0,2,30,0) ) secondsSkip = 15.0; else secondsSkip = 30.0; int second = worldMinDate.Second; second -= second % (int)secondsSkip; DateTime currentTickDate = new DateTime( worldMinDate.Year, worldMinDate.Month, worldMinDate.Day, worldMinDate.Hour, worldMinDate.Minute, second,0 ); while ( currentTickDate < worldMaxDate ) { double world = (double)currentTickDate.Ticks; if ( world >= this.WorldMin && world <= this.WorldMax ) { largeTickPositions.Add( world ); } currentTickDate = currentTickDate.AddSeconds( secondsSkip ); } } // Less than 2 hours, then large ticks on minute spacings. else if ( timeLength < new TimeSpan(0,2,0,0,0) ) { this.LargeTickLabelType_ = LargeTickLabelType.hourMinute; double minuteSkip; if ( timeLength < new TimeSpan(0,0,10,0,0) ) minuteSkip = 1.0; else if ( timeLength < new TimeSpan(0,0,20,0,0) ) minuteSkip = 2.0; else if ( timeLength < new TimeSpan(0,0,50,0,0) ) minuteSkip = 5.0; else if ( timeLength < new TimeSpan(0,2,30,0,0) ) minuteSkip = 15.0; else //( timeLength < new TimeSpan( 0,5,0,0,0) ) minuteSkip = 30.0; int minute = worldMinDate.Minute; minute -= minute % (int)minuteSkip; DateTime currentTickDate = new DateTime( worldMinDate.Year, worldMinDate.Month, worldMinDate.Day, worldMinDate.Hour, minute,0,0 ); while ( currentTickDate < worldMaxDate ) { double world = (double)currentTickDate.Ticks; if ( world >= this.WorldMin && world <= this.WorldMax ) { largeTickPositions.Add( world ); } currentTickDate = currentTickDate.AddMinutes( minuteSkip ); } } // Less than 2 days, then large ticks on hour spacings. else if ( timeLength < new TimeSpan(2,0,0,0,0) ) { this.LargeTickLabelType_ = LargeTickLabelType.hourMinute; double hourSkip; if ( timeLength < new TimeSpan(0,10,0,0,0) ) hourSkip = 1.0; else if ( timeLength < new TimeSpan(0,20,0,0,0) ) hourSkip = 2.0; else hourSkip = 6.0; int hour = worldMinDate.Hour; hour -= hour % (int)hourSkip; DateTime currentTickDate = new DateTime( worldMinDate.Year, worldMinDate.Month, worldMinDate.Day, hour,0,0,0 ); while ( currentTickDate < worldMaxDate ) { double world = (double)currentTickDate.Ticks; if ( world >= this.WorldMin && world <= this.WorldMax ) { largeTickPositions.Add( world ); } currentTickDate = currentTickDate.AddHours( hourSkip ); } } // less than 5 months, then large ticks on day spacings. else if ( timeLength < new TimeSpan(daysInMonth*4,0,0,0,0)) { this.LargeTickLabelType_ = LargeTickLabelType.day; double daySkip; if ( timeLength < new TimeSpan(10,0,0,0,0) ) daySkip = 1.0; else if (timeLength < new TimeSpan(20,0,0,0,0) ) daySkip = 2.0; else if (timeLength < new TimeSpan(7*10,0,0,0,0) ) daySkip = 7.0; else daySkip = 14.0; DateTime currentTickDate = new DateTime( worldMinDate.Year, worldMinDate.Month, worldMinDate.Day ); if (daySkip == 2.0) { TimeSpan timeSinceBeginning = currentTickDate - DateTime.MinValue; if (timeSinceBeginning.Days % 2 == 1) currentTickDate = currentTickDate.AddDays(-1.0); } if (daySkip == 7 || daySkip == 14.0) { DayOfWeek dow = currentTickDate.DayOfWeek; switch (dow) { case DayOfWeek.Monday: break; case DayOfWeek.Tuesday: currentTickDate = currentTickDate.AddDays(-1.0); break; case DayOfWeek.Wednesday: currentTickDate = currentTickDate.AddDays(-2.0); break; case DayOfWeek.Thursday: currentTickDate = currentTickDate.AddDays(-3.0); break; case DayOfWeek.Friday: currentTickDate = currentTickDate.AddDays(-4.0); break; case DayOfWeek.Saturday: currentTickDate = currentTickDate.AddDays(-5.0); break; case DayOfWeek.Sunday: currentTickDate = currentTickDate.AddDays(-6.0); break; } } if (daySkip == 14.0f) { TimeSpan timeSinceBeginning = currentTickDate - DateTime.MinValue; if ((timeSinceBeginning.Days / 7) % 2 == 1) { currentTickDate = currentTickDate.AddDays(-7.0); } } while ( currentTickDate < worldMaxDate ) { double world = (double)currentTickDate.Ticks; if ( world >= this.WorldMin && world <= this.WorldMax ) { largeTickPositions.Add( world ); } currentTickDate = currentTickDate.AddDays(daySkip); } } // else ticks on month or year spacings. else if ( timeLength >= new TimeSpan(daysInMonth*4,0,0,0,0) ) { int monthSpacing = 0; if ( timeLength.Days < daysInMonth*(12*3+6) ) { LargeTickLabelType_ = LargeTickLabelType.month; if ( timeLength.Days < daysInMonth*10 ) monthSpacing = 1; else if ( timeLength.Days < daysInMonth*(12*2) ) monthSpacing = 3; else // if ( timeLength.Days < daysInMonth*(12*3+6) ) monthSpacing = 6; } else { LargeTickLabelType_ = LargeTickLabelType.year; if (timeLength.Days < daysInMonth * (12 * 6)) monthSpacing = 12; else if (timeLength.Days < daysInMonth * (12 * 12)) monthSpacing = 24; else if (timeLength.Days < daysInMonth * (12 * 30)) monthSpacing = 60; else monthSpacing = 120; //LargeTickLabelType_ = LargeTickLabelType.none; } // truncate start DateTime currentTickDate = new DateTime( worldMinDate.Year, worldMinDate.Month, 1 ); if (monthSpacing > 1) { currentTickDate = currentTickDate.AddMonths( -(currentTickDate.Month-1)%monthSpacing ); } // Align on 2 or 5 year boundaries if necessary. if (monthSpacing >= 24) { currentTickDate = currentTickDate.AddYears( -(currentTickDate.Year)%(monthSpacing/12) ); } //this.firstLargeTick_ = (double)currentTickDate.Ticks; if ( LargeTickLabelType_ != LargeTickLabelType.none ) { while ( currentTickDate < worldMaxDate ) { double world = (double)currentTickDate.Ticks; if ( world >= this.WorldMin && world <= this.WorldMax ) { largeTickPositions.Add( world ); } currentTickDate = currentTickDate.AddMonths( monthSpacing ); } } } } else { for (DateTime date = worldMinDate; date < worldMaxDate; date += largeTickStep_) { largeTickPositions.Add((double)date.Ticks); } } } /// /// Compute the small tick positions for largetick size of one or more years. /// - inside the domain or the large tick positons, is take the mid-point of pairs of large ticks /// - outside the large tick range, check if a half tick is inside the world min/max /// This method works only if there are atleast 2 large ticks, /// since we don't know if its minutes, hours, month, or yearly divisor. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// Read in the large tick positions /// Fill in the corresponding small tick positions /// Added by Rosco Hill internal override void WorldTickPositions_SecondPass( Point physicalMin, Point physicalMax, ArrayList largeTickPositions, ref ArrayList smallTickPositions ) { if (largeTickPositions.Count < 2 || !(LargeTickLabelType_.Equals(LargeTickLabelType.year))) { smallTickPositions = new ArrayList(); ; } else { smallTickPositions = new ArrayList(); double diff = 0.5 * (((double)largeTickPositions[1]) - ((double)largeTickPositions[0])); if (((double)largeTickPositions[0] - diff) > this.WorldMin) { smallTickPositions.Add((double)largeTickPositions[0] - diff); } for (int i = 0; i < largeTickPositions.Count - 1; i++) { smallTickPositions.Add(((double)largeTickPositions[i]) + diff); } if (((double)largeTickPositions[largeTickPositions.Count - 1] + diff) < this.WorldMax) { smallTickPositions.Add((double)largeTickPositions[largeTickPositions.Count - 1] + diff); } } } /// /// The distance between large ticks. If this is set to Zero [default], /// this distance will be calculated automatically. /// public TimeSpan LargeTickStep { set { largeTickStep_ = value; } get { return largeTickStep_; } } private TimeSpan largeTickStep_ = TimeSpan.Zero; } } nplot-gtk-0.9.9.2/lib/ErrorHandler.cs0000644000175000017500000001147310512404106017771 0ustar carlosblecarlosble/* NPlot - A charting library for .NET ErrorHandler.cs Copyright (C) 2004 Matt Howlett 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 following text in the documentation and / or other materials provided with the distribution: "This product includes software developed as part of the NPlot charting library project available from: http://www.nplot.com/" ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. $Id: ErrorHandler.cs,v 1.2 2004/11/04 12:18:24 mhowlett Exp $ */ using System; using System.Diagnostics; namespace NPlot { /// /// Error class that /// (a) adds source of problem. /// (b) by default throws exception. /// (c) default behaviour can be overridden. /// public class ErrorHandler { /// /// The singular ErrorHandler instance /// public static readonly ErrorHandler Instance = new ErrorHandler(); /// /// Defines the allowed message levels. /// public enum Level { /// /// Debugging Message. Note it's best not to use the general /// handle method to emit these - use the conditional Debug /// function. /// Debug = 0, /// /// Something went wrong, but code execution can continue. /// Continuing = 1, /// /// Something wend wrong, and code execution can not continue. /// Critical = 2 } private delegate void HandlerDelegate( string message ); private HandlerDelegate[] handlers_; private void HandleError( string message ) { throw new System.Exception( message ); } private void NullHandler( string message ) { // do nothing. } private ErrorHandler() { // set up default handlers_ = new HandlerDelegate[3]; handlers_[0] = new HandlerDelegate(HandleError); handlers_[1] = new HandlerDelegate(HandleError); handlers_[2] = new HandlerDelegate(HandleError); } /// /// Handles a debug message. /// /// message to handle [Conditional("DEBUG")] public void DebugError( string message ) { handlers_[(int)Level.Debug]( GetPrepend() + message ); } /// /// Handles a continuing error. /// /// message to handle public void ContinuingError( string message ) { handlers_[(int)Level.Continuing]( GetPrepend() + message ); } /// /// Handles a critical error. /// /// message to handle public void CriticalError( string message ) { handlers_[(int)Level.Critical]( GetPrepend() + message ); } /// /// Handles a message of the given level. /// /// The message level. /// The message to handle. public void Handle( Level level, string message ) { handlers_[(int)level]( GetPrepend() + message ); } /// /// Get text to prepend to log message to describe its origin. This is the first /// place in stack outside Cts.Library.MessageLog. /// /// string to prepend to messages detailing its origin. private string GetPrepend() { System.Diagnostics.StackTrace st = new StackTrace(); System.Diagnostics.StackFrame sf = null; string prepend = ""; int i = 0; while (i < st.FrameCount) { sf = st.GetFrame(i); if ( sf.GetMethod().ReflectedType != this.GetType() ) { break; } i += 1; } sf = st.GetFrame(i); prepend = "[" + sf.GetMethod().ReflectedType + "." + sf.GetMethod().Name + "] "; return prepend; } } } nplot-gtk-0.9.9.2/lib/FilledRegion.cs0000644000175000017500000001545410512404106017750 0ustar carlosblecarlosble/* NPlot - A charting library for .NET FilledRegion.cs Copyright (C) 2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// A quick and dirty Filled region plottable object /// public class FilledRegion : IDrawable { /// /// Constructor /// /// LinePlot that provides bounds to filled region [upper or lower] /// LinePlot that provides bounds to filled region [upper or lower] /// TODO: make this work with other plot types. public FilledRegion( LinePlot lp1, LinePlot lp2 ) { lp1_ = lp1; lp2_ = lp2; } /// /// Constructor /// /// Vertical line to provide bounds for filled region /// The other Vertical line to provide bounds for filled region public FilledRegion(VerticalLine l1, VerticalLine l2) { vl1_ = l1; vl2_ = l2; } /// /// Constructor /// /// Vertical line to provide bounds for filled region /// The other Vertical line to provide bounds for filled region public FilledRegion(HorizontalLine l1, HorizontalLine l2) { hl1_ = l1; hl2_ = l2; } /// /// Draw the filled region /// /// The GDI+ surface on which to draw. /// The X-Axis to draw against. /// The Y-Axis to draw against. public void Draw( System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis); Brush b = brush_; if (b == null) { b = areaBrush_.Get(new Rectangle(xAxis.PhysicalMin.X, yAxis.PhysicalMax.Y, xAxis.PhysicalLength, yAxis.PhysicalLength)); } if (hl1_ != null && hl2_ != null) { PointF[] points = new PointF[4]; points[0] = t.Transform(xAxis.Axis.WorldMin, hl1_.OrdinateValue); points[1] = t.Transform(xAxis.Axis.WorldMax, hl1_.OrdinateValue); points[2] = t.Transform(xAxis.Axis.WorldMax, hl2_.OrdinateValue); points[3] = t.Transform(xAxis.Axis.WorldMin, hl2_.OrdinateValue); g.FillPolygon(b, points); } else if (vl1_ != null && vl2_ != null) { PointF[] points = new PointF[4]; points[0] = t.Transform(vl1_.AbscissaValue, yAxis.Axis.WorldMin); points[1] = t.Transform(vl1_.AbscissaValue, yAxis.Axis.WorldMax); points[2] = t.Transform(vl2_.AbscissaValue, yAxis.Axis.WorldMax); points[3] = t.Transform(vl2_.AbscissaValue, yAxis.Axis.WorldMin); g.FillPolygon(b, points); } else if (lp1_ != null && lp2_ != null) { SequenceAdapter a1 = new SequenceAdapter(lp1_.DataSource, lp1_.DataMember, lp1_.OrdinateData, lp1_.AbscissaData); SequenceAdapter a2 = new SequenceAdapter(lp2_.DataSource, lp2_.DataMember, lp2_.OrdinateData, lp2_.AbscissaData); int count = a1.Count + a2.Count; PointF[] points = new PointF[count]; for (int i = 0; i < a1.Count; ++i) { points[i] = t.Transform(a1[i]); } for (int i = 0; i < a2.Count; ++i) { points[i + a1.Count] = t.Transform(a2[a2.Count - i - 1]); } g.FillPolygon(b, points); } else { throw new NPlotException("One of bounds was set to null"); } } /// /// Use this brush (and not a RectangleBrush) for drawing. /// public Brush Brush { set { brush_ = value; areaBrush_ = null; } } /// /// Use this RectangleBrush (and not a normal Brush) for drawing. /// public IRectangleBrush RectangleBrush { set { brush_ = null; areaBrush_ = value; } } private VerticalLine vl1_; private VerticalLine vl2_; private HorizontalLine hl1_; private HorizontalLine hl2_; private LinePlot lp1_; private LinePlot lp2_; private Brush brush_ = new SolidBrush( Color.GhostWhite ); private IRectangleBrush areaBrush_ = null; } } nplot-gtk-0.9.9.2/lib/FontScaler.cs0000644000175000017500000000311610512404106017435 0ustar carlosblecarlosble/* NPlot - A charting library for .NET FontScaler.cs Copyright (C) 2003 Matt Howlett 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 following text in the documentation and / or other materials provided with the distribution: "This product includes software developed as part of the NPlot charting library project available from: http://www.nplot.com/" ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. $Id: FontScaler.cs,v 1.10 2004/11/04 12:18:24 mhowlett Exp $ */ using System; using System.Drawing; namespace NPlot { } nplot-gtk-0.9.9.2/lib/Grid.cs0000644000175000017500000001571210512404106016267 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Grid.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; using System.Collections; 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 } /// /// 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; } } GridType horizontalGridType_; /// /// Specifies the vertical grid type (none, coarse, or fine). /// public GridType VerticalGridType { get { return verticalGridType_; } set { verticalGridType_ = value; } } GridType verticalGridType_; /// /// The pen used to draw major (coarse) grid lines. /// public System.Drawing.Pen MajorGridPen { get { return majorGridPen_; } set { majorGridPen_ = value; } } private Pen majorGridPen_; /// /// The pen used to draw minor (fine) grid lines. /// public System.Drawing.Pen MinorGridPen { get { return minorGridPen_; } set { minorGridPen_ = value; } } private Pen 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, System.Collections.ArrayList a, bool horizontal, Pen p ) { for (int i=0; i /// 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 (this.horizontalGridType_ != GridType.None) { xAxis.Axis.WorldTickPositions_FirstPass( xAxis.PhysicalMin, xAxis.PhysicalMax, out xLargePositions, out xSmallPositions ); DrawGridLines( g, xAxis, yAxis, xLargePositions, true, this.MajorGridPen ); } if (this.verticalGridType_ != GridType.None) { yAxis.Axis.WorldTickPositions_FirstPass( yAxis.PhysicalMin, yAxis.PhysicalMax, out yLargePositions, out ySmallPositions ); DrawGridLines( g, yAxis, xAxis, yLargePositions, false, this.MajorGridPen ); } if (this.horizontalGridType_ == GridType.Fine) { xAxis.Axis.WorldTickPositions_SecondPass( xAxis.PhysicalMin, xAxis.PhysicalMax, xLargePositions, ref xSmallPositions ); DrawGridLines( g, xAxis, yAxis, xSmallPositions, true, this.MinorGridPen ); } if (this.verticalGridType_ == GridType.Fine) { yAxis.Axis.WorldTickPositions_SecondPass( yAxis.PhysicalMin, yAxis.PhysicalMax, yLargePositions, ref ySmallPositions ); DrawGridLines( g, yAxis, xAxis, ySmallPositions, false, this.MinorGridPen ); } } } } nplot-gtk-0.9.9.2/lib/HistogramPlot.cs0000644000175000017500000003141710512404106020176 0ustar carlosblecarlosble/* NPlot - A charting library for .NET HistogramPlot.cs Copyright (C) 2003 Matt Howlett, Paolo Pierini Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; using System.Collections; namespace NPlot { /// /// Provides ability to draw histogram plots. /// public class HistogramPlot : BaseSequencePlot, IPlot, ISequencePlot { /// /// Set/Get the brush to use if the histogram is filled. /// public IRectangleBrush RectangleBrush { get { return rectangleBrush_; } set { rectangleBrush_ = value; } } private IRectangleBrush rectangleBrush_ = new RectangleBrushes.Solid( Color.Black ); /// /// Constructor /// public HistogramPlot() { } /// /// Renders the histogram. /// /// The Graphics surface on which to draw /// The X-Axis to draw against. /// The Y-Axis to draw against. public void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); float yoff; for ( int i=0; i /// Whether or not the histogram columns will be filled. /// public bool Filled { get { return filled_; } set { filled_ = value; } } private bool filled_ = false; private float baseWidth_ = 1.0f; /// /// The width of the histogram bar as a proportion of the data spacing /// (in range 0.0 - 1.0). /// public float BaseWidth { get { return baseWidth_; } set { if (value > 0.0 && value <= 1.0) { baseWidth_ = value; } else { throw new NPlotException( "Base width must be between 0.0 and 1.0" ); } } } /// /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); Axis a = data.SuggestXAxis(); PointD p1; PointD p2; PointD p3; PointD p4; if (data.Count < 2) { p1 = data[0]; p1.X -= 1.0; p2 = data[0]; p3 = p1; p4 = p2; } else { p1 = data[0]; p2 = data[1]; p3 = data[data.Count-2]; p4 = data[data.Count-1]; } double offset1; double offset2; if (!center_) { offset1 = 0.0f; offset2 = p4.X - p3.X; } else { offset1 = (p2.X - p1.X)/2.0f; offset2 = (p4.X - p3.X)/2.0f; } a.WorldMin -= offset1; a.WorldMax += offset2; return a; } /// /// Returns a y-axis that is suitable for drawing this plot. /// /// A suitable y-axis. public Axis SuggestYAxis() { if ( this.isStacked_ ) { double tmpMax = 0.0f; ArrayList adapterList = new ArrayList(); HistogramPlot currentPlot = this; do { adapterList.Add( new SequenceAdapter( currentPlot.DataSource, currentPlot.DataMember, currentPlot.OrdinateData, currentPlot.AbscissaData ) ); } while ((currentPlot = currentPlot.stackedTo_) != null); SequenceAdapter[] adapters = (SequenceAdapter[])adapterList.ToArray(typeof(SequenceAdapter)); for (int i=0; i /// Histogram bars extend from the data value to this value. Default value is 0. /// public double CenterLine { get { return centerLine_; } set { centerLine_ = value; } } */ private bool center_ = true; /// /// If true, each histogram column will be centered on the associated abscissa value. /// If false, each histogram colum will be drawn between the associated abscissa value, and the next abscissa value. /// Default value is true. /// public bool Center { set { center_ = value; } get { return center_; } } /// /// If this histogram plot has another stacked on top, this will be true. Else false. /// public bool IsStacked { get { return isStacked_; } } private bool isStacked_; private HistogramPlot stackedTo_; /// /// Stack the histogram to another HistogramPlot. /// public void StackedTo(HistogramPlot hp) { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); SequenceAdapter hpData = new SequenceAdapter( hp.DataSource, hp.DataMember, hp.OrdinateData, hp.AbscissaData ); if ( hp != null ) { isStacked_ = true; if ( hpData.Count != data.Count ) { throw new NPlotException("Can stack HistogramPlot data only with the same number of datapoints."); } for ( int i=0; i < data.Count; ++i ) { if ( data[i].X != hpData[i].X ) { throw new NPlotException("Can stack HistogramPlot data only with the same X coordinates."); } if ( hpData[i].Y < 0.0f) { throw new NPlotException("Can stack HistogramPlot data only with positive Y coordinates."); } } } stackedTo_ = hp; } /// /// 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 (Filled) { g.FillRectangle( rectangleBrush_.Get(startEnd), startEnd ); } g.DrawRectangle( Pen, startEnd.X, startEnd.Y, startEnd.Width, startEnd.Height ); } /// /// The pen used to draw the plot /// public System.Drawing.Pen Pen { get { return pen_; } set { pen_ = value; } } private System.Drawing.Pen pen_ = new Pen(Color.Black); /// /// The color of the pen used to draw lines in this plot. /// public System.Drawing.Color Color { set { if (pen_ != null) { pen_.Color = value; } else { pen_ = new Pen(value); } } get { return pen_.Color; } } /// /// Horizontal position of histogram columns is offset by this much (in world coordinates). /// public double BaseOffset { set { baseOffset_ = value; } get { return baseOffset_; } } private double baseOffset_; } } nplot-gtk-0.9.9.2/lib/HorizontalLine.cs0000644000175000017500000001707610512404106020350 0ustar carlosblecarlosble/* NPlot - A charting library for .NET HorizontalLine.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 a horizontal line on a plot surface. /// public class HorizontalLine : IPlot { /// /// Constructor /// /// ordinate (Y) value of line. public HorizontalLine( double ordinateValue ) { this.value_ = ordinateValue; } /// /// Constructor /// /// ordinate (Y) value of line. /// draw the line using this color. public HorizontalLine( double ordinateValue, Color color ) { this.value_ = ordinateValue; this.pen_ = new Pen( color ); } /// /// Constructor /// /// ordinate (Y) value of line. /// Pen to use to draw the line. public HorizontalLine( double ordinateValue, Pen pen ) { this.value_ = ordinateValue; this.pen_ = pen; } /// /// Draws a representation of the horizontal line 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(System.Drawing.Graphics g, System.Drawing.Rectangle startEnd) { g.DrawLine( pen_, startEnd.Left, (startEnd.Top + startEnd.Bottom)/2, startEnd.Right, (startEnd.Top + startEnd.Bottom)/2 ); } /// /// A label to associate with the plot - used in the legend. /// public string Label { get { return label_; } set { this.label_ = value; } } private string label_ = ""; /// /// Whether or not to include an entry for this plot in the legend if it exists. /// public bool ShowInLegend { get { return showInLegend_; } set { this.showInLegend_ = value; } } private bool showInLegend_ = false; /// /// Returns null indicating that x extremities of the line are variable. /// /// null public Axis SuggestXAxis() { return null; } /// /// Returns a y-axis that is suitable for drawing this plot. /// /// A suitable y-axis. public Axis SuggestYAxis() { return new LinearAxis( this.value_, this.value_ ); } /// /// Writes text data describing the horizontal line object to the supplied string builder. It is /// possible to specify that the data will be written only if the line is in the specified /// region. /// /// the StringBuilder object to write to. /// a region used if onlyInRegion is true. /// If true, data will be written only if the line is in the specified region. public void WriteData(System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion) { // return if line is not in plot region and if (value_ > region.Y+region.Height || value_ < region.Y) { if (onlyInRegion) { return; } } sb.Append( "Label: " ); sb.Append( this.Label ); sb.Append( "\r\n" ); sb.Append( value_.ToString() ); sb.Append( "\r\n" ); } /// /// Draws the horizontal line 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 void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { int xMin = xAxis.PhysicalMin.X; int xMax = xAxis.PhysicalMax.X; xMin += pixelIndent_; xMax -= pixelIndent_; float length = Math.Abs(xMax - xMin); float lengthDiff = length - length*scale_; float indentAmount = lengthDiff/2; xMin += (int)indentAmount; xMax -= (int)indentAmount; int yPos = (int)yAxis.WorldToPhysical( value_, false ).Y; g.DrawLine( pen_, new System.Drawing.Point( xMin, yPos ), new System.Drawing.Point( xMax, yPos ) ); // todo: clip and proper logic for flipped axis min max. } private double value_; /// /// ordinate (Y) value to draw horizontal line at. /// public double OrdinateValue { get { return value_; } set { value_ = value; } } private Pen pen_ = new Pen( Color.Black ); /// /// Pen to use to draw the horizontal line. /// public Pen Pen { get { return pen_; } set { pen_ = value; } } /// /// Each end of the line is indented by this many pixels. /// public int PixelIndent { get { return pixelIndent_; } set { pixelIndent_ = value; } } private int pixelIndent_ = 0; /// /// The line length is multiplied by this amount. Default /// corresponds to a value of 1.0. /// public float LengthScale { get { return scale_; } set { scale_ = value; } } private float scale_ = 1.0f; } } nplot-gtk-0.9.9.2/lib/house_rules.txt0000644000175000017500000000371210512404106020146 0ustar carlosblecarlosbleHouse Rules and random notes: Note: I haven't followed these always. They reflect my current preferences, which vary a little from time to time. Anything reasonably close is good enough. o Classes begin with a capital letter and each world is capitalized. Eg: HistogramPlot o Class member functions begin with capital letter and each word is capitalized. Eg: public void DrawTicks() o Class member variables begin with a lower case letter, each word there-after capitalized. Trailing underscore. Eg: float worldMax_ o variables begin with a lower case letter, each world there-after capitalized. This includes variables in a argumant list. Eg: float worldMax public void DrawTicks( float myArgument ) o use ++i over i++. (habbit from c++, ++i never less efficient than i++, sometimes more). o always use braces. Do: if ( a == 3 ) { return; } not if ( a == 3 ) return; o add your name to the copyright list of a file if you do significant modifications to it, or create it. o Don't use hungarian notation. :-). It's not the done thing in C#, and the other rules here allow differentiation between identifier types. o braces like this: if (a == 3) { Console.WriteLine( "Hello world\n" ); } not like this: if (a == 3) { Console.WriteLine( "Hello world\n" ); } o spaces like this: if (a == 3) not like this: if( a == 3 ) or this: if (a==3) or this: if(a==3) o Comments: (1) Avoid obvious comments, they annoy me. (2) Make sure you _really_ understand what is going on before commenting. No comment is much much better than an incorrect comment. (3) Use comments to leave notes to other coders (in particular me), so that I can quickly see what has changed. I'll feel free to delete them. o CVS: Don't check in code that doesn't compile and run. nplot-gtk-0.9.9.2/lib/icon.ico0000644000175000017500000000047610512404106016500 0ustar carlosblecarlosble(( f`ffffffffff`fffgwwwwww   m?qcnplot-gtk-0.9.9.2/lib/IDrawable.cs0000644000175000017500000000531710512404106017234 0ustar carlosblecarlosble/* NPlot - A charting library for .NET IDrawable.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// Defines a Draw method for drawing objects against an x and y /// Physical Axis. /// public interface IDrawable { /// /// Draws this object against an x and y PhysicalAxis. /// /// The graphics surface on which to draw. /// The physical x-axis to draw against. /// The physical y-axis to draw against. void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ); } } nplot-gtk-0.9.9.2/lib/IDrawable3D.cs0000644000175000017500000000165110512404106017420 0ustar carlosblecarlosble// ******** experimental ******** /* using System; using System.Drawing; namespace NPlot { /// /// Defines a Draw method for drawing objects against x, y and z /// Physical Axes. /// public interface IDrawable3D { /// /// Draws this object against x, y and z PhysicalAxes. /// /// The graphics surface on which to draw. /// The physical x-axis to draw against. /// The physical y-axis to draw against. /// The physical z-axis to draw against. /// Other or different parameters will probably be needed here - basically /// the supplied parameters need to allow the Draw method to do the world -> physical /// transform. void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, PhysicalAxis zAxis ); } } */nplot-gtk-0.9.9.2/lib/IGradient.cs0000644000175000017500000000520210512404106017241 0ustar carlosblecarlosble/* NPlot - A charting library for .NET IGradient.cs Copyright (C) 2003-2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; namespace NPlot { /// /// Defines a gradient. /// public interface IGradient { /// /// Gets a color corresponding to a number between 0.0 and 1.0 inclusive. /// /// the number to get corresponding color for (between 0.0 and 1.0) /// The color corresponding to the supplied number. Color GetColor( double prop ); } } nplot-gtk-0.9.9.2/lib/ImagePlot.cs0000644000175000017500000002422010512404106017255 0ustar carlosblecarlosble/* NPlot - A charting library for .NET ImagePlot.cs Copyright (C) 2003-2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; namespace NPlot { /// /// Encapsulates functionality for plotting data as a 2D image chart. /// public class ImagePlot : IPlot { private double[,] data_; private double xStart_ = 0.0; private double xStep_ = 1.0; private double yStart_ = 0.0; private double yStep_ = 1.0; /// /// At or below which value a minimum gradient color should be used. /// public double DataMin { get { return dataMin_; } set { dataMin_ = value; } } private double dataMin_; /// /// At or above which value a maximum gradient color should be used. /// public double DataMax { get { return dataMax_; } set { dataMax_ = value; } } private double dataMax_; /// /// Calculates the minimum and maximum values of the data array. /// private void calculateMinMax() { dataMin_ = data_[0,0]; dataMax_ = data_[0,0]; for (int i=0; idataMax_) { dataMax_ = data_[i,j]; } } } } /// /// Constructor /// /// the 2D array to plot /// the world value corresponding to the 1st position in the x-direction /// the world step size between pixels in the x-direction. /// the world value corresponding to the 1st position in the y-direction /// the world step size between pixels in the y-direction. /// no adapters for this yet - when we get some more 2d /// plotting functionality, then perhaps create some. public ImagePlot( double[,] data, double xStart, double xStep, double yStart, double yStep ) { #if CHECK_ERRORS if (data == null || data.GetLength(0) == 0 || data.GetLength(1) == 0) { throw new NPlotException( "ERROR: ImagePlot.ImagePlot: Data null, or zero length" ); } #endif this.data_ = data; this.xStart_ = xStart; this.xStep_ = xStep; this.yStart_ = yStart; this.yStep_ = yStep; this.calculateMinMax(); } /// /// Constructor /// /// The 2D array to plot. public ImagePlot( double[,] data ) { this.data_ = data; this.calculateMinMax(); } /// /// Draw on to the supplied graphics surface against the supplied axes. /// /// The graphics surface on which to draw. /// The X-Axis to draw against. /// The Y-Axis to draw against. /// TODO: block positions may be off by a pixel or so. maybe. Re-think calculations public void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { if ( data_==null || data_.GetLength(0) == 0 || data_.GetLength(1) == 0 ) { return; } double worldWidth = xAxis.Axis.WorldMax - xAxis.Axis.WorldMin; double numBlocksHorizontal = worldWidth / this.xStep_; double worldHeight = yAxis.Axis.WorldMax - yAxis.Axis.WorldMin; double numBlocksVertical = worldHeight / this.yStep_; double physicalWidth = xAxis.PhysicalMax.X - xAxis.PhysicalMin.X; double blockWidth = physicalWidth / numBlocksHorizontal; bool wPositive = true; if (blockWidth < 0.0) { wPositive = false; } blockWidth = Math.Abs(blockWidth)+1; double physicalHeight = yAxis.PhysicalMax.Y - yAxis.PhysicalMin.Y; double blockHeight = physicalHeight / numBlocksVertical; bool hPositive = true; if (blockHeight < 0.0) { hPositive = false; } blockHeight = Math.Abs(blockHeight)+1; for (int i=0; i /// The gradient that specifies the mapping between value and color. /// /// memory allocation in get may be inefficient. public IGradient Gradient { get { if (gradient_ == null) { // TODO: suboptimal. gradient_ = new LinearGradient( Color.FromArgb(255,255,255), Color.FromArgb(0,0,0) ); } return this.gradient_; } set { this.gradient_ = value; } } private IGradient gradient_; /// /// 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 ) { // not implemented yet. } /// /// A label to associate with the plot - used in the legend. /// public string Label { get { return label_; } set { this.label_ = value; } } private string label_ = ""; /// /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { if (this.center_) { return new LinearAxis( this.xStart_ - this.xStep_/2.0, this.xStart_ + this.xStep_ * data_.GetLength(1) - this.xStep_/2.0 ); } return new LinearAxis( this.xStart_, this.xStart_ + this.xStep_ * data_.GetLength(1) ); } /// /// Returns a y-axis that is suitable for drawing this plot. /// /// A suitable y-axis. public Axis SuggestYAxis() { if (this.center_) { return new LinearAxis( this.yStart_ - this.yStep_/2.0, this.yStart_ + this.yStep_ * data_.GetLength(0) - this.yStep_/2.0 ); } return new LinearAxis( this.yStart_, this.yStart_ + this.yStep_ * data_.GetLength(0) ); } /// /// If true, pixels are centered on their respective coordinates. If false, they are drawn /// between their coordinates and the coordinates of the the next point in each direction. /// public bool Center { set { center_ = value; } get { return center_; } } private bool center_ = true; /// /// Whether or not to include an entry for this plot in the legend if it exists. /// public bool ShowInLegend { get { return showInLegend_; } set { this.showInLegend_ = value; } } private bool showInLegend_ = true; /// /// Write data associated with the plot as text. /// /// the string builder to write to. /// Only write out data in this region if onlyInRegion is true. /// If true, only data in region is written, else all data is written. /// TODO: not implemented. public void WriteData( System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion ) { } } } nplot-gtk-0.9.9.2/lib/IMeshPlot.cs0000644000175000017500000000317410512404106017245 0ustar carlosblecarlosble/* NPlot - A charting library for .NET IMeshPlot.cs Copyright (C) 2003 Matt Howlett 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 following text in the documentation and / or other materials provided with the distribution: "This product includes software developed as part of the NPlot charting library project available from: http://www.nplot.com/" ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. $Id: IMeshPlot.cs,v 1.9 2004/10/23 07:08:35 mhowlett Exp $ */ namespace NPlot { /// /// TODO /// public interface IMeshPlot : IPlot { } } nplot-gtk-0.9.9.2/lib/IPlot.cs0000644000175000017500000000704010512404106016424 0ustar carlosblecarlosble/* NPlot - A charting library for .NET IPlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Drawing; namespace NPlot { /// /// Defines the interface for objects that (a) can draw a representation of /// themselves in the legend and (b) can recommend a good axis to draw themselves /// against. /// public interface IPlot : IDrawable { /// /// Method used to draw a representation of the plot in a legend. /// void DrawInLegend( Graphics g, Rectangle startEnd ); /// /// The label associated with the plot [used in legend] /// string Label { get; set; } /// /// Whether or not to include an entry for this plot in the legend if it exists. /// bool ShowInLegend { get; set; } /// /// The method used to set the default abscissa axis. /// Axis SuggestXAxis(); /// /// The method used to set the default ordinate axis. /// Axis SuggestYAxis(); /// /// Write data associated with the plot as text. /// /// the string builder to write to. /// Only write out data in this region if onlyInRegion is true. /// If true, only data in region is written, else all data is written. void WriteData( System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion ); } }nplot-gtk-0.9.9.2/lib/IPlot3D.cs0000644000175000017500000000077610512404106016624 0ustar carlosblecarlosble/* using System; namespace NPlot { /// /// 3D plottable objects implement this interface. /// public interface IPlot3D { /// /// The method used to set the default x axis. /// Axis SuggestXAxis(); /// /// The method used to set the default y axis. /// Axis SuggestYAxis(); /// /// The method used to set the default z axis. /// Axis SuggestZAxis(); } } */nplot-gtk-0.9.9.2/lib/IPlotSurface2D.cs0000644000175000017500000002036010512404106020123 0ustar carlosblecarlosble/* NPlot - A charting library for .NET IPlotSurface2D.cs Copyright (C) 2003 Paolo Pierini, Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; namespace NPlot { /// /// Defines the PlotSurface2D interface - All specific PlotSurface2D classes /// that use PlotSurface2D for their underlying operations should implement /// this class. /// public interface IPlotSurface2D { /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. /// The z-ordering when drawing (objects with lower numbers are drawn first) void Add( IDrawable p, int zOrder ); /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. /// The z-ordering when drawing (objects with lower numbers are drawn first) void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp, int zOrder ); /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. void Add(IDrawable p); /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. void Add(IDrawable p, NPlot.PlotSurface2D.XAxisPosition xax, NPlot.PlotSurface2D.YAxisPosition yax); /// /// Clears the PlotSurface2D. /// void Clear(); /// /// Gets or Sets the legend to use with this plot surface. /// NPlot.Legend Legend { get; set; } /// /// Setting this value determines the order (relative to IDrawables added to the plot surface) /// that the legend is drawn. /// int LegendZOrder { get; set; } /// /// The distance in pixels to leave between of the edge of the bounding rectangle /// supplied to the Draw method, and the markings that make up the plot. /// int Padding { get; set; } /// /// A color used to paint the plot background. Mutually exclusive with PlotBackImage and PlotBackBrush /// System.Drawing.Color PlotBackColor { set; } /// /// An imaged used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// System.Drawing.Bitmap PlotBackImage { set; } /// /// A Rectangle brush used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// IRectangleBrush PlotBackBrush { set; } /// /// The plot surface title. /// string Title { get; set; } /// /// Whether or not the title will be scaled according to size of the plot /// surface. /// bool AutoScaleTitle { get; set; } /// /// When plots are added to the plot surface, the axes they are attached to /// are immediately modified to reflect data of the plot. If /// AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will /// be turned in to auto scaling ones if they are not already [tick marks, /// tick text and label size scaled to size of plot surface]. If false, /// axes will not be autoscaling. /// bool AutoScaleAutoGeneratedAxes { get; set; } /// /// Sets the title to be drawn using a solid brush of this color. /// System.Drawing.Color TitleColor { set; } /// /// The brush used for drawing the title. /// System.Drawing.Brush TitleBrush { get; set; } /// /// The plot title font. /// System.Drawing.Font TitleFont { get; set; } /// /// Smoothing mode to use when drawing plots. /// System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get; set; } /// /// Add an axis constraint to the plot surface. Axis constraints can /// specify relative world-pixel scalings, absolute axis positions etc. /// /// The axis constraint to add. void AddAxesConstraint( AxesConstraint c ); /// /// The bottom abscissa axis. /// Axis XAxis1 { get; set; } /// /// The top abscissa axis. /// Axis XAxis2 { get; set; } /// /// The left ordinate axis. /// Axis YAxis1 { get; set; } /// /// The right ordinate axis. /// Axis YAxis2 { get; set; } /// /// Remove a drawable object from the plot surface. /// /// the object to remove /// whether or not to update the axes after removal. void Remove( IDrawable p, bool updateAxes ); /// /// Gets an array list containing all drawables currently added to the PlotSurface2D. /// ArrayList Drawables { get; } /* /// /// Calculates axes approprate to IPlots on PlotSurface. Note that /// this is done automatically as a new plot is added. You may wish /// to call this again if you update data in the plot. /// void AutoCalculateAxes(); /// /// C /// /// void UpdateAxes( IPlot p ); */ } } nplot-gtk-0.9.9.2/lib/IPlotSurface2Dnew.cs0000644000175000017500000000110410512404106020630 0ustar carlosblecarlosble// ******** experimental ******** /* namespace NPlot { /// /// Defines the PlotSurface2Dnew interface - All specific PlotSurface2Dnew classes /// that use PlotSurface2Dnew for their underlying operations should implement /// this class. TODO: this is experimental. /// public interface IPlotSurface2Dnew { /// /// The distance in pixels to leave between of the edge of the bounding rectangle /// supplied to the Draw method, and the markings that make up the plot. /// int Padding { get; set; } } } */nplot-gtk-0.9.9.2/lib/IPlotSurface3D.cs0000644000175000017500000000025710512404106020127 0ustar carlosblecarlosble// ******** experimental ******** /* using System; namespace NPlot { /// /// TODO. /// public interface IPlotSurface3D { } } */nplot-gtk-0.9.9.2/lib/ISequencePlot.cs0000644000175000017500000000570110512404106020117 0ustar carlosblecarlosble/* NPlot - A charting library for .NET IPlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; namespace NPlot { /// /// Defines an mix-in style interface for plots that use SequenceAdapter to interpret supplied data. /// public interface ISequencePlot { /// /// Gets or sets the source containing a list of values used to populate the plot object. /// object DataSource { get; set; } /// /// Gets or sets the specific data member in a multimember data source to get data from. /// string DataMember { get; set; } /// /// Gets or sets the data, or column name for the abscissa [x] axis. /// object AbscissaData { get; set; } /// /// Gets or sets the data, or column name for the ordinate [y] axis. /// object OrdinateData { get; set; } } } nplot-gtk-0.9.9.2/lib/ISurface.cs0000644000175000017500000000666210512404106017107 0ustar carlosblecarlosble/* NPlot - A charting library for .NET ISurface.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Windows.Forms; namespace NPlot { /// /// All PlotSurface's implement this interface. /// /// Some of the parameter lists will change to be made more uniform. public interface ISurface { /// /// Provides functionality for drawing the control. /// /// paint event args /// width of the control. /// height of the control. void DoPaint( PaintEventArgs pe, int width, int height ); /// /// Provides functionality for handling mouse up events. /// /// mouse event args /// the control void DoMouseUp( MouseEventArgs e, System.Windows.Forms.Control ctr ); /// /// Provides functionality for handling mouse move events. /// /// mouse event args /// the control void DoMouseMove( MouseEventArgs e, System.Windows.Forms.Control ctr ); /// /// Provides functionality for handling mouse down events. /// /// mouse event args void DoMouseDown( MouseEventArgs e ); } } nplot-gtk-0.9.9.2/lib/ITransform2D.cs0000644000175000017500000000533210512404106017651 0ustar carlosblecarlosble/* NPlot - A charting library for .NET ITransform2D.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// This interface is useful in the Plot classes for transforming /// world to physical coordinates. Create on using the GetTransformer /// static method in Transform2D. /// public interface ITransform2D { /// /// Transforms the given world point to physical coordinates /// PointF Transform( double x, double y ); /// /// Transforms the given world point to physical coordinates /// PointF Transform( PointD worldPoint ); } } nplot-gtk-0.9.9.2/lib/LabelAxis.cs0000644000175000017500000002443410512404106017247 0ustar carlosblecarlosble/* NPlot - A charting library for .NET LabelAxis.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; using System.Drawing; namespace NPlot { /// /// Allows the creation of axes with any number of user defined labels at /// user defined world values along the axis. /// public class LabelAxis : Axis { /// /// Deep copy of LabelAxis. /// /// A copy of the LinearAxis Class. public override object Clone() { LabelAxis a = new LabelAxis(); // ensure that this isn't being called on a derived type. If it is, then oh no! if (this.GetType() != a.GetType()) { throw new NPlotException( "Error. Clone method is not defined in derived type." ); } DoClone( this, a ); return a; } /// /// Helper method for Clone. /// /// The original object to clone. /// The cloned object. protected static void DoClone( LabelAxis b, LabelAxis a ) { Axis.DoClone( b, a ); a.labels_ = (ArrayList)b.labels_.Clone(); a.numbers_ = (ArrayList)b.numbers_.Clone(); a.ticksBetweenText_ = b.ticksBetweenText_; a.sortDataIfNecessary_ = b.sortDataIfNecessary_; } /// /// Initialise LabelAxis to default state. /// private void Init() { labels_ = new ArrayList(); numbers_ = new ArrayList(); } /// /// Copy constructor /// /// The Axis to clone. /// TODO: [review notes] I don't think this will work as desired. public LabelAxis( Axis a ) : base( a ) { Init(); } /// /// Default constructor /// public LabelAxis() : base() { Init(); } /// /// Constructor /// /// Minimum world value /// Maximum world value public LabelAxis( double worldMin, double worldMax ) : base( worldMin, worldMax ) { Init(); } /// /// Adds a label to the axis /// /// The label /// The world value at which to place the label public void AddLabel( string name, double val ) { labels_.Add( name ); numbers_.Add( val ); } /// /// Given Graphics surface, and physical extents of axis, draw ticks and /// associated labels. /// /// The GDI+ Graphics surface on which to draw. /// The physical location of the world min point /// The physical location of the world max point /// out: smallest box that completely encompasses all of the ticks and tick labels. /// out: a suitable offset from the axis to draw the axis label. protected override void DrawTicks( Graphics g, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { Point tLabelOffset; Rectangle tBoundingBox; labelOffset = this.getDefaultLabelOffset( physicalMin, physicalMax ); boundingBox = null; // draw the tick labels (but not the ticks). PointF lastPos = WorldToPhysical( (double)numbers_[0], physicalMin, physicalMax, true ); for (int i=0; i WorldMin && (double)numbers_[i] < WorldMax) { // check to make sure labels are far enough appart. PointF thisPos = WorldToPhysical( (double)numbers_[i], physicalMin, physicalMax, true ); float dist = Utils.Distance( thisPos, lastPos ); if ( i==0 || (dist > this.PhysicalSpacingMin) ) { lastPos = thisPos; this.DrawTick( g, (double)numbers_[i], 0, (string)labels_[i], new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); Axis.UpdateOffsetAndBounds( ref labelOffset, ref boundingBox, tLabelOffset, tBoundingBox ); } } } // now draw the ticks (which might not be aligned with the tick text). ArrayList largeTickPositions; ArrayList smallTickPositions; WorldTickPositions_FirstPass( physicalMin, physicalMax, out largeTickPositions, out smallTickPositions ); lastPos = WorldToPhysical( (double)largeTickPositions[0], physicalMin, physicalMax, true ); for (int i=0; i this.PhysicalSpacingMin) ) { lastPos = thisPos; this.DrawTick( g, tickPos, LargeTickSize, "", new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); Axis.UpdateOffsetAndBounds( ref labelOffset, ref boundingBox, tLabelOffset, tBoundingBox ); } } } /// /// Determines the positions, in world coordinates, of the large ticks. /// /// Label axes do not have small ticks. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// null internal override void WorldTickPositions_FirstPass( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { smallTickPositions = null; largeTickPositions = new ArrayList(); // if ticks correspond to position of text if (!ticksBetweenText_) { for (int i=0; i WorldMin && (double)numbers_[i] < WorldMax) { largeTickPositions.Add( numbers_[i] ); } } } // if ticks correspond to gaps between text else { ArrayList numbers_copy; if (sortDataIfNecessary_) { numbers_copy = (ArrayList)numbers_.Clone(); // shallow copy. numbers_copy.Sort(); } else { numbers_copy = numbers_; } for (int i=1; i WorldMin && worldPosition < WorldMax) { largeTickPositions.Add( worldPosition ); } } } } /// /// If true, large ticks are drawn between the labels, rather /// than at the position of the labels. /// public bool TicksBetweenText { get { return ticksBetweenText_; } set { ticksBetweenText_ = value; } } private bool ticksBetweenText_ = false; /// /// If your data may be be specified out of order (that is /// abscissa values with a higher index may be less than /// abscissa values of a lower index), then data sorting /// may be necessary to implement some of the functionality /// of this object. If you know your data is already /// ordered with abscissa values lowest -> highest, then /// you may set this to false. It's default is true. /// public bool SortDataIfNecessary { get { return sortDataIfNecessary_; } set { sortDataIfNecessary_ = value; } } private bool sortDataIfNecessary_ = true; /// /// If consecutive labels are less than this number of pixels appart, /// some of the labels will not be drawn. /// public int PhysicalSpacingMin { get { return physicalSpacingMin_; } set { physicalSpacingMin_ = value; } } private int physicalSpacingMin_ = 0; private ArrayList labels_; private ArrayList numbers_; } } nplot-gtk-0.9.9.2/lib/LabelPointPlot.cs0000644000175000017500000002037410512404106020272 0ustar carlosblecarlosble/* NPlot - A charting library for .NET LabelPointPlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Data; namespace NPlot { /// /// Encapsulates functionality /// public class LabelPointPlot : PointPlot, ISequencePlot { /// /// This class us used in conjunction with SequenceAdapter to interpret data /// specified to the TextPlot class. /// private class TextDataAdapter { private object data_; private object dataSource_; private string dataMember_; public TextDataAdapter( object dataSource, string dataMember, object data ) { this.data_ = data; this.dataSource_ = dataSource; this.dataMember_ = dataMember; } public string this[int i] { get { // this is inefficient [could set up delegates in constructor]. if (data_ is string[]) { return ((string[])data_)[i]; } if (data_ is string) { if (dataSource_ == null) { throw new NPlotException( "Error: DataSource null" ); } System.Data.DataRowCollection rows; if ( dataSource_ is System.Data.DataSet ) { if (dataMember_ != null) { // TODO error check rows = ((DataTable)((DataSet)dataSource_).Tables[dataMember_]).Rows; } else { // TODO error check rows = ((DataTable)((DataSet)dataSource_).Tables[0]).Rows; } } else if (dataSource_ is System.Data.DataTable ) { rows = ((DataTable)dataSource_).Rows; } else { throw new NPlotException ( "not implemented yet" ); } return (string)((System.Data.DataRow)(rows[i]))[(string)data_]; } if (data_ is System.Collections.ArrayList) { object dataPoint = ((System.Collections.ArrayList)data_)[i]; if (dataPoint is string) return (string)dataPoint; throw new NPlotException( "TextDataAdapter: data not in recognised format" ); } if (data_ == null) { return "text"; } throw new NPlotException( "Text data not of recognised type" ); } } public int Count { get { // this is inefficient [could set up delegates in constructor]. if (data_ == null) { return 0; } if (data_ is string[]) { return ((string[])data_).Length; } if (data_ is System.Collections.ArrayList) { return ((System.Collections.ArrayList)data_).Count; } throw new NPlotException( "Text data not in correct format" ); } } } /// /// Enumeration of all label positions relative to a point. /// public enum LabelPositions { /// /// Above the point /// Above, /// /// Below the point /// Below, /// /// To the left of the point /// Left, /// /// To the right of the point /// Right } /// /// Default Constructor /// public LabelPointPlot() { } /// /// Constructor /// /// The marker type to use for this plot. public LabelPointPlot( Marker marker ) : base( marker ) { } /// /// The position of the text label in relation to the point. /// public LabelPositions LabelTextPosition { get { return labelTextPosition_; } set { labelTextPosition_ = value; } } private LabelPositions labelTextPosition_ = LabelPositions.Above; /// /// The text datasource to attach to each point. /// public object TextData { get { return textData_; } set { textData_ = value; } } object textData_; /// /// The Font used to write text. /// public Font Font { get { return font_; } set { font_ = value; } } private Font font_ = new Font( "Arial", 8.0f ); /// /// Draws the 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 override void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); TextDataAdapter textData = new TextDataAdapter( this.DataSource, this.DataMember, this.TextData ); // first plot the marker // we can do this cast, since the constructor accepts only this type! for (int i=0; i /// Legend functionality specific to Legends associated with a PlotSurface2D. /// public class Legend : LegendBase { /// /// Enumeration of possible Legend placements. /// public enum Placement { /// /// Inside the plot area. /// Inside = 0, /// /// Outside the plot area. /// Outside = 1 } private int xOffset_; private int yOffset_; private PlotSurface2D.XAxisPosition xAttach_; private PlotSurface2D.YAxisPosition yAttach_; private Placement horizontalEdgePlacement_; private Placement verticalEdgePlacement_; private bool neverShiftAxes_; /// /// Whether or not the positions of the Axes may be shifted to make /// room for the Legend. /// public bool NeverShiftAxes { get { return neverShiftAxes_; } set { neverShiftAxes_ = value; } } /// /// Offset from the chosen Y-Axis. TODO: better description. /// public int XOffset { get { return xOffset_; } set { xOffset_ = value; } } /// /// Offset from the X-Axis. TODO: better description. /// public int YOffset { get { return yOffset_; } set { yOffset_ = value; } } /// /// Whether or not to attach the legend on the inside of the top /// or bottom axis (which, is specified using the AttachTo method) or the /// outside. /// public Legend.Placement VerticalEdgePlacement { get { return verticalEdgePlacement_; } set { verticalEdgePlacement_ = value; } } /// /// Whether or not to attach the legend on the inside of the /// left or right axis (which, is specified using the AttachTo method) /// or the outside. /// public Legend.Placement HorizontalEdgePlacement { get { return horizontalEdgePlacement_; } set { horizontalEdgePlacement_ = value; } } /// /// Specify the Axes to attach the legend to. /// /// Specify which horizontal axis the legend should be attached to. /// Specify which vertical axis the legend should be attached to. public void AttachTo( PlotSurface2D.XAxisPosition xa, PlotSurface2D.YAxisPosition ya ) { xAttach_ = xa; yAttach_ = ya; } /// /// Default constructor. /// public Legend() { xAttach_ = PlotSurface2D.XAxisPosition.Top; yAttach_ = PlotSurface2D.YAxisPosition.Right; xOffset_ = 10; yOffset_ = 1; verticalEdgePlacement_ = Placement.Outside; horizontalEdgePlacement_ = Placement.Inside; neverShiftAxes_ = false; } /// /// Updates the PlotSurface2D axes to compensate for the legend. /// /// the bottom x axis /// the left y axis /// the top x axis /// the right y axis /// list of plots. /// scale parameter (for text and other) /// padding around plot within bounds. /// graphics surface bounds /// legend position public void UpdateAxesPositions( PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2, ArrayList plots, float scale, int padding, Rectangle bounds, out Point position ) { int leftIndent = 0; int rightIndent = 0; int bottomIndent = 0; int topIndent = 0; position = new Point(0,0); // now determine if legend should change any of these (legend should be fully // visible at all times), and draw legend. Rectangle legendWidthHeight = this.GetBoundingBox( new Point(0,0), plots, scale ); if (legendWidthHeight.Width > bounds.Width) { legendWidthHeight.Width = bounds.Width; } // (1) calculate legend position. // y position.Y = this.yOffset_; if ( this.xAttach_ == PlotSurface2D.XAxisPosition.Bottom ) { position.Y += pYAxis1.PhysicalMin.Y; if ( this.horizontalEdgePlacement_ == Legend.Placement.Inside ) { position.Y -= legendWidthHeight.Height; } } else { position.Y += pYAxis1.PhysicalMax.Y; if ( this.horizontalEdgePlacement_ == Legend.Placement.Outside ) { position.Y -= legendWidthHeight.Height; } } // x position.X = this.xOffset_; if ( this.yAttach_ == PlotSurface2D.YAxisPosition.Left ) { if ( this.verticalEdgePlacement_ == Legend.Placement.Outside ) { position.X -= legendWidthHeight.Width; } position.X += pXAxis1.PhysicalMin.X; } else { if ( this.verticalEdgePlacement_ == Legend.Placement.Inside ) { position.X -= legendWidthHeight.Width; } position.X += pXAxis1.PhysicalMax.X; } // determine update amounts for axes if ( !this.neverShiftAxes_ ) { if ( position.X < padding ) { int changeAmount = -position.X + padding; // only allow axes to move away from bounds. if ( changeAmount > 0 ) { leftIndent = changeAmount; } position.X += changeAmount; } if ( position.X + legendWidthHeight.Width > bounds.Right - padding ) { int changeAmount = (position.X - bounds.Right + legendWidthHeight.Width + padding ); // only allow axes to move away from bounds. if ( changeAmount > 0.0f ) { rightIndent = changeAmount; } position.X -= changeAmount; } if ( position.Y < padding ) { int changeAmount = -position.Y + padding; // only allow axes to move away from bounds. if ( changeAmount > 0.0f ) { topIndent = changeAmount; } position.Y += changeAmount; } if ( position.Y + legendWidthHeight.Height > bounds.Bottom - padding ) { int changeAmount = (position.Y - bounds.Bottom + legendWidthHeight.Height + padding ); // only allow axes to move away from bounds. if ( changeAmount > 0.0f ) { bottomIndent = changeAmount; } position.Y -= changeAmount; } // update axes. pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X + leftIndent, pXAxis1.PhysicalMin.Y - bottomIndent ); pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X - rightIndent, pXAxis1.PhysicalMax.Y - bottomIndent ); pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X + leftIndent, pYAxis1.PhysicalMin.Y - bottomIndent ); pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X + leftIndent, pYAxis1.PhysicalMax.Y + topIndent ); pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X + leftIndent, pXAxis2.PhysicalMin.Y + topIndent ); pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X - rightIndent, pXAxis2.PhysicalMax.Y + topIndent ); pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X - rightIndent, pYAxis2.PhysicalMin.Y - bottomIndent ); pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X - rightIndent, pYAxis2.PhysicalMax.Y + topIndent ); } } } } nplot-gtk-0.9.9.2/lib/LegendBase.cs0000644000175000017500000002663710512404106017403 0ustar carlosblecarlosble/* NPlot - A charting library for .NET LegendBase.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; using System.Drawing; namespace NPlot { /// /// Provides functionality for drawing legends. /// /// /// The class is quite closely tied to PlotSurface2D. /// public class LegendBase { /// /// Constructor. /// public LegendBase() { this.Font = new Font( new FontFamily("Arial"), 10, FontStyle.Regular, GraphicsUnit.Pixel ); this.BackgroundColor = Color.White; this.BorderColor = Color.Black; this.TextColor = Color.Black; this.borderStyle_ = BorderType.Shadow; this.autoScaleText_ = false; } /// /// Get the bounding box of the rectangle. /// /// the position of the top left of the legend. /// Array of plot objects to appear in the legend. /// if the legend is set to scale, the amount to scale by.> /// /// do implementation that doesn't call draw. Change xPos, yPos to PointF public Rectangle GetBoundingBox( Point position, ArrayList plots, float scale ) { System.Drawing.Bitmap b = new System.Drawing.Bitmap(1,1); Graphics g = Graphics.FromImage(b); return this.Draw( g, position, plots, scale ); } /// /// Draw The legend /// /// The graphics surface on which to draw /// The position of the top left of the axis. /// Array of plot objects to appear in the legend. /// if the legend is set to scale, the amount to scale by. /// bounding box public Rectangle Draw( Graphics g, Point position, ArrayList plots, float scale ) { // first of all determine the Font to use in the legend. Font textFont; if (this.AutoScaleText) { textFont = Utils.ScaleFont( this.font_, scale ); } else { textFont = this.font_; } // determine max width and max height of label strings and // count the labels. int labelCount = 0; int maxHt = 0; int maxWd = 0; int unnamedCount = 0; for (int i=0; i maxHt ) { maxHt = (int)labelSize.Height; } if ( labelSize.Width > maxWd ) { maxWd = (int)labelSize.Width; } ++labelCount; } bool extendingHorizontally = numberItemsHorizontally_ == -1; bool extendingVertically = numberItemsVertically_ == -1; // determine width in legend items count units. int widthInItemCount = 0; if (extendingVertically) { if (labelCount >= numberItemsHorizontally_) { widthInItemCount = numberItemsHorizontally_; } else { widthInItemCount = labelCount; } } else if (extendingHorizontally) { widthInItemCount = labelCount / numberItemsVertically_; if (labelCount % numberItemsVertically_ != 0) widthInItemCount += 1; } else { throw new NPlotException( "logic error in legend base" ); } // determine height of legend in items count units. int heightInItemCount = 0; if (extendingHorizontally) { if (labelCount >= numberItemsVertically_) { heightInItemCount = numberItemsVertically_; } else { heightInItemCount = labelCount; } } else // extendingVertically { heightInItemCount = labelCount / numberItemsHorizontally_; if (labelCount % numberItemsHorizontally_ != 0) heightInItemCount += 1; } int lineLength = 20; int hSpacing = (int)(5.0f * scale); int vSpacing = (int)(3.0f * scale); int boxWidth = (int) ((float)widthInItemCount * (lineLength + maxWd + hSpacing * 2.0f ) + hSpacing); int boxHeight = (int)((float)heightInItemCount * (maxHt + vSpacing) + vSpacing); int totalWidth = boxWidth; int totalHeight = boxHeight; // draw box around the legend. if ( this.BorderStyle == BorderType.Line ) { g.FillRectangle( new SolidBrush( this.bgColor_ ), position.X, position.Y, boxWidth, boxHeight ); g.DrawRectangle( new Pen( this.borderColor_ ), position.X, position.Y, boxWidth, boxHeight ); } else if ( this.BorderStyle == BorderType.Shadow ) { int offset = (int)(4.0f * scale); g.FillRectangle( new SolidBrush( Color.FromArgb(128, Color.Gray) ), position.X+offset, position.Y+offset, boxWidth, boxHeight ); g.FillRectangle( new SolidBrush( this.bgColor_ ), position.X, position.Y, boxWidth, boxHeight ); g.DrawRectangle( new Pen( this.borderColor_ ), position.X, position.Y, boxWidth, boxHeight ); totalWidth += offset; totalHeight += offset; } /* else if ( this.BorderStyle == BorderType.Curved ) { // TODO. make this nice. } */ else { // do nothing. } // now draw entries in box.. labelCount = 0; unnamedCount = 0; int plotCount = -1; for (int i=0; i /// The font used to draw text in the legend. /// public Font Font { get { return this.font_; } set { this.font_ = value; } } private Font font_; /// /// The color used to draw text in the legend. /// public Color TextColor { get { return this.textColor_; } set { this.textColor_ = value; } } Color textColor_; /// /// The background color of the legend. /// public Color BackgroundColor { get { return bgColor_; } set { bgColor_ = value; } } Color bgColor_; /// /// The color of the legend border. /// public Color BorderColor { get { return borderColor_; } set { borderColor_ = value; } } Color borderColor_; /// /// The types of legend borders (enum). /// public enum BorderType { /// /// No border. /// None = 0, /// /// Line border. /// Line = 1, /// /// Shaded border. /// Shadow = 2 //Curved = 3 } /// /// The border style to use for the legend. /// public Legend.BorderType BorderStyle { get { return borderStyle_; } set { borderStyle_ = value; } } private NPlot.Legend.BorderType borderStyle_; /// /// Whether or not to auto scale text in the legend according the physical /// dimensions of the plot surface. /// public bool AutoScaleText { get { return autoScaleText_; } set { autoScaleText_ = value; } } bool autoScaleText_; /// /// Setting this does two things. First of all, it sets the maximum number of /// items in the legend vertically. Second of all, it makes the legend grow /// horizontally (as it must given this constraint). /// public int NumberItemsVertically { set { this.numberItemsVertically_ = value; this.numberItemsHorizontally_ = -1; } } int numberItemsVertically_ = -1; /// /// Setting this does two things. First of all, it sets the maximum number of /// items in the legend horizontally. Second of all, it makes the legend grow /// vertically (as it must given this constraint). /// public int NumberItemsHorizontally { set { this.numberItemsHorizontally_ = value; this.numberItemsVertically_ = -1; } } int numberItemsHorizontally_ = 1; } } nplot-gtk-0.9.9.2/lib/license.txt0000644000175000017500000000415510512404106017235 0ustar carlosblecarlosbleNPlot - A charting library for .NET Copyright (C) 2003-2005 Matt Howlett and others. Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. nplot-gtk-0.9.9.2/lib/LinearAxis.cs0000644000175000017500000004561010512404106017441 0ustar carlosblecarlosble/* NPlot - A charting library for .NET LinearAxis.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Drawing; using System.Collections; using System; using System.Text; using System.Diagnostics; namespace NPlot { /// /// Provides functionality for drawing axes with a linear numeric scale. /// public class LinearAxis : Axis, System.ICloneable { /// /// Deep copy of LinearAxis. /// /// A copy of the LinearAxis Class public override object Clone() { LinearAxis a = new LinearAxis(); // ensure that this isn't being called on a derived type. If it is, then oh no! if (this.GetType() != a.GetType()) { throw new NPlotException( "Clone not defined in derived type. Help!" ); } this.DoClone( this, a ); return a; } /// /// Helper method for Clone. /// protected void DoClone( LinearAxis b, LinearAxis a ) { Axis.DoClone( b, a ); a.numberSmallTicks_ = b.numberSmallTicks_; a.largeTickValue_ = b.largeTickValue_; a.largeTickStep_ = b.largeTickStep_; a.offset_ = b.offset_; a.scale_ = b.scale_; } /// /// Copy constructor /// /// The Axis to clone public LinearAxis( Axis a ) : base( a ) { Init(); } /// /// Default constructor. /// public LinearAxis() : base() { Init(); } /// /// Construct a linear axis with the provided world min and max values. /// /// the world minimum value of the axis. /// the world maximum value of the axis. public LinearAxis( double worldMin, double worldMax ) : base( worldMin, worldMax ) { Init(); } private void Init() { this.NumberFormat = "{0:g5}"; } /// /// Draws the large and small ticks [and tick labels] for this axis. /// /// The graphics surface on which to draw. /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// out: smallest box that completely surrounds all ticks and associated labels for this axis. /// out: offset from the axis to draw the axis label. protected override void DrawTicks( Graphics g, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { Point tLabelOffset; Rectangle tBoundingBox; labelOffset = this.getDefaultLabelOffset( physicalMin, physicalMax ); boundingBox = null; ArrayList largeTickPositions; ArrayList smallTickPositions; this.WorldTickPositions( physicalMin, physicalMax, out largeTickPositions, out smallTickPositions ); labelOffset = new Point( 0, 0 ); boundingBox = null; if (largeTickPositions.Count > 0) { for (int i = 0; i < largeTickPositions.Count; ++i) { double labelNumber = (double)largeTickPositions[i]; // TODO: Find out why zero is sometimes significantly not zero [seen as high as 10^-16]. if (Math.Abs(labelNumber) < 0.000000000000001) { labelNumber = 0.0; } StringBuilder label = new StringBuilder(); label.AppendFormat(this.NumberFormat, labelNumber); this.DrawTick( g, ((double)largeTickPositions[i]/this.scale_-this.offset_), this.LargeTickSize, label.ToString(), new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); Axis.UpdateOffsetAndBounds( ref labelOffset, ref boundingBox, tLabelOffset, tBoundingBox ); } } for (int i = 0; i /// Determines the positions, in world coordinates, of the small ticks /// if they have not already been generated. /// /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// The positions of the large ticks. /// If null, small tick positions are returned via this parameter. Otherwise this function does nothing. internal override void WorldTickPositions_SecondPass( Point physicalMin, Point physicalMax, ArrayList largeTickPositions, ref ArrayList smallTickPositions ) { // return if already generated. if (smallTickPositions != null) return; int physicalAxisLength = Utils.Distance( physicalMin, physicalMax ); double adjustedMax = this.AdjustedWorldValue( WorldMax ); double adjustedMin = this.AdjustedWorldValue( WorldMin ); smallTickPositions = new ArrayList(); // TODO: Can optimize this now. bool shouldCullMiddle; double bigTickSpacing = this.DetermineLargeTickStep( physicalAxisLength, out shouldCullMiddle ); int nSmall = this.DetermineNumberSmallTicks( bigTickSpacing ); double smallTickSpacing = bigTickSpacing / (double)nSmall; // if there is at least one big tick if (largeTickPositions.Count > 0) { double pos1 = (double)largeTickPositions[0] - smallTickSpacing; while (pos1 > adjustedMin) { smallTickPositions.Add( pos1 ); pos1 -= smallTickSpacing; } } for (int i = 0; i < largeTickPositions.Count; ++i ) { for (int j = 1; j < nSmall; ++j ) { double pos = (double)largeTickPositions[i] + ((double)j) * smallTickSpacing; if (pos <= adjustedMax) { smallTickPositions.Add( pos ); } } } } /// /// Adjusts a real world value to one that has been modified to /// reflect the Axis Scale and Offset properties. /// /// world value to adjust /// adjusted world value public double AdjustedWorldValue( double world ) { return world * this.scale_ + this.offset_; } /// /// Determines the positions, in world coordinates, of the large ticks. /// When the physical extent of the axis is small, some of the positions /// that were generated in this pass may be converted to small tick /// positions and returned as well. /// /// If the LargeTickStep isn't set then this is calculated automatically and /// depends on the physical extent of the axis. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// ArrayList containing the positions of the small ticks if calculated, null otherwise. internal override void WorldTickPositions_FirstPass( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { // (1) error check if ( double.IsNaN(WorldMin) || double.IsNaN(WorldMax) ) { throw new NPlotException( "world extent of axis not set." ); } double adjustedMax = this.AdjustedWorldValue( WorldMax ); double adjustedMin = this.AdjustedWorldValue( WorldMin ); // (2) determine distance between large ticks. bool shouldCullMiddle; double tickDist = this.DetermineLargeTickStep( Utils.Distance(physicalMin, physicalMax), out shouldCullMiddle ); // (3) determine starting position. double first = 0.0f; if (!double.IsNaN(largeTickValue_)) { // this works for both case when largTickValue_ lt or gt adjustedMin. first = largeTickValue_ + (Math.Ceiling((adjustedMin-largeTickValue_)/tickDist))*tickDist; } else { if( adjustedMin > 0.0 ) { double nToFirst = Math.Floor(adjustedMin / tickDist) + 1.0f; first = nToFirst * tickDist; } else { double nToFirst = Math.Floor(-adjustedMin/tickDist) - 1.0f; first = -nToFirst * tickDist; } // could miss one, if first is just below zero. if ((first - tickDist) >= adjustedMin) { first -= tickDist; } } // (4) now make list of large tick positions. largeTickPositions = new ArrayList(); if (tickDist < 0.0) // some sanity checking. TODO: remove this. throw new NPlotException( "Tick dist is negative" ); double position = first; int safetyCount = 0; while ( (position <= adjustedMax) && (++safetyCount < 5000) ) { largeTickPositions.Add( position ); position += tickDist; } // (5) if the physical extent is too small, and the middle // ticks should be turned into small ticks, then do this now. smallTickPositions = null; if (shouldCullMiddle) { smallTickPositions = new ArrayList(); if (largeTickPositions.Count > 2) { for (int i=1; i /// Calculates the world spacing between large ticks, based on the physical /// axis length (parameter), world axis length, Mantissa values and /// MinPhysicalLargeTickStep. A value such that at least two /// /// physical length of the axis /// Returns true if we were forced to make spacing of /// large ticks too small in order to ensure that there are at least two of /// them. The draw ticks method should not draw more than two large ticks if this /// returns true. /// Large tick spacing /// TODO: This can be optimised a bit. private double DetermineLargeTickStep( float physicalLength, out bool shouldCullMiddle ) { shouldCullMiddle = false; if ( double.IsNaN(WorldMin) || double.IsNaN(WorldMax) ) { throw new NPlotException( "world extent of axis not set." ); } // if the large tick has been explicitly set, then return this. if ( !double.IsNaN(largeTickStep_) ) { if ( largeTickStep_ <= 0.0f ) { throw new NPlotException( "can't have negative or zero tick step - reverse WorldMin WorldMax instead." ); } return largeTickStep_; } // otherwise we need to calculate the large tick step ourselves. // adjust world max and min for offset and scale properties of axis. double adjustedMax = this.AdjustedWorldValue( WorldMax ); double adjustedMin = this.AdjustedWorldValue( WorldMin ); double range = adjustedMax - adjustedMin; // if axis has zero world length, then return arbitrary number. if ( Utils.DoubleEqual( adjustedMax, adjustedMin ) ) { return 1.0f; } double approxTickStep; if (TicksIndependentOfPhysicalExtent) { approxTickStep = range / 6.0f; } else { approxTickStep = (MinPhysicalLargeTickStep / physicalLength) * range; } double exponent = Math.Floor( Math.Log10( approxTickStep ) ); double mantissa = Math.Pow( 10.0, Math.Log10( approxTickStep ) - exponent ); // determine next whole mantissa below the approx one. int mantissaIndex = Mantissas.Length-1; for (int i=1; i physicalLength/2) { shouldCullMiddle = true; mantissaIndex -= 1; if (mantissaIndex == -1) { mantissaIndex = Mantissas.Length-1; exponent -= 1.0; } tickStep = Math.Pow( 10.0, exponent ) * Mantissas[mantissaIndex]; physicalStep = (float)((tickStep / range) * physicalLength); } } // and we're done. return Math.Pow( 10.0, exponent ) * Mantissas[mantissaIndex]; } /// /// Given the large tick step, determine the number of small ticks that should /// be placed in between. /// /// the large tick step. /// the number of small ticks to place between large ticks. private int DetermineNumberSmallTicks( double bigTickDist ) { if (this.numberSmallTicks_ != null) { return (int)this.numberSmallTicks_+1; } if (this.SmallTickCounts.Length != this.Mantissas.Length) { throw new NPlotException( "Mantissa.Length != SmallTickCounts.Length" ); } if (bigTickDist > 0.0f) { double exponent = Math.Floor( Math.Log10( bigTickDist ) ); double mantissa = Math.Pow( 10.0, Math.Log10( bigTickDist ) - exponent ); for (int i=0; i /// The distance between large ticks. If this is set to NaN [default], /// this distance will be calculated automatically. /// public double LargeTickStep { set { largeTickStep_ = value; } get { return largeTickStep_; } } /// /// If set !NaN, gives the distance between large ticks. /// private double largeTickStep_ = double.NaN; /// /// If set, a large tick will be placed at this position, and other large ticks will /// be placed relative to this position. /// public double LargeTickValue { set { largeTickValue_ = value; } get { return largeTickValue_; } } private double largeTickValue_ = double.NaN; /// /// The number of small ticks between large ticks. /// public int NumberOfSmallTicks { set { numberSmallTicks_ = value; } get { // TODO: something better here. return (int)numberSmallTicks_; } } private object numberSmallTicks_ = null; /// /// Scale to apply to world values when labelling axis: /// (labelWorld = world * scale + offset). This does not /// affect the "real" world range of the axis. /// public double Scale { get { return scale_; } set { scale_ = value; } } /// /// Offset to apply to world values when labelling the axis: /// (labelWorld = axisWorld * scale + offset). This does not /// affect the "real" world range of the axis. /// public double Offset { get { return offset_; } set { offset_ = value; } } /// /// If LargeTickStep isn't specified, then a suitable value is /// calculated automatically. To determine the tick spacing, the /// world axis length is divided by ApproximateNumberLargeTicks /// and the next lowest distance m*10^e for some m in the Mantissas /// set and some integer e is used as the large tick spacing. /// public float ApproxNumberLargeTicks = 3.0f; /// /// If LargeTickStep isn't specified, then a suitable value is /// calculated automatically. The value will be of the form /// m*10^e for some m in this set. /// public double[] Mantissas = {1.0, 2.0, 5.0}; /// /// If NumberOfSmallTicks isn't specified then .... /// If specified LargeTickStep manually, then no small ticks unless /// NumberOfSmallTicks specified. /// public int[] SmallTickCounts = {4, 1, 4}; private double offset_ = 0.0; private double scale_ = 1.0; } } nplot-gtk-0.9.9.2/lib/LinearGradient.cs0000644000175000017500000001054210512404106020266 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Gradient.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// Class for creating a linear gradient. /// public class LinearGradient : IGradient { /// /// Constructor. /// /// The color corresponding to 0.0 /// The color corresponding to 1.0 public LinearGradient( Color minColor, Color maxColor ) { this.minColor_ = minColor; this.maxColor_ = maxColor; } /// /// The color corresponding to 0.0 /// public Color MaxColor { get { return this.maxColor_; } set { this.maxColor_ = value; } } private Color maxColor_; /// /// The color corresponding to 1.0 /// public Color MinColor { get { return this.minColor_; } set { this.minColor_ = value; } } private Color minColor_; /// /// The color corresponding to NaN /// public Color VoidColor { get { return voidColor_; } set { voidColor_ = value; } } private Color voidColor_ = Color.Black; /// /// Gets a color corresponding to a number between 0.0 and 1.0 inclusive. The color will /// be a linear interpolation of the min and max colors. /// /// the number to get corresponding color for (between 0.0 and 1.0) /// The color corresponding to the supplied number. public Color GetColor( double prop ) { if (Double.IsNaN(prop)) { return voidColor_; } if ( prop <= 0.0 ) { return this.MinColor; } if ( prop >= 1.0 ) { return this.MaxColor; } byte r = (byte)((int)(this.MinColor.R) + (int)(((double)this.MaxColor.R - (double)this.MinColor.R)*prop)); byte g = (byte)((int)(this.MinColor.G) + (int)(((double)this.MaxColor.G - (double)this.MinColor.G)*prop)); byte b = (byte)((int)(this.MinColor.B) + (int)(((double)this.MaxColor.B - (double)this.MinColor.B)*prop)); return Color.FromArgb(r,g,b); } } } nplot-gtk-0.9.9.2/lib/LinePlot.cs0000644000175000017500000002374410512404106017134 0ustar carlosblecarlosble/* NPlot - A charting library for .NET LinePlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Diagnostics; namespace NPlot { /// /// Encapsulates functionality for plotting data as a line chart. /// public class LinePlot : BaseSequencePlot, IPlot, ISequencePlot { /// /// Default constructor /// public LinePlot() { } /// /// Constructor /// /// The data source to associate with this plot public LinePlot( object dataSource ) { this.DataSource = dataSource; } /// /// Constructor /// /// the ordinate data to associate with this plot. /// the abscissa data to associate with this plot. public LinePlot( object ordinateData, object abscissaData ) { this.OrdinateData = ordinateData; this.AbscissaData = abscissaData; } /// /// Draws the line 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. /// If true draw the shadow for the line. If false, draw line. public void DrawLineOrShadow( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow ) { Pen shadowPen = null; if (drawShadow) { shadowPen = (Pen)this.Pen.Clone(); shadowPen.Color = this.ShadowColor; } SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); ITransform2D t = Transform2D.GetTransformer( xAxis, yAxis ); int numberPoints = data.Count; if (data.Count == 0) { return; } // clipping is now handled assigning a clip region in the // graphic object before this call if (numberPoints == 1) { PointF physical = t.Transform( data[0] ); if (drawShadow) { g.DrawLine( shadowPen, physical.X - 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y, physical.X + 0.5f + this.ShadowOffset.X, physical.Y + this.ShadowOffset.Y ); } else { g.DrawLine( Pen, physical.X-0.5f, physical.Y, physical.X+0.5f, physical.Y); } } else { // prepare for clipping double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); if (leftCutoff > rightCutoff) { Utils.Swap(ref leftCutoff, ref rightCutoff); } if (drawShadow) { // correct cut-offs double shadowCorrection = xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0,0), false); leftCutoff -= shadowCorrection; rightCutoff -= shadowCorrection; } for (int i = 1; i < numberPoints; ++i) { // check to see if any values null. If so, then continue. double dx1 = data[i-1].X; double dx2 = data[i].X; double dy1 = data[i-1].Y; double dy2 = data[i].Y; if ( Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2) ) { continue; } // do horizontal clipping here, to speed up if ((dx1 < leftCutoff || rightCutoff < dx1) && (dx2 < leftCutoff || rightCutoff < dx2)) { continue; } // else draw line. PointF p1 = t.Transform( data[i-1] ); PointF p2 = t.Transform( data[i] ); // when very far zoomed in, points can fall ontop of each other, // and g.DrawLine throws an overflow exception if (p1.Equals(p2)) continue; if (drawShadow) { g.DrawLine( shadowPen, p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y, p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y ); } else { g.DrawLine( Pen, p1.X, p1.Y, p2.X, p2.Y ); } } } } /// /// Draws the line 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 void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { if (this.shadow_) { this.DrawLineOrShadow( g, xAxis, yAxis, true ); } this.DrawLineOrShadow( g, xAxis, yAxis, false ); } /// /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { SequenceAdapter data_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.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( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); return data_.SuggestYAxis(); } /// /// If true, draw a shadow under the line. /// public bool Shadow { get { return shadow_; } set { shadow_ = value; } } private bool shadow_ = false; /// /// Color of line shadow if drawn. Use Shadow method to turn shadow on and off. /// public Color ShadowColor { get { return shadowColor_; } set { shadowColor_ = value; } } private Color shadowColor_ = Color.FromArgb(100,100,100); /// /// Offset of shadow line from primary line. /// public Point ShadowOffset { get { return shadowOffset_; } set { shadowOffset_ = value; } } private Point shadowOffset_ = new Point( 1, 1 ); /// /// 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 virtual void DrawInLegend(Graphics g, Rectangle startEnd) { g.DrawLine(pen_, startEnd.Left, (startEnd.Top + startEnd.Bottom) / 2, startEnd.Right, (startEnd.Top + startEnd.Bottom) / 2); } /// /// The pen used to draw the plot /// public System.Drawing.Pen Pen { get { return pen_; } set { pen_ = value; } } private System.Drawing.Pen pen_ = new Pen(Color.Black); /// /// The color of the pen used to draw lines in this plot. /// public System.Drawing.Color Color { set { if (pen_ != null) { pen_.Color = value; } else { pen_ = new Pen(value); } } get { return pen_.Color; } } } } nplot-gtk-0.9.9.2/lib/LogAxis.cs0000644000175000017500000004707310512404106016755 0ustar carlosblecarlosble/* NPlot - A charting library for .NET LogAxis.cs Copyright (C) 2003 Paolo Pierini, Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Collections; using System.Text; namespace NPlot { /// /// The class implementing logarithmic axes. /// public class LogAxis : Axis { /// /// Deep Copy of the LogAxis. /// /// A Copy of the LogAxis Class. public override object Clone() { LogAxis a = new LogAxis(); if (this.GetType() != a.GetType()) { throw new NPlotException("Clone not defined in derived type. Help!"); } this.DoClone( this, a ); return a; } /// /// Helper method for Clone (actual implementation) /// /// The original object to clone. /// The cloned object. protected void DoClone(LogAxis b, LogAxis a) { Axis.DoClone(b,a); // add specific elemtents of the class for the deep copy of the object a.numberSmallTicks_ = b.numberSmallTicks_; a.largeTickValue_ = b.largeTickValue_; a.largeTickStep_ = b.largeTickStep_; } /// /// Default constructor. /// public LogAxis() : base() { Init(); } /// /// Copy Constructor /// /// The Axis to clone. public LogAxis(Axis a) : base(a) { Init(); } /// /// Constructor /// /// Minimum World value for the axis. /// Maximum World value for the axis. public LogAxis(double worldMin, double worldMax) : base( worldMin, worldMax ) { Init(); } private void Init() { this.NumberFormat = "{0:g5}"; } /// /// Draw the ticks. /// /// The drawing surface on which to draw. /// The minimum physical extent of the axis. /// The maximum physical extent of the axis. /// out: smallest box that completely encompasses all of the ticks and tick labels. /// out: a suitable offset from the axis to draw the axis label. /// An ArrayList containing the offset from the axis required for an axis label /// to miss this tick, followed by a bounding rectangle for the tick and tickLabel drawn. protected override void DrawTicks( Graphics g, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { Point tLabelOffset; Rectangle tBoundingBox; labelOffset = this.getDefaultLabelOffset( physicalMin, physicalMax ); boundingBox = null; ArrayList largeTickPositions; ArrayList smallTickPositions; this.WorldTickPositions( physicalMin, physicalMax, out largeTickPositions, out smallTickPositions ); Point offset = new Point( 0, 0 ); object bb = null; // Missed this protection if (largeTickPositions.Count > 0) { for (int i=0; i 0) { for (int i=0; i /// Determines the positions, in world coordinates, of the small ticks /// if they have not already been generated. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// The positions of the large ticks, unchanged /// If null, small tick positions are returned via this parameter. Otherwise this function does nothing. internal override void WorldTickPositions_SecondPass( Point physicalMin, Point physicalMax, ArrayList largeTickPositions, ref ArrayList smallTickPositions ) { if (smallTickPositions != null) { throw new NPlotException( "not expecting smallTickPositions to be set already." ); } smallTickPositions = new ArrayList(); // retrieve the spacing of the big ticks. Remember this is decades! double bigTickSpacing = this.DetermineTickSpacing(); int nSmall = this.DetermineNumberSmallTicks( bigTickSpacing ); // now we have to set the ticks // let us start with the easy case where the major tick distance // is larger than a decade if ( bigTickSpacing > 1.0f ) { if (largeTickPositions.Count > 0) { // deal with the smallticks preceding the // first big tick double pos1 = (double)largeTickPositions[0]; while (pos1 > this.WorldMin) { pos1 = pos1 / 10.0f; smallTickPositions.Add( pos1 ); } // now go on for all other Major ticks for (int i=0; i 0) { // first deal with the smallticks preceding the first big tick // positioning before the first tick double pos1=(double)largeTickPositions[0]/10.0f; for (int i=0; ithis.WorldMin) { smallTickPositions.Add(pos); } } // now go on for all other Major ticks for (int i=0; ithis.WorldMin && pos< this.WorldMax ) { smallTickPositions.Add(pos); } } } } } private static double m_d5Log = -Math.Log10(0.5); // .30103 private static double m_d5RegionPos = Math.Abs(m_d5Log + ((1 - m_d5Log) / 2)); // ' .6505 private static double m_d5RegionNeg = Math.Abs(m_d5Log / 2); // '.1505 private void CalcGrids( double dLenAxis, int nNumDivisions, ref double dDivisionInterval) { double dMyInterval = dLenAxis / nNumDivisions; double dPower = Math.Log10(dMyInterval); dDivisionInterval = 10 ^ (int)dPower; double dFixPower = dPower - (int)dPower; double d5Region = Math.Abs(dPower - dFixPower); double dMyMult; if (dPower < 0) { d5Region = -(dPower - dFixPower); dMyMult = 0.5; } else { d5Region = 1 - (dPower - dFixPower); dMyMult = 5; } if ((d5Region >= m_d5RegionNeg) && (d5Region <= m_d5RegionPos)) { dDivisionInterval = dDivisionInterval * dMyMult; } } /// /// Determines the positions, in world coordinates, of the log spaced large ticks. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// null internal override void WorldTickPositions_FirstPass( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { smallTickPositions = null; largeTickPositions = new ArrayList(); if ( double.IsNaN(WorldMin) || double.IsNaN(WorldMax) ) { throw new NPlotException( "world extent of axis not set." ); } double roundTickDist = this.DetermineTickSpacing( ); // now determine first tick position. double first = 0.0f; // if the user hasn't specified a large tick position. if (double.IsNaN(largeTickValue_)) { if( WorldMin > 0.0 ) { double nToFirst = Math.Floor(Math.Log10(WorldMin) / roundTickDist)+1.0f; first = nToFirst * roundTickDist; } // could miss one, if first is just below zero. if (first-roundTickDist >= Math.Log10(WorldMin)) { first -= roundTickDist; } } // the user has specified one place they would like a large tick placed. else { first = Math.Log10( this.LargeTickValue ); // TODO: check here not too much different. // could result in long loop. while (first < Math.Log10(WorldMin)) { first += roundTickDist; } while (first > Math.Log10(WorldMin)+roundTickDist) { first -= roundTickDist; } } double mark = first; while (mark <= Math.Log10(WorldMax)) { // up to here only logs are dealt with, but I want to return // a real value in the arraylist double val; val = Math.Pow( 10.0, mark ); largeTickPositions.Add( val ); mark += roundTickDist; } } /// /// Determines the tick spacing. /// /// The tick spacing (in decades!) private double DetermineTickSpacing( ) { if ( double.IsNaN(WorldMin) || double.IsNaN(WorldMax) ) { throw new NPlotException( "world extent of axis is not set." ); } // if largeTickStep has been set, it is used if ( !double.IsNaN( this.largeTickStep_) ) { if ( this.largeTickStep_ <= 0.0f ) { throw new NPlotException( "can't have negative tick step - reverse WorldMin WorldMax instead." ); } return this.largeTickStep_; } double MagRange = (double)(Math.Floor(Math.Log10(WorldMax)) - Math.Floor(Math.Log10(WorldMin))+1.0); if ( MagRange > 0.0 ) { // for now, a simple logic // start with a major tick every order of magnitude, and // increment if in order not to have more than 10 ticks in // the plot. double roundTickDist=1.0F; int nticks=(int)(MagRange/roundTickDist); while (nticks > 10) { roundTickDist++; nticks=(int)(MagRange/roundTickDist); } return roundTickDist; } else { return 0.0f; } } /// /// Determines the number of small ticks between two large ticks. /// /// The distance between two large ticks. /// The number of small ticks. private int DetermineNumberSmallTicks( double bigTickDist ) { // if the big ticks is more than one decade, the // small ticks are every decade, I don't let the user set it. if (this.numberSmallTicks_ != null && bigTickDist == 1.0f) { return (int)this.numberSmallTicks_+1; } // if we are plotting every decade, we have to // put the log ticks. As a start, I put every // small tick (.2,.3,.4,.5,.6,.7,.8,.9) if (bigTickDist == 1.0f) { return 8; } // easy, put a tick every missed decade else if (bigTickDist > 1.0f) { return (int)bigTickDist - 1; } else { throw new NPlotException("Wrong Major tick distance setting"); } } /// /// The step between large ticks, expressed in decades for the Log scale. /// public double LargeTickStep { set { largeTickStep_ = value; } get { return largeTickStep_; } } /// /// Position of one of the large ticks [other positions will be calculated relative to this one]. /// public double LargeTickValue { set { largeTickValue_ = value; } get { return largeTickValue_; } } /// /// The number of small ticks between large ticks. /// public int NumberSmallTicks { set { numberSmallTicks_ = value; } } // Private members private object numberSmallTicks_; private double largeTickValue_ = double.NaN; private double largeTickStep_ = double.NaN; /// /// World to physical coordinate transform. /// /// The coordinate value to transform. /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// if false, then physical value may extend outside worldMin / worldMax. If true, the physical value returned will be clipped to physicalMin or physicalMax if it lies outside this range. /// The transformed coordinates. /// TODO: make Reversed property work for this. public override PointF WorldToPhysical( double coord, PointF physicalMin, PointF physicalMax, bool clip ) { // if want clipped value, return extrema if outside range. if (clip) { if (coord > WorldMax) { return physicalMax; } if (coord < WorldMin) { return physicalMin; } } if (coord < 0.0f) { throw new NPlotException( "Cannot have negative values for data using Log Axis" ); } // inside range or don't want to clip. double lrange = (double)(Math.Log10(WorldMax) - Math.Log10(WorldMin)); double prop = (double)((Math.Log10(coord) - Math.Log10(WorldMin)) / lrange); PointF offset = new PointF( (float)(prop * (physicalMax.X - physicalMin.X)), (float)(prop * (physicalMax.Y - physicalMin.Y)) ); return new PointF( physicalMin.X + offset.X, physicalMin.Y + offset.Y ); } /// /// Return the world coordinate of the projection of the point p onto /// the axis. /// /// The point to project onto the axis /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// If true, the world value will be clipped to WorldMin or WorldMax as appropriate if it lies outside this range. /// The world value corresponding to the projection of the point p onto the axis. public override double PhysicalToWorld( PointF p, PointF physicalMin, PointF physicalMax, bool clip ) { // use the base method to do the projection on the axis. double t = base.PhysicalToWorld( p, physicalMin, physicalMax, clip ); // now reconstruct phys dist prop along this assuming linear scale as base method did. double v = (t - this.WorldMin) / (this.WorldMax - this.WorldMin); double ret = WorldMin*Math.Pow( WorldMax / WorldMin, v ); // if want clipped value, return extrema if outside range. if (clip) { ret = Math.Max( ret, WorldMin ); ret = Math.Min( ret, WorldMax ); } return ret; } /// /// The minimum world extent of the axis. Must be greater than zero. /// public override double WorldMin { get { return (double)base.WorldMin; } set { if (value > 0.0f) { base.WorldMin = value; } else { throw new NPlotException("Cannot have negative values in Log Axis"); } } } /// /// The maximum world extent of the axis. Must be greater than zero. /// public override double WorldMax { get { return (double)base.WorldMax; } set { if (value > 0.0F) { base.WorldMax = value; } else { throw new NPlotException("Cannot have negative values in Log Axis"); } } } /// /// Get whether or not this axis is linear. It is not. /// public override bool IsLinear { get { return false; } } } } nplot-gtk-0.9.9.2/lib/Marker.cs0000644000175000017500000002637510512404106016632 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Marker.cs Copyright (C) 2003 Paolo Pierini, Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; namespace NPlot { /// /// Encapsulates functionality relating to markers used by the PointPlot class. /// public class Marker { /// /// Enumeration of all different types of marker. /// public enum MarkerType { /// /// A simple cross marker (x). /// Cross1, /// /// Another simple cross marker (+). /// Cross2, /// /// A circle marker. /// Circle, /// /// A square marker. /// Square, /// /// A triangle marker (upwards). /// Triangle, /// /// A triangle marker (upwards). /// TriangleUp, /// /// A triangle marker (upwards). /// TriangleDown, /// /// A diamond, /// Diamond, /// /// A filled circle /// FilledCircle, /// /// A filled square /// FilledSquare, /// /// A filled triangle /// FilledTriangle, /// /// A small flag (up) /// Flag, /// /// A small flag (up) /// FlagUp, /// /// A small flag (down) /// FlagDown, /// /// No marker /// None } private MarkerType markerType_; private int size_; private int h_; private System.Drawing.Pen pen_ = new Pen( Color.Black ); private System.Drawing.Brush brush_ = new SolidBrush( Color.Black ); private bool filled_ = false; private bool dropLine_ = false; /// /// The type of marker. /// public MarkerType Type { get { return markerType_; } set { markerType_ = value; } } /// /// Whether or not to draw a dropline. /// public bool DropLine { get { return dropLine_; } set { dropLine_ = value; } } /// /// The marker size. /// public int Size { get { return size_; } set { size_ = value; h_ = size_/2; } } /// /// The brush used to fill the marker. /// public Brush FillBrush { get { return brush_; } set { brush_ = value; } } /// /// Fill with color. /// public bool Filled { get { return filled_; } set { filled_ = value; } } /// /// Sets the pen color and fill brush to be solid with the specified color. /// public System.Drawing.Color Color { set { pen_.Color = value; brush_ = new SolidBrush( value ); } get { return pen_.Color; } } /// /// The Pen used to draw the marker. /// public System.Drawing.Pen Pen { set { pen_ = value; } get { return pen_; } } /// /// Default constructor. /// public Marker() { markerType_ = MarkerType.Square; Size = 4; filled_ = false; } /// /// Constructor /// /// The marker type. public Marker( MarkerType markertype ) { markerType_ = markertype; Size = 4; filled_ = false; } /// /// Constructor /// /// The marker type. /// The marker size. public Marker( MarkerType markertype, int size ) { markerType_ = markertype; Size = size; filled_ = false; } /// /// Constructor /// /// The marker type. /// The marker size. /// The marker color. public Marker( MarkerType markertype, int size, Color color ) { markerType_ = markertype; Size = size; Color = color; filled_ = false; } /// /// Constructor /// /// The marker type. /// The marker size. /// The marker Pen. public Marker( MarkerType markertype, int size, Pen pen ) { markerType_ = markertype; Size = size; Pen = pen; filled_ = false; } /// /// Constructor /// /// The marker type. /// The marker size. /// The marker Pen. /// The fill flag. public Marker( MarkerType markertype, int size, Pen pen, bool fill ) { markerType_ = markertype; Size = size; Pen = pen; filled_ = fill; } /// /// Draws the marker at the given position /// /// The graphics surface on which to draw. /// The [physical] x position to draw the marker. /// The [physical] y position to draw the marker. public void Draw( Graphics g, int x, int y ) { switch (markerType_) { case MarkerType.Cross1: g.DrawLine( pen_, x-h_, y+h_, x+h_, y-h_ ); g.DrawLine( pen_, x+h_, y+h_, x-h_, y-h_ ); break; case MarkerType.Cross2: g.DrawLine( pen_, x, y-h_, x, y+h_ ); g.DrawLine( pen_, x-h_, y, x+h_, y ); break; case MarkerType.Circle: g.DrawEllipse( pen_, x-h_, y-h_, size_, size_ ); if ( this.filled_ ) { g.FillEllipse( brush_, x-h_, y-h_, size_, size_ ); } break; case MarkerType.Square: g.DrawRectangle( pen_, x-h_, y-h_, size_, size_ ); if ( this.filled_ ) { g.FillRectangle( brush_, x-h_, y-h_, size_, size_ ); } break; case MarkerType.Triangle: case MarkerType.TriangleDown: { Point p1 = new Point( x-h_, y-h_ ); Point p2 = new Point( x, y+h_ ); Point p3 = new Point( x+h_, y-h_ ); Point [] pts = new Point [3] { p1, p2, p3 }; GraphicsPath gp = new GraphicsPath(); gp.AddPolygon( pts ); g.DrawPath( pen_, gp ); if (this.filled_) { g.FillPath( brush_, gp ); } break; } case MarkerType.TriangleUp: { Point p1 = new Point( x-h_, y+h_ ); Point p2 = new Point( x, y-h_ ); Point p3 = new Point( x+h_, y+h_ ); Point [] pts = new Point [3] { p1, p2, p3 }; GraphicsPath gp = new GraphicsPath(); gp.AddPolygon( pts ); g.DrawPath( pen_, gp ); if (this.filled_) { g.FillPath( brush_, gp ); } break; } case MarkerType.FilledCircle: g.DrawEllipse( pen_, x-h_, y-h_, size_, size_ ); g.FillEllipse( brush_, x-h_, y-h_, size_, size_ ); break; case MarkerType.FilledSquare: g.DrawRectangle( pen_, x-h_, y-h_, size_, size_ ); g.FillRectangle( brush_, x-h_, y-h_, size_, size_ ); break; case MarkerType.FilledTriangle: { Point p1 = new Point( x-h_, y-h_ ); Point p2 = new Point( x, y+h_ ); Point p3 = new Point( x+h_, y-h_ ); Point [] pts = new Point [3] { p1, p2, p3 }; GraphicsPath gp = new GraphicsPath(); gp.AddPolygon( pts ); g.DrawPath( pen_, gp ); g.FillPath( brush_, gp ); break; } case MarkerType.Diamond: { Point p1 = new Point( x-h_, y ); Point p2 = new Point( x, y-h_ ); Point p3 = new Point( x+h_, y ); Point p4 = new Point( x, y+h_ ); Point [] pts = new Point [4] { p1, p2, p3, p4 }; GraphicsPath gp = new GraphicsPath(); gp.AddPolygon( pts ); g.DrawPath( pen_, gp ); if (this.filled_) { g.FillPath( brush_, gp ); } break; } case MarkerType.Flag: case MarkerType.FlagUp: { Point p1 = new Point( x, y ); Point p2 = new Point( x, y-size_ ); Point p3 = new Point( x+size_, y-size_+size_/3 ); Point p4 = new Point( x, y-size_+2*size_/3 ); g.DrawLine( pen_, p1, p2 ); Point [] pts = new Point [3] { p2, p3, p4 }; GraphicsPath gp = new GraphicsPath(); gp.AddPolygon( pts ); g.DrawPath( pen_, gp ); if (this.filled_) { g.FillPath( brush_, gp ); } break; } case MarkerType.FlagDown: { Point p1 = new Point( x, y ); Point p2 = new Point( x, y+size_ ); Point p3 = new Point( x+size_, y+size_-size_/3 ); Point p4 = new Point( x, y+size_-2*size_/3 ); g.DrawLine( pen_, p1, p2 ); Point [] pts = new Point [3] { p2, p3, p4 }; GraphicsPath gp = new GraphicsPath(); gp.AddPolygon( pts ); g.DrawPath( pen_, gp ); if (this.filled_) { g.FillPath( brush_, gp ); } break; } case MarkerType.None: break; } } } } nplot-gtk-0.9.9.2/lib/MarkerItem.cs0000644000175000017500000001037010512404106017435 0ustar carlosblecarlosble/* NPlot - A charting library for .NET MarkerItem.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// Class for placement of a single marker. /// public class MarkerItem : IDrawable { private Marker marker_; private double x_; private double y_; /// /// Constructs a square marker at the (world) point point. /// /// the world position at which to place the marker public MarkerItem( PointD point ) { marker_ = new Marker( Marker.MarkerType.Square ); x_ = point.X; y_ = point.Y; } /// /// Default constructor - a square black marker. /// /// The world x position of the marker /// The world y position of the marker public MarkerItem( double x, double y ) { marker_ = new Marker( Marker.MarkerType.Square ); x_ = x; y_ = y; } /// /// Constructor /// /// The marker to place on the chart. /// The world x position of the marker /// The world y position of the marker public MarkerItem( Marker marker, double x, double y ) { marker_ = marker; x_ = x; y_ = y; } /// /// Constructor /// /// The marker to place on the chart. /// The world position of the marker public MarkerItem( Marker marker, PointD point ) { marker_ = marker; x_ = point.X; y_ = point.Y; } /// /// Draws the marker on a plot surface. /// /// graphics surface on which to draw /// The X-Axis to draw against. /// The Y-Axis to draw against. public void Draw( System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { PointF point = new PointF( xAxis.WorldToPhysical( x_, true ).X, yAxis.WorldToPhysical( y_, true ).Y ); marker_.Draw( g, (int)point.X, (int)point.Y ); } } } nplot-gtk-0.9.9.2/lib/NPlot.csproj0000644000175000017500000003420410512404106017326 0ustar carlosblecarlosble nplot-gtk-0.9.9.2/lib/NPlot.csproj.user0000644000175000017500000000341510512404106020303 0ustar carlosblecarlosble nplot-gtk-0.9.9.2/lib/NPlot.ndoc0000644000175000017500000004555110512404106016760 0ustar carlosblecarlosble nplot-gtk-0.9.9.2/lib/NPlot.sln0000644000175000017500000000272110512404106016621 0ustar carlosblecarlosbleMicrosoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPlot", "NPlot.csproj", "{E6867FF5-74EC-4464-8958-D71CB46232F3}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NPlotDemo", "..\demos\cs\NPlotDemo.csproj", "{7427C7A7-6CB0-4CB3-A0DB-F11603C5C29A}" ProjectSection(ProjectDependencies) = postProject {E6867FF5-74EC-4464-8958-D71CB46232F3} = {E6867FF5-74EC-4464-8958-D71CB46232F3} EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {E6867FF5-74EC-4464-8958-D71CB46232F3}.Debug.ActiveCfg = Debug|.NET {E6867FF5-74EC-4464-8958-D71CB46232F3}.Debug.Build.0 = Debug|.NET {E6867FF5-74EC-4464-8958-D71CB46232F3}.Release.ActiveCfg = Release|.NET {E6867FF5-74EC-4464-8958-D71CB46232F3}.Release.Build.0 = Release|.NET {7427C7A7-6CB0-4CB3-A0DB-F11603C5C29A}.Debug.ActiveCfg = Debug|.NET {7427C7A7-6CB0-4CB3-A0DB-F11603C5C29A}.Debug.Build.0 = Debug|.NET {7427C7A7-6CB0-4CB3-A0DB-F11603C5C29A}.Release.ActiveCfg = Release|.NET {7427C7A7-6CB0-4CB3-A0DB-F11603C5C29A}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal nplot-gtk-0.9.9.2/lib/PageAlignedPhysicalAxis.cs0000644000175000017500000001205710512404106022063 0ustar carlosblecarlosble/* NPlot - A charting library for .NET PageAlignedPhysicalAxis.cs Copyright (C) 2005 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; namespace NPlot { /// /// The bare minimum needed to do world->physical and physical->world transforms for /// vertical axes. Also includes tick placements. Built for speed. /// /// currently unused public class PageAlignedPhysicalAxis { private int pMin_; private int pMax_; private int pLength_; // cached. private double worldMin_; private double worldMax_; private double worldLength_; // cached. /// /// Construct from a fully-blown physical axis. /// /// the physical axis to get initial values from. public PageAlignedPhysicalAxis( PhysicalAxis physicalAxis ) { worldMin_ = physicalAxis.Axis.WorldMin; worldMax_ = physicalAxis.Axis.WorldMax; worldLength_ = worldMax_ - worldMin_; if ( physicalAxis.PhysicalMin.X == physicalAxis.PhysicalMax.X ) { pMin_ = physicalAxis.PhysicalMin.Y; pMax_ = physicalAxis.PhysicalMax.Y; } else if ( physicalAxis.PhysicalMin.Y == physicalAxis.PhysicalMax.Y ) { pMin_ = physicalAxis.PhysicalMin.X; pMax_ = physicalAxis.PhysicalMax.X; } else { throw new NPlotException( "Physical axis is not page aligned" ); } pLength_ = pMax_ - pMin_; } /// /// return the physical coordinate corresponding to the supplied world coordinate. /// /// world coordinate to determine physical coordinate for. /// the physical coordinate corresoindng to the supplied world coordinate. public float WorldToPhysical( double world ) { return (float)(((world-worldMin_) / worldLength_) * (float)pLength_ + (float)pMin_); } /// /// return the physical coordinate corresponding to the supplied world coordinate, /// clipped if it is outside the bounds of the axis /// /// world coordinate to determine physical coordinate for. /// the physical coordinate corresoindng to the supplied world coordinate. public float WorldToPhysicalClipped( double world ) { if (world > worldMax_) { return pMax_; } if (world < worldMin_) { return pMin_; } // is this quicker than returning WorldToPhysical? return (float)(((world-worldMin_) / worldLength_) * (float)pLength_ + (float)pMin_); } /// /// return the world coordinate corresponding to the supplied physical coordinate. /// /// physical coordinate to determine world coordinate for. /// the world coordinate corresponding to the supplied public double PhysicalToWorld( float physical ) { return ((float)(physical-pMin_) / (float)pLength_) * worldLength_ + worldMin_; } } } nplot-gtk-0.9.9.2/lib/PhysicalAxis.cs0000644000175000017500000002154610512404106020005 0ustar carlosblecarlosble/* NPlot - A charting library for .NET PhysicalAxis.cs Copyright (C) 2003 Matt Howlett, Paolo Pierini Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; using System.Collections; namespace NPlot { /// /// This class adds physical positioning information [PhysicalMin, PhysicalMax] /// and related functionality on top of a specific Axis class. /// /// It's an interesting /// question where to put this information. It belongs with every specific axis /// type, but on the other hand, users of the library as it is normally used /// should not see it because /// positioning of axes is handled internally by PlotSurface2D. Therefore it doesn't make sense /// to put it in the Axis class unless it is internal. But if this were done it would restrict /// use of this information outside the library always, which is not what is wanted. /// The main disadvantage with the method chosen is that there is a lot of passing /// of the positional information between physical axis and the underlying logical /// axis type. /// /// C# doesn't have templates. If it did, I might derive PhysicalAxis from the /// templated Axis type (LinearAxis etc). Instead, have used a has-a relationship /// with an Axis superclass. /// public class PhysicalAxis { /// /// Prevent default construction. /// private PhysicalAxis() { } /// /// Construct /// /// The axis this is a physical representation of. /// the physical position of the world minimum axis value. /// the physical position of the world maximum axis value. public PhysicalAxis( Axis a, Point physicalMin, Point physicalMax ) { this.Axis = a; this.PhysicalMin = physicalMin; this.PhysicalMax = physicalMax; } /// /// Returns the smallest rectangle that completely contains all parts of the axis [including ticks and label]. /// /// the smallest rectangle that completely contains all parts of the axis [including ticks and label]. public virtual Rectangle GetBoundingBox() { System.Drawing.Bitmap scratchArea_ = new System.Drawing.Bitmap( 1, 1 ); Graphics g = Graphics.FromImage( scratchArea_ ); Rectangle bounds; this.Draw( g, out bounds ); return bounds; } /// /// Draws the axis on the given graphics surface. /// /// The graphics surface on which to draw. /// out: the axis bounding box - the smallest rectangle that /// completely contains all parts of the axis [including ticks and label]. public virtual void Draw( System.Drawing.Graphics g, out Rectangle boundingBox ) { this.Axis.Draw( g, PhysicalMin, PhysicalMax, out boundingBox ); } /// /// Given a world coordinate value, returns the physical position of the /// coordinate along the axis. /// /// the world coordinate /// if true, the physical position returned will be clipped to the physical max / min position as appropriate if the world value is outside the limits of the axis. /// the physical position of the coordinate along the axis. public PointF WorldToPhysical( double coord, bool clip ) { return Axis.WorldToPhysical( coord, PhysicalMin, PhysicalMax, clip ); } /// /// Given a physical point on the graphics surface, returns the world /// value of it's projection onto the axis [i.e. closest point on the axis]. /// The function is implemented for axes of arbitrary orientation. /// /// Physical point to find corresponding world value of. /// if true, returns a world position outside WorldMin / WorldMax /// range if this is closer to the axis line. If false, such values will /// be clipped to be either WorldMin or WorldMax as appropriate. /// the world value of the point's projection onto the axis. public double PhysicalToWorld( Point p, bool clip ) { return Axis.PhysicalToWorld( p, PhysicalMin, PhysicalMax, clip ); } /// /// This sets new world limits for the axis from two physical points /// selected within the plot area. /// /// The upper left point of the selection. /// The lower right point of the selection. public void SetWorldLimitsFromPhysical( Point min, Point max ) { double minc; double maxc; if (Axis != null) { minc = Axis.WorldMin; maxc = Axis.WorldMax; if ( !Axis.Reversed ) { double tmp = this.PhysicalToWorld(min,true); Axis.WorldMax = this.PhysicalToWorld(max,true); Axis.WorldMin = tmp; } else { double tmp = this.PhysicalToWorld(min,true); Axis.WorldMin = this.PhysicalToWorld(max,true); Axis.WorldMax = tmp; } // need to trap somehow if the user selects an // arbitrarily small range. Otherwise the GDI+ // drawing routines lead to an overflow in painting // the picture. This may be not the optimal solution, // but if the GDI+ draw leads to an overflow the // graphic surface becomes unusable anymore and I // had difficulty to trap the error. double half = (Axis.WorldMin + Axis.WorldMax)/2; double width = Axis.WorldMax - Axis.WorldMin; if (Math.Abs(half/width) > 1.0e12) { Axis.WorldMin = minc; Axis.WorldMax = maxc; } } } /// /// The physical position corresponding to WorldMin. /// public Point PhysicalMin { get { return physicalMin_; } set { physicalMin_ = value; } } private Point physicalMin_; /// /// The physical position corresponding to WorldMax. /// public Point PhysicalMax { get { return physicalMax_; } set { physicalMax_ = value; } } private Point physicalMax_; /// /// The axis this object adds physical extents to. /// public Axis Axis { get { return axis_; } set { axis_ = value; } } private Axis axis_; /// /// The length in pixels of the axis. /// public int PhysicalLength { get { return Utils.Distance( PhysicalMin, PhysicalMax ); } } /// /// The length in world coordinates of one pixel. /// public double PixelWorldLength { get { return this.Axis.WorldLength / this.PhysicalLength; } } } } nplot-gtk-0.9.9.2/lib/PiAxis.cs0000644000175000017500000001533010512404106016573 0ustar carlosblecarlosble/* NPlot - A charting library for .NET PiAxis.cs Copyright (C) 2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Collections; namespace NPlot { /// /// Axis with labels in multiples of Pi. Maybe needs a better name. /// Lots of functionality still to be added - currently only puts labels /// at whole increments of pi, want arbitrary increments, automatically /// determined and dependance on physical length. /// Volunteers? /// public class PiAxis : Axis { /// /// Deep copy of PiAxis. /// /// A copy of the LinearAxis Class. public override object Clone() { PiAxis a = new PiAxis(); // ensure that this isn't being called on a derived type. If it is, then oh no! if (this.GetType() != a.GetType()) { throw new NPlotException( "Error. Clone method is not defined in derived type." ); } DoClone( this, a ); return a; } /// /// Helper method for Clone. /// /// The original object to clone. /// The cloned object. protected static void DoClone( PiAxis b, PiAxis a ) { Axis.DoClone( b, a ); } /// /// Initialise PiAxis to default state. /// private void Init() { } /// /// Copy constructor /// /// The Axis to clone. /// TODO: [review notes] I don't think this will work as desired. public PiAxis( Axis a ) : base( a ) { Init(); } /// /// Default constructor /// public PiAxis() : base() { Init(); } /// /// Constructor /// /// Minimum world value /// Maximum world value public PiAxis( double worldMin, double worldMax ) : base( worldMin, worldMax ) { Init(); } /// /// Given Graphics surface, and physical extents of axis, draw ticks and /// associated labels. /// /// The GDI+ Graphics surface on which to draw. /// The physical location of the world min point /// The physical location of the world max point /// out: smallest box that completely encompasses all of the ticks and tick labels. /// out: a suitable offset from the axis to draw the axis label. protected override void DrawTicks( Graphics g, Point physicalMin, Point physicalMax, out object labelOffset, out object boundingBox ) { Point tLabelOffset; Rectangle tBoundingBox; labelOffset = this.getDefaultLabelOffset( physicalMin, physicalMax ); boundingBox = null; int start = (int)Math.Ceiling( this.WorldMin / Math.PI ); int end = (int)Math.Floor( this.WorldMax / Math.PI ); // sanity checking. if ( end - start < 0 || end - start > 30 ) { return; } for (int i=start; i<=end; ++i) { string label = i.ToString() + "Pi"; if (i == 0) label = "0"; else if (i == 1) label = "Pi"; this.DrawTick( g, i*Math.PI, this.LargeTickSize, label, new Point(0,0), physicalMin, physicalMax, out tLabelOffset, out tBoundingBox ); Axis.UpdateOffsetAndBounds( ref labelOffset, ref boundingBox, tLabelOffset, tBoundingBox ); } } /// /// Determines the positions, in world coordinates, of the large ticks. /// /// Label axes do not have small ticks. /// /// The physical position corresponding to the world minimum of the axis. /// The physical position corresponding to the world maximum of the axis. /// ArrayList containing the positions of the large ticks. /// null internal override void WorldTickPositions_FirstPass( Point physicalMin, Point physicalMax, out ArrayList largeTickPositions, out ArrayList smallTickPositions ) { smallTickPositions = null; largeTickPositions = new ArrayList(); int start = (int)Math.Ceiling( this.WorldMin / Math.PI ); int end = (int)Math.Floor( this.WorldMax / Math.PI ); // sanity checking. if ( end - start < 0 || end - start > 30 ) { return; } for (int i=start; i /// Description rsume de PiePlot. /// public class PiePlot : BasePlot, IPlot { public PiePlot(ISequenceAdapter datas) { // // TODO: ajoutez ici la logique du constructeur // this.Data=datas; _brushes=new Brush[_MaxBrush]; _brushes[0] = Brushes.DarkBlue; _brushes[1] = Brushes.Yellow; _brushes[2] = Brushes.Green; _brushes[3] = Brushes.Brown; _brushes[4] = Brushes.Blue; _brushes[5] = Brushes.Red; _brushes[6] = Brushes.LightGreen; _brushes[7] = Brushes.Salmon; } private ISequenceAdapter data_; private double _Total; const int _MaxBrush=8; private Brush[] _brushes; public ISequenceAdapter Data { get { return data_; } set { data_ = value; // calculate the sum of all value (this is related to 360) _Total = 0; for ( int i=0; i /// Implements the surface on which IDrawables are drawn. Is extended /// by Bitmap.PlotSurface2D, Windows.PlotSurface2D etc. TODO: better explanation. /// public class PlotSurface2D : IPlotSurface2D { /// /// Possible positions of the X axis. /// public enum XAxisPosition { /// /// X axis is on the top. /// Top = 1, //Center = 2, /// /// X axis is on the bottom. /// Bottom = 3, } /// /// Possible positions of the Y axis. /// public enum YAxisPosition { /// /// Y axis on the left. /// Left = 1, // Center /// /// Y axis on the right. /// Right = 3, } private System.Drawing.StringFormat titleDrawFormat_; private Font titleFont_; private string title_; private Brush titleBrush_; private int padding_; private Axis xAxis1_; private Axis yAxis1_; private Axis xAxis2_; private Axis yAxis2_; private PhysicalAxis pXAxis1Cache_; private PhysicalAxis pYAxis1Cache_; private PhysicalAxis pXAxis2Cache_; private PhysicalAxis pYAxis2Cache_; private bool autoScaleAutoGeneratedAxes_ = false; private bool autoScaleTitle_ = false; private object plotAreaBoundingBoxCache_; private object bbXAxis1Cache_; private object bbXAxis2Cache_; private object bbYAxis1Cache_; private object bbYAxis2Cache_; private object bbTitleCache_; private object plotBackColor_ = null; private System.Drawing.Bitmap plotBackImage_ = null; private IRectangleBrush plotBackBrush_ = null; private System.Collections.ArrayList drawables_; private System.Collections.ArrayList xAxisPositions_; private System.Collections.ArrayList yAxisPositions_; private System.Collections.ArrayList zPositions_; private System.Collections.SortedList ordering_; private System.Drawing.Drawing2D.SmoothingMode smoothingMode_; private ArrayList axesConstraints_ = null; private Legend legend_; /// /// The physical bounding box of the last drawn plot surface area is available here. /// public Rectangle PlotAreaBoundingBoxCache { get { if (plotAreaBoundingBoxCache_ == null) { return Rectangle.Empty; } else { return (Rectangle)plotAreaBoundingBoxCache_; } } } /// /// Performs a hit test with the given point and returns information /// about the object being hit. /// /// The point to test. /// public System.Collections.ArrayList HitTest(Point p) { System.Collections.ArrayList a = new System.Collections.ArrayList(); // this is the case if PlotSurface has been cleared. if (bbXAxis1Cache_ == null) { return a; } else if (bbXAxis1Cache_ != null && ((Rectangle) bbXAxis1Cache_ ).Contains(p)) { a.Add( this.xAxis1_ ); return a; } else if (bbYAxis1Cache_ != null && ((Rectangle) bbYAxis1Cache_ ).Contains(p)) { a.Add( this.yAxis1_ ); return a; } else if (bbXAxis2Cache_ != null && ((Rectangle) bbXAxis2Cache_ ).Contains(p)) { a.Add( this.xAxis2_ ); return a; } else if (bbXAxis2Cache_ != null && ((Rectangle) bbYAxis2Cache_ ).Contains(p)) { a.Add( this.yAxis2_ ); return a; } else if (bbTitleCache_ != null && ((Rectangle) bbTitleCache_ ).Contains(p)) { a.Add( this ); return a; } else if (plotAreaBoundingBoxCache_ != null && ((Rectangle) plotAreaBoundingBoxCache_ ).Contains(p)) { a.Add( this ); return a; } return a; } /// /// The bottom abscissa axis. /// public Axis XAxis1 { get { return xAxis1_; } set { xAxis1_ = value; } } /// /// The left ordinate axis. /// public Axis YAxis1 { get { return yAxis1_; } set { yAxis1_ = value; } } /// /// The top abscissa axis. /// public Axis XAxis2 { get { return xAxis2_; } set { xAxis2_ = value; } } /// /// The right ordinate axis. /// public Axis YAxis2 { get { return yAxis2_; } set { yAxis2_ = value; } } /// /// The physical XAxis1 that was last drawn. /// public PhysicalAxis PhysicalXAxis1Cache { get { return pXAxis1Cache_; } } /// /// The physical YAxis1 that was last drawn. /// public PhysicalAxis PhysicalYAxis1Cache { get { return pYAxis1Cache_; } } /// /// The physical XAxis2 that was last drawn. /// public PhysicalAxis PhysicalXAxis2Cache { get { return pXAxis2Cache_; } } /// /// The physical YAxis2 that was last drawn. /// public PhysicalAxis PhysicalYAxis2Cache { get { return pYAxis2Cache_; } } /// /// The chart title. /// public string Title { get { return title_; } set { title_ = value; } } /// /// The plot title font. /// public Font TitleFont { get { return titleFont_; } set { titleFont_ = value; } } /// /// The distance in pixels to leave between of the edge of the bounding rectangle /// supplied to the Draw method, and the markings that make up the plot. /// public int Padding { get { return padding_; } set { padding_ = value; } } /// /// Sets the title to be drawn using a solid brush of this color. /// public Color TitleColor { set { titleBrush_ = new SolidBrush( value ); } } /// /// The brush used for drawing the title. /// public Brush TitleBrush { get { return titleBrush_; } set { titleBrush_ = value; } } /// /// A color used to paint the plot background. Mutually exclusive with PlotBackImage and PlotBackBrush /// public System.Drawing.Color PlotBackColor { set { plotBackColor_ = value; plotBackBrush_ = null; plotBackImage_ = null; } } /// /// An imaged used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// public System.Drawing.Bitmap PlotBackImage { set { plotBackImage_ = value; plotBackColor_ = null; plotBackBrush_ = null; } } /// /// A Rectangle brush used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// public IRectangleBrush PlotBackBrush { set { plotBackBrush_ = value; plotBackColor_ = null; plotBackImage_ = null; } } /// /// Smoothing mode to use when drawing plots. /// public System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get { return smoothingMode_; } set { this.smoothingMode_ = value; } } private void Init() { drawables_ = new ArrayList(); xAxisPositions_ = new ArrayList(); yAxisPositions_ = new ArrayList(); zPositions_ = new ArrayList(); ordering_ = new SortedList(); FontFamily fontFamily = new FontFamily("Arial"); TitleFont = new Font(fontFamily, 14, FontStyle.Regular, GraphicsUnit.Pixel); padding_ = 10; title_ = ""; autoScaleTitle_ = false; autoScaleAutoGeneratedAxes_ = false; xAxis1_ = null; xAxis2_ = null; yAxis1_ = null; yAxis2_ = null; pXAxis1Cache_ = null; pYAxis1Cache_ = null; pXAxis2Cache_ = null; pYAxis2Cache_ = null; titleBrush_ = new SolidBrush( Color.Black ); plotBackColor_ = Color.White; this.legend_ = null; smoothingMode_ = System.Drawing.Drawing2D.SmoothingMode.None; axesConstraints_ = new ArrayList(); } /// /// Default constructor. /// public PlotSurface2D() { // only create this once. titleDrawFormat_ = new StringFormat(); titleDrawFormat_.Alignment = StringAlignment.Center; Init(); } private float DetermineScaleFactor( int w, int h ) { float diag = (float)Math.Sqrt( w*w + h*h ); float scaleFactor = (diag / 1400.0f)*2.4f; if ( scaleFactor > 1.0f ) { return scaleFactor; } else { return 1.0f; } } /// /// Adds a drawable object to the plot surface with z-order 0. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. public void Add(IDrawable p) { Add(p, 0); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, int zOrder ) { Add( p, XAxisPosition.Bottom, YAxisPosition.Left, zOrder ); } /// /// Adds a drawable object to the plot surface against the specified axes with /// z-order of 0. If the object is an IPlot, the PlotSurface2D axes will also /// be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. public void Add(IDrawable p, XAxisPosition xp, YAxisPosition yp) { Add(p, xp, yp, 0); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, XAxisPosition xp, YAxisPosition yp, int zOrder ) { drawables_.Add( p ); xAxisPositions_.Add( xp ); yAxisPositions_.Add( yp ); zPositions_.Add((double)zOrder); // fraction is to make key unique. With 10 million plots at same z, this buggers up.. double fraction = (double)(++uniqueCounter_)/10000000.0f; ordering_.Add( (double)zOrder + fraction, drawables_.Count - 1 ); // if p is just an IDrawable, then it can't affect the axes. if ( p is IPlot ) { UpdateAxes( false ); } } private int uniqueCounter_ = 0; private void UpdateAxes( bool recalculateAll ) { if (drawables_.Count != xAxisPositions_.Count || drawables_.Count != yAxisPositions_.Count) { throw new NPlotException("plots and axis position arrays our of sync"); } int position = 0; // if we're not recalculating axes using all iplots then set // position to last one in list. if (!recalculateAll) { position = drawables_.Count - 1; if (position < 0) position = 0; } if (recalculateAll) { this.xAxis1_ = null; this.yAxis1_ = null; this.xAxis2_ = null; this.yAxis2_ = null; } for (int i = position; i < drawables_.Count; ++i) { // only update axes if this drawable is an IPlot. if (!(drawables_[position] is IPlot)) continue; IPlot p = (IPlot)drawables_[position]; XAxisPosition xap = (XAxisPosition)xAxisPositions_[position]; YAxisPosition yap = (YAxisPosition)yAxisPositions_[position]; if (xap == XAxisPosition.Bottom) { if (this.xAxis1_ == null) { this.xAxis1_ = p.SuggestXAxis(); if (this.xAxis1_ != null) { this.xAxis1_.TicksAngle = -(float)Math.PI / 2.0f; } } else { this.xAxis1_.LUB(p.SuggestXAxis()); } if (this.xAxis1_ != null) { this.xAxis1_.MinPhysicalLargeTickStep = 50; if (this.AutoScaleAutoGeneratedAxes) { this.xAxis1_.AutoScaleText = true; this.xAxis1_.AutoScaleTicks = true; this.xAxis1_.TicksIndependentOfPhysicalExtent = true; } else { this.xAxis1_.AutoScaleText = false; this.xAxis1_.AutoScaleTicks = false; this.xAxis1_.TicksIndependentOfPhysicalExtent = false; } } } if (xap == XAxisPosition.Top) { if (this.xAxis2_ == null) { this.xAxis2_ = p.SuggestXAxis(); if (this.xAxis2_ != null) { this.xAxis2_.TicksAngle = (float)Math.PI / 2.0f; } } else { this.xAxis2_.LUB(p.SuggestXAxis()); } if (this.xAxis2_ != null) { this.xAxis2_.MinPhysicalLargeTickStep = 50; if (this.AutoScaleAutoGeneratedAxes) { this.xAxis2_.AutoScaleText = true; this.xAxis2_.AutoScaleTicks = true; this.xAxis2_.TicksIndependentOfPhysicalExtent = true; } else { this.xAxis2_.AutoScaleText = false; this.xAxis2_.AutoScaleTicks = false; this.xAxis2_.TicksIndependentOfPhysicalExtent = false; } } } if (yap == YAxisPosition.Left) { if (this.yAxis1_ == null) { this.yAxis1_ = p.SuggestYAxis(); if (this.yAxis1_ != null) { this.yAxis1_.TicksAngle = (float)Math.PI / 2.0f; } } else { this.yAxis1_.LUB(p.SuggestYAxis()); } if (this.yAxis1_ != null) { if (this.AutoScaleAutoGeneratedAxes) { this.yAxis1_.AutoScaleText = true; this.yAxis1_.AutoScaleTicks = true; this.yAxis1_.TicksIndependentOfPhysicalExtent = true; } else { this.yAxis1_.AutoScaleText = false; this.yAxis1_.AutoScaleTicks = false; this.yAxis1_.TicksIndependentOfPhysicalExtent = false; } } } if (yap == YAxisPosition.Right) { if (this.yAxis2_ == null) { this.yAxis2_ = p.SuggestYAxis(); if (this.yAxis2_ != null) { this.yAxis2_.TicksAngle = -(float)Math.PI / 2.0f; } } else { this.yAxis2_.LUB(p.SuggestYAxis()); } if (this.yAxis2_ != null) { if (this.AutoScaleAutoGeneratedAxes) { this.yAxis2_.AutoScaleText = true; this.yAxis2_.AutoScaleTicks = true; this.yAxis2_.TicksIndependentOfPhysicalExtent = true; } else { this.yAxis2_.AutoScaleText = false; this.yAxis2_.AutoScaleTicks = false; this.yAxis2_.TicksIndependentOfPhysicalExtent = false; } } } } } private void DetermineAxesToDraw( out Axis xAxis1, out Axis xAxis2, out Axis yAxis1, out Axis yAxis2 ) { xAxis1 = this.xAxis1_; xAxis2 = this.xAxis2_; yAxis1 = this.yAxis1_; yAxis2 = this.yAxis2_; if (this.xAxis1_ == null) { if (this.xAxis2_ == null) { throw new NPlotException( "Error: No X-Axis specified" ); } xAxis1 = (Axis)this.xAxis2_.Clone(); xAxis1.HideTickText = true; xAxis1.TicksAngle = -(float)Math.PI / 2.0f; } if (this.xAxis2_ == null) { // don't need to check if xAxis1_ == null, as case already handled above. xAxis2 = (Axis)this.xAxis1_.Clone(); xAxis2.HideTickText = true; xAxis2.TicksAngle = (float)Math.PI / 2.0f; } if (this.yAxis1_ == null) { if (this.yAxis2_ == null) { throw new NPlotException( "Error: No Y-Axis specified" ); } yAxis1 = (Axis)this.yAxis2_.Clone(); yAxis1.HideTickText = true; yAxis1.TicksAngle = (float)Math.PI / 2.0f; } if (this.yAxis2_ == null) { // don't need to check if yAxis1_ == null, as case already handled above. yAxis2 = (Axis)this.yAxis1_.Clone(); yAxis2.HideTickText = true; yAxis2.TicksAngle = -(float)Math.PI / 2.0f; } } private void DeterminePhysicalAxesToDraw( Rectangle bounds, Axis xAxis1, Axis xAxis2, Axis yAxis1, Axis yAxis2, out PhysicalAxis pXAxis1, out PhysicalAxis pXAxis2, out PhysicalAxis pYAxis1, out PhysicalAxis pYAxis2 ) { System.Drawing.Rectangle cb = bounds; pXAxis1 = new PhysicalAxis( xAxis1, new Point( cb.Left, cb.Bottom ), new Point( cb.Right, cb.Bottom ) ); pYAxis1 = new PhysicalAxis( yAxis1, new Point( cb.Left, cb.Bottom ), new Point( cb.Left, cb.Top ) ); pXAxis2 = new PhysicalAxis( xAxis2, new Point( cb.Left, cb.Top), new Point( cb.Right, cb.Top) ); pYAxis2 = new PhysicalAxis( yAxis2, new Point( cb.Right, cb.Bottom ), new Point( cb.Right, cb.Top ) ); int bottomIndent = padding_; if (!pXAxis1.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pXAxis1.GetBoundingBox(); // finally determine its indentation from the bottom bottomIndent = bottomIndent + bb.Bottom - cb.Bottom; } int leftIndent = padding_; if (!pYAxis1.Axis.Hidden) { // evaluate its bounding box Rectangle bb = pYAxis1.GetBoundingBox(); // finally determine its indentation from the left leftIndent = leftIndent - bb.Left + cb.Left; } int topIndent = padding_; float scale = this.DetermineScaleFactor( bounds.Width, bounds.Height ); int titleHeight; if (this.AutoScaleTitle) { titleHeight = Utils.ScaleFont(titleFont_, scale).Height; } else { titleHeight = titleFont_.Height; } //count number of new lines in title. int nlCount = 0; for (int i=0; i /// Draw the the PlotSurface2D and all contents [axes, drawables, and legend] on the /// supplied graphics surface. /// /// The graphics surface on which to draw. /// A bounding box on this surface that denotes the area on the /// surface to confine drawing to. public void Draw( Graphics g, Rectangle bounds ) { // determine font sizes and tick scale factor. float scale = DetermineScaleFactor( bounds.Width, bounds.Height ); // if there is nothing to plot, return. if ( drawables_.Count == 0 ) { // draw title float x_center = (bounds.Left + bounds.Right)/2.0f; float y_center = (bounds.Top + bounds.Bottom)/2.0f; Font scaled_font; if (this.AutoScaleTitle) { scaled_font = Utils.ScaleFont( titleFont_, scale ); } else { scaled_font = titleFont_; } g.DrawString( title_, scaled_font, this.titleBrush_, new PointF(x_center,y_center), titleDrawFormat_ ); return; } // determine the [non physical] axes to draw based on the axis properties set. Axis xAxis1 = null; Axis xAxis2 = null; Axis yAxis1 = null; Axis yAxis2 = null; this.DetermineAxesToDraw( out xAxis1, out xAxis2, out yAxis1, out yAxis2 ); // apply scale factor to axes as desired. if (xAxis1.AutoScaleTicks) xAxis1.TickScale = scale; if (xAxis1.AutoScaleText) xAxis1.FontScale = scale; if (yAxis1.AutoScaleTicks) yAxis1.TickScale = scale; if (yAxis1.AutoScaleText) yAxis1.FontScale = scale; if (xAxis2.AutoScaleTicks) xAxis2.TickScale = scale; if (xAxis2.AutoScaleText) xAxis2.FontScale = scale; if (yAxis2.AutoScaleTicks) yAxis2.TickScale = scale; if (yAxis2.AutoScaleText) yAxis2.FontScale = scale; // determine the default physical positioning of those axes. PhysicalAxis pXAxis1 = null; PhysicalAxis pYAxis1 = null; PhysicalAxis pXAxis2 = null; PhysicalAxis pYAxis2 = null; this.DeterminePhysicalAxesToDraw( bounds, xAxis1, xAxis2, yAxis1, yAxis2, out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2 ); float oldXAxis2Height = pXAxis2.PhysicalMin.Y; // Apply axes constraints for (int i=0; i this.legendZOrder_) { // draw legend. if ( !legendDrawn && this.legend_ != null ) { legend_.Draw( g, legendPosition, this.drawables_, scale ); legendDrawn = true; } } IDrawable drawable = (IDrawable)drawables_[i]; XAxisPosition xap = (XAxisPosition)xAxisPositions_[i]; YAxisPosition yap = (YAxisPosition)yAxisPositions_[i]; PhysicalAxis drawXAxis; PhysicalAxis drawYAxis; if ( xap == XAxisPosition.Bottom ) { drawXAxis = pXAxis1; } else { drawXAxis = pXAxis2; } if ( yap == YAxisPosition.Left ) { drawYAxis = pYAxis1; } else { drawYAxis = pYAxis2; } // set the clipping region.. (necessary for zoom) g.Clip = new Region((Rectangle)plotAreaBoundingBoxCache_); // plot. drawable.Draw( g, drawXAxis, drawYAxis ); // reset it.. g.ResetClip(); } if ( !legendDrawn && this.legend_ != null ) { legend_.Draw( g, legendPosition, this.drawables_, scale ); } // cache the physical axes we used on this draw; this.pXAxis1Cache_ = pXAxis1; this.pYAxis1Cache_ = pYAxis1; this.pXAxis2Cache_ = pXAxis2; this.pYAxis2Cache_ = pYAxis2; g.SmoothingMode = smoothSave; // now draw axes. Rectangle axisBounds; pXAxis1.Draw( g, out axisBounds ); pXAxis2.Draw( g, out axisBounds ); pYAxis1.Draw( g, out axisBounds ); pYAxis2.Draw( g, out axisBounds ); #if DEBUG_BOUNDING_BOXES g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbXAxis1Cache_ ); g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbXAxis2Cache_ ); g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbYAxis1Cache_ ); g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbYAxis2Cache_ ); g.DrawRectangle( new Pen(Color.Red,5.0F),(Rectangle) plotAreaBoundingBoxCache_); //if(this.ShowLegend)g.DrawRectangle( new Pen(Color.Chocolate, 3.0F), (Rectangle) bbLegendCache_); g.DrawRectangle( new Pen(Color.DeepPink,2.0F), (Rectangle) bbTitleCache_); #endif } /// /// Clears the plot and resets all state to the default. /// public void Clear() { Init(); } /// /// Legend to use. If this property is null [default], then the plot /// surface will have no corresponding legend. /// public NPlot.Legend Legend { get { return this.legend_; } set { this.legend_ = value; } } /// /// Add an axis constraint to the plot surface. Axes constraints give you /// control over where NPlot positions each axes, and the world - pixel /// ratio. /// /// The axis constraint to add. public void AddAxesConstraint( AxesConstraint constraint ) { this.axesConstraints_.Add( constraint ); } /// /// Whether or not the title will be scaled according to size of the plot surface. /// public bool AutoScaleTitle { get { return autoScaleTitle_; } set { autoScaleTitle_ = value; } } /// /// When plots are added to the plot surface, the axes they are attached to /// are immediately modified to reflect data of the plot. If /// AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will /// be turned in to auto scaling ones if they are not already [tick marks, /// tick text and label size scaled to size of plot surface]. If false, /// axes will not be autoscaling. /// public bool AutoScaleAutoGeneratedAxes { get { return autoScaleAutoGeneratedAxes_; } set { autoScaleAutoGeneratedAxes_ = value; } } /// /// Remove a drawable object. /// Note that axes are not updated. /// /// Drawable to remove. /// if true, the axes are updated. public void Remove( IDrawable p, bool updateAxes ) { int index = drawables_.IndexOf( p ); if (index < 0) return; drawables_.RemoveAt( index ); xAxisPositions_.RemoveAt( index ); yAxisPositions_.RemoveAt( index ); zPositions_.RemoveAt(index); if (updateAxes) { this.UpdateAxes(true); } this.RefreshZOrdering(); } /// /// If a plot is removed, then the ordering_ list needs to be /// recalculated. /// private void RefreshZOrdering() { uniqueCounter_ = 0; ordering_ = new SortedList(); for (int i = 0; i < zPositions_.Count; ++i) { double zpos = Convert.ToDouble(zPositions_[i]); double fraction = (double)(++uniqueCounter_) / 10000000.0f; double d = zpos + fraction; ordering_.Add(d, i); } } /// /// Gets an array list containing all drawables currently added to the PlotSurface2D. /// public ArrayList Drawables { get { return this.drawables_; } } /// /// Returns the x-axis associated with a given plot. /// /// the plot to get associated x-axis. /// the axis associated with the plot. public Axis WhichXAxis( IPlot plot ) { int index = drawables_.IndexOf( plot ); XAxisPosition p = (XAxisPosition)xAxisPositions_[index]; if ( p == XAxisPosition.Bottom ) return this.xAxis1_; else return this.xAxis2_; } /// /// Returns the y-axis associated with a given plot. /// /// the plot to get associated y-axis. /// the axis associated with the plot. public Axis WhichYAxis( IPlot plot ) { int index = drawables_.IndexOf( plot ); YAxisPosition p = (YAxisPosition)yAxisPositions_[index]; if ( p == YAxisPosition.Left ) return this.yAxis1_; else return this.yAxis2_; } /// /// Setting this value determines the order (relative to IDrawables added to the plot surface) /// that the legend is drawn. /// public int LegendZOrder { get { return legendZOrder_; } set { legendZOrder_ = value; } } int legendZOrder_ = -1; } } nplot-gtk-0.9.9.2/lib/PlotSurface2Dnew.cs0000644000175000017500000002430710512404106020531 0ustar carlosblecarlosble// ******** experimental ******** /* using System; using System.Xml; using System.Data; using System.Collections; using System.IO; using System.Reflection; using System.Drawing; namespace NPlot { class PlotSurface2Dnew { private ArrayList axisLines_; private ArrayList axisDefinitions_; private ArrayList drawables_; private ArrayList xAxisPositions_; private ArrayList yAxisPositions_; private System.Collections.Hashtable axes_; /// /// PlotSurface2D styles supplied with the library. /// public enum PlotSurfaceStyle { Standard, CrossedAxes, OppositeCloned } private class AxisDefinition { public string Name = ""; public AxisLine axisLine = null; public int Min = 0; public int Max = 100; } private class AxisLine { public enum OrientationType { Horizontal, Vertical } public string Name = ""; public OrientationType Orientation = OrientationType.Horizontal; public float Position = 0; } /// /// Constructor /// public PlotSurface2Dnew() { Init(); } private AxisDefinition parseAxis( XmlNode node ) { // get Parameters AxisDefinition d = new AxisDefinition(); for (int i=0; i 100) { ErrorHandler.Instance.CriticalError( "min value must be between 0 and 100" ); } break; case "physicalmax": try { d.Max = Convert.ToInt32( a.Value ); } catch { ErrorHandler.Instance.CriticalError( "max value not numeric" ); } if (d.Max < 0 || d.Max > 100) { ErrorHandler.Instance.CriticalError( "max value must be between 0 and 100" ); } break; default: ErrorHandler.Instance.CriticalError( "unknown attribute: " + a.Name ); break; } } return d; } private AxisLine parseAxisLine( XmlNode node ) { AxisLine l = new AxisLine(); for (int i=0; i 100) { ErrorHandler.Instance.CriticalError( "axis position must be between 0 and 100" ); } break; default: ErrorHandler.Instance.CriticalError( "unknown axis line attribute: " + a.Name ); break; } } return l; } public void SetDefinition( ) { Assembly ass = Assembly.GetExecutingAssembly(); System.IO.Stream xmlStream = ass.GetManifestResourceStream( "NPlot.PlotSurfaceDefinitions.OppositeCloned.xml" ); // load xml XmlDocument xmlDoc = null; try { xmlDoc = new XmlDocument(); xmlDoc.Load( xmlStream ); } catch { ErrorHandler.Instance.CriticalError( "PlotSurface2D definition file malformed" ); } XmlElement el = xmlDoc.DocumentElement; // check we're a PlotSurface2D. if (el.Name.ToLower() != "plotsurface2d") { ErrorHandler.Instance.CriticalError( "Root element must be PlotSurface2D" ); return; } // enforce only one axis set for now. if (el.ChildNodes.Count != 1) { ErrorHandler.Instance.CriticalError( "need one and only one axis set." ); return; } // loop around all AxisSets. foreach (XmlNode n in el.ChildNodes) { if (n.Name.ToLower() != "axisset") { ErrorHandler.Instance.CriticalError( "Expected AxisSet node" ); return; } // loop around all nodes in this axis set. foreach (XmlNode n2 in n.ChildNodes) { switch (n2.Name.ToLower()) { case "axisline": { axisLines_.Add( parseAxisLine(n2) ); break; } case "axis": { axisDefinitions_.Add( parseAxis(n2) ); break; } default: { ErrorHandler.Instance.CriticalError( "Unexpected node type encountered: " + n2.Name ); return; } } } // end loop around each node in axis set // add all axes to class for (int i=0; i /// The distance in pixels to leave between of the edge of the bounding rectangle /// supplied to the Draw method, and the markings that make up the plot. /// public int Padding { get { return padding_; } set { padding_ = value; } } private int padding_; private void Init() { axes_ = null; drawables_ = new ArrayList(); xAxisPositions_ = new ArrayList(); yAxisPositions_ = new ArrayList(); axisLines_ = new ArrayList(); axisDefinitions_ = new ArrayList(); padding_ = 10; } /// /// Draw the the PlotSurface2D and all contents [axes, drawables, and legend] on the /// supplied graphics surface. /// /// The graphics surface on which to draw. /// A bounding box on this surface that denotes the area on the /// surface to confine drawing to. public void Draw( Graphics g, Rectangle bounds ) { Rectangle realBounds = new Rectangle( bounds.X + padding_ / 2, bounds.Y + padding_ / 2, bounds.Width - padding_, bounds.Height - padding_ ); // create initial set of physical axes. These will // be moved later to ensure everything is drawn ok. ArrayList physicalAxes = new ArrayList(); for (int i=0; i /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. public void Add( IDrawable p, string xAxis, string yAxis ) { drawables_.Add( p ); xAxisPositions_.Add( xAxis ); yAxisPositions_.Add( yAxis ); if ( p is IPlot ) { this.UpdateAxes(); } } } } */nplot-gtk-0.9.9.2/lib/PlotSurface3D.cs0000644000175000017500000000344310512404106020016 0ustar carlosblecarlosble// ******** experimental ******** /* NPlot - A charting library for .NET PlotSurface3D.cs Copyright (C) 2003 Matt Howlett 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 following text in the documentation and / or other materials provided with the distribution: "This product includes software developed as part of the NPlot charting library project available from: http://www.nplot.com/" ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. $Id: PlotSurface3D.cs,v 1.9 2004/11/17 10:39:19 mhowlett Exp $ */ /* using System; namespace NPlot { /// /// TODO /// public class PlotSurface3D : IPlotSurface3D { /// /// TODO /// public PlotSurface3D() { } } } */nplot-gtk-0.9.9.2/lib/PlotSurfaceDefinitions/0000755000175000017500000000000010512404132021467 5ustar carlosblecarlosblenplot-gtk-0.9.9.2/lib/PlotSurfaceDefinitions/CrossedAxes.xml0000644000175000017500000000135110512404106024435 0ustar carlosblecarlosble nplot-gtk-0.9.9.2/lib/PlotSurfaceDefinitions/OppositeCloned.xml0000644000175000017500000000103310512404106025136 0ustar carlosblecarlosble nplot-gtk-0.9.9.2/lib/PlotSurfaceDefinitions/Standard.xml0000644000175000017500000000051010512404106023746 0ustar carlosblecarlosble nplot-gtk-0.9.9.2/lib/PointD.cs0000644000175000017500000000574010512404106016577 0ustar carlosblecarlosble/* NPlot - A charting library for .NET PointD.cs Copyright (C) 2003-2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ namespace NPlot { /// /// Represtents a point in two-dimensional space. Used for representation /// of points world coordinates. /// public struct PointD { /// /// X-Coordinate of the point. /// public double X; /// /// Y-Coordinate of the point. /// public double Y; /// /// Constructor /// /// X-Coordinate of the point. /// Y-Coordinate of the point. public PointD( double x, double y ) { X = x; Y = y; } /// /// returns a string representation of the point. /// /// string representation of the point. public override string ToString() { return X.ToString() + "\t" + Y.ToString(); } } } nplot-gtk-0.9.9.2/lib/PointD3D.cs0000644000175000017500000000153610512404106016765 0ustar carlosblecarlosble// ******** experimental ******** /* using System; namespace NPlot { /// /// Represtents a point in three-dimensional space. Used for representation /// of points world coordinates. /// public struct PointD3D { /// /// X-Coordinate of the point. /// public double X; /// /// Y-Coordinate of the point. /// public double Y; /// /// Z-Coordinate of the point. /// public double Z; /// /// Constructor /// /// X-Coordinate of the point. /// Y-Coordinate of the point. /// Z-Coordinate of the point. public PointD3D( double x, double y, double z ) { X = x; Y = y; Z = z; } } } */nplot-gtk-0.9.9.2/lib/PointPlot.cs0000644000175000017500000001347310512404106017334 0ustar carlosblecarlosble/* NPlot - A charting library for .NET PointPlot.cs Copyright (C) 2003 Matt Howlett, Paolo Pierini Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; } /// /// 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( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); float leftCutoff_ = xAxis.PhysicalMin.X - marker_.Size; float rightCutoff_ = xAxis.PhysicalMax.X + marker_.Size; for (int i=0; i /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { SequenceAdapter data_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.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( this.DataSource, this.DataMember, this.OrdinateData, this.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); } } /// /// The Marker object used for the plot. /// public Marker Marker { set { marker_ = value; } get { return marker_; } } } }nplot-gtk-0.9.9.2/lib/PointPlot3D.cs0000644000175000017500000000217510512404106017520 0ustar carlosblecarlosble// ******** experimental ******** /* using System; using System.Drawing; namespace NPlot { /// /// Think we should just implement point plot first, unless you need /// other stuff. /// public class PointPlot3D : BasePlot3D, IPlot3D { /// /// Constructor /// public PointPlot3D() { } /// /// Draws the points on the supplied axes. TODO. /// /// /// /// /// void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, PhysicalAxis zAxis ) { } /// /// The method used to set the default x axis. /// public Axis SuggestXAxis() { return null; } /// /// The method used to set the default y axis. /// public Axis SuggestYAxis() { return null; } /// /// The method used to set the default z axis. /// public Axis SuggestZAxis() { return null; } } } */nplot-gtk-0.9.9.2/lib/RectangleBrushes.cs0000644000175000017500000010720710512404106020643 0ustar carlosblecarlosble/* NPlot - A charting library for .NET RectangleBrushes.cs Copyright (C) 2005 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; namespace NPlot { /// /// Classes that implement this interface can provide a brush /// sized according to a given rectangle. /// public interface IRectangleBrush { /// /// Gets a brush according to the supplied rectangle. /// /// the rectangle used to construct the brush /// The brush Brush Get( Rectangle rectangle ); } /// /// Collection of useful brushes. /// public class RectangleBrushes { /// /// A solid brush /// public class Solid : IRectangleBrush { Brush brush_; /// /// Constructor /// /// brush color public Solid( Color c ) { brush_ = new SolidBrush( c ); } /// /// Gets a brush according to the supplied rectangle. /// /// the rectangle used to construct the brush /// The solid brush public Brush Get( Rectangle rectangle ) { return brush_; } #region Default Brushes /// /// AliceBlue solid brush. /// public static Solid AliceBlue { get { return new Solid( Color.AliceBlue ); } } /// /// AntiqueWhite solid brush. /// public static Solid AntiqueWhite { get { return new Solid( Color.AntiqueWhite ); } } /// /// Aqua solid brush. /// public static Solid Aqua { get { return new Solid( Color.Aqua ); } } /// /// Aquamarine solid brush. /// public static Solid Aquamarine { get { return new Solid( Color.Aquamarine ); } } /// /// Azure solid brush. /// public static Solid Azure { get { return new Solid( Color.Azure ); } } /// /// Beige solid brush. /// public static Solid Beige { get { return new Solid( Color.Beige ); } } /// /// Bisque solid brush. /// public static Solid Bisque { get { return new Solid( Color.Bisque ); } } /// /// Black solid brush. /// public static Solid Black { get { return new Solid( Color.Black ); } } /// /// BlanchedAlmond solid brush. /// public static Solid BlanchedAlmond { get { return new Solid( Color.BlanchedAlmond ); } } /// /// Blue solid brush. /// public static Solid Blue { get { return new Solid( Color.Blue ); } } /// /// BlueViolet solid brush. /// public static Solid BlueViolet { get { return new Solid( Color.BlueViolet ); } } /// /// Brown solid brush. /// public static Solid Brown { get { return new Solid( Color.Brown ); } } /// /// BurlyWood solid brush. /// public static Solid BurlyWood { get { return new Solid( Color.BurlyWood ); } } /// /// CadetBlue solid brush. /// public static Solid CadetBlue { get { return new Solid( Color.CadetBlue ); } } /// /// Chartreuse solid brush. /// public static Solid Chartreuse { get { return new Solid( Color.Chartreuse ); } } /// /// Chocolate solid brush. /// public static Solid Chocolate { get { return new Solid( Color.Chocolate ); } } /// /// Coral solid brush. /// public static Solid Coral { get { return new Solid( Color.Coral ); } } /// /// CornflowerBlue solid brush. /// public static Solid CornflowerBlue { get { return new Solid( Color.CornflowerBlue ); } } /// /// Cornsilk solid brush. /// public static Solid Cornsilk { get { return new Solid( Color.Cornsilk ); } } /// /// Crimson solid brush. /// public static Solid Crimson { get { return new Solid( Color.Crimson ); } } /// /// Cyan solid brush. /// public static Solid Cyan { get { return new Solid( Color.Cyan ); } } /// /// DarkBlue solid brush. /// public static Solid DarkBlue { get { return new Solid( Color.DarkBlue ); } } /// /// DarkCyan solid brush. /// public static Solid DarkCyan { get { return new Solid( Color.DarkCyan ); } } /// /// DarkGoldenrod solid brush. /// public static Solid DarkGoldenrod { get { return new Solid( Color.DarkGoldenrod ); } } /// /// DarkGray solid brush. /// public static Solid DarkGray { get { return new Solid( Color.DarkGray ); } } /// /// DarkGreen solid brush. /// public static Solid DarkGreen { get { return new Solid( Color.DarkGreen ); } } /// /// DarkKhaki solid brush. /// public static Solid DarkKhaki { get { return new Solid( Color.DarkKhaki ); } } /// /// DarkMagenta solid brush. /// public static Solid DarkMagenta { get { return new Solid( Color.DarkMagenta ); } } /// /// DarkOliveGreen solid brush. /// public static Solid DarkOliveGreen { get { return new Solid( Color.DarkOliveGreen ); } } /// /// DarkOrange solid brush. /// public static Solid DarkOrange { get { return new Solid( Color.DarkOrange ); } } /// /// DarkOrchid solid brush. /// public static Solid DarkOrchid { get { return new Solid( Color.DarkOrchid ); } } /// /// DarkRed solid brush. /// public static Solid DarkRed { get { return new Solid( Color.DarkRed ); } } /// /// DarkSalmon solid brush. /// public static Solid DarkSalmon { get { return new Solid( Color.DarkSalmon ); } } /// /// DarkSeaGreen solid brush. /// public static Solid DarkSeaGreen { get { return new Solid( Color.DarkSeaGreen ); } } /// /// DarkSlateBlue solid brush. /// public static Solid DarkSlateBlue { get { return new Solid( Color.DarkSlateBlue ); } } /// /// DarkSlateGray solid brush. /// public static Solid DarkSlateGray { get { return new Solid( Color.DarkSlateGray ); } } /// /// DarkTurquoise solid brush. /// public static Solid DarkTurquoise { get { return new Solid( Color.DarkTurquoise ); } } /// /// DarkViolet solid brush. /// public static Solid DarkViolet { get { return new Solid( Color.DarkViolet ); } } /// /// DeepPink solid brush. /// public static Solid DeepPink { get { return new Solid( Color.DeepPink ); } } /// /// DeepSkyBlue solid brush. /// public static Solid DeepSkyBlue { get { return new Solid( Color.DeepSkyBlue ); } } /// /// DimGray solid brush. /// public static Solid DimGray { get { return new Solid( Color.DimGray ); } } /// /// DodgerBlue solid brush. /// public static Solid DodgerBlue { get { return new Solid( Color.DodgerBlue ); } } /// /// Firebrick solid brush. /// public static Solid Firebrick { get { return new Solid( Color.Firebrick ); } } /// /// FloralWhite solid brush. /// public static Solid FloralWhite { get { return new Solid( Color.FloralWhite ); } } /// /// ForestGreen solid brush. /// public static Solid ForestGreen { get { return new Solid( Color.ForestGreen ); } } /// /// Fuchsia solid brush. /// public static Solid Fuchsia { get { return new Solid( Color.Fuchsia ); } } /// /// Gainsboro solid brush. /// public static Solid Gainsboro { get { return new Solid( Color.Gainsboro ); } } /// /// GhostWhite solid brush. /// public static Solid GhostWhite { get { return new Solid( Color.GhostWhite ); } } /// /// Gold solid brush. /// public static Solid Gold { get { return new Solid( Color.Gold ); } } /// /// Goldenrod solid brush. /// public static Solid Goldenrod { get { return new Solid( Color.Goldenrod ); } } /// /// Gray solid brush. /// public static Solid Gray { get { return new Solid( Color.Gray ); } } /// /// Green solid brush. /// public static Solid Green { get { return new Solid( Color.Green ); } } /// /// GreenYellow solid brush. /// public static Solid GreenYellow { get { return new Solid( Color.GreenYellow ); } } /// /// Honeydew solid brush. /// public static Solid Honeydew { get { return new Solid( Color.Honeydew ); } } /// /// HotPink solid brush. /// public static Solid HotPink { get { return new Solid( Color.HotPink ); } } /// /// IndianRed solid brush. /// public static Solid IndianRed { get { return new Solid( Color.IndianRed ); } } /// /// Indigo solid brush. /// public static Solid Indigo { get { return new Solid( Color.Indigo ); } } /// /// Ivory solid brush. /// public static Solid Ivory { get { return new Solid( Color.Ivory ); } } /// /// Khaki solid brush. /// public static Solid Khaki { get { return new Solid( Color.Khaki ); } } /// /// Lavender solid brush. /// public static Solid Lavender { get { return new Solid( Color.Lavender ); } } /// /// LavenderBlush solid brush. /// public static Solid LavenderBlush { get { return new Solid( Color.LavenderBlush ); } } /// /// LawnGreen solid brush. /// public static Solid LawnGreen { get { return new Solid( Color.LawnGreen ); } } /// /// LemonChiffon solid brush. /// public static Solid LemonChiffon { get { return new Solid( Color.LemonChiffon ); } } /// /// LightBlue solid brush. /// public static Solid LightBlue { get { return new Solid( Color.LightBlue ); } } /// /// LightCoral solid brush. /// public static Solid LightCoral { get { return new Solid( Color.LightCoral ); } } /// /// LightCyan solid brush. /// public static Solid LightCyan { get { return new Solid( Color.LightCyan ); } } /// /// LightGoldenrodYellow solid brush. /// public static Solid LightGoldenrodYellow { get { return new Solid( Color.LightGoldenrodYellow ); } } /// /// LightGray solid brush. /// public static Solid LightGray { get { return new Solid( Color.LightGray ); } } /// /// LightGreen solid brush. /// public static Solid LightGreen { get { return new Solid( Color.LightGreen ); } } /// /// LightPink solid brush. /// public static Solid LightPink { get { return new Solid( Color.LightPink ); } } /// /// LightSalmon solid brush. /// public static Solid LightSalmon { get { return new Solid( Color.LightSalmon ); } } /// /// LightSeaGreen solid brush. /// public static Solid LightSeaGreen { get { return new Solid( Color.LightSeaGreen ); } } /// /// LightSkyBlue solid brush. /// public static Solid LightSkyBlue { get { return new Solid( Color.LightSkyBlue ); } } /// /// LightSlateGray solid brush. /// public static Solid LightSlateGray { get { return new Solid( Color.LightSlateGray ); } } /// /// LightSteelBlue solid brush. /// public static Solid LightSteelBlue { get { return new Solid( Color.LightSteelBlue ); } } /// /// LightYellow solid brush. /// public static Solid LightYellow { get { return new Solid( Color.LightYellow ); } } /// /// Lime solid brush. /// public static Solid Lime { get { return new Solid( Color.Lime ); } } /// /// LimeGreen solid brush. /// public static Solid LimeGreen { get { return new Solid( Color.LimeGreen ); } } /// /// Color.Linen solid brush. /// public static Solid Linen { get { return new Solid( Color.Linen ); } } /// /// Color.Magenta solid brush. /// public static Solid Magenta { get { return new Solid( Color.Magenta ); } } /// /// Maroon solid brush. /// public static Solid Maroon { get { return new Solid( Color.Maroon ); } } /// /// MediumAquamarine solid brush. /// public static Solid MediumAquamarine { get { return new Solid( Color.MediumAquamarine ); } } /// /// MediumBlue solid brush. /// public static Solid MediumBlue { get { return new Solid( Color.MediumBlue ); } } /// /// MediumOrchid solid brush. /// public static Solid MediumOrchid { get { return new Solid( Color.MediumOrchid ); } } /// /// MediumPurple solid brush. /// public static Solid MediumPurple { get { return new Solid( Color.MediumPurple ); } } /// /// MediumSeaGreen solid brush. /// public static Solid MediumSeaGreen { get { return new Solid( Color.MediumSeaGreen ); } } /// /// MediumSlateBlue solid brush. /// public static Solid MediumSlateBlue { get { return new Solid( Color.MediumSlateBlue ); } } /// /// MediumSpringGreen solid brush. /// public static Solid MediumSpringGreen { get { return new Solid( Color.MediumSpringGreen ); } } /// /// MediumTurquoise solid brush. /// public static Solid MediumTurquoise { get { return new Solid( Color.MediumTurquoise ); } } /// /// MediumVioletRed solid brush. /// public static Solid MediumVioletRed { get { return new Solid( Color.MediumVioletRed ); } } /// /// MidnightBlue solid brush. /// public static Solid MidnightBlue { get { return new Solid( Color.MidnightBlue ); } } /// /// MintCream solid brush. /// public static Solid MintCream { get { return new Solid( Color.MintCream ); } } /// /// MistyRose solid brush. /// public static Solid MistyRose { get { return new Solid( Color.MistyRose ); } } /// /// Moccasin solid brush. /// public static Solid Moccasin { get { return new Solid( Color.Moccasin ); } } /// /// NavajoWhite solid brush. /// public static Solid NavajoWhite { get { return new Solid( Color.NavajoWhite ); } } /// /// Navy solid brush. /// public static Solid Navy { get { return new Solid( Color.Navy ); } } /// /// OldLace solid brush. /// public static Solid OldLace { get { return new Solid( Color.OldLace ); } } /// /// Olive solid brush. /// public static Solid Olive { get { return new Solid( Color.Olive ); } } /// /// OliveDrab solid brush. /// public static Solid OliveDrab { get { return new Solid( Color.OliveDrab ); } } /// /// Orange solid brush. /// public static Solid Orange { get { return new Solid( Color.Orange ); } } /// /// OrangeRed solid brush. /// public static Solid OrangeRed { get { return new Solid( Color.OrangeRed ); } } /// /// Orchid solid brush. /// public static Solid Orchid { get { return new Solid( Color.Orchid ); } } /// /// PaleGoldenrod solid brush. /// public static Solid PaleGoldenrod { get { return new Solid( Color.PaleGoldenrod ); } } /// /// PaleGreen solid brush. /// public static Solid PaleGreen { get { return new Solid( Color.PaleGreen ); } } /// /// PaleTurquoise solid brush. /// public static Solid PaleTurquoise { get { return new Solid( Color.PaleTurquoise ); } } /// /// PaleVioletRed solid brush. /// public static Solid PaleVioletRed { get { return new Solid( Color.PaleVioletRed ); } } /// /// PapayaWhip solid brush. /// public static Solid PapayaWhip { get { return new Solid( Color.PapayaWhip ); } } /// /// PeachPuff solid brush. /// public static Solid PeachPuff { get { return new Solid( Color.PeachPuff ); } } /// /// Peru solid brush. /// public static Solid Peru { get { return new Solid( Color.Peru ); } } /// /// Pink solid brush. /// public static Solid Pink { get { return new Solid( Color.Pink ); } } /// /// Plum solid brush. /// public static Solid Plum { get { return new Solid( Color.Plum ); } } /// /// PowderBlue solid brush. /// public static Solid PowderBlue { get { return new Solid( Color.PowderBlue ); } } /// /// Purple solid brush. /// public static Solid Purple { get { return new Solid( Color.Purple ); } } /// /// Red solid brush. /// public static Solid Red { get { return new Solid( Color.Red ); } } /// /// RosyBrown solid brush. /// public static Solid RosyBrown { get { return new Solid( Color.RosyBrown ); } } /// /// RoyalBlue solid brush. /// public static Solid RoyalBlue { get { return new Solid( Color.RoyalBlue ); } } /// /// SaddleBrown solid brush. /// public static Solid SaddleBrown { get { return new Solid( Color.SaddleBrown ); } } /// /// Salmon solid brush. /// public static Solid Salmon { get { return new Solid( Color.Salmon ); } } /// /// SandyBrown solid brush. /// public static Solid SandyBrown { get { return new Solid( Color.SandyBrown ); } } /// /// SeaGreen solid brush. /// public static Solid SeaGreen { get { return new Solid( Color.SeaGreen ); } } /// /// SeaShell solid brush. /// public static Solid SeaShell { get { return new Solid( Color.SeaShell ); } } /// /// Sienna solid brush. /// public static Solid Sienna { get { return new Solid( Color.Sienna ); } } /// /// Silver solid brush. /// public static Solid Silver { get { return new Solid( Color.Silver ); } } /// /// SkyBlue solid brush. /// public static Solid SkyBlue { get { return new Solid( Color.SkyBlue ); } } /// /// SlateBlue solid brush. /// public static Solid SlateBlue { get { return new Solid( Color.SlateBlue ); } } /// /// SlateGray solid brush. /// public static Solid SlateGray { get { return new Solid( Color.SlateGray ); } } /// /// Snow solid brush. /// public static Solid Snow { get { return new Solid( Color.Snow ); } } /// /// SpringGreen solid brush. /// public static Solid SpringGreen { get { return new Solid( Color.SpringGreen ); } } /// /// SteelBlue solid brush. /// public static Solid SteelBlue { get { return new Solid( Color.SteelBlue ); } } /// /// Tan solid brush. /// public static Solid Tan { get { return new Solid( Color.Tan ); } } /// /// Teal solid brush. /// public static Solid Teal { get { return new Solid( Color.Teal ); } } /// /// Thistle solid brush. /// public static Solid Thistle { get { return new Solid( Color.Thistle ); } } /// /// Tomato solid brush. /// public static Solid Tomato { get { return new Solid( Color.Tomato ); } } /// /// Transparent solid brush. /// public static Solid Transparent { get { return new Solid( Color.Transparent ); } } /// /// Turquoise solid brush. /// public static Solid Turquoise { get { return new Solid( Color.Turquoise ); } } /// /// Violet solid brush. /// public static Solid Violet { get { return new Solid( Color.Violet ); } } /// /// Wheat solid brush. /// public static Solid Wheat { get { return new Solid( Color.Wheat ); } } /// /// White solid brush. /// public static Solid White { get { return new Solid( Color.White ); } } /// /// WhiteSmoke solid brush. /// public static Solid WhiteSmoke { get { return new Solid( Color.WhiteSmoke ); } } /// /// Yellow solid brush. /// public static Solid Yellow { get { return new Solid( Color.Yellow ); } } /// /// YellowGreen solid brush. /// public static Solid YellowGreen { get { return new Solid( Color.YellowGreen ); } } #endregion } /// /// A brush with horizontal gradient. /// public class Horizontal : IRectangleBrush { private Color c1_; private Color c2_; /// /// Constructor /// /// Color on left. /// Color on right. public Horizontal( Color c1, Color c2 ) { c1_ = c1; c2_ = c2; } /// /// Gets a brush according to the supplied rectangle. /// /// the rectangle used to construct the brush /// The horizontal brush public Brush Get( Rectangle rectangle ) { return new LinearGradientBrush( rectangle, c1_, c2_, LinearGradientMode.Horizontal ); } #region DefaultBrushes /// /// Default brush - fades from faint blue to white. /// public static Horizontal FaintBlueFade { get { return new Horizontal( Color.FromArgb(200,200,255), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static Horizontal FaintRedFade { get { return new Horizontal( Color.FromArgb(255,200,200), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static Horizontal FaintGreenFade { get { return new Horizontal( Color.FromArgb(200,255,200), Color.FromArgb(255,255,255) ); } } #endregion } /// /// A brush with vertical gradient. /// public class Vertical : IRectangleBrush { private Color c1_; private Color c2_; /// /// Constructor /// /// top color [or bottom?] /// bottom color [or top?] public Vertical( Color c1, Color c2 ) { c1_ = c1; c2_ = c2; } /// /// Gets a brush according to the supplied rectangle. /// /// the rectangle used to construct the brush /// The vertical brush public Brush Get( Rectangle rectangle ) { return new LinearGradientBrush( rectangle, c1_, c2_, LinearGradientMode.Vertical ); } #region DefaultBrushes /// /// Default brush - fades from faint blue to white. /// public static Vertical FaintBlueFade { get { return new Vertical( Color.FromArgb(200,200,255), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static Vertical FaintRedFade { get { return new Vertical( Color.FromArgb(255,200,200), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static Vertical FaintGreenFade { get { return new Vertical( Color.FromArgb(200,255,200), Color.FromArgb(255,255,255) ); } } #endregion } /// /// A brush with horizontal gradient that fades into center then out again. /// public class HorizontalCenterFade : IRectangleBrush { private Color c1_; private Color c2_; /// /// Constructor /// /// inner color /// outer color public HorizontalCenterFade( Color c1, Color c2 ) { c1_ = c1; c2_ = c2; } /// /// Gets a brush according to the supplied rectangle. /// /// the rectangle used to construct the brush /// The horizontal center fade brush public Brush Get( Rectangle rectangle ) { LinearGradientBrush brush = new LinearGradientBrush( rectangle, c1_, c2_, LinearGradientMode.Horizontal ); float[] relativeIntensities = { 0.0f, 0.9f, 1.0f, 0.9f, 0.0f }; float[] relativePositions = { 0.0f, 0.4f, 0.5f, 0.6f, 1.0f }; Blend blend = new Blend(); blend.Factors = relativeIntensities; blend.Positions = relativePositions; brush.Blend = blend; return brush; } #region DefaultBrushes /// /// Default brush - fades from faint blue to white. /// public static HorizontalCenterFade FaintBlueFade { get { return new HorizontalCenterFade( Color.FromArgb(200,200,255), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static HorizontalCenterFade FaintRedFade { get { return new HorizontalCenterFade( Color.FromArgb(255,200,200), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static HorizontalCenterFade FaintGreenFade { get { return new HorizontalCenterFade( Color.FromArgb(200,255,200), Color.FromArgb(255,255,255) ); } } #endregion } /// /// Brush with vertical gradient that fades into center then out again. /// public class VerticalCenterFade : IRectangleBrush { private Color c1_; private Color c2_; /// /// Constructor /// /// inner color /// outer color public VerticalCenterFade( Color c1, Color c2 ) { c1_ = c1; c2_ = c2; } /// /// Gets a brush according to the supplied rectangle. /// /// the rectangle used to construct the brush /// The vertical center fade brush public Brush Get( Rectangle rectangle ) { LinearGradientBrush brush = new LinearGradientBrush( rectangle, c1_, c2_, LinearGradientMode.Vertical ); float[] relativeIntensities = { 0.0f, 0.9f, 1.0f, 0.9f, 0.0f }; float[] relativePositions = { 0.0f, 0.4f, 0.5f, 0.6f, 1.0f }; Blend blend = new Blend(); blend.Factors = relativeIntensities; blend.Positions = relativePositions; brush.Blend = blend; return brush; } #region DefaultBrushes /// /// Default brush - fades from faint blue to white. /// public static VerticalCenterFade FaintBlueFade { get { return new VerticalCenterFade( Color.FromArgb(200,200,255), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static VerticalCenterFade FaintRedFade { get { return new VerticalCenterFade( Color.FromArgb(255,200,200), Color.FromArgb(255,255,255) ); } } /// /// Default brush - fades from faint red to white. /// public static VerticalCenterFade FaintGreenFade { get { return new VerticalCenterFade( Color.FromArgb(200,255,200), Color.FromArgb(255,255,255) ); } } #endregion } } } nplot-gtk-0.9.9.2/lib/RectangleD.cs0000644000175000017500000000667510512404106017422 0ustar carlosblecarlosble/* NPlot - A charting library for .NET RectangleD.cs Copyright (C) 2005 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// Stores a set of four double numbers that represent the location and size of /// a rectangle. TODO: implement more functionality similar to Drawing.RectangleF. /// public struct RectangleD { /// /// Constructor /// public RectangleD( double x, double y, double width, double height ) { x_ = x; y_ = y; width_ = width; height_ = height; } /// /// The rectangle height. /// public double Height { get { return height_; } set { height_ = value; } } /// /// The rectangle width. /// public double Width { get { return width_; } set { width_ = value; } } /// /// The minimum x coordinate of the rectangle. /// public double X { get { return x_; } set { x_ = value; } } /// /// The minimum y coordinate of the rectangle. /// public double Y { get { return y_; } set { y_ = value; } } private double x_; private double y_; private double width_; private double height_; } } nplot-gtk-0.9.9.2/lib/SequenceAdapter.cs0000644000175000017500000002741410512404106020455 0ustar carlosblecarlosble/* NPlot - A charting library for .NET SequenceAdapter.cs Copyright (C) 2003-2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; using System.Data; namespace NPlot { /// /// This class is responsible for interpreting the various ways you can /// specify data to plot objects using the DataSource, DataMember, ordinateData /// and AbscissaData properties. It is a bridge that provides access to this /// data via a single interface. /// public class SequenceAdapter { private AdapterUtils.IAxisSuggester XAxisSuggester_; private AdapterUtils.IAxisSuggester YAxisSuggester_; private AdapterUtils.ICounter counter_; private AdapterUtils.IDataGetter xDataGetter_; private AdapterUtils.IDataGetter yDataGetter_; /// /// Constructor. The data source specifiers must be specified here. /// /// The source containing a list of values to plot. /// The specific data member in a multimember data source to get data from. /// The source containing a list of values to plot on the ordinate axis, or a the name of the column to use for this data. /// The source containing a list of values to plot on the abscissa axis, or a the name of the column to use for this data. public SequenceAdapter( object dataSource, string dataMember, object ordinateData, object abscissaData ) { if (dataSource == null && dataMember == null) { if (ordinateData is IList) { this.YAxisSuggester_ = new AdapterUtils.AxisSuggester_IList((IList)ordinateData); if (ordinateData is Double[]) this.yDataGetter_ = new AdapterUtils.DataGetter_DoublesArray((Double[])ordinateData); else this.yDataGetter_ = new AdapterUtils.DataGetter_IList((IList)ordinateData); this.counter_ = new AdapterUtils.Counter_IList((IList)ordinateData); if (abscissaData is IList) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_IList((IList)abscissaData); if (abscissaData is Double[]) this.xDataGetter_ = new AdapterUtils.DataGetter_DoublesArray((Double[])abscissaData); else this.xDataGetter_ = new AdapterUtils.DataGetter_IList((IList)abscissaData); return; } else if (abscissaData is StartStep) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_StartStep((StartStep)abscissaData, (IList)ordinateData); this.xDataGetter_ = new AdapterUtils.DataGetter_StartStep((StartStep)abscissaData); return; } else if (abscissaData == null) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_Auto((IList)ordinateData); this.xDataGetter_ = new AdapterUtils.DataGetter_Count(); return; } } else if (ordinateData == null) { if (abscissaData == null) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_Null(); this.YAxisSuggester_ = new AdapterUtils.AxisSuggester_Null(); this.counter_ = new AdapterUtils.Counter_Null(); this.xDataGetter_ = new AdapterUtils.DataGetter_Null(); this.yDataGetter_ = new AdapterUtils.DataGetter_Null(); return; } else if (abscissaData is IList) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_IList((IList)abscissaData); this.YAxisSuggester_ = new AdapterUtils.AxisSuggester_Auto((IList)abscissaData); this.counter_ = new AdapterUtils.Counter_IList((IList)abscissaData); if (abscissaData is Double[]) this.xDataGetter_ = new AdapterUtils.DataGetter_DoublesArray((Double[])abscissaData); else this.xDataGetter_ = new AdapterUtils.DataGetter_IList((IList)abscissaData); this.yDataGetter_ = new AdapterUtils.DataGetter_Count(); return; } else { // unknown. } } else { // unknown } } else if (dataSource is IList && dataMember == null) { if (dataSource is DataView) { DataView data = (DataView)dataSource; this.counter_ = new AdapterUtils.Counter_DataView(data); this.xDataGetter_ = new AdapterUtils.DataGetter_DataView(data, (string)abscissaData); this.yDataGetter_ = new AdapterUtils.DataGetter_DataView(data, (string)ordinateData); this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_DataView(data, (string)abscissaData); this.YAxisSuggester_ = new AdapterUtils.AxisSuggester_DataView(data, (string)ordinateData); return; } else { this.YAxisSuggester_ = new AdapterUtils.AxisSuggester_IList((IList)dataSource); this.counter_ = new AdapterUtils.Counter_IList((IList)dataSource); this.yDataGetter_ = new AdapterUtils.DataGetter_IList((IList)dataSource); if ((ordinateData == null) && (abscissaData == null)) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_Auto((IList)dataSource); this.xDataGetter_ = new AdapterUtils.DataGetter_Count(); return; } else if ((ordinateData == null) && (abscissaData is StartStep)) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_StartStep((StartStep)abscissaData, (IList)ordinateData); this.xDataGetter_ = new AdapterUtils.DataGetter_StartStep((StartStep)abscissaData); return; } else if ((ordinateData == null) && (abscissaData is IList)) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_IList((IList)abscissaData); this.xDataGetter_ = new AdapterUtils.DataGetter_IList((IList)abscissaData); return; } else { // unknown. } } } else if ( ((dataSource is DataTable) && (dataMember == null)) || (dataSource is DataSet) ) { DataRowCollection rows = null; if (dataSource is DataSet) { if (dataMember != null) { rows = ((DataTable)((DataSet)dataSource).Tables[dataMember]).Rows; } else { rows = ((DataTable)((DataSet)dataSource).Tables[0]).Rows; } } else { rows = ((DataTable)dataSource).Rows; } this.yDataGetter_ = new AdapterUtils.DataGetter_Rows(rows, (string)ordinateData); this.YAxisSuggester_ = new AdapterUtils.AxisSuggester_Rows(rows, (string)ordinateData); this.counter_ = new AdapterUtils.Counter_Rows(rows); if ((abscissaData is string) && (ordinateData is string)) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_Rows(rows, (string)abscissaData); this.xDataGetter_ = new AdapterUtils.DataGetter_Rows(rows, (string)abscissaData); return; } else if ((abscissaData == null) && (ordinateData is string)) { this.XAxisSuggester_ = new AdapterUtils.AxisSuggester_RowAuto(rows); this.xDataGetter_ = new AdapterUtils.DataGetter_Count(); return; } else { // unknown. } } else { // unknown. } throw new NPlotException( "Do not know how to interpret data provided to chart." ); } /// /// Returns the number of points. /// public int Count { get { return counter_.Count; } } /// /// Returns the ith point. /// public PointD this[int i] { get { return new PointD( this.xDataGetter_.Get(i), this.yDataGetter_.Get(i) ); } } /// /// Returns an x-axis that is suitable for drawing the data. /// /// A suitable x-axis. public Axis SuggestXAxis() { return this.XAxisSuggester_.Get(); } /// /// Returns a y-axis that is suitable for drawing the data. /// /// A suitable y-axis. public Axis SuggestYAxis() { Axis a = this.YAxisSuggester_.Get(); // TODO make 0.08 a parameter. a.IncreaseRange( 0.08 ); return a; } /// /// Writes data out as text. /// /// StringBuilder to write to. /// Only write out data in this region if onlyInRegion is true. /// If true, only data in region is written, else all data is written. public void WriteData( System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion ) { for (int i=0; i= region.X && this[i].X <= region.X+region.Width) && (this[i].Y >= region.Y && this[i].Y <= region.Y+region.Height)) ) continue; sb.Append( this[i].ToString() ); sb.Append( "\r\n" ); } } } } nplot-gtk-0.9.9.2/lib/SequenceAdapter3D.cs0000644000175000017500000000071510512404106020637 0ustar carlosblecarlosble// ******** experimental ******** /* using System; namespace NPlot { /// /// This class will be analogous to SequenceAdapter for 2D charting. /// Don't use it initially - offer only one method of getting in data /// for similicity. /// TODO. Not implemented. /// public class SequenceAdapter3D { /// /// Constructor. TODO. /// public SequenceAdapter3D() { } } } */nplot-gtk-0.9.9.2/lib/StartStep.cs0000644000175000017500000000631310512404106017330 0ustar carlosblecarlosble/* NPlot - A charting library for .NET StartStep.cs Copyright (C) 2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; namespace NPlot { /// /// Encapsulates a Start and Step value. This is useful for specifying a regularly spaced set of /// abscissa values. /// public class StartStep { private double start_; private double step_; /// /// Constructor /// /// the first value of the set of points specified by this object. /// the step that specifies the separation between successive points. public StartStep( double start, double step ) { this.Start = start; this.Step = step; } /// /// The first value of the set of points specified by this object. /// public double Start { get { return start_; } set { this.start_ = value; } } /// /// The step that specifies the separation between successive points. /// public double Step { get { return this.step_; } set { this.step_ = value; } } } } nplot-gtk-0.9.9.2/lib/StepPlot.cs0000644000175000017500000002170610512404106017154 0ustar carlosblecarlosble/* NPlot - A charting library for .NET StepPlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 plotting data as a stepped line. /// public class StepPlot : BaseSequencePlot, IPlot, ISequencePlot { /// /// Constructor. /// public StepPlot() { this.Center = false; } /// /// Draws the step 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( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false); double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false); for (int i=0; i rightCutoff ) && (p2.X < leftCutoff || p2.X > rightCutoff ) && (p3.X < leftCutoff || p3.X > rightCutoff ) ) { continue; } if (!this.hideHorizontalSegments_) { if (scale_ != 1.0f) { float middle = (xPos2.X + xPos1.X) / 2.0f; float width = xPos2.X - xPos1.X; width *= this.scale_; g.DrawLine( Pen, (int)(middle-width/2.0f), yPos1.Y, (int)(middle+width/2.0f), yPos2.Y ); } else { g.DrawLine( Pen, xPos1.X, yPos1.Y, xPos2.X, yPos2.Y ); } } if (!this.hideVerticalSegments_) { g.DrawLine( Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y ); } } } /// /// Returns an X-axis suitable for use by this plot. The axis will be one that is just long /// enough to show all data. /// /// X-axis suitable for use by this plot. public Axis SuggestXAxis() { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); if (data.Count < 2) { return data.SuggestXAxis(); } // else Axis a = data.SuggestXAxis(); PointD p1 = data[0]; PointD p2 = data[1]; PointD p3 = data[data.Count-2]; PointD p4 = data[data.Count-1]; double offset1; double offset2; if (!center_) { offset1 = 0.0f; offset2 = p4.X - p3.X; } else { offset1 = (p2.X - p1.X)/2.0f; offset2 = (p4.X - p3.X)/2.0f; } a.WorldMin -= offset1; a.WorldMax += offset2; return a; } /// /// Returns an Y-axis suitable for use by this plot. The axis will be one that is just long /// enough to show all data. /// /// Y-axis suitable for use by this plot. public Axis SuggestYAxis() { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); return data.SuggestYAxis(); } /// /// Gets or sets whether or not steps should be centered. If true, steps will be centered on the /// X abscissa values. If false, the step corresponding to a given x-value will be drawn between /// this x-value and the next x-value at the current y-height. /// public bool Center { set { center_ = value; } get { return center_; } } private bool center_; /// /// 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 virtual void DrawInLegend(Graphics g, Rectangle startEnd) { g.DrawLine(pen_, startEnd.Left, (startEnd.Top + startEnd.Bottom) / 2, startEnd.Right, (startEnd.Top + startEnd.Bottom) / 2); } /// /// The pen used to draw the plot /// public System.Drawing.Pen Pen { get { return pen_; } set { pen_ = value; } } private System.Drawing.Pen pen_ = new Pen(Color.Black); /// /// The color of the pen used to draw lines in this plot. /// public System.Drawing.Color Color { set { if (pen_ != null) { pen_.Color = value; } else { pen_ = new Pen(value); } } get { return pen_.Color; } } /// /// If true, then vertical lines are hidden. /// public bool HideVerticalSegments { get { return hideVerticalSegments_; } set { hideVerticalSegments_ = value; } } bool hideVerticalSegments_ = false; /// /// If true, then vertical lines are hidden. /// public bool HideHorizontalSegments { get { return hideHorizontalSegments_; } set { hideHorizontalSegments_ = value; } } bool hideHorizontalSegments_ = false; /// /// The horizontal line length is multiplied by this amount. Default /// corresponds to a value of 1.0. /// public float WidthScale { get { return scale_; } set { scale_ = value; } } private float scale_ = 1.0f; } } nplot-gtk-0.9.9.2/lib/TextItem.cs0000644000175000017500000001100110512404106017130 0ustar carlosblecarlosble/* NPlot - A charting library for .NET TextItem.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// This class implements drawing text against two physical axes. /// public class TextItem : IDrawable { private void Init() { FontFamily fontFamily = new FontFamily("Arial"); font_ = new Font(fontFamily, 10, FontStyle.Regular, GraphicsUnit.Pixel); } /// /// Constructor /// /// The position the text starts. /// The text. public TextItem( PointD position, string text ) { start_ = position; text_ = text; Init(); } /// /// Text associated. /// public string Text { get { return text_; } set { text_ = value; } } private string text_ = ""; /// /// The starting point for the text. /// public PointD Start { get { return start_; } set { start_ = value; } } private PointD start_; /// /// Draws the text on a plot surface. /// /// graphics surface on which to draw /// The X-Axis to draw against. /// The Y-Axis to draw against. public void Draw( System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { Point startPoint = new Point( (int)xAxis.WorldToPhysical( start_.X, true ).X, (int)yAxis.WorldToPhysical( start_.Y, true ).Y ); g.DrawString(text_, font_, textBrush_,(int)startPoint.X,(int)startPoint.Y); } /// /// The brush used to draw the text. /// public Brush TextBrush { get { return textBrush_; } set { textBrush_ = value; } } /// /// Set the text to be drawn with a solid brush of this color. /// public Color TextColor { set { textBrush_ = new SolidBrush( value ); } } /// /// The font used to draw the text associated with the arrow. /// public Font TextFont { get { return this.font_; } set { this.font_ = value; } } private Brush textBrush_ = new SolidBrush( Color.Black ); private Pen pen_ = new Pen( Color.Black ); private Font font_; } } nplot-gtk-0.9.9.2/lib/Transform2D.cs0000644000175000017500000001442710512404106017545 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Transform2D.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 transforming world to physical coordinates optimally. /// /// The existence of the whole ITransform2D thing might need revising. Not convinced it's the best way. public class Transform2D { /// /// Constructs the optimal ITransform2D object for the supplied x and y axes. /// /// The xAxis to use for the world to physical transform. /// The yAxis to use for the world to physical transform. /// An ITransform2D derived object for converting from world to physical coordinates. public static ITransform2D GetTransformer( PhysicalAxis xAxis, PhysicalAxis yAxis ) { ITransform2D ret = null; // if (xAxis.Axis.IsLinear && yAxis.Axis.IsLinear && !xAxis.Axis.Reversed && !yAxis.Axis.Reversed) // ret = new FastTransform2D( xAxis, yAxis ); // else // ret = new DefaultTransform2D( xAxis, yAxis ); ret = new DefaultTransform2D( xAxis, yAxis ); return ret; } /// /// This class does world -> physical transforms for the general case /// public class DefaultTransform2D : ITransform2D { private PhysicalAxis xAxis_; private PhysicalAxis yAxis_; /// /// Constructor /// /// The x-axis to use for transforms /// The y-axis to use for transforms public DefaultTransform2D( PhysicalAxis xAxis, PhysicalAxis yAxis ) { xAxis_ = xAxis; yAxis_ = yAxis; } /// /// Transforms the given world point to physical coordinates /// /// x coordinate of world point to transform. /// y coordinate of world point to transform. /// the corresponding physical point. public PointF Transform( double x, double y ) { return new PointF( xAxis_.WorldToPhysical( x, false ).X, yAxis_.WorldToPhysical( y, false ).Y ); } /// /// Transforms the given world point to physical coordinates /// /// the world point to transform /// the corresponding physical point public PointF Transform( PointD worldPoint ) { return new PointF( xAxis_.WorldToPhysical( worldPoint.X, false ).X, yAxis_.WorldToPhysical( worldPoint.Y, false ).Y ); } } /// /// This class does highly efficient world->physical and physical->world transforms /// for linear axes. /// public class FastTransform2D : ITransform2D { private PageAlignedPhysicalAxis xAxis_; private PageAlignedPhysicalAxis yAxis_; /// /// Constructor /// /// The x-axis to use for transforms /// The y-axis to use for transforms public FastTransform2D( PhysicalAxis xAxis, PhysicalAxis yAxis ) { xAxis_ = new PageAlignedPhysicalAxis( xAxis ); yAxis_ = new PageAlignedPhysicalAxis( yAxis ); } /// /// Transforms the given world point to physical coordinates /// /// x coordinate of world point to transform. /// y coordinate of world point to transform. /// the corresponding physical point. public PointF Transform( double x, double y ) { return new PointF( xAxis_.WorldToPhysicalClipped( x ), yAxis_.WorldToPhysicalClipped( y ) ); } /// /// Transforms the given world point to physical coordinates /// /// the world point to transform /// the corresponding physical point public PointF Transform( PointD worldPoint ) { return new PointF( xAxis_.WorldToPhysical( worldPoint.X ), yAxis_.WorldToPhysical( worldPoint.Y ) ); } } } } nplot-gtk-0.9.9.2/lib/Utils.cs0000644000175000017500000002653010512404106016502 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Utils.cs Copyright (C) 2003-2004 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; using System.Data; using System.Collections; namespace NPlot { /// /// General purpose utility functions used internally. /// internal class Utils { /// /// Numbers less than this are considered insignificant. This number is /// bigger than double.Epsilon. /// public const double Epsilon = double.Epsilon * 1000.0; /// /// Returns true if the absolute difference between parameters is less than Epsilon /// /// first number to compare /// second number to compare /// true if equal, false otherwise public static bool DoubleEqual( double a, double b ) { if ( System.Math.Abs(a-b) < Epsilon ) { return true; } return false; } /// /// Swaps the value of two doubles. /// /// first value to swap. /// second value to swap. public static void Swap( ref double a, ref double b ) { double c = a; a = b; b = c; } /// /// Calculate the distance between two points, a and b. /// /// First point /// Second point /// Distance between points a and b public static float Distance( PointF a, PointF b ) { return (float)System.Math.Sqrt( (a.X - b.X)*(a.X - b.X) + (a.Y - b.Y)*(a.Y - b.Y) ); } /// /// Calculate the distance between two points, a and b. /// /// First point /// Second point /// Distance between points a and b public static int Distance( Point a, Point b ) { return (int)System.Math.Sqrt( (a.X - b.X)*(a.X - b.X) + (a.Y - b.Y)*(a.Y - b.Y) ); } /// /// Converts an object of type DateTime or IConvertible to double representation. /// Mapping is 1:1. Note: the System.Convert.ToDouble method can not convert a boxed /// DateTime to double. This implementation can - but the "is" check probably makes /// it much slower. /// /// Compare speed with System.Convert.ToDouble and revise code that calls this if significant speed difference. /// The object to convert to double. /// double value associated with the object. public static double ToDouble( object o ) { if (o is DateTime) { return (double)(((DateTime)o).Ticks); } else if (o is IConvertible) { return System.Convert.ToDouble(o); } throw new NPlotException( "Invalid datatype" ); } /// /// Returns the minimum and maximum values in an IList. The members of the list /// can be of different types - any type for which the function Utils.ConvertToDouble /// knows how to convert into a double. /// /// The IList to search. /// The minimum value. /// The maximum value. /// true if min max set, false otherwise (a == null or zero length). public static bool ArrayMinMax( IList a, out double min, out double max ) { if ( a == null || a.Count == 0 ) { min = 0.0; max = 0.0; return false; } min = Utils.ToDouble(a[0]); max = Utils.ToDouble(a[0]); foreach ( object o in a ) { double e = Utils.ToDouble(o); if ( (min.Equals (double.NaN)) && (!e.Equals (double.NaN)) ) { // if min/max are double.NaN and the current value not, then // set them to the current value. min = e; max = e; } if (!double.IsNaN(e)) { if (e < min) { min = e; } if (e > max) { max = e; } } } if (min.Equals (double.NaN)) { // if min == double.NaN, then max is also double.NaN min = 0.0; max = 0.0; return false; } return true; } /// /// Returns the minimum and maximum values in a DataRowCollection. /// /// The row collection to search. /// The minimum value. /// The maximum value. /// The name of the column in the row collection to search over. /// true is min max set, false otherwise (a = null or zero length). public static bool RowArrayMinMax( DataRowCollection rows, out double min, out double max, string columnName ) { // double[] is a reference type and can be null, if it is then I reckon the best // values for min and max are also null. double is a value type so can't be set // to null. So min an max return object, and we understand that if it is not null // it is a boxed double (same trick I use lots elsewhere in the lib). The // wonderful comment I didn't write at the top should explain everything. if ( rows == null || rows.Count == 0 ) { min = 0.0; max = 0.0; return false; } min = Utils.ToDouble( (rows[0])[columnName] ); max = Utils.ToDouble( (rows[0])[columnName] ); foreach ( DataRow r in rows ) { double e = Utils.ToDouble( r[columnName] ); if ( (min.Equals (double.NaN)) && (!e.Equals (double.NaN)) ) { // if min/max are double.NaN and the current value not, then // set them to the current value. min = e; max = e; } if (!double.IsNaN(e)) { if (e < min) { min = e; } if (e > max) { max = e; } } } if (min.Equals (double.NaN)) { // if min == double.NaN, then max is also double.NaN min = 0.0; max = 0.0; return false; } return true; } /// /// Returns the minimum and maximum values in a DataView. /// /// The DataView to search. /// The minimum value. /// The maximum value. /// The name of the column in the row collection to search over. /// true is min max set, false otherwise (a = null or zero length). public static bool DataViewArrayMinMax( DataView data, out double min, out double max, string columnName ) { // double[] is a reference type and can be null, if it is then I reckon the best // values for min and max are also null. double is a value type so can't be set // to null. So min an max return object, and we understand that if it is not null // it is a boxed double (same trick I use lots elsewhere in the lib). The // wonderful comment I didn't write at the top should explain everything. if ( data == null || data.Count == 0 ) { min = 0.0; max = 0.0; return false; } min = Utils.ToDouble( (data[0])[columnName] ); max = Utils.ToDouble( (data[0])[columnName] ); for (int i=0; i max) { max = e; } } return true; } /// /// Returns unit vector along the line a->b. /// /// line start point. /// line end point. /// The unit vector along the specified line. public static PointF UnitVector( PointF a, PointF b ) { PointF dir = new PointF( b.X - a.X, b.Y - a.Y ); double dirNorm = System.Math.Sqrt( dir.X*dir.X + dir.Y*dir.Y ); if ( dirNorm > 0.0f ) { dir = new PointF( (float)((1.0f/dirNorm)*dir.X), (float)((1.0f/dirNorm)*dir.Y) ); // normalised axis direction vector } return dir; } /// /// Get a Font exactly the same as the passed in one, except for scale factor. /// /// The font to scale. /// Scale by this factor. /// The scaled font. public static Font ScaleFont( Font initial, double scale ) { FontStyle fs = initial.Style; GraphicsUnit gu = initial.Unit; double sz = initial.Size; sz = sz * scale ; string nm = initial.Name; return new Font( nm, (float)sz, fs, gu ); } /// /// Creates a bitmap from another that is tiled size times in each direction. /// /// bitmap to tile /// number of times to tile in each direction. /// the tiled bitmap. public static System.Drawing.Bitmap TiledImage( System.Drawing.Bitmap image, Size size ) { System.Drawing.Bitmap final = new System.Drawing.Bitmap( size.Width, size.Height ); for (int i=0; i<(size.Width / image.Width)+1; ++i) { for (int j=0; j<(size.Height / image.Height)+1; ++j) { Graphics.FromImage( final ).DrawImage( image, i*image.Width, j*image.Height ); } } return final; } } } nplot-gtk-0.9.9.2/lib/VerticalLine.cs0000644000175000017500000001704510512404106017764 0ustar carlosblecarlosble/* NPlot - A charting library for .NET VerticalLine.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 a vertical line on a plot surface. /// public class VerticalLine : IPlot { /// /// Constructor /// /// abscissa (X) value of line. public VerticalLine( double abscissaValue ) { this.value_ = abscissaValue; } /// /// Constructor /// /// abscissa (X) value of line. /// draw the line using this color. public VerticalLine( double abscissaValue, Color color ) { this.value_ = abscissaValue; this.pen_ = new Pen( color ); } /// /// Constructor /// /// abscissa (X) value of line. /// Pen to use to draw the line. public VerticalLine( double abscissaValue, Pen pen ) { this.value_ = abscissaValue; this.pen_ = pen; } /// /// Draws a representation of the line 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(System.Drawing.Graphics g, System.Drawing.Rectangle startEnd) { g.DrawLine( pen_, startEnd.Left, (startEnd.Top + startEnd.Bottom)/2, startEnd.Right, (startEnd.Top + startEnd.Bottom)/2 ); } /// /// A label to associate with the plot - used in the legend. /// public string Label { get { return label_; } set { this.label_ = value; } } private string label_ = ""; /// /// Whether or not to include an entry for this plot in the legend if it exists. /// public bool ShowInLegend { get { return showInLegend_; } set { this.showInLegend_ = value; } } private bool showInLegend_ = false; /// /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { return new LinearAxis( value_, value_ ); } /// /// Returns null indicating that y extremities of the line are variable. /// /// null public Axis SuggestYAxis() { return null; } /// /// Writes text data describing the vertical line object to the supplied string builder. It is /// possible to specify that the data will be written only if the line is in the specified /// region. /// /// the StringBuilder object to write to. /// a region used if onlyInRegion is true. /// If true, data will be written only if the line is in the specified region. public void WriteData(System.Text.StringBuilder sb, RectangleD region, bool onlyInRegion) { // return if line is not in plot region and if (value_ > region.X+region.Width || value_ < region.X) { if (onlyInRegion) { return; } } sb.Append( "Label: " ); sb.Append( this.Label ); sb.Append( "\r\n" ); sb.Append( value_.ToString() ); sb.Append( "\r\n" ); } /// /// Draws the vertical line 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 void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { int yMin = yAxis.PhysicalMin.Y; int yMax = yAxis.PhysicalMax.Y; yMin -= pixelIndent_; yMax += pixelIndent_; float length = Math.Abs(yMax - yMin); float lengthDiff = length - length*scale_; float indentAmount = lengthDiff/2; yMin -= (int)indentAmount; yMax += (int)indentAmount; int xPos = (int)xAxis.WorldToPhysical( value_, false ).X; g.DrawLine( pen_, new System.Drawing.Point( xPos, yMin ), new System.Drawing.Point( xPos, yMax ) ); // todo: clip and proper logic for flipped axis min max. } /// /// abscissa (X) value to draw horizontal line at. /// public double AbscissaValue { get { return value_; } set { value_ = value; } } /// /// Pen to use to draw the horizontal line. /// public Pen Pen { get { return pen_; } set { pen_ = value; } } private double value_; private Pen pen_ = new Pen( Color.Black ); /// /// Each end of the line is indented by this many pixels. /// public int PixelIndent { get { return pixelIndent_; } set { pixelIndent_ = value; } } private int pixelIndent_ = 0; /// /// The line length is multiplied by this amount. Default /// corresponds to a value of 1.0. /// public float LengthScale { get { return scale_; } set { scale_ = value; } } private float scale_ = 1.0f; } } nplot-gtk-0.9.9.2/lib/Web.Design.PlotSurface2D.cs0000644000175000017500000001010510512404106021732 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Web.PlotSurface2d.cs Copyright (C) 2003 Matt Howlett, Paolo Pierini Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Imaging; using System.IO; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel; using NPlot; namespace NPlot { namespace Web { namespace Design { /// /// The Design Time rendered for the NPlot.web.PlotSurface2D control. /// public class PlotSurface2D : System.Web.UI.Design.ControlDesigner { /// /// The design time generated HTML for the control. /// /// A string containing the HTML rendering. public override string GetDesignTimeHtml() { // Extremely simple design time rendering! // will work on something better sooner or later. // This acts as a placeholder. Web.PlotSurface2D plot = (Web.PlotSurface2D)Component; int xs = Convert.ToInt32(plot.Width.Value); if ( xs < 1 ) return ""; int ys = Convert.ToInt32(plot.Height.Value); if ( ys < 1 ) return ""; StringWriter sw = new StringWriter(); HtmlTextWriter output= new HtmlTextWriter(sw); output.AddAttribute("border",plot.BorderWidth.ToString()); output.AddAttribute("borderColor",plot.BorderColor.ToKnownColor().ToString()); output.AddAttribute("cellSpacing","0"); output.AddAttribute("cellPadding","0"); output.AddAttribute("width",xs.ToString()); output.RenderBeginTag("table "); output.RenderBeginTag("tr"); output.AddAttribute("vAlign","center"); output.AddAttribute("align","middle"); output.AddAttribute("height",ys.ToString()); output.RenderBeginTag("td"); output.RenderBeginTag("P"); output.Write("PlotSurface2D:" + plot.Title); output.RenderEndTag(); output.RenderEndTag(); output.RenderEndTag(); output.RenderEndTag(); output.Flush(); return sw.ToString(); } } } } } nplot-gtk-0.9.9.2/lib/Web.PlotSurface2D.cs0000644000175000017500000004053010512404106020527 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Web.PlotSurface2d.cs Copyright (C) 2003 Matt Howlett, Paolo Pierini Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Imaging; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel; using System.IO; using System.Collections; using System.Text; namespace NPlot { namespace Web { /// /// A PlotSurface2D web control. Rather than use this control, I generally create bitmaps /// using Bitmap.PlotSurface2D, then use the ToBrowser() method in Bitmap.PlotSurface2D to /// return them as a page request response (and point the src in an image tag to this page). /// /// This is not as nice from a users perspective but is more efficient. /// /// Note: this control can chew up memory until the user session ends if the client cancels /// the page load before the image has loaded. /// [ DefaultProperty("Title"), ToolboxData("<{0}:PlotSurface2D runat=server>"), Designer(typeof(NPlot.Web.Design.PlotSurface2D)) ] public class PlotSurface2D : System.Web.UI.WebControls.WebControl, IPlotSurface2D { private NPlot.PlotSurface2D ps_ = new NPlot.PlotSurface2D(); /// /// Default constructor. /// public PlotSurface2D() : base() { } /// /// The URL to redirect for the plot. /// private string plotUrl; /// /// the prefix used for the session variables /// private string prefix() { string toReturn = "__PlotSurface2D_"; toReturn += this.ClientID; toReturn += "_"; toReturn += this.Page.ToString(); toReturn += "_"; return toReturn; } /// /// Clears the plot. /// public void Clear() { ps_.Clear(); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. public void Add( IDrawable p ) { ps_.Add( p ); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp ) { ps_.Add( p, xp, yp ); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, int zOrder ) { ps_.Add( p, zOrder ); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp, int zOrder ) { ps_.Add( p, xp, yp , zOrder); } /// /// The plot surface title. /// [ Browsable(true), Bindable(true) ] public string Title { get { return ps_.Title; } set { ps_.Title = value; } } /// /// The plot title font. /// [ Browsable(true) ] public System.Drawing.Font TitleFont { get { return ps_.TitleFont; } set { ps_.TitleFont = value; } } /// /// The distance in pixels to leave between of the edge of the bounding rectangle /// supplied to the Draw method, and the markings that make up the plot. /// [ Browsable(true), Category("Data"), Bindable(true) ] public int Padding { get { return ps_.Padding; } set { ps_.Padding = value; } } /// /// The first abscissa axis. /// [ Browsable(false), Bindable(false) ] public Axis XAxis1 { get { return ps_.XAxis1; } set { ps_.XAxis1 = value; } } /// /// The first ordinate axis. /// [ Browsable(false), Bindable(false) ] public Axis YAxis1 { get { return ps_.YAxis1; } set { ps_.YAxis1 = value; } } /// /// The second abscissa axis. /// [ Browsable(false), Bindable(false) ] public Axis XAxis2 { get { return ps_.XAxis2; } set { ps_.XAxis2 = value; } } /// /// The second ordinate axis. /// [ Browsable(false), Bindable(false) ] public Axis YAxis2 { get { return ps_.YAxis2; } set { ps_.YAxis2 = value; } } /// /// A color used to paint the plot background. Mutually exclusive with PlotBackImage and PlotBackBrush /// [ Bindable(true), Browsable(true) ] public System.Drawing.Color PlotBackColor { set { ps_.PlotBackColor = value; } } /// /// An imaged used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// public System.Drawing.Bitmap PlotBackImage { set { ps_.PlotBackImage = value; } } /// /// A Rectangle brush used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// public IRectangleBrush PlotBackBrush { set { ps_.PlotBackBrush = value; } } /// /// Gets or Sets the legend to use with this plot surface. /// [ Bindable(false), Browsable(false) ] public NPlot.Legend Legend { get { return ps_.Legend; } set { ps_.Legend = value; } } /// /// Gets or Sets the legend z-order. /// [ Bindable(true), Browsable(true) ] public int LegendZOrder { get { return ps_.LegendZOrder; } set { ps_.LegendZOrder = value; } } /// /// Smoothing mode to use when drawing plots. /// [ Bindable(true), Browsable(true) ] public System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get { return ps_.SmoothingMode; } set { ps_.SmoothingMode = value; } } /// /// The bitmap background color outside the bounds of the plot surface. /// [ Bindable(true), Browsable(true) ] public override Color BackColor { set { backColor_ = value; } } object backColor_ = null; /// /// Ivan Ivanov wrote this function. From his email: /// If the request string contains encoded parameters values [e.g. # - %23]. /// The call to request.Url.ToString() will decode values [e.g. instead of %23 /// it will return #]. On the subsequent request to the page that contains the /// nplot control [when the actual drawing of the image takes place] the request /// url will be cut up to the unformated value [e.g. #] and since the PlotSurface2D_ /// is added at the end of the query string, it will be missing. /// /// private String buildPlotURL() { StringBuilder urlParams = new StringBuilder(); foreach (string getParamName in Context.Request.QueryString.AllKeys) { urlParams.Append(getParamName + "=" + Context.Server.UrlEncode(Context.Request.QueryString[getParamName]) + "&"); } return Context.Request.Url.AbsolutePath + (urlParams.Length > 0 ? "?" + urlParams.Append("PlotSurface2D_" + this.ClientID + "=1").ToString() : "?PlotSurface2D_" + this.ClientID + "=1"); } /// /// Initialization event. /// /// protected override void OnInit(EventArgs e) { System.Web.HttpRequest request = Context.Request; System.Web.HttpResponse response = Context.Response; if (request.Params["PlotSurface2D_" + this.ClientID] != null) { // retrieve the bitmap and display response.Clear(); try { response.ContentType = "Image/Png"; System.Drawing.Bitmap bmp = (System.Drawing.Bitmap) Context.Session[prefix()+"PNG"]; // don't ask why, but if I write directly to the response // I have a GDI+ error, if I first write to a MemoryStream and // then to the response.OutputStream I don't get an error. System.IO.MemoryStream s = new System.IO.MemoryStream(); bmp.Save( s, System.Drawing.Imaging.ImageFormat.Png); s.WriteTo(response.OutputStream); Context.Session.Remove(prefix()+"PNG"); } catch (Exception ex) { response.ContentType = "Text/HTML"; response.Write( ex.Message ); } finally { response.Flush(); response.End(); } } this.plotUrl = this.buildPlotURL(); base.OnInit (e); } /// /// Render this control as an HTML stream. /// /// The HTML writer to write out to. protected override void Render(HtmlTextWriter output) { // first of all render the bitmap; System.Drawing.Bitmap b = new System.Drawing.Bitmap( (int)this.Width.Value, (int)this.Height.Value ); if (backColor_!=null) { Graphics g = Graphics.FromImage( b ); g.FillRectangle( (new Pen( (Color)this.backColor_)).Brush,0,0,b.Width,b.Height ); } ps_.Draw( Graphics.FromImage(b), new System.Drawing.Rectangle(0,0,b.Width,b.Height) ); // then store in context memory. Context.Session[prefix()+"PNG"] = b; // now render html. if (this.BorderStyle == BorderStyle.None) { output.AddAttribute("border","0"); } else { output.AddAttribute("border",this.BorderWidth.ToString()); output.AddAttribute("borderColor",this.BorderColor.ToKnownColor().ToString()); } output.AddAttribute("cellSpacing","0"); output.AddAttribute("cellPadding","0"); output.RenderBeginTag("table"); output.RenderBeginTag("tr"); output.AddAttribute("vAlign","center"); output.AddAttribute("align","middle"); output.RenderBeginTag("td"); output.RenderBeginTag("P"); output.AddAttribute("src",this.plotUrl); output.AddAttribute("alt",this.ToolTip); output.RenderBeginTag("img"); output.RenderEndTag(); output.RenderEndTag(); output.RenderEndTag(); output.RenderEndTag(); output.RenderEndTag(); output.Flush(); } /// /// Add an axis constraint to the plot surface. Axis constraints can /// specify relative world-pixel scalings, absolute axis positions etc. /// /// The axis constraint to add. public void AddAxesConstraint( AxesConstraint c ) { ps_.AddAxesConstraint( c ); } /// /// Whether or not the title will be scaled according to size of the plot /// surface. /// [ Browsable(true), Bindable(true) ] public bool AutoScaleTitle { get { return ps_.AutoScaleTitle; } set { ps_.AutoScaleTitle = value; } } /// /// When plots are added to the plot surface, the axes they are attached to /// are immediately modified to reflect data of the plot. If /// AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will /// be turned in to auto scaling ones if they are not already [tick marks, /// tick text and label size scaled to size of plot surface]. If false, /// axes will not be autoscaling. /// [ Browsable(true), Bindable(true), ] public bool AutoScaleAutoGeneratedAxes { get { return ps_.AutoScaleAutoGeneratedAxes; } set { ps_.AutoScaleAutoGeneratedAxes = value; } } /// /// Sets the title to be drawn using a solid brush of this color. /// [ Browsable(true), Bindable(true) ] public Color TitleColor { set { ps_.TitleColor = value; } } /// /// The brush used for drawing the title. /// [ Browsable(false) ] public Brush TitleBrush { get { return ps_.TitleBrush; } set { ps_.TitleBrush = value; } } /// /// Remove a drawable object from the plot surface. /// /// the drawable to remove /// whether or not to update the axes after removing the idrawable. public void Remove( IDrawable p, bool updateAxes ) { ps_.Remove( p, updateAxes ); } /// /// Gets an array list containing all drawables currently added to the PlotSurface2D. /// [ Browsable(false) ] public ArrayList Drawables { get { return ps_.Drawables; } } } } } nplot-gtk-0.9.9.2/lib/Windows.PlotSurface.cs0000644000175000017500000000476710512404106021272 0ustar carlosblecarlosbleusing System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; namespace NPlot.Windows { /// /// An all encompasing Windows.Forms PlotSurface. This class allows you /// to place a single control in your form layout and draw to any type of /// plot surface (PlotSurface2D, PlotSurface3D etc) on it. As there is only /// one type of plot surface currently, this /// class isn't necessary... but more a planned soon. /// Also, the implementation isn't finished. /// public class PlotSurface : System.Windows.Forms.UserControl { /// /// control resize handler. /// /// event args. protected override void OnResize( EventArgs e ) { this.Refresh(); base.OnResize(e); } /// /// control paint handler. /// /// paint event args. protected override void OnPaint( PaintEventArgs pe ) { surface_.DoPaint( pe, this.Width, this.Height ); base.OnPaint(pe); } /// /// Mouse down event handler. /// /// mouse event args protected override void OnMouseDown(MouseEventArgs e) { surface_.DoMouseDown(e); base.OnMouseDown(e); } /// /// Mouse Up event handler. /// /// mouse event args. protected override void OnMouseUp(MouseEventArgs e) { surface_.DoMouseUp(e, this); base.OnMouseUp(e); } /// /// Mouse Move event handler. /// /// mouse event args. protected override void OnMouseMove(MouseEventArgs e) { surface_.DoMouseMove(e, this); base.OnMouseMove(e); } /* enum Type { PlotSurface2D, PlotSurface2Dnew, PlotSurface3D, PieChart } */ ISurface surface_ = null; /// /// Gets the underlying plot surface. /// public ISurface Surface { get { return surface_; } } /// /// Constructor. /// public PlotSurface() { // double buffer, and update when resize. base.SetStyle(ControlStyles.AllPaintingInWmPaint, true); base.SetStyle(ControlStyles.DoubleBuffer, true); base.SetStyle(ControlStyles.UserPaint, true); base.ResizeRedraw = true; surface_ = new NPlot.Windows.PlotSurface2D(); } } } nplot-gtk-0.9.9.2/lib/Windows.PlotSurface.resx0000644000175000017500000000330510512404106021631 0ustar carlosblecarlosble text/microsoft-resx 1.0.0.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 nplot-gtk-0.9.9.2/lib/Windows.PlotSurface2D.cs0000644000175000017500000026152610512404106021456 0ustar carlosblecarlosble/* NPlot - A charting library for .NET Windows.PlotSurface2d.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.Drawing.Printing; using NPlot; namespace NPlot.Windows { /// /// A Windows.Forms PlotSurface2D control. /// /// /// Unfortunately it's not possible to derive from both Control and NPlot.PlotSurface2D. /// [ ToolboxBitmapAttribute(typeof(NPlot.Windows.PlotSurface2D),"PlotSurface2D.ico") ] public class PlotSurface2D : System.Windows.Forms.Control, IPlotSurface2D, ISurface { private System.Windows.Forms.ToolTip coordinates_; private System.Collections.ArrayList selectedObjects_; private NPlot.PlotSurface2D ps_; private Axis xAxis1ZoomCache_; private Axis yAxis1ZoomCache_; private Axis xAxis2ZoomCache_; private Axis yAxis2ZoomCache_; /// /// Flag to display a coordinates in a tooltip. /// [ Category("PlotSurface2D"), Description("Whether or not to show coordinates in a tool tip when the mouse hovers above the plot area."), Browsable(true), Bindable(true) ] public bool ShowCoordinates { get { return this.coordinates_.Active; } set { this.coordinates_.Active = value; } } /// /// Default constructor. /// public PlotSurface2D() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // double buffer, and update when resize. base.SetStyle(ControlStyles.AllPaintingInWmPaint, true); base.SetStyle(ControlStyles.DoubleBuffer, true); base.SetStyle(ControlStyles.UserPaint, true); base.ResizeRedraw = true; ps_ = new NPlot.PlotSurface2D(); this.InteractionOccured += new InteractionHandler( OnInteractionOccured ); this.PreRefresh += new PreRefreshHandler( OnPreRefresh ); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// /// Modified! :-) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.coordinates_ = new System.Windows.Forms.ToolTip(this.components); // // PlotSurface2D // this.BackColor = System.Drawing.SystemColors.ControlLightLight; this.Size = new System.Drawing.Size(328, 272); } KeyEventArgs lastKeyEventArgs_ = null; /// /// the key down callback /// /// information pertaining to the event protected override void OnKeyDown(KeyEventArgs e) { lastKeyEventArgs_ = e; } /// /// The key up callback. /// /// information pertaining to the event protected override void OnKeyUp(KeyEventArgs e) { lastKeyEventArgs_ = e; } /// /// the paint event callback. /// /// the PaintEventArgs protected override void OnPaint( PaintEventArgs pe ) { DoPaint( pe, this.Width, this.Height ); base.OnPaint(pe); } /// /// All functionality of the OnPaint method is provided by this function. /// This allows use of the all encompasing PlotSurface. /// /// the PaintEventArgs from paint event. /// width of the control /// height of the control public void DoPaint( PaintEventArgs pe, int width, int height ) { this.PreRefresh(this); foreach (Interactions.Interaction i in interactions_) { i.DoPaint(pe,width,height); } /* // make sure don't redraw after a refresh. this.horizontalBarPos_ = -1; this.verticalBarPos_ = -1; */ Graphics g = pe.Graphics; Rectangle border = new Rectangle( 0, 0, width, height ); if ( g == null ) { throw (new NPlotException("null graphics context!")); } if ( ps_ == null ) { throw (new NPlotException("null NPlot.PlotSurface2D")); } if ( border == Rectangle.Empty ) { throw (new NPlotException("null border context")); } this.Draw( g, border ); } /// /// Draws the plot surface on the supplied graphics surface [not the control surface]. /// /// The graphics surface on which to draw /// A bounding box on this surface that denotes the area on the /// surface to confine drawing to. public void Draw( Graphics g, Rectangle bounds ) { // If we are not in design mode then draw as normal. if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) { this.drawDesignMode( g, bounds ); } ps_.Draw( g, bounds ); } /// /// Draw a lightweight representation of us for design mode. /// private void drawDesignMode( Graphics g, Rectangle bounds ) { g.DrawRectangle( new Pen(Color.Black), bounds.X + 2, bounds.Y + 2, bounds.Width-4, bounds.Height-4 ); g.DrawString( "PlotSurface2D: " + this.Title, this.TitleFont, this.TitleBrush, bounds.X + bounds.Width/2.0f, bounds.Y + bounds.Height/2.0f ); } /// /// Clears the plot and resets to default values. /// public void Clear() { xAxis1ZoomCache_ = null; yAxis1ZoomCache_ = null; xAxis2ZoomCache_ = null; yAxis2ZoomCache_ = null; ps_.Clear(); interactions_.Clear(); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. public void Add( IDrawable p ) { ps_.Add( p ); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp ) { ps_.Add( p, xp, yp ); } /// /// Adds a drawable object to the plot surface. If the object is an IPlot, /// the PlotSurface2D axes will also be updated. /// /// The IDrawable object to add to the plot surface. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, int zOrder ) { ps_.Add( p, zOrder ); } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against. /// The z-ordering when drawing (objects with lower numbers are drawn first) public void Add( IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp, int zOrder ) { ps_.Add( p, xp, yp , zOrder); } /// /// Gets or Sets the legend to use with this plot surface. /// [ Browsable(false), Bindable(false) ] public NPlot.Legend Legend { get { return ps_.Legend; } set { ps_.Legend = value; } } /// /// Gets or Sets the legend z-order. /// [ Browsable(true), Bindable(true), Category("PlotSurface2D"), Description("Determines the order with respect to other IDrawables on the plot surface in which the legend is drawn. " + "The higher this value, the higher the position in the draw order." ) ] public int LegendZOrder { get { return ps_.LegendZOrder; } set { ps_.LegendZOrder = value; } } /// /// Whether or not the title will be scaled according to size of the plot /// surface. /// [ Browsable(true), Bindable(true), Description("Whether or not the title will be scaled according to size of the plot surface."), Category("PlotSurface2D") ] public bool AutoScaleTitle { get { return ps_.AutoScaleTitle; } set { ps_.AutoScaleTitle = value; } } /// /// When plots are added to the plot surface, the axes they are attached to /// are immediately modified to reflect data of the plot. If /// AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will /// be turned in to auto scaling ones if they are not already [tick marks, /// tick text and label size scaled to size of plot surface]. If false, /// axes will not be autoscaling. /// [ Browsable(true), Bindable(true), Description( "When plots are added to the plot surface, the axes they are attached to are immediately modified " + "to reflect data of the plot. If AutoScaleAutoGeneratedAxes is true when a plot is added, the axes will be " + "turned in to auto scaling ones if they are not already [tick marks, tick text and label size scaled to size " + "of plot surface]. If false, axes will not be autoscaling." ), Category("PlotSurface2D") ] public bool AutoScaleAutoGeneratedAxes { get { return ps_.AutoScaleAutoGeneratedAxes; } set { ps_.AutoScaleAutoGeneratedAxes = value; } } /// /// The plot surface title. /// [ Category("PlotSurface2D"), Description("The plot surface title"), Browsable(true), Bindable(true) ] public string Title { get { return ps_.Title; } set { ps_.Title = value; //helpful in design view. But crap in applications! //this.Refresh(); } } /// /// The font used to draw the title. /// [ Category("PlotSurface2D"), Description("The font used to draw the title."), Browsable(true), Bindable(false) ] public Font TitleFont { get { return ps_.TitleFont; } set { ps_.TitleFont = value; } } /// /// Padding of this width will be left between what is drawn and the control border. /// [ Category("PlotSurface2D"), Description("Padding of this width will be left between what is drawn and the control border."), Browsable(true), Bindable(true) ] public int Padding { get { return ps_.Padding; } set { ps_.Padding = value; } } /// /// The first abscissa axis. /// /// [ Browsable(false) ] public Axis XAxis1 { get { return ps_.XAxis1; } set { ps_.XAxis1 = value; } } /// /// The first ordinate axis. /// [ Browsable(false) ] public Axis YAxis1 { get { return ps_.YAxis1; } set { ps_.YAxis1 = value; } } /// /// The second abscissa axis. /// [ Browsable(false) ] public Axis XAxis2 { get { return ps_.XAxis2; } set { ps_.XAxis2 = value; } } /// /// The second ordinate axis. /// [ Browsable(false) ] public Axis YAxis2 { get { return ps_.YAxis2; } set { ps_.YAxis2 = value; } } /// /// The physical XAxis1 that was last drawn. /// [ Browsable(false) ] public PhysicalAxis PhysicalXAxis1Cache { get { return ps_.PhysicalXAxis1Cache; } } /// /// The physical YAxis1 that was last drawn. /// [ Browsable(false) ] public PhysicalAxis PhysicalYAxis1Cache { get { return ps_.PhysicalYAxis1Cache; } } /// /// The physical XAxis2 that was last drawn. /// [ Browsable(false) ] public PhysicalAxis PhysicalXAxis2Cache { get { return ps_.PhysicalXAxis2Cache; } } /// /// The physical YAxis2 that was last drawn. /// [ Browsable(false) ] public PhysicalAxis PhysicalYAxis2Cache { get { return ps_.PhysicalYAxis2Cache; } } /// /// A color used to paint the plot background. Mutually exclusive with PlotBackImage and PlotBackBrush /// /// not browsable or bindable because only set method. [ Category("PlotSurface2D"), Description("Set the plot background color."), Browsable(true), Bindable(false) ] public System.Drawing.Color PlotBackColor { set { ps_.PlotBackColor = value; } } /// /// An imaged used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// /// not browsable or bindable because only set method. [ Browsable(false), Bindable(false) ] public System.Drawing.Bitmap PlotBackImage { set { ps_.PlotBackImage = value; } } /// /// A Rectangle brush used to paint the plot background. Mutually exclusive with PlotBackColor and PlotBackBrush /// /// not browsable or bindable because only set method. [ Browsable(false), Bindable(false) ] public IRectangleBrush PlotBackBrush { set { ps_.PlotBackBrush = value; } } /// /// Sets the title to be drawn using a solid brush of this color. /// /// not browsable or bindable because only set method. [ Browsable(false), Bindable(false) ] public Color TitleColor { set { ps_.TitleColor = value; } } /// /// The brush used for drawing the title. /// [ Browsable(true), Bindable(true), Description("The brush used for drawing the title."), Category("PlotSurface2D") ] public Brush TitleBrush { get { return ps_.TitleBrush; } set { ps_.TitleBrush = value; } } /// /// Set smoothing mode for drawing plot objects. /// [ Category("PlotSurface2D"), Description("Set smoothing mode for drawing plot objects."), Browsable(true), Bindable(true) ] public System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get { return ps_.SmoothingMode; } set { ps_.SmoothingMode = value; } } /// /// Mouse down event handler. /// /// the event args. protected override void OnMouseDown(MouseEventArgs e) { DoMouseDown(e); base.OnMouseDown(e); } /// /// All functionality of the OnMouseDown function is contained here. /// This allows use of the all encompasing PlotSurface. /// /// The mouse event args from the window we are drawing to. public void DoMouseDown( MouseEventArgs e ) { bool dirty = false; foreach (Interactions.Interaction i in interactions_) { i.DoMouseDown(e,this); dirty |= i.DoMouseDown(e,this); } if (dirty) { Refresh(); } } /// /// Mouse Wheel event handler. /// /// the event args protected override void OnMouseWheel( System.Windows.Forms.MouseEventArgs e ) { DoMouseWheel(e); base.OnMouseWheel(e); } /// /// All functionality of the OnMouseWheel function is containd here. /// This allows use of the all encompasing PlotSurface. /// /// the event args. public void DoMouseWheel(MouseEventArgs e) { bool dirty = false; foreach (Interactions.Interaction i in interactions_) { i.DoMouseWheel(e, this); dirty |= i.DoMouseWheel(e, this); } if (dirty) { Refresh(); } } /// /// All functionality of the OnMouseMove function is contained here. /// This allows use of the all encompasing PlotSurface. /// /// The mouse event args from the window we are drawing to. /// The control that the mouse event happened in. public void DoMouseMove( MouseEventArgs e, System.Windows.Forms.Control ctr ) { bool dirty = false; foreach (Interactions.Interaction i in interactions_) { i.DoMouseMove(e, ctr, lastKeyEventArgs_); dirty |= i.DoMouseMove(e, ctr, lastKeyEventArgs_); } if (dirty) { Refresh(); } // Update coordinates if necessary. if ( coordinates_.Active ) { // we are here Point here = new Point( e.X, e.Y ); if ( ps_.PlotAreaBoundingBoxCache.Contains(here) ) { coordinates_.ShowAlways = true; // according to Mns Erlandson, this can sometimes be the case. if (this.PhysicalXAxis1Cache == null) return; if (this.PhysicalYAxis1Cache == null) return; double x = this.PhysicalXAxis1Cache.PhysicalToWorld( here, true ); double y = this.PhysicalYAxis1Cache.PhysicalToWorld( here, true ); string s = ""; if (!DateTimeToolTip) { s = "(" + x.ToString("g4") + "," + y.ToString("g4") + ")"; } else { DateTime dateTime = new DateTime((long)x); s = dateTime.ToShortDateString() + " " + dateTime.ToLongTimeString() + Environment.NewLine + y.ToString("f4"); } coordinates_.SetToolTip( this, s ); } else { coordinates_.ShowAlways = false; } } } /// /// MouseMove event handler. /// /// The event arguments. protected override void OnMouseMove(MouseEventArgs e) { DoMouseMove( e, this ); base.OnMouseMove( e ); } /// /// MouseLeave event handler. It has to invalidate the control to get rid of /// any remnant of vertical and horizontal guides. /// /// The event arguments. protected override void OnMouseLeave(EventArgs e) { DoMouseLeave( e, this ); base.OnMouseLeave(e); } /// /// /// /// /// public void DoMouseLeave(EventArgs e, System.Windows.Forms.Control ctr) { bool dirty = false; foreach (Interactions.Interaction i in interactions_) { dirty = i.DoMouseLeave(e, this) || dirty; } if (dirty) Refresh(); } /// /// When true, tool tip will display x value as a DateTime. Quick hack - this will probably be /// changed at some point. /// [ Bindable(true), Browsable(true), Category("PlotSurface2D"), Description("When true, tool tip will display x value as a DateTime. Quick hack - this will probably be changed at some point.") ] public bool DateTimeToolTip { get { return dateTimeToolTip_; } set { dateTimeToolTip_ = value; } } private bool dateTimeToolTip_ = false; /// /// All functionality of the OnMouseUp function is contained here. /// This allows use of the all encompasing PlotSurface. /// /// The mouse event args from the window we are drawing to. /// The control that the mouse event happened in. public void DoMouseUp( MouseEventArgs e, System.Windows.Forms.Control ctr ) { bool dirty = false; ArrayList local_interactions = (ArrayList)interactions_.Clone(); foreach (Interactions.Interaction i in local_interactions) { dirty |= i.DoMouseUp(e,ctr); } if (dirty) { Refresh(); } if (e.Button == MouseButtons.Right) { Point here = new Point(e.X, e.Y); selectedObjects_ = ps_.HitTest(here); if (rightMenu_ != null) rightMenu_.Menu.Show(ctr, here); } } /// /// mouse up event handler. /// /// The event arguments. protected override void OnMouseUp( MouseEventArgs e ) { DoMouseUp(e, this); base.OnMouseUp(e); } /// /// sets axes to be those saved in the cache. /// public void OriginalDimensions() { if ( xAxis1ZoomCache_ != null ) { this.XAxis1 = xAxis1ZoomCache_; this.XAxis2 = xAxis2ZoomCache_; this.YAxis1 = yAxis1ZoomCache_; this.YAxis2 = yAxis2ZoomCache_; xAxis1ZoomCache_ = null; xAxis2ZoomCache_ = null; yAxis1ZoomCache_ = null; yAxis2ZoomCache_ = null; } this.Refresh(); } private void DrawHorizontalSelection(Point start, Point end, System.Windows.Forms.UserControl ctr) { // the clipping rectangle in screen coordinates Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps_.PlotAreaBoundingBoxCache.X, (int)ps_.PlotAreaBoundingBoxCache.Y, (int)ps_.PlotAreaBoundingBoxCache.Width, (int)ps_.PlotAreaBoundingBoxCache.Height)); start = ctr.PointToScreen(start); end = ctr.PointToScreen(end); ControlPaint.FillReversibleRectangle( new Rectangle((int)Math.Min(start.X,end.X), (int)clip.Y, (int)Math.Abs(end.X-start.X), (int)clip.Height), Color.White ); } /// /// Add an axis constraint to the plot surface. Axis constraints can /// specify relative world-pixel scalings, absolute axis positions etc. /// /// The axis constraint to add. public void AddAxesConstraint( AxesConstraint c ) { ps_.AddAxesConstraint( c ); } /// /// Print the chart as currently shown by the control /// /// If true, show print preview window. public void Print( bool preview ) { PrintDocument printDocument = new PrintDocument(); printDocument.PrintPage += new PrintPageEventHandler(NPlot_PrintPage); printDocument.DefaultPageSettings.Landscape = true; DialogResult result; if (!preview) { PrintDialog dlg = new PrintDialog(); dlg.Document = printDocument; result = dlg.ShowDialog(); } else { PrintPreviewDialog dlg = new PrintPreviewDialog(); dlg.Document = printDocument; result = dlg.ShowDialog(); } if (result == DialogResult.OK) { try { printDocument.Print(); } catch { Console.WriteLine( "caught\n" ); } } } private void NPlot_PrintPage(object sender, PrintPageEventArgs ev) { Rectangle r = ev.MarginBounds; this.Draw( ev.Graphics, r ); ev.HasMorePages = false; } /// /// Coppies the chart currently shown in the control to the clipboard as an image. /// public void CopyToClipboard() { System.Drawing.Bitmap b = new System.Drawing.Bitmap( this.Width, this.Height ); System.Drawing.Graphics g = Graphics.FromImage( b ); g.Clear(Color.White); this.Draw( g, new Rectangle( 0, 0, b.Width-1, b.Height-1 ) ); Clipboard.SetDataObject( b, true ); } /// /// Coppies data in the current plot surface view window to the clipboard /// as text. /// public void CopyDataToClipboard() { System.Text.StringBuilder sb = new System.Text.StringBuilder(); for (int i=0; i /// Remove a drawable object from the plot surface. /// /// the drawable to remove /// whether or not to update the axes after removing the idrawable. public void Remove(IDrawable p, bool updateAxes) { ps_.Remove(p, updateAxes); } /// /// Gets an array list containing all drawables currently added to the PlotSurface2D. /// [ Browsable(false), Bindable(false) ] public ArrayList Drawables { get { return ps_.Drawables; } } /// /// Sets the right context menu. Custom menus can be designed by overriding /// NPlot.Windows.PlotSurface2D.ContextMenu. /// [ Browsable(false), Bindable(false) ] public NPlot.Windows.PlotSurface2D.PlotContextMenu RightMenu { get { return rightMenu_; } set { rightMenu_ = value; if (rightMenu_ != null) { rightMenu_.PlotSurface2D = this; } } } private NPlot.Windows.PlotSurface2D.PlotContextMenu rightMenu_ = null; /// /// Gets an instance of a NPlot.Windows.PlotSurface2D.ContextMenu that /// is useful in typical situations. /// public static PlotContextMenu DefaultContextMenu { get { return new NPlot.Windows.PlotSurface2D.PlotContextMenu(); } } /// /// Allows access to the PlotSurface2D. /// [ Browsable(false), Bindable(false) ] public NPlot.PlotSurface2D Inner { get { return ps_; } } /// /// Remembers the current axes - useful in interactions. /// public void CacheAxes() { if (xAxis1ZoomCache_ == null && xAxis2ZoomCache_ == null && yAxis1ZoomCache_ == null && yAxis2ZoomCache_ == null) { if (this.XAxis1 != null) { xAxis1ZoomCache_ = (Axis)this.XAxis1.Clone(); } if (this.XAxis2 != null) { xAxis2ZoomCache_ = (Axis)this.XAxis2.Clone(); } if (this.YAxis1 != null) { yAxis1ZoomCache_ = (Axis)this.YAxis1.Clone(); } if (this.YAxis2 != null) { yAxis2ZoomCache_ = (Axis)this.YAxis2.Clone(); } } } /// /// Encapsulates a number of separate "Interactions". An interaction is basically /// a set of handlers for mouse and keyboard events that work together in a /// specific way. /// public abstract class Interactions { /// /// Base class for an interaction. All methods are virtual. Not abstract as not all interactions /// need to use all methods. Default functionality for each method is to do nothing. /// public class Interaction { /// /// Handler for this interaction if a mouse down event is received. /// /// event args /// reference to the control /// true if plot surface needs refreshing. public virtual bool DoMouseDown(MouseEventArgs e, System.Windows.Forms.Control ctr) { return false; } /// /// Handler for this interaction if a mouse up event is received. /// /// event args /// reference to the control /// true if plot surface needs refreshing. public virtual bool DoMouseUp(MouseEventArgs e, System.Windows.Forms.Control ctr) { return false; } /// /// Handler for this interaction if a mouse move event is received. /// /// event args /// reference to the control /// /// true if plot surface needs refreshing. public virtual bool DoMouseMove(MouseEventArgs e, System.Windows.Forms.Control ctr, KeyEventArgs lastKeyEventArgs) { return false; } /// /// Handler for this interaction if a mouse move event is received. /// /// event args /// reference to the control /// true if plot surface needs refreshing. public virtual bool DoMouseWheel(MouseEventArgs e, System.Windows.Forms.Control ctr) { return false; } /// /// Handler for this interaction if a mouse Leave event is received. /// /// event args /// reference to the control /// true if the plot surface needs refreshing. public virtual bool DoMouseLeave(EventArgs e, System.Windows.Forms.Control ctr) { return false; } /// /// Handler for this interaction if a paint event is received. /// /// paint event args /// /// public virtual void DoPaint(PaintEventArgs pe, int width, int height) { } } #region RubberBandSelection /// /// /// public class RubberBandSelection : Interaction { private bool selectionInitiated_ = false; /// /// /// /// /// public override bool DoMouseDown(MouseEventArgs e, Control ctr) { // keep track of the start point and flag that select initiated. selectionInitiated_ = true; startPoint_.X = e.X; startPoint_.Y = e.Y; // invalidate the end point endPoint_ = unset_; return false; } /// /// /// /// /// /// public override bool DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs) { if ((e.Button == MouseButtons.Left) && selectionInitiated_) { // we are here Point here = new Point(e.X, e.Y); // delete the previous box if (endPoint_ != unset_) { this.DrawRubberBand(startPoint_, endPoint_, ctr); } endPoint_ = here; // and redraw the last one this.DrawRubberBand(startPoint_, endPoint_, ctr); } return false; } /// /// /// /// /// public override bool DoMouseUp(MouseEventArgs e, Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; // handle left button (selecting region). if ((e.Button == MouseButtons.Left) && selectionInitiated_) { endPoint_.X = e.X; endPoint_.Y = e.Y; // flag stopped selecting. selectionInitiated_ = false; if (endPoint_ != unset_) { this.DrawRubberBand(startPoint_, endPoint_, ctr); } Point minPoint = new Point(0, 0); minPoint.X = Math.Min(startPoint_.X, endPoint_.X); minPoint.Y = Math.Min(startPoint_.Y, endPoint_.Y); Point maxPoint = new Point(0, 0); maxPoint.X = Math.Max(startPoint_.X, endPoint_.X); maxPoint.Y = Math.Max(startPoint_.Y, endPoint_.Y); Rectangle r = ps.PlotAreaBoundingBoxCache; if (minPoint != maxPoint && (r.Contains(minPoint) || r.Contains(maxPoint))) { ((Windows.PlotSurface2D)ctr).CacheAxes(); ((Windows.PlotSurface2D)ctr).PhysicalXAxis1Cache.SetWorldLimitsFromPhysical(minPoint, maxPoint); ((Windows.PlotSurface2D)ctr).PhysicalXAxis2Cache.SetWorldLimitsFromPhysical(minPoint, maxPoint); ((Windows.PlotSurface2D)ctr).PhysicalYAxis1Cache.SetWorldLimitsFromPhysical(maxPoint, minPoint); ((Windows.PlotSurface2D)ctr).PhysicalYAxis2Cache.SetWorldLimitsFromPhysical(maxPoint, minPoint); // reset the start/end points startPoint_ = unset_; endPoint_ = unset_; ((Windows.PlotSurface2D)ctr).InteractionOccured(this); return true; } } return false; } /// /// Draws a rectangle representing selection area. /// /// a corner of the rectangle. /// a corner of the rectangle diagonally opposite the first. /// The control to draw to - this may not be us, if we have /// been contained by a PlotSurface. private void DrawRubberBand(Point start, Point end, System.Windows.Forms.Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; Rectangle rect = new Rectangle(); // the clipping rectangle in screen coordinates Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height)); // convert to screen coords start = ctr.PointToScreen(start); end = ctr.PointToScreen(end); // now, "normalize" the rectangle if (start.X < end.X) { rect.X = start.X; rect.Width = end.X - start.X; } else { rect.X = end.X; rect.Width = start.X - end.X; } if (start.Y < end.Y) { rect.Y = start.Y; rect.Height = end.Y - start.Y; } else { rect.Y = end.Y; rect.Height = start.Y - end.Y; } rect = Rectangle.Intersect(rect, clip); ControlPaint.DrawReversibleFrame( new Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), Color.White, FrameStyle.Dashed); } private Point startPoint_ = new Point(-1, -1); private Point endPoint_ = new Point(-1, -1); // this is the condition for an unset point private Point unset_ = new Point(-1, -1); } #endregion #region HorizontalGuideline /// /// Horizontal line interaction /// public class HorizontalGuideline : Interaction { private int barPos_; private Color color_; /// /// Constructor /// public HorizontalGuideline() { color_ = Color.Black; } /// /// Constructor /// /// public HorizontalGuideline(Color lineColor) { color_ = lineColor; } /// /// /// /// /// /// public override void DoPaint(PaintEventArgs pe, int width, int height) { barPos_ = -1; } /// /// /// /// /// /// public override bool DoMouseMove(MouseEventArgs e, System.Windows.Forms.Control ctr, KeyEventArgs lastKeyEventArgs) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; // if mouse isn't in plot region, then don't draw horizontal line if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < (ps.PlotAreaBoundingBoxCache.Bottom-1)) { if (ps.PhysicalXAxis1Cache != null) { // the clipping rectangle in screen coordinates Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height)); Point p = ctr.PointToScreen(new Point(e.X, e.Y)); if (barPos_ != -1) { ControlPaint.DrawReversibleLine( new Point(clip.Left, barPos_), new Point(clip.Right, barPos_), color_); } if (p.Y < clip.Bottom && p.Y > clip.Top) { ControlPaint.DrawReversibleLine( new Point(clip.Left, p.Y), new Point(clip.Right, p.Y), color_); barPos_ = p.Y; } else { barPos_ = -1; } } } else { if (barPos_ != -1) { Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height) ); ControlPaint.DrawReversibleLine( new Point(clip.Left, barPos_), new Point(clip.Right, barPos_), color_); barPos_ = -1; } } return false; } /// /// /// /// /// /// public override bool DoMouseLeave(EventArgs e, System.Windows.Forms.Control ctr) { if (barPos_ != -1) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height)); ControlPaint.DrawReversibleLine( new Point(clip.Left, barPos_), new Point(clip.Right, barPos_), color_); barPos_ = -1; } return false; } } #endregion #region VerticalGuideline /// /// /// public class VerticalGuideline : Interaction { private int barPos_; private Color color_; /// /// /// public VerticalGuideline() { color_ = Color.Black; } /// /// /// /// public VerticalGuideline(Color lineColor) { color_ = lineColor; } /// /// /// /// /// /// public override void DoPaint(PaintEventArgs pe, int width, int height) { barPos_ = -1; } /// /// /// /// /// /// public override bool DoMouseMove(MouseEventArgs e, System.Windows.Forms.Control ctr, KeyEventArgs lastKeyEventArgs) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; // if mouse isn't in plot region, then don't draw horizontal line if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < (ps.PlotAreaBoundingBoxCache.Right-1) && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) { if (ps.PhysicalXAxis1Cache != null) { // the clipping rectangle in screen coordinates Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height)); Point p = ctr.PointToScreen(new Point(e.X, e.Y)); if (barPos_ != -1) { ControlPaint.DrawReversibleLine( new Point(barPos_, clip.Top), new Point(barPos_, clip.Bottom), color_); } if (p.X < clip.Right && p.X > clip.Left) { ControlPaint.DrawReversibleLine( new Point(p.X, clip.Top), new Point(p.X, clip.Bottom), color_); barPos_ = p.X; } else { barPos_ = -1; } } } else { if (barPos_ != -1) { Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height) ); ControlPaint.DrawReversibleLine( new Point(barPos_, clip.Top), new Point(barPos_, clip.Bottom), color_); barPos_ = -1; } } return false; } /// /// Handler for mouse leave event /// /// event args /// /// public override bool DoMouseLeave(EventArgs e, System.Windows.Forms.Control ctr) { if (barPos_ != -1) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height)); ControlPaint.DrawReversibleLine( new Point(barPos_, clip.Top), new Point(barPos_, clip.Bottom), color_); barPos_ = -1; } return false; } } #endregion #region HorizontalDrag /// /// /// public class HorizontalDrag : Interaction { /// /// /// /// /// public override bool DoMouseDown(MouseEventArgs e, Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < (ps.PlotAreaBoundingBoxCache.Right) && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) { dragInitiated_ = true; lastPoint_.X = e.X; lastPoint_.Y = e.Y; } return false; } /// /// /// /// /// /// public override bool DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if ((e.Button == MouseButtons.Left) && dragInitiated_) { int diffX = e.X - lastPoint_.X; ((Windows.PlotSurface2D)ctr).CacheAxes(); // original code was using PixelWorldLength of the physical axis // but it was not working for non-linear axes - the code below works // in all cases if (ps.XAxis1 != null) { Axis axis = ps.XAxis1; PointF pMin = ps.PhysicalXAxis1Cache.PhysicalMin; PointF pMax = ps.PhysicalXAxis1Cache.PhysicalMax; PointF physicalWorldMin = pMin; PointF physicalWorldMax = pMax; physicalWorldMin.X -= diffX; physicalWorldMax.X -= diffX; double newWorldMin = axis.PhysicalToWorld(physicalWorldMin, pMin, pMax, false); double newWorldMax = axis.PhysicalToWorld(physicalWorldMax, pMin, pMax, false); axis.WorldMin = newWorldMin; axis.WorldMax = newWorldMax; } if (ps.XAxis2 != null) { Axis axis = ps.XAxis2; PointF pMin = ps.PhysicalXAxis2Cache.PhysicalMin; PointF pMax = ps.PhysicalXAxis2Cache.PhysicalMax; PointF physicalWorldMin = pMin; PointF physicalWorldMax = pMax; physicalWorldMin.X -= diffX; physicalWorldMax.X -= diffX; double newWorldMin = axis.PhysicalToWorld(physicalWorldMin, pMin, pMax, false); double newWorldMax = axis.PhysicalToWorld(physicalWorldMax, pMin, pMax, false); axis.WorldMin = newWorldMin; axis.WorldMax = newWorldMax; } lastPoint_ = new Point(e.X, e.Y); ((Windows.PlotSurface2D)ctr).InteractionOccured(this); return true; } return false; } /// /// /// /// /// public override bool DoMouseUp(MouseEventArgs e, Control ctr) { if ((e.Button == MouseButtons.Left) && dragInitiated_) { lastPoint_ = unset_; dragInitiated_ = false; } return false; } private bool dragInitiated_ = false; private Point lastPoint_ = new Point(-1, -1); // this is the condition for an unset point private Point unset_ = new Point(-1, -1); } #endregion #region VerticalDrag /// /// /// public class VerticalDrag : Interaction { /// /// /// /// /// public override bool DoMouseDown(MouseEventArgs e, Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < (ps.PlotAreaBoundingBoxCache.Right) && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) { dragInitiated_ = true; lastPoint_.X = e.X; lastPoint_.Y = e.Y; } return false; } /// /// /// /// /// /// public override bool DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if ((e.Button == MouseButtons.Left) && dragInitiated_) { int diffY = e.Y - lastPoint_.Y; ((Windows.PlotSurface2D)ctr).CacheAxes(); if (ps.YAxis1 != null) { Axis axis = ps.YAxis1; PointF pMin = ps.PhysicalYAxis1Cache.PhysicalMin; PointF pMax = ps.PhysicalYAxis1Cache.PhysicalMax; PointF physicalWorldMin = pMin; PointF physicalWorldMax = pMax; physicalWorldMin.Y -= diffY; physicalWorldMax.Y -= diffY; double newWorldMin = axis.PhysicalToWorld(physicalWorldMin, pMin, pMax, false); double newWorldMax = axis.PhysicalToWorld(physicalWorldMax, pMin, pMax, false); axis.WorldMin = newWorldMin; axis.WorldMax = newWorldMax; } if (ps.YAxis2 != null) { Axis axis = ps.YAxis2; PointF pMin = ps.PhysicalYAxis2Cache.PhysicalMin; PointF pMax = ps.PhysicalYAxis2Cache.PhysicalMax; PointF physicalWorldMin = pMin; PointF physicalWorldMax = pMax; physicalWorldMin.Y -= diffY; physicalWorldMax.Y -= diffY; double newWorldMin = axis.PhysicalToWorld(physicalWorldMin, pMin, pMax, false); double newWorldMax = axis.PhysicalToWorld(physicalWorldMax, pMin, pMax, false); axis.WorldMin = newWorldMin; axis.WorldMax = newWorldMax; } lastPoint_ = new Point(e.X, e.Y); ((Windows.PlotSurface2D)ctr).InteractionOccured(this); return true; } return false; } /// /// /// /// /// public override bool DoMouseUp(MouseEventArgs e, Control ctr) { if ((e.Button == MouseButtons.Left) && dragInitiated_) { lastPoint_ = unset_; dragInitiated_ = false; } return false; } private bool dragInitiated_ = false; private Point lastPoint_ = new Point(-1, -1); // this is the condition for an unset point private Point unset_ = new Point(-1, -1); } #endregion #region HorizontalRangeSelection /// /// This plot intraction allows the user to select horizontal regions. /// public class HorizontalRangeSelection : Interaction { private bool selectionInitiated_ = false; private Point startPoint_ = new Point(-1, -1); private Point endPoint_ = new Point(-1, -1); private Point previousPoint_ = new Point(-1, -1); private Point unset_ = new Point(-1, -1); private int minimumPixelDistanceForSelect_ = 5; private double smallestAllowedRange_ = double.Epsilon * 100.0; /// /// Default constructor /// public HorizontalRangeSelection() { } /// /// Constructor /// /// the smallest distance between the selected xmin and xmax for the selection to be performed. public HorizontalRangeSelection( double smallestAllowedRange ) { this.smallestAllowedRange_ = smallestAllowedRange; } /// /// The minimum width of the selected region (in pixels) for the interaction to zoom. /// public int MinimumPixelDistanceForSelect { get { return minimumPixelDistanceForSelect_; } set { minimumPixelDistanceForSelect_ = value; } } /// /// The smallest range (distance between world min and world max) selectable. /// If a smaller region is selected, the selection will do nothing. /// public double SmallestAllowedRange { get { return smallestAllowedRange_; } set { smallestAllowedRange_ = value; } } /// /// Handler for mouse down event for this interaction /// /// the mouse event args /// the plot surface this event applies to public override bool DoMouseDown(MouseEventArgs e, Control ctr ) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) { // keep track of the start point and flag that select initiated. selectionInitiated_ = true; startPoint_.X = e.X; startPoint_.Y = e.Y; previousPoint_.X = e.X; previousPoint_.Y = e.Y; // invalidate the end point endPoint_ = unset_; return false; } selectionInitiated_ = false; endPoint_ = unset_; startPoint_ = unset_; return false; } /// /// Handler for mouse move event for this interaction /// /// the mouse event args /// the plot surface this event applies to /// public override bool DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; // if dragging on axis to zoom. if ((e.Button == MouseButtons.Left) && selectionInitiated_) { Point endPoint_ = previousPoint_; if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) { endPoint_ = new Point(e.X, e.Y); this.DrawHorizontalSelection(previousPoint_, endPoint_, ctr); previousPoint_ = endPoint_; } else { endPoint_ = new Point(e.X, e.Y); if (e.X < ps.PlotAreaBoundingBoxCache.Left) endPoint_.X = ps.PlotAreaBoundingBoxCache.Left + 1; if (e.X > ps.PlotAreaBoundingBoxCache.Right) endPoint_.X = ps.PlotAreaBoundingBoxCache.Right - 1; this.DrawHorizontalSelection(previousPoint_, endPoint_, ctr); previousPoint_ = endPoint_; } } return false; } /// /// Handler for mouse up event for this interaction /// /// the mouse event args /// the plot surface this event applies to public override bool DoMouseUp(MouseEventArgs e, Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if ((e.Button == MouseButtons.Left) && selectionInitiated_) { endPoint_.X = e.X; endPoint_.Y = e.Y; if (e.X < ps.PlotAreaBoundingBoxCache.Left) endPoint_.X = ps.PlotAreaBoundingBoxCache.Left + 1; if (e.X > ps.PlotAreaBoundingBoxCache.Right) endPoint_.X = ps.PlotAreaBoundingBoxCache.Right - 1; // flag stopped selecting. selectionInitiated_ = false; if (endPoint_ != unset_) { this.DrawHorizontalSelection(startPoint_, endPoint_, ctr); } // ignore very small selections if (Math.Abs(endPoint_.X - startPoint_.X) < minimumPixelDistanceForSelect_) { return false; } ((Windows.PlotSurface2D)ctr).CacheAxes(); // determine the new x axis 1 world limits (and check to see if they are far enough appart). double xAxis1Min = double.NaN; double xAxis1Max = double.NaN; if (ps.XAxis1 != null) { int x1 = (int)Math.Min(endPoint_.X, startPoint_.X); int x2 = (int)Math.Max(endPoint_.X, startPoint_.X); int y = ps.PhysicalXAxis1Cache.PhysicalMax.Y; xAxis1Min = ps.PhysicalXAxis1Cache.PhysicalToWorld(new Point(x1, y), true); xAxis1Max = ps.PhysicalXAxis1Cache.PhysicalToWorld(new Point(x2, y), true); if (xAxis1Max - xAxis1Min < this.smallestAllowedRange_) { return false; } } // determine the new x axis 2 world limits (and check to see if they are far enough appart). double xAxis2Min = double.NaN; double xAxis2Max = double.NaN; if (ps.XAxis2 != null) { int x1 = (int)Math.Min(endPoint_.X, startPoint_.X); int x2 = (int)Math.Max(endPoint_.X, startPoint_.X); int y = ps.PhysicalXAxis2Cache.PhysicalMax.Y; xAxis2Min = ps.PhysicalXAxis2Cache.PhysicalToWorld(new Point(x1, y), true); xAxis2Max = ps.PhysicalXAxis2Cache.PhysicalToWorld(new Point(x2, y), true); if (xAxis2Max - xAxis2Min < smallestAllowedRange_) { return false; } } // now actually update the world limits. if (ps.XAxis1 != null) { ps.XAxis1.WorldMax = xAxis1Max; ps.XAxis1.WorldMin = xAxis1Min; } if (ps.XAxis2 != null) { ps.XAxis2.WorldMax = xAxis2Max; ps.XAxis2.WorldMin = xAxis2Min; } ((Windows.PlotSurface2D)ctr).InteractionOccured(this); return true; } return false; } private void DrawHorizontalSelection(Point start, Point end, System.Windows.Forms.Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; // the clipping rectangle in screen coordinates Rectangle clip = ctr.RectangleToScreen( new Rectangle( (int)ps.PlotAreaBoundingBoxCache.X, (int)ps.PlotAreaBoundingBoxCache.Y, (int)ps.PlotAreaBoundingBoxCache.Width, (int)ps.PlotAreaBoundingBoxCache.Height)); start = ctr.PointToScreen(start); end = ctr.PointToScreen(end); ControlPaint.FillReversibleRectangle( new Rectangle((int)Math.Min(start.X, end.X), (int)clip.Y, (int)Math.Abs(end.X - start.X), (int)clip.Height), Color.White); } } #endregion #region AxisDrag /// /// /// public class AxisDrag : Interaction { /// /// /// /// public AxisDrag(bool enableDragWithCtr) { enableDragWithCtr_ = enableDragWithCtr; } private bool enableDragWithCtr_ = false; private Axis axis_ = null; private bool doing_ = false; private Point lastPoint_ = new Point(); private PhysicalAxis physicalAxis_ = null; private Point startPoint_ = new Point(); /// /// /// /// /// public override bool DoMouseDown(MouseEventArgs e, Control ctr) { // if the mouse is inside the plot area [the tick marks are here and part of the // axis], then don't invoke drag. NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right && e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) { return false; } if ((e.Button == MouseButtons.Left)) { // see if hit with axis. ArrayList objects = ps.HitTest(new Point(e.X, e.Y)); foreach (object o in objects) { if (o is NPlot.Axis) { doing_ = true; axis_ = (Axis)o; PhysicalAxis[] physicalAxisList = new PhysicalAxis[] { ps.PhysicalXAxis1Cache, ps.PhysicalXAxis2Cache, ps.PhysicalYAxis1Cache, ps.PhysicalYAxis2Cache }; if (ps.PhysicalXAxis1Cache.Axis == axis_) physicalAxis_ = ps.PhysicalXAxis1Cache; else if (ps.PhysicalXAxis2Cache.Axis == axis_) physicalAxis_ = ps.PhysicalXAxis2Cache; else if (ps.PhysicalYAxis1Cache.Axis == axis_) physicalAxis_ = ps.PhysicalYAxis1Cache; else if (ps.PhysicalYAxis2Cache.Axis == axis_) physicalAxis_ = ps.PhysicalYAxis2Cache; lastPoint_ = startPoint_ = new Point(e.X, e.Y); return false; } } } return false; } /// /// /// /// /// /// public override bool DoMouseMove(MouseEventArgs e, Control ctr, KeyEventArgs lastKeyEventArgs) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; // if dragging on axis to zoom. if ((e.Button == MouseButtons.Left) && doing_ && physicalAxis_ != null) { if (enableDragWithCtr_ && lastKeyEventArgs != null && lastKeyEventArgs.Control) { } else { float dist = (e.X - lastPoint_.X) + (-e.Y + lastPoint_.Y); lastPoint_ = new Point(e.X, e.Y); if (dist > sensitivity_ / 3.0f) { dist = sensitivity_ / 3.0f; } PointF pMin = physicalAxis_.PhysicalMin; PointF pMax = physicalAxis_.PhysicalMax; double physicalWorldLength = Math.Sqrt((pMax.X - pMin.X) * (pMax.X - pMin.X) + (pMax.Y - pMin.Y) * (pMax.Y - pMin.Y)); float prop = (float)(physicalWorldLength * dist / sensitivity_); prop *= 2; ((Windows.PlotSurface2D)ctr).CacheAxes(); float relativePosX = (startPoint_.X - pMin.X) / (pMax.X - pMin.X); float relativePosY = (startPoint_.Y - pMin.Y) / (pMax.Y - pMin.Y); if (float.IsInfinity(relativePosX) || float.IsNaN(relativePosX)) relativePosX = 0.0f; if (float.IsInfinity(relativePosY) || float.IsNaN(relativePosY)) relativePosY = 0.0f; PointF physicalWorldMin = pMin; PointF physicalWorldMax = pMax; physicalWorldMin.X += relativePosX * prop; physicalWorldMax.X -= (1 - relativePosX) * prop; physicalWorldMin.Y -= relativePosY * prop; physicalWorldMax.Y += (1 - relativePosY) * prop; double newWorldMin = axis_.PhysicalToWorld(physicalWorldMin, pMin, pMax, false); double newWorldMax = axis_.PhysicalToWorld(physicalWorldMax, pMin, pMax, false); axis_.WorldMin = newWorldMin; axis_.WorldMax = newWorldMax; ((Windows.PlotSurface2D)ctr).InteractionOccured(this); return true; } } return false; } /// /// /// /// /// public override bool DoMouseUp(MouseEventArgs e, Control ctr) { if (doing_) { doing_ = false; axis_ = null; physicalAxis_ = null; lastPoint_ = new Point(); } return false; } private float sensitivity_ = 200.0f; /// /// /// /// public float Sensitivity { get { return sensitivity_; } set { sensitivity_ = value; } } } #endregion #region MouseWheelZoom /// /// /// public class MouseWheelZoom : Interaction { private Point point_ = new Point(-1, -1); //private bool mouseDown_ = false; /// /// /// /// /// public override bool DoMouseUp(MouseEventArgs e, Control ctr) { //mouseDown_ = false; return false; } /// /// /// /// /// public override bool DoMouseDown(MouseEventArgs e, Control ctr) { //NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; //if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right && // e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom) //{ // point_.X = e.X; // point_.Y = e.Y; // mouseDown_ = true; //} return false; } /// /// /// /// /// public override bool DoMouseWheel(MouseEventArgs e, Control ctr) { NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner; ((Windows.PlotSurface2D)ctr).CacheAxes(); float delta = (float)e.Delta / (float)e.Delta; delta *= sensitivity_; Axis axis = null; PointF pMin = PointF.Empty; PointF pMax = PointF.Empty; KeyEventArgs keyArgs = ((Windows.PlotSurface2D)ctr).lastKeyEventArgs_; bool zoom = (keyArgs != null && keyArgs.Control); if (keyArgs != null && keyArgs.Shift) { axis = ps.YAxis1; pMin = ps.PhysicalYAxis1Cache.PhysicalMin; pMax = ps.PhysicalYAxis1Cache.PhysicalMax; } else { axis = ps.XAxis1; pMin = ps.PhysicalXAxis1Cache.PhysicalMin; pMax = ps.PhysicalXAxis1Cache.PhysicalMax; } if (axis == null) return false; PointF physicalWorldMin = pMin; PointF physicalWorldMax = pMax; physicalWorldMin.X -= delta; physicalWorldMax.X -= (zoom) ? -delta : delta; physicalWorldMin.Y += delta; physicalWorldMax.Y += (zoom) ? -delta : delta; double newWorldMin = axis.PhysicalToWorld(physicalWorldMin, pMin, pMax, false); double newWorldMax = axis.PhysicalToWorld(physicalWorldMax, pMin, pMax, false); axis.WorldMin = newWorldMin; axis.WorldMax = newWorldMax; ((Windows.PlotSurface2D)ctr).InteractionOccured(this); return true; } /// /// Number of screen pixels equivalent to one wheel step. /// public float Sensitivity { get { return sensitivity_; } set { sensitivity_ = value; } } private float sensitivity_ = 60.0f; } #endregion } private ArrayList interactions_ = new ArrayList(); /// /// Adds and interaction to the plotsurface that adds functionality that responds /// to a set of mouse / keyboard events. /// /// the interaction to add. public void AddInteraction(Interactions.Interaction i) { interactions_.Add(i); } /// /// Remove a previously added interaction /// /// interaction to remove public void RemoveInteraction(Interactions.Interaction i) { interactions_.Remove(i); } /// /// This is the signature of the function used for InteractionOccurred events. /// /// TODO: expand this to include information about the event. /// /// public delegate void InteractionHandler(object sender); /// /// Event is fired when an interaction happens with the plot that causes it to be modified. /// public event InteractionHandler InteractionOccured; /// /// Default function called when plotsurface modifying interaction occured. /// /// Override this, or add method to InteractionOccured event. /// /// protected void OnInteractionOccured(object sender) { // do nothing. } /// /// This is the signature of the function used for PreRefresh events. /// /// public delegate void PreRefreshHandler(object sender); /// /// Event fired when we are about to paint. /// public event PreRefreshHandler PreRefresh; /// /// Default function called just before a refresh happens. /// /// protected void OnPreRefresh(object sender) { // do nothing. } #region class PlotContextMenu /// /// Summary description for ContextMenu. /// public class PlotContextMenu { #region IPlotMenuItem /// /// elements of the MenuItems array list must implement this interface. /// public interface IPlotMenuItem { /// /// Gets the Windows.Forms.MenuItem associated with the PlotMenuItem /// System.Windows.Forms.MenuItem MenuItem { get; } /// /// This method is called for each menu item before the menu is /// displayed. It is useful for implementing check marks, disabling /// etc. /// /// void OnPopup( PlotContextMenu plotContextMenu ); } #endregion #region PlotMenuSeparator /// /// A plot menu item for separators. /// public class PlotMenuSeparator : IPlotMenuItem { /// /// Constructor /// /// public PlotMenuSeparator( int index ) { menuItem_ = new System.Windows.Forms.MenuItem(); index_ = index; menuItem_.Index = index_; menuItem_.Text = "-"; } private int index_; /// /// Index of this menu item in the menu. /// public int Index { get { return index_; } } private System.Windows.Forms.MenuItem menuItem_; /// /// The Windows.Forms.MenuItem associated with this IPlotMenuItem /// public System.Windows.Forms.MenuItem MenuItem { get { return menuItem_; } } /// /// /// /// public void OnPopup( PlotContextMenu plotContextMenu ) { // do nothing. } } #endregion #region PlotMenuItem /// /// A Plot menu item suitable for specifying basic menu items /// public class PlotMenuItem : IPlotMenuItem { /// /// Constructor /// /// Menu item text /// Index in the manu /// EventHandler to call if menu selected. public PlotMenuItem( string text, int index, EventHandler callback ) { text_ = text; index_ = index; callback_ = callback; menuItem_ = new System.Windows.Forms.MenuItem(); menuItem_.Index = index; menuItem_.Text = text; menuItem_.Click += new System.EventHandler(callback); } private string text_; /// /// The text to put in the menu for this menu item. /// public string Text { get { return text_; } } private int index_; /// /// Index of this menu item in the menu. /// public int Index { get { return index_; } } private EventHandler callback_; /// /// EventHandler to call if menu selected. /// public EventHandler Callback { get { return callback_; } } private System.Windows.Forms.MenuItem menuItem_; /// /// The Windows.Forms.MenuItem associated with this IPlotMenuItem /// public System.Windows.Forms.MenuItem MenuItem { get { return menuItem_; } } /// /// Called before menu drawn. /// /// The plot menu this item is a member of. public virtual void OnPopup( PlotContextMenu plotContextMenu ) { // do nothing. } } #endregion #region PlotZoomBackMenuItem /// /// A Plot Menu Item that provides necessary functionality for the /// zoom back menu item (graying out if zoomed right out in addition /// to basic functionality). /// public class PlotZoomBackMenuItem : PlotMenuItem { /// /// Constructor /// /// Text associated with this item in the menu. /// Index of this item in the menu. /// EventHandler to call when menu item is selected. public PlotZoomBackMenuItem( string text, int index, EventHandler callback ) : base( text, index, callback ) { } /// /// Called before menu drawn. /// /// The plot menu this item is a member of. public override void OnPopup( PlotContextMenu plotContextMenu ) { this.MenuItem.Enabled = plotContextMenu.plotSurface2D_.xAxis1ZoomCache_ != null; } } #endregion #region PlotShowCoordinatesMenuItem /// /// A Plot Menu Item that provides necessary functionality for the /// show coordinates menu item (tick mark toggle in addition to basic /// functionality). /// public class PlotShowCoordinatesMenuItem : PlotMenuItem { /// /// Constructor /// /// Text associated with this item in the menu. /// Index of this item in the menu. /// EventHandler to call when menu item is selected. public PlotShowCoordinatesMenuItem( string text, int index, EventHandler callback ) : base( text, index, callback ) { } /// /// Called before menu drawn. /// /// The plot menu this item is a member of. public override void OnPopup( PlotContextMenu plotContextMenu ) { this.MenuItem.Checked = plotContextMenu.plotSurface2D_.ShowCoordinates; } } #endregion private System.Windows.Forms.ContextMenu rightMenu_ = null; private ArrayList menuItems_ = null; /// /// Gets an arraylist of all PlotMenuItems that comprise the /// menu. If this list is changed, this class must be told to /// update using the Update method. /// public ArrayList MenuItems { get { return menuItems_; } } /// /// The PlotSurface2D associated with the context menu. Generally, the user /// should not set this. It is used internally by PlotSurface2D. /// public Windows.PlotSurface2D PlotSurface2D { set { this.plotSurface2D_ = value; } } /// /// The PlotSurface2D associated with the context menu. Classes inherited /// from PlotContextMenu will likely use this to implement their functionality. /// protected Windows.PlotSurface2D plotSurface2D_; /// /// Sets the context menu according to the IPlotMenuItem's in the provided /// ArrayList. The current menu items can be obtained using the MenuItems /// property and extended if desired. /// /// public void SetMenuItems(ArrayList menuItems) { this.menuItems_ = menuItems; this.rightMenu_ = new System.Windows.Forms.ContextMenu(); foreach (IPlotMenuItem item in menuItems_) { this.rightMenu_.MenuItems.Add( item.MenuItem ); } this.rightMenu_.Popup += new System.EventHandler(this.rightMenu__Popup); } /// /// Constructor creates /// public PlotContextMenu() { ArrayList menuItems = new ArrayList(); menuItems = new ArrayList(); menuItems.Add( new PlotZoomBackMenuItem( "Original Dimensions", 0, new EventHandler(this.mnuOriginalDimensions_Click) ) ); menuItems.Add( new PlotShowCoordinatesMenuItem( "Show World Coordinates", 1, new EventHandler(this.mnuDisplayCoordinates_Click) ) ); menuItems.Add( new PlotMenuSeparator(2) ); menuItems.Add( new PlotMenuItem( "Print", 3, new EventHandler(this.mnuPrint_Click )) ); menuItems.Add( new PlotMenuItem( "Print Preview", 4, new EventHandler(this.mnuPrintPreview_Click) ) ); menuItems.Add( new PlotMenuItem( "Copy To Clipboard", 5, new EventHandler(this.mnuCopyToClipboard_Click) ) ); menuItems.Add( new PlotMenuItem( "Copy Data To Clipboard", 6, new EventHandler(this.mnuCopyDataToClipboard_Click) ) ); this.SetMenuItems( menuItems ); } private void mnuOriginalDimensions_Click(object sender, System.EventArgs e) { plotSurface2D_.OriginalDimensions(); } private void mnuCopyToClipboard_Click(object sender, System.EventArgs e) { plotSurface2D_.CopyToClipboard(); } private void mnuCopyDataToClipboard_Click(object sender, System.EventArgs e) { plotSurface2D_.CopyDataToClipboard(); } private void mnuPrint_Click(object sender, System.EventArgs e) { plotSurface2D_.Print( false ); } private void mnuPrintPreview_Click(object sender, System.EventArgs e) { plotSurface2D_.Print( true ); } private void mnuDisplayCoordinates_Click(object sender, System.EventArgs e) { plotSurface2D_.ShowCoordinates = !plotSurface2D_.ShowCoordinates; } private void rightMenu__Popup(object sender, System.EventArgs e) { foreach (IPlotMenuItem item in menuItems_) { item.OnPopup( this ); } } /// /// Gets the Windows.Forms context menu managed by this object. /// public System.Windows.Forms.ContextMenu Menu { get { return rightMenu_; } } } #endregion /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); } private System.ComponentModel.IContainer components; } } nplot-gtk-0.9.9.2/lib/Windows.PlotSurface2Dnew.cs0000644000175000017500000000746410512404106022167 0ustar carlosblecarlosble// ******** experimental ******** /* using System; using System.Collections; using System.ComponentModel; using System.Drawing; using System.Data; using System.Windows.Forms; using System.IO; namespace NPlot.Windows { /// /// Experimental /// public class PlotSurface2Dnew : System.Windows.Forms.UserControl, IPlotSurface2Dnew { /// /// Required designer variable. /// private System.ComponentModel.Container components = null; /// /// Constructor /// public PlotSurface2Dnew() { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); // double buffer, and update when resize. base.SetStyle(ControlStyles.AllPaintingInWmPaint, true); base.SetStyle(ControlStyles.DoubleBuffer, true); base.SetStyle(ControlStyles.UserPaint, true); base.ResizeRedraw = true; } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if( components != null ) components.Dispose(); } base.Dispose( disposing ); } #region Component Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { components = new System.ComponentModel.Container(); } #endregion private NPlot.PlotSurface2Dnew Inner = new NPlot.PlotSurface2Dnew(); /// /// Experimental /// public void SetDefinition( ) { Inner.SetDefinition( ); } /// /// the paint event callback. /// /// paint event arguments - used to get graphics surface to draw on. protected override void OnPaint( PaintEventArgs pe ) { Graphics g = pe.Graphics; Rectangle border = new Rectangle( 0, 0, this.Width, this.Height ); if ( g == null ) { ErrorHandler.Instance.CriticalError( "graphics context null" ); } if ( border == Rectangle.Empty ) { ErrorHandler.Instance.CriticalError( "Control has zero extent" ); return; } this.Draw( g, border ); base.OnPaint(pe); } /// /// Draws the plot surface on the supplied graphics surface [not the control surface]. /// /// The graphics surface on which to draw /// A bounding box on this surface that denotes the area on the /// surface to confine drawing to. public void Draw( Graphics g, Rectangle bounds ) { try { Inner.Draw( g, bounds ); } catch (Exception ex) { System.Diagnostics.Debugger.Log( 1, "", "Exception drawing plot:" + ex + "\r\n" ); } } /// /// Padding of this width will be left between what is drawn and the control border. /// [ Category("PlotSurface2D"), Description("Padding of this width will be left between what is drawn and the control border."), Browsable(true) ] public int Padding { get { return Inner.Padding; } set { Inner.Padding = value; } } /// /// Adds a drawable object to the plot surface against the specified axes. If /// the object is an IPlot, the PlotSurface2D axes will also be updated. /// /// the IDrawable object to add to the plot surface /// the x-axis to add the plot against. /// the y-axis to add the plot against.am> public void Add( IDrawable p, string xAxis, string yAxis ) { this.Inner.Add( p, xAxis, yAxis ); } } } */ nplot-gtk-0.9.9.2/lib/Makefile0000644000175000017500000000457310512404106016516 0ustar carlosblecarlosbleCSC=mcs -debug+ VERSION=0.9.9.2 NPLOT_SOURCES = \ AdapterUtils.cs \ NPlotException.cs \ ArrowItem.cs \ AssemblyInfo.cs \ AxesConstraint.cs \ Axis.cs \ BasePlot.cs \ BaseSequenceLinePlot.cs \ BaseSequencePlot.cs \ Bitmap.PlotSurface2D.cs \ CandlePlot.cs \ DateTimeAxis.cs \ ErrorHandler.cs \ FilledRegion.cs \ FontScaler.cs \ Grid.cs \ HistogramPlot.cs \ HorizontalLine.cs \ IDrawable.cs \ IGradient.cs \ ImagePlot.cs \ IMeshPlot.cs \ IPlot.cs \ IPlotSurface2D.cs \ ITransform2D.cs \ ISequencePlot.cs \ LabelAxis.cs \ LabelPointPlot.cs \ LegendBase.cs \ Legend.cs \ LinearAxis.cs \ LinearGradient.cs \ LinePlot.cs \ LogAxis.cs \ Marker.cs \ MarkerItem.cs \ PageAlignedPhysicalAxis.cs \ PhysicalAxis.cs \ PiAxis.cs \ PiePlot.cs \ PlotSurface2D.cs \ PlotSurface3D.cs \ PointD.cs \ PointPlot.cs \ RectangleBrushes.cs \ RectangleD.cs \ SequenceAdapter.cs \ StartStep.cs \ StepPlot.cs \ Transform2D.cs \ Utils.cs \ VerticalLine.cs \ Web.Design.PlotSurface2D.cs \ Web.PlotSurface2D.cs NPLOT_GTK_SOURCES = \ Gtk.PlotSurface2D.cs \ sysdraw.cs all: NPlot.dll NPlot.Gtk.dll tests tests: mf.exe test.exe NPLOT_DLLS= -r:System.Web \ -r:System.Design \ -r:System.Drawing \ -r:System.Data NPLOT_GTK_DLLS= -r:System.Web \ -r:System.Design \ -r:System.Drawing \ -r:System.Data \ -pkg:gtk-sharp-2.0 \ -r:NPlot.dll NPlot.dll: $(NPLOT_SOURCES) Makefile $(CSC) $(NPLOT_SOURCES) -target:library -out:NPlot.dll $(NPLOT_DLLS) NPlot.Gtk.dll: $(NPLOT_SOURCES) $(NPLOT_GTK_SOURCES) NPlot.dll Makefile $(CSC) $(NPLOT_GTK_SOURCES) -target:library -out:NPlot.Gtk.dll $(NPLOT_GTK_DLLS) mf.exe: MainForm.cs NPlot.Gtk.dll $(CSC) MainForm.cs -out:mf.exe -r:NPlot.dll -r:NPlot.Gtk.dll -pkg:gtk-sharp-2.0 -r:System.Drawing -r:System.Data -resource:asx_jbh.xml,NPlotDemo.resources.asx_jbh.xml test.exe: NPlot.dll test.cs $(CSC) test.cs -r:NPlot.dll -r:NPlot.Gtk.dll -pkg:gtk-sharp-2.0 -r:System.Drawing install: NPlot.dll NPlot.Gtk.dll -mkdir -p $(prefix)/lib/nplot cp NPlot.dll NPlot.Gtk.dll $(prefix)/lib/mono/1.0/ sed -e "s,@prefix@,$(prefix),g" -e "s/@VERSION@/$(VERSION)/" < nplot.pc.in > $(prefix)/lib/pkgconfig/nplot.pc sed -e "s,@prefix@,$(prefix),g" -e "s/@VERSION@/$(VERSION)/" < nplot-gtk.pc.in > $(prefix)/lib/pkgconfig/nplot-gtk.pc clean: rm *exe *dll *mdb nplot-gtk-0.9.9.2/lib/test.cs0000644000175000017500000001061610512404106016357 0ustar carlosblecarlosble#define GTK #if GTK using Gtk; using NPlot.Gtk; #endif using NPlot; using System.Drawing; using System.Drawing.Imaging; class X { public static float[] makeDaub( int len ) { float[] daub4_h = { 0.482962913145f, 0.836516303737f, 0.224143868042f, -0.129409522551f }; float[] daub4_g = { -0.129409522551f, -0.224143868042f, 0.836516303737f, -0.482962913145f }; float[] a = new float[len]; a[8] = 1.0f; float[] t; int ns = 4; // number smooth while ( ns < len/2 ) { t = (float[])a.Clone(); ns *= 2; for ( int i=0; i<(ns*2); ++i ) a[i] = 0.0f; // wavelet contribution for ( int i=0; i nplot-gtk-0.9.9.2/lib/sysdraw.cs0000644000175000017500000000276110512404106017076 0ustar carlosblecarlosble// // System.Drawing integration with Gtk# // // Miguel de Icaza // // API issues: // Maybe make the translation `out' parameters so they are explicit and the user knows about it? // Add a way to copy a Graphics into a drawable? // using System; using System.Reflection; using System.Runtime.InteropServices; namespace Gdk { public class Graphics { [DllImport("libgdk-win32-2.0-0.dll")] internal static extern IntPtr gdk_x11_drawable_get_xdisplay (IntPtr raw); [DllImport("libgdk-win32-2.0-0.dll")] internal static extern IntPtr gdk_x11_drawable_get_xid (IntPtr raw); public static System.Drawing.Graphics FromDrawable (Gdk.Drawable drawable) { IntPtr x_drawable; int x_off = 0, y_off = 0; if (drawable is Gdk.Window){ ((Gdk.Window) drawable).GetInternalPaintInfo(out drawable, out x_off, out y_off); } x_drawable = drawable.Handle; IntPtr display = gdk_x11_drawable_get_xdisplay (x_drawable); Type graphics = typeof (System.Drawing.Graphics); MethodInfo mi = graphics.GetMethod ("FromXDrawable", BindingFlags.Static | BindingFlags.NonPublic); if (mi == null) throw new NotImplementedException ("In this implementation I can not get a graphics from a drawable"); object [] args = new object [2] { (IntPtr) gdk_x11_drawable_get_xid (drawable.Handle), (IntPtr) display }; object r = mi.Invoke (null, args); System.Drawing.Graphics g = (System.Drawing.Graphics) r; g.TranslateTransform (-x_off, -y_off); return g; } } } nplot-gtk-0.9.9.2/lib/Gtk.PlotSurface2D.cs0000644000175000017500000001145210512404106020540 0ustar carlosblecarlosbleusing System; using System.Collections; using System.ComponentModel; using System.Data; using Gtk; using System.Drawing; namespace NPlot { namespace Gtk { public class PlotSurface2D : DrawingArea, IPlotSurface2D { NPlot.PlotSurface2D ps; /*Axis xAxis1Cache; Axis yAxis1Cache; Axis xAxis2Cache; Axis yAxis2Cache;*/ // The cache. System.Drawing.Bitmap bitmap_cache; Gdk.Rectangle current_allocation; // The current allocation. bool allocated = false; public PlotSurface2D (IntPtr x) : base (x) { Console.WriteLine (Environment.StackTrace); } public PlotSurface2D () { ps = new NPlot.PlotSurface2D (); CanFocus = false; SetSizeRequest (200, 200); } public void Refresh () { UpdateCache (); QueueDrawArea (0, 0, Allocation.Width, Allocation.Height); } protected override bool OnExposeEvent (Gdk.EventExpose args) { Gdk.Rectangle area = args.Area; Console.WriteLine (area); using (Graphics g = Gdk.Graphics.FromDrawable (args.Window)){ Rectangle bounds = new Rectangle (area.X, area.Y, area.Width, area.Height); g.DrawImage (bitmap_cache, bounds, bounds, GraphicsUnit.Pixel); } return true; } protected override void OnSizeAllocated (Gdk.Rectangle allocation) { allocated = true; current_allocation = allocation; UpdateCache (); base.OnSizeAllocated (allocation); } void UpdateCache () { if (!allocated) return; if (bitmap_cache != null) bitmap_cache.Dispose (); bitmap_cache = new System.Drawing.Bitmap (current_allocation.Width, current_allocation.Height); using (Graphics g = Graphics.FromImage (bitmap_cache)){ Rectangle bounds = new Rectangle ( 0, 0, current_allocation.Width, current_allocation.Height); ps.Draw (g, bounds); } } #region IPlotSurface2D interface implementation public void Add (IDrawable p, int zOrder) { ps.Add (p, zOrder); } public void Add (IDrawable p) { ps.Add (p); } public void Add (IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp) { ps.Add (p, xp, yp); } public void Add (NPlot.IDrawable p, NPlot.PlotSurface2D.XAxisPosition xp, NPlot.PlotSurface2D.YAxisPosition yp, int zOrder) { ps.Add (p, xp, yp, zOrder); } public void Clear() { ps.Clear (); } public NPlot.Legend Legend { get { return ps.Legend; } set { ps.Legend = value; } } public int Padding { get { return ps.Padding; } set { ps.Padding = value; } } public int LegendZOrder { get { return ps.LegendZOrder; } set { ps.LegendZOrder = value; } } public System.Drawing.Color PlotBackColor { set { ps.PlotBackColor = value; } } public System.Drawing.Bitmap PlotBackImage { set { ps.PlotBackImage = value; } } public IRectangleBrush PlotBackBrush { set { ps.PlotBackBrush = value; } } public Color TitleColor { set { ps.TitleColor = value; } } public Brush TitleBrush { get { return ps.TitleBrush; } set { ps.TitleBrush = value; } } /// /// Gets an array list containing all drawables currently added to the PlotSurface2D. /// public ArrayList Drawables { get { return ps.Drawables; } } public void Remove (IDrawable p, bool updateAxes) { ps.Remove(p, updateAxes); } public string Title { get { return ps.Title; } set { ps.Title = value; } } public System.Drawing.Font TitleFont { get { return ps.TitleFont; } set { ps.TitleFont = value; } } public System.Drawing.Drawing2D.SmoothingMode SmoothingMode { get { return ps.SmoothingMode; } set { ps.SmoothingMode = value; } } public void AddAxesConstraint (AxesConstraint c) { ps.AddAxesConstraint (c); } public Axis XAxis1 { get { return ps.XAxis1; } set { ps.XAxis1 = value; } } public Axis YAxis1 { get { return ps.YAxis1; } set { ps.YAxis1 = value; } } public Axis XAxis2 { get { return ps.XAxis2; } set { ps.XAxis2 = value; } } public Axis YAxis2 { get { return ps.YAxis2; } set { ps.YAxis2 = value; } } public bool AutoScaleTitle { get { return ps.AutoScaleTitle; } set { ps.AutoScaleTitle = value; } } public bool AutoScaleAutoGeneratedAxes { get { return ps.AutoScaleAutoGeneratedAxes; } set { ps.AutoScaleAutoGeneratedAxes = value; } } public System.Drawing.Bitmap Bitmap { get { return bitmap_cache;} } public int Width { get { return current_allocation.Width; } } public int Height { get { return current_allocation.Height;} } #endregion } } } nplot-gtk-0.9.9.2/lib/MainForm.cs0000644000175000017500000012416410512404106017114 0ustar carlosblecarlosble/* NPlot - A plotting library for .NET Main.cs Copyright (C) 2003-2004 Matt Howlett, Paolo Pierini Port to Gtk# Miguel de icaza 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 following text in the documentation and / or other materials provided with the distribution: "This product includes software developed as part of the NPlot charting library project available from: http://www.nplot.com/" ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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; using System.Drawing.Drawing2D; using System.Collections; using System.ComponentModel; using Gtk; using System.Data; using NPlot; using System.IO; using System.Reflection; namespace NPlotDemo { /// /// The main demo window. /// public class PlotSurface2DDemo : Gtk.Window { static void Main() { Application.Init (); Window mf = new PlotSurface2DDemo (); mf.Show (); Application.Run (); } /// /// used to keep track of the current demo plot being displayed. /// private int currentPlot = 0; /// /// delegate for plot demo functions. /// private delegate void PlotDemoDelegate(); /// /// list of the plot demos, initialized in the form constructor. /// private PlotDemoDelegate [] PlotRoutines; // Note that a NPlot.Windows.PlotSurface2D class // is used here. This has exactly the same // functionality as the NPlot.PlotSurface2D // class, except that it is derived from Forms.UserControl // and automatically paints itself in a windows.forms // application. Windows.PlotSurface2D can also paint itself // to other arbitrary Drawing.Graphics drawing surfaces // using the Draw method. (see printing later). Gtk.Button quitButton; Gtk.Button nextPlotButton; Gtk.Button prevPlotButton; NPlot.Gtk.PlotSurface2D plotSurface; double[] PlotQEExampleValues; string[] PlotQEExampleTextValues; public void PlotCircular() { this.plotSurface.Clear(); plotSurface.Add( new HorizontalLine( 0.0, Color.LightGray ) ); plotSurface.Add( new VerticalLine( 0.0, Color.LightGray ) ); const int N = 400; const double start = -Math.PI * 7.0; const double end = Math.PI * 7.0; double[] xs = new double[N]; double[] ys = new double[N]; for (int i=0; i 1.0f); } // transform to the tilted twiss ellipse for (int i =0; i= min && x[i] <= max) { int j; j = Convert.ToInt32(Nbin * (x[i] - min) / range); xh[j] += 1; } } StepPlot sp= new StepPlot(); sp.OrdinateData = xh; sp.AbscissaData = new StartStep( min, range / Nbin ); sp.Center = true; plotSurface.Add(sp, PlotSurface2D.XAxisPosition.Bottom, PlotSurface2D.YAxisPosition.Right); // axis formatting LinearAxis ly2 = (LinearAxis)plotSurface.YAxis2; ly2.WorldMin = 0.0f; ly2.Label = "Beam Density [a.u.]"; ly2.NumberOfSmallTicks = 2; sp.Pen = new Pen( Color.Green, 2 ); // Finally, refreshes the plot plotSurface.Refresh(); } // Fill the array containing the rms twiss ellipse data points // ellipse is g*x^2+a*x*y+b*y^2=e private void TwissEllipse(float a, float b, float g, float e, ref float [] x, ref float [] y) { float rot, sr, cr, brot; if (a==0) { rot=0; } else { rot=(float)(.5*Math.Atan(2.0 * a / (g - b))); } sr = (float)Math.Sin(rot); cr = (float)Math.Cos(rot); brot = g * sr * sr - 2.0F * a * sr * cr + b * cr * cr; int npt=x.Length; float theta; for (int i=0; i 18.0f) { PlotQEExampleTextValues[i] = "KCsTe"; } else { PlotQEExampleTextValues[i] = ""; } s[i] = i.ToString("00") + ".1"; } PointPlot pp = new PointPlot(); pp.DataSource = PlotQEExampleValues; pp.Marker = new Marker( Marker.MarkerType.Square, 10 ); pp.Marker.DropLine = true; pp.Marker.Pen = Pens.CornflowerBlue; pp.Marker.Filled = false; plotSurface.Add( pp ); LabelPointPlot tp1 = new LabelPointPlot(); tp1.DataSource = PlotQEExampleValues; tp1.TextData = PlotQEExampleTextValues; tp1.LabelTextPosition = LabelPointPlot.LabelPositions.Above; tp1.Marker = new Marker( Marker.MarkerType.None, 10 ); plotSurface.Add( tp1 ); LabelAxis la = new LabelAxis( plotSurface.XAxis1 ); for (int i=0; i /// callback for quit button click /// /// unused /// unused private void quitButton_Click(object sender, System.EventArgs e) { Application.Quit (); } /// /// callback for next button click /// /// unused /// unused private void nextPlotButton_Click(object sender, System.EventArgs e) { currentPlot += 1; if (currentPlot == PlotRoutines.Length) { currentPlot = 0; } int id = currentPlot+1; PlotRoutines[currentPlot](); } /// /// Callback for prev button click. /// /// unused /// unused private void prevPlotButton_Click(object sender, System.EventArgs e) { currentPlot--; if( currentPlot == -1 ) currentPlot = PlotRoutines.Length-1; PlotRoutines[currentPlot](); } } } nplot-gtk-0.9.9.2/lib/asx_jbh.xml0000644000175000017500000007630710512404107017223 0ustar carlosblecarlosble 1270061 800 2003-10-23T00:00:00.0000000+10:00 2.2 2.15 2.27 2.25 28859100 2.25 1270060 800 2003-10-24T00:00:00.0000000+10:00 2.25 2.2 2.25 2.2 7942070 2.2 1270059 800 2003-10-27T00:00:00.0000000+10:00 2.2 2.16 2.2 2.16 2957960 2.16 1270058 800 2003-10-28T00:00:00.0000000+10:00 2.15 2.1 2.16 2.13 1875630 2.13 1270057 800 2003-10-29T00:00:00.0000000+10:00 2.12 2.11 2.13 2.12 1638610 2.12 1270056 800 2003-10-30T00:00:00.0000000+10:00 2.12 2.12 2.13 2.12 992206 2.12 1270055 800 2003-10-31T00:00:00.0000000+10:00 2.12 2.11 2.13 2.12 607660 2.12 1270054 800 2003-11-03T00:00:00.0000000+10:00 2.14 2.13 2.16 2.16 416467 2.16 1270053 800 2003-11-04T00:00:00.0000000+10:00 2.15 2.14 2.17 2.15 322063 2.15 1270052 800 2003-11-05T00:00:00.0000000+10:00 2.14 2.12 2.15 2.12 519158 2.12 1270051 800 2003-11-06T00:00:00.0000000+10:00 2.12 2.11 2.13 2.11 1710010 2.11 1270050 800 2003-11-07T00:00:00.0000000+10:00 2.12 2.11 2.12 2.12 1157040 2.12 1270049 800 2003-11-10T00:00:00.0000000+10:00 2.12 2.12 2.2 2.19 694342 2.19 1270048 800 2003-11-11T00:00:00.0000000+10:00 2.17 2.16 2.19 2.18 481938 2.18 1270047 800 2003-11-12T00:00:00.0000000+10:00 2.19 2.17 2.19 2.17 529080 2.17 1270046 800 2003-11-13T00:00:00.0000000+10:00 2.16 2.15 2.17 2.16 102304 2.16 1270045 800 2003-11-14T00:00:00.0000000+10:00 2.16 2.15 2.17 2.16 1298980 2.16 1270044 800 2003-11-17T00:00:00.0000000+10:00 2.15 2.15 2.16 2.15 199497 2.15 1270043 800 2003-11-18T00:00:00.0000000+10:00 2.15 2.15 2.16 2.15 962087 2.15 1270042 800 2003-11-19T00:00:00.0000000+10:00 2.15 2.11 2.15 2.13 161224 2.13 1270041 800 2003-11-20T00:00:00.0000000+10:00 2.14 2.13 2.15 2.14 328917 2.14 1270040 800 2003-11-21T00:00:00.0000000+10:00 2.13 2.11 2.14 2.11 1149870 2.11 1270039 800 2003-11-24T00:00:00.0000000+10:00 2.15 2.1 2.15 2.1 151047 2.1 1270038 800 2003-11-25T00:00:00.0000000+10:00 2.11 2.11 2.13 2.12 294019 2.12 1270037 800 2003-11-26T00:00:00.0000000+10:00 2.12 2.07 2.12 2.09 127703 2.09 1270036 800 2003-11-27T00:00:00.0000000+10:00 2.08 2.06 2.09 2.09 180497 2.09 1270035 800 2003-11-28T00:00:00.0000000+10:00 2.08 2.04 2.09 2.07 900945 2.07 1270034 800 2003-12-01T00:00:00.0000000+10:00 2.06 1.98 2.06 2 2511580 2 1270033 800 2003-12-02T00:00:00.0000000+10:00 2 2 2.04 2.02 700512 2.02 1270032 800 2003-12-03T00:00:00.0000000+10:00 2.03 2.01 2.06 2.04 225952 2.04 1270031 800 2003-12-04T00:00:00.0000000+10:00 2.05 2.05 2.09 2.08 412150 2.08 1270030 800 2003-12-05T00:00:00.0000000+10:00 2.1 2.08 2.1 2.08 1201620 2.08 1270029 800 2003-12-08T00:00:00.0000000+10:00 2.11 2.1 2.13 2.1 857738 2.1 1270028 800 2003-12-09T00:00:00.0000000+10:00 2.12 2.09 2.15 2.1 974466 2.1 1270027 800 2003-12-10T00:00:00.0000000+10:00 2.11 2.1 2.12 2.1 313790 2.1 1270026 800 2003-12-11T00:00:00.0000000+10:00 2.11 2.11 2.13 2.11 98018 2.11 1270025 800 2003-12-12T00:00:00.0000000+10:00 2.13 2.13 2.16 2.13 695692 2.13 1270092 800 2003-12-15T00:00:00.0000000+10:00 2.16 2.16 2.25 2.25 603413 2.25 1270091 800 2003-12-16T00:00:00.0000000+10:00 2.25 2.2 2.27 2.2 170126 2.2 1270090 800 2003-12-17T00:00:00.0000000+10:00 2.2 2.16 2.2 2.18 175635 2.18 1270089 800 2003-12-18T00:00:00.0000000+10:00 2.2 2.18 2.24 2.2 172018 2.2 1270088 800 2003-12-19T00:00:00.0000000+10:00 2.24 2.23 2.25 2.23 414466 2.23 1270087 800 2003-12-22T00:00:00.0000000+10:00 2.23 2.23 2.36 2.33 1033800 2.33 1270086 800 2003-12-23T00:00:00.0000000+10:00 2.34 2.33 2.37 2.34 414269 2.34 1270085 800 2003-12-24T00:00:00.0000000+10:00 2.34 2.28 2.34 2.28 43449 2.28 1270084 800 2003-12-29T00:00:00.0000000+10:00 2.27 2.25 2.35 2.3 808493 2.3 1270083 800 2003-12-30T00:00:00.0000000+10:00 2.33 2.3 2.34 2.3 118392 2.3 1270082 800 2003-12-31T00:00:00.0000000+10:00 2.3 2.27 2.32 2.31 38701 2.31 1270081 800 2004-01-02T00:00:00.0000000+10:00 2.31 2.3 2.31 2.3 39391 2.3 1270080 800 2004-01-05T00:00:00.0000000+10:00 2.32 2.3 2.32 2.32 102553 2.32 1270079 800 2004-01-06T00:00:00.0000000+10:00 2.33 2.33 2.36 2.34 182445 2.34 1270078 800 2004-01-07T00:00:00.0000000+10:00 2.34 2.3 2.34 2.31 93615 2.31 1270077 800 2004-01-08T00:00:00.0000000+10:00 2.31 2.3 2.33 2.31 277660 2.31 1270076 800 2004-01-09T00:00:00.0000000+10:00 2.32 2.3 2.33 2.32 133586 2.32 1270075 800 2004-01-12T00:00:00.0000000+10:00 2.3 2.29 2.34 2.34 95611 2.34 1270074 800 2004-01-13T00:00:00.0000000+10:00 2.33 2.3 2.34 2.32 213210 2.32 1270073 800 2004-01-14T00:00:00.0000000+10:00 2.33 2.31 2.33 2.33 87866 2.33 1270072 800 2004-01-15T00:00:00.0000000+10:00 2.33 2.32 2.34 2.33 153354 2.33 1270071 800 2004-01-16T00:00:00.0000000+10:00 2.32 2.31 2.34 2.31 270317 2.31 1270070 800 2004-01-19T00:00:00.0000000+10:00 2.32 2.3 2.34 2.31 611958 2.31 1270069 800 2004-01-20T00:00:00.0000000+10:00 2.31 2.31 2.34 2.32 303270 2.32 1270068 800 2004-01-21T00:00:00.0000000+10:00 2.33 2.32 2.34 2.33 351439 2.33 1270067 800 2004-01-22T00:00:00.0000000+10:00 2.33 2.31 2.33 2.32 114096 2.32 1270066 800 2004-01-23T00:00:00.0000000+10:00 2.32 2.32 2.34 2.34 185381 2.34 1270065 800 2004-01-27T00:00:00.0000000+10:00 2.34 2.34 2.39 2.37 283286 2.37 1270064 800 2004-01-28T00:00:00.0000000+10:00 2.42 2.35 2.42 2.35 259467 2.35 1270063 800 2004-01-29T00:00:00.0000000+10:00 2.35 2.31 2.36 2.33 728816 2.33 1270062 800 2004-01-30T00:00:00.0000000+10:00 2.32 2.3 2.35 2.3 187145 2.3 1270132 800 2004-02-02T00:00:00.0000000+10:00 2.32 2.24 2.32 2.25 267460 2.21 1270131 800 2004-02-03T00:00:00.0000000+10:00 2.25 2.2 2.25 2.24 226846 2.2 1270130 800 2004-02-04T00:00:00.0000000+10:00 2.24 2.2 2.34 2.34 70673 2.3 1270129 800 2004-02-05T00:00:00.0000000+10:00 2.34 2.28 2.34 2.29 78104 2.25 1270128 800 2004-02-06T00:00:00.0000000+10:00 2.3 2.3 2.31 2.3 32504 2.26 1270127 800 2004-02-09T00:00:00.0000000+10:00 2.3 2.29 2.3 2.29 40805 2.25 1270126 800 2004-02-10T00:00:00.0000000+10:00 2.3 2.29 2.3 2.3 43131 2.26 1270125 800 2004-02-11T00:00:00.0000000+10:00 2.3 2.3 2.32 2.31 103542 2.27 1270124 800 2004-02-12T00:00:00.0000000+10:00 2.31 2.3 2.39 2.39 73995 2.35 1270123 800 2004-02-13T00:00:00.0000000+10:00 2.39 2.35 2.39 2.36 345250 2.32 1270122 800 2004-02-16T00:00:00.0000000+10:00 2.37 2.36 2.39 2.39 44182 2.35 1270121 800 2004-02-17T00:00:00.0000000+10:00 2.39 2.39 2.43 2.43 303605 2.39 1270120 800 2004-02-18T00:00:00.0000000+10:00 2.44 2.43 2.46 2.46 238403 2.42 1270119 800 2004-02-19T00:00:00.0000000+10:00 2.44 2.27 2.45 2.4 627202 2.36 1270118 800 2004-02-20T00:00:00.0000000+10:00 2.39 2.35 2.4 2.36 531169 2.32 1270117 800 2004-02-23T00:00:00.0000000+10:00 2.37 2.35 2.37 2.35 851091 2.31 1270116 800 2004-02-24T00:00:00.0000000+10:00 2.36 2.34 2.36 2.36 432450 2.32 1270115 800 2004-02-25T00:00:00.0000000+10:00 2.36 2.34 2.36 2.35 335388 2.31 1270114 800 2004-02-26T00:00:00.0000000+10:00 2.36 2.26 2.36 2.3 233483 2.26 1270113 800 2004-02-27T00:00:00.0000000+10:00 2.31 2.28 2.31 2.28 130417 2.24 1270112 800 2004-03-01T00:00:00.0000000+10:00 2.3 2.29 2.36 2.3 107894 2.26 1270111 800 2004-03-02T00:00:00.0000000+10:00 2.3 2.3 2.32 2.3 204795 2.26 1270110 800 2004-03-03T00:00:00.0000000+10:00 2.3 2.27 2.3 2.27 87493 2.23 1270109 800 2004-03-04T00:00:00.0000000+10:00 2.29 2.27 2.29 2.28 454592 2.24 1270108 800 2004-03-05T00:00:00.0000000+10:00 2.28 2.27 2.28 2.28 88654 2.24 1270107 800 2004-03-08T00:00:00.0000000+10:00 2.28 2.27 2.28 2.28 62144 2.24 1270106 800 2004-03-09T00:00:00.0000000+10:00 2.27 2.21 2.27 2.22 154286 2.18 1270105 800 2004-03-10T00:00:00.0000000+10:00 2.25 2.23 2.25 2.25 184503 2.21 1270104 800 2004-03-11T00:00:00.0000000+10:00 2.25 2.24 2.25 2.24 151054 2.2 1270103 800 2004-03-12T00:00:00.0000000+10:00 2.25 2.23 2.27 2.25 80501 2.21 1270102 800 2004-03-15T00:00:00.0000000+10:00 2.25 2.24 2.25 2.25 55148 2.21 1270101 800 2004-03-16T00:00:00.0000000+10:00 2.23 2.2 2.23 2.21 574151 2.17 1270100 800 2004-03-17T00:00:00.0000000+10:00 2.24 2.2 2.25 2.2 77342 2.16 1270099 800 2004-03-18T00:00:00.0000000+10:00 2.2 2.2 2.22 2.2 407286 2.16 1270098 800 2004-03-19T00:00:00.0000000+10:00 2.23 2.23 2.3 2.3 251454 2.26 1270097 800 2004-03-22T00:00:00.0000000+10:00 2.3 2.25 2.3 2.25 74821 2.21 1270096 800 2004-03-23T00:00:00.0000000+10:00 2.25 2.2 2.25 2.2 127139 2.16 1270095 800 2004-03-24T00:00:00.0000000+10:00 2.2 2.18 2.2 2.18 1468360 2.14 1270094 800 2004-03-25T00:00:00.0000000+10:00 2.17 2.16 2.17 2.16 199240 2.12 1270093 800 2004-03-26T00:00:00.0000000+10:00 2.16 2.13 2.17 2.14 222053 2.1 nplot-gtk-0.9.9.2/lib/NPlot.dll.mdb0000644000175000017500000040536510512404267017364 0ustar carlosblecarlosble#&E'|GgZn D6 2/home/carlosble/svns/nplot-gtk/lib/AdapterUtils.csegh i@fiwwwwt_min t_max en colNamemin max rs uw0y5{F}W\qy|5W\qy|Aq+ Bmin max *2:R:*22:CSS[oE F7777W7G H  I  ''''7 Joooo&'K%'79: ;L8;' min max FHJ;OCSKTcK;CCKMBT__g{egh iNfi min max tvx;}CKcK;CCKOpSS[o P Q????OS T U/ Vgggg W X ()Y')O O O O _ ;=> Z<> GH [FH XY ]WY/ / / / ? gij ^hjw w w w st_rt a      bW W W W w c  d  eO O O O _  6BMf  $>h    ' g_ _ _ _ o %' $o # "_ !  w   rt hj? WY FH <>_ ') /Opfi BT '8; %'  7  WqfiSystemSystem.Collections System.DataNPlot4/home/carlosble/svns/nplot-gtk/lib/NPlotException.csEGiFG____oNPjOPUWkVW(VW'OP&oFGSystemNPlot//home/carlosble/svns/nplot-gtk/lib/ArrowItem.csQrSxTUlRU]r_x`abm^b+krmxnopqnlqcccc fontFamilyMFG HEH !angle mul normAngle toPoint]xDir yDir xOff yOff  fromPoint] head] xOff2 yOff2 textSizeq halfSizeqquadrantSlideLength  quadrantF quadrantprop dist offsetFromMiddlea>?}~ 4[t  #_! /!C#d%u&'(23689:=?BD!E-FEIJKZN_PmQyRUX[]^_behlqT_!EJZ_mq?11{|oz|????Op~qr's____otuv7777GwxyzWWWWg{|{z||~ }////? ~wwww WWWWg@?>g=<;:?9~8z|Bq7g6543G210o/'.-~,Oz|+lq*+^b)RUAEHSystemSystem.DrawingNPlot2/home/carlosble/svns/nplot-gtk/lib/AssemblyInfo.cs4/home/carlosble/svns/nplot-gtk/lib/AxesConstraint.csT VWUWZZZZrb def%cf"#$%& desiredLength currentLengthdelta changeLeft changeRightstuwx#y({3}E~GJOQTAp3TEJOTr   m ! e!e!e!e!}! !!!!!'()*+ desiredLength currentLengthdelta changeBottom changeTop$*5GIMRUXKz5XGMRX " "!"x" # p#p#p#p##    ##### ?!a"#&')*-B.G1R3d4678;<>E?iD BBRdD $ $ $ $$`bc acH%H%H%H%`%mop qnq%%%%%{}~ |%%%%& %H&H&H&H&p&,-./0123456789:;< xWorldRange xPhysicalRange  xDirPixelSize  yWorldRange yPhysicalRange  yDirPixelSize currentAspectRatio toAdd  newHeight changeInHeight changeBottom changeTop toAdd  newWidth changeInWidth changeLeft changeRightCGd Jz@p  Iy 9l 2&&&!()P)Op&N&|M%nqL`%acK%DJ# I#H8#G!F}!E-!rDcfCrUWSystemSystem.DrawingSystem.Drawing.Drawing2DNPlot*/home/carlosble/svns/nplot-gtk/lib/Axis.cs%+1p+p+p+p++ %+18?+++++ %+2 , , , ,8, =a79< =&>-?/ 4?p,p,t,~,, KL MN$O0P<QHRTS`TlUxVWXYZ[\_`acd%g*j1kGl]msopr%*1Hr,,,,- > fontFamilyM|}~%,3>IPW^elw~'{....2.D.,/  +CEG +CEEGd/d/d/d// (49JVfvV(49VJVfv//// \0 ?@ABCD _physicalMina _physicalMaxarange prop  largeClip offseta  ! "%&,.002<4>6J8L;Q=]?_AkImJ{OPRSUWXZ[_c.dZ m0L<>JLQm]_kmd000Q1 I2 EFGHIJKL _physicalMina _physicalMaxaaxis_X axis_Y len posRelaprop world }  (8HMRw u222b33 MNOPQRSTUVWXYZextraOffsetAmount  offsetLength  x_component  y_component theta averagea labelSizeqdrawRectm recPointsa x1 x2 y1 y2$/:CjzI_s|AJl/C:Cz(J4J44N56 [\]^_`abcdefghijklmnopqrstuvwx tickStartaaxisDirax1 y1  tickVectoratickEndaminXminYmaxX maxY textSizeq textCenterX  textCenterY  textScaledTickVectora rotatePointa actualAngle radAngle m recPointsat_x1 t_x2 t_y1 t_y2 drawRectbx1 by1 bx2 by2 drawRect  drawRect_int #&)+*Z-/17:; @9AOBeC{DGTV]`ad+e?fSkXlaojp~stx}+0U`s1:[|0<HR\iot )66SXo+0U`t6 N66n79 ; yz{|}~x1x2y1y2bounds labelOffset tickBounds labelBounds(<P_j   j<<0<< = lo]norm1 norm2 b$% &3'Y)`-h.j0q1y4~6`hqy~"6 h=h=x=== HIMGML>L>L>L>d> pqr or>>>>>  >>>>?  ?=?GGGGG BCACHHHH-H QRPReHeHeHeHuH UVTVHHHHH bc acHHHHI fg eg=I=I=I=IMI rsqsIIIII vwuwIIIII JJJJ%J ]J]J]J]JmJ JJJJJ JJJJJ 5K5K5K5KEK }K}K}K}KK KKKKK  L L L LL  ULULULULeL LLLLL LLLLL  -M-M-M-M=M uMuMuMuMM MMMMM    NNNNN MNMNMNMN]N   NNNNN #$"$NNNNN XYWY%O%O%O%O5O mOmOmOmO}O  OOOOO PPPPP MPMPMPMP]P PPPPP PPPPP %Q%Q%Q%Q5Q mQmQmQmQ}Q QQQQQ ()')QQQQ R ,-+-ERERERERUR NOPQMQRRRRR RMQ@9DUR+- R')Q}Q5QPPL@]PPO}O?T??>or5OWYd>GM>"60=; 64u2d0/S8,R+Q+,/{-Hr,4?N"$N ]NN  MM=M~L}L|eL{LzKyKxEKwJvJumJt%JsIuwrIqsqMIegpIacoHTVnuHPRm-HAClG=?kG,/jMG(*iGhFgmF f%FeEdEcMEbEaD`uD_-D^C]C\UC[ CZBY}BX5BWAiqVAegU]ARTTANP System.Drawing.Drawing2DSystem.DrawingSystemSystem.CollectionsNPlot ./home/carlosble/svns/nplot-gtk/lib/BasePlot.csJKIKXXXXX NOMOXXXXX \][]3Y3Y3Y3YCY `a_a{Y{Y{Y{YY mnlnYYYYY qrpr Z Z Z ZZ ~}SZSZSZSZcZ ZZZZZ ZcZ}ZprYlnY_aCY[]XMOXIK SystemSystem.DrawingNPlot :/home/carlosble/svns/nplot-gtk/lib/BaseSequenceLinePlot.cs<[[[[["#!# \ \ \ \\&'%'Q\Q\Q\Q\a\>? =?\\\\\35 69;) )2;\\\\ ]\=?]2;a\%'\!#[SystemSystem.DrawingNPlot6/home/carlosble/svns/nplot-gtk/lib/BaseSequencePlot.csdata_tlop*q7rCsL ks]]] ^=^HI GIu^u^u^u^^LM KM^^^^^YZ XZ_____]^ \^M_M_M_M_]_=^ks]_\^_XZ^KM^GI SystemNPlot :/home/carlosble/svns/nplot-gtk/lib/Bitmap.PlotSurface2D.csKMNO LO4`4`4`4`T`UWX Y VY`````cd )bd`````lm *km,a,a,a,atttt uxPos1xPos2minDistxPos3xPos4 *HLXv     X ODuDuXuuvcd bearishBrushm bullishBrushmoffset  addAmount  stickWidth minDist pIi point xPos yPos1 yPos2 yPos3yPos4 #0$<&H'J)U,d-n/v23578;FFIJMOP\RaS{TUWijkl0n5pAq]sftuvxyz}F%2Ud20Af P-^v^vvcw x candleData07 QSySyWyjyy candleData07 RyyyyypI C S!z!z%z.zFzx Twx~z~z~z~zz ?zzzzz @{{{{{ AN{N{N{N{^{ B{{{{{ C{{{{{ D&|&|&|&|6| En|n|n|n|~| F||||| G||||} HF}F}F}F}V} I}}}}} J}}}}}GH KFH~~~~.~KMOP LJPf~f~f~f~~ef Mdf~~~~~ij Nhj [VVVVf \&-4;FV a    ,!=)FVa ])min max minStep first second first second first second  first  second  +AXpz6Qb %Kk6Az66b%Kkk ` JЁ min_l max_l min_h max_h a !6;Vqz 6;q a @@Tރsizeln qsv!x-{9}I~Zp{ !-9I ^i&&*5x open low high close x open low high  close 79 B9DEEgFGHJNPLQdR|STV[^ 9EL _4^ =5zwxhj~df~JP.~FH}}FzV}}|~|6|{{^{{zyyy&v u ݄i U4^ )  ft|t4tss\s~sqsrmor`b@ A DFG)H2ICJLK]MfRjWY^`fhjlnqr uxx!z&{;xJ}WQjj 6! @+KM;MRv j WW&; nS}nn֏#diff i'/4<b|'/4| o``h{ g[[[[k hk#(S}6`ߊ?y{nqde^`]LUSystemSystem.DrawingSystem.CollectionsSystem.GlobalizationNPlot2/home/carlosble/svns/nplot-gtk/lib/ErrorHandler.cs_bcd&e:fN p`fIIIIyWX rVX] s[]op tnp9999Iyz uxz vɛɛɛɛٛ w!stsfprependi38<HP<38 xYYi%$!#ٛ"xz!Inpy`f []VXSystemSystem.DiagnosticsNPlot2/home/carlosble/svns/nplot-gtk/lib/FilledRegion.csFHIJ$}GJ''''GRTUV$~SV^`ab$_bממממtbmpointsapointsaa1ta2tcountpointsai imopruUwmxtyz{}~!9@h8k| "Um9 "l '//Wȟ СССС*)+Hl(_b'SV&GGJSystemSystem.DrawingNPlot0/home/carlosble/svns/nplot-gtk/lib/FontScaler.cs*/home/carlosble/svns/nplot-gtk/lib/Grid.cspattern Z\]^-`9bIdPeW[eRip1ap2ap3ap4a+8?M[`n|?[`|ΣNxLargePositionsyLargePositionsxSmallPositionsySmallPositions.?Jev?Jvopnpstrt>>>>NΦΦΦΦަ&^^^^n65n432n1&0ަ/.Nrt-np,R[eSystemSystem.DrawingSystem.Drawing.Drawing2DSystem.CollectionsNPlot3/home/carlosble/svns/nplot-gtk/lib/HistogramPlot.csW2Y8XYiiiiy     datatyoff ip1Tp2Toffset offset  currentPlotyval  stackedToDatat offset  xPos1a yPos1a xPos2ayPos2awidth height xoff rdii m%n-oOsTubvmwxyz|}~-;>DLQ'7G[o ,Clwi%b;QG ,wc@ datatap1Tp2Tp3Tp4Toffset1 offset2  %19PX[^cks"$%&)*-.0 1 1^c1Ȯ !tmpMax  adapterList currentPlotadaptersti tmpHeight jadatat;= >@CI>KLNbNePjQrQuSzTQUVNXZ[_bd  >bjrz 9d  D¯"#$datathpDatati<CJ[fhmC[ffm" F  *IJHJjjjjzMNLN² BBBBR ',7 ',7ҳҳҳҳBBBBRҴҴҴҴ*bbbbr  ) )bbbbrErFCD*BrA*K2Jұ@>R?I9dH1= <;R: GYc7yXY9²LN8zHJSystemSystem.DrawingSystem.Drawing.Drawing2DSystem.CollectionsNPlot4/home/carlosble/svns/nplot-gtk/lib/HorizontalLine.csD&F,G3EGƸƸƸƸ޸!O&Q,R3S?PS6!Z&\,]3^:[^nnnn!hj<gjƹƹƹƹֹ!!VVVVf!,23?LXjv,323 !%&'()*xMinxMaxlength  lengthDiff  indentAmount yPos )2<GPV\u ..F!tusu0000@!xywyxxxx!м!!PPPP`!!!((((8!pppp!Ⱦ!!HHHHX!ZXYXȾWV8UTS`_^]f\RQмPwyO@su[ֹgjN[^M6PSL޸EG SystemSystem.DrawingNPlot! //home/carlosble/svns/nplot-gtk/lib/IDrawable.cs//home/carlosble/svns/nplot-gtk/lib/IGradient.cs//home/carlosble/svns/nplot-gtk/lib/ImagePlot.cs7=DKRZbh#7=DJ#+,ijnop&p(r-r/t4vLx_zw|r}p~&--4L_wm~SS[k#-./0123456789:;<= worldWidth numBlocksHorizontal  worldHeight numBlocksVertical  physicalWidth  blockWidth  wPositivephysicalHeight  blockHeight hPositive i j wX  wY pIxy./GPhq#6IP[bmx28K./K22#P[bmx(KK # SSSS[#)+ .T/{ T(/#8: =T>{ T7>#mlmSSSS[#NOMO#RSQS#_`^`####3#cdbdkkkk{# 3: 3###[[[[k##MNLN#IJHJ3333C#Z[Y[{{{{#^_]_#s[lmm]_lY[jLNkCHJr7>q(/ihkp[ g#foa`nm~e{bdd3^`cQSbMO"SystemSystem.DrawingSystem.Drawing.Drawing2DNPlot#"//home/carlosble/svns/nplot-gtk/lib/IMeshPlot.cs+/home/carlosble/svns/nplot-gtk/lib/IPlot.cs4/home/carlosble/svns/nplot-gtk/lib/IPlotSurface2D.cs2/home/carlosble/svns/nplot-gtk/lib/ITransform2D.cs3/home/carlosble/svns/nplot-gtk/lib/ISequencePlot.cs//home/carlosble/svns/nplot-gtk/lib/LabelAxis.cssuvtv%|~ }%OOOOg%>aHJLN"O)P+"GP%Y[\^3_?`KX`M%hi jgj% %?@ABCDEFGHIJ tLabelOffset] tBoundingBoxlastPosaithisPosadist largeTickPositionssmallTickPositionsi tickPos  thisPosa dist :<A{#/QTYj:#A{QY %%U%KLMNi numbers_copyi worldPosition  Wko   #kWk#eeu f%./-/%23136666F%EFDF~~~~%IJHJ%WXVX%[\Z\VVVVf%|fZ\{VXzHJyDFxF13w-/#-vgu}ttvgj~MX`}GP$SystemSystem.CollectionsSystem.DrawingNPlot%$4/home/carlosble/svns/nplot-gtk/lib/LabelPointPlot.cs )AAAAQ)YZ[\]^_datattextDataiptTxPosayPosasizeq68= E"g#w$%'(+,H.M/1245I9N<T=_>dh@t6t=d=NgNNMMNT_@ )RRRRb)))****:)rrrr))LNO PQMQ*) +;LW +;Lbbbb)`arows dataPoint Z\_a.c9hDjTm_nrtvxy}!(3>DO.9DT_3>DV )@:bQ .V*MQ(SystemSystem.Drawing System.DataNPlot)(0/home/carlosble/svns/nplot-gtk/lib/LegendBase.csGIJ0K;LFMQNXO_HO+bcbgi\]^_[_9+defghijklmnopqrstuvwxyz{|}~textFontY labelCountmaxHtmaxWd unnamedCountiplabel labelSizeq extendingHorizontally extendingVertically widthInItemCount heightInItemCount lineLengthhSpacingvSpacingboxWidth boxHeight totalWidth totalHeightoffset plotCountipxposyposlineXPoslineYPostextXPostextYPoslabeloq ruz&{(|*},~/~27IN]inw~ %*-29CPV[fip|)LQ]h)5 : @GR]bmx !$'!(%+)8+T &/7INin-%*-9V[fp|L]8%5:G]bxk+gqq+5646)+9:8:aaaaq+FGEG+JKIK+WXVX9999I+[\Z\+higi+lmkm!+YYYYi+++1111A+yyyy++Ai!kmgiZ\IVXIKEGq8:)46k+9[_HO*SystemSystem.CollectionsSystem.DrawingNPlot+*,/home/carlosble/svns/nplot-gtk/lib/Legend.cs #*18  - $- leftIndent rightIndent bottomIndent topIndentlegendWidthHeight changeAmount  changeAmount  changeAmount changeAmount(;IVb   9>I^{"$&(*-/1358:$<1>>@ACQEoGIKPQR S>UoVWX\9;Ib9>{I^9$Q>Ao\ 8\\,-ab `b-ef df -qr prDDDDT-uv tv--,-ddddt---<<<<L-|\$Lt,tvTpr df`b,SystemSystem.DrawingSystem.Drawing.Drawing2DSystem.CollectionsNPlot-,0/home/carlosble/svns/nplot-gtk/lib/LinearAxis.cshjkik/rftlursu$$$$</~fnttttt/a HJLN"O*P,"#GP/XZ[\^+_7`C$W`BBBBz/ %/ tLabelOffset] tBoundingBoxlargeTickPositionssmallTickPositionsi labelNumber labeli 37CFK[p{?ERCCKp{R?&a/physicalAxisLength adjustedMax  adjustedMin shouldCullMiddlebigTickSpacing nSmallsmallTickSpacing pos1 i j pos  ,4@JR^pu^u' /(/ adjustedMax  adjustedMin shouldCullMiddletickDist first nToFirst nToFirst position  safetyCount i culledPositions,. 1+286E<V>^AnBFHIJMNRT[]^`ab fgh#l<m@oFqNs[s^ucvus{yz{| +n#F[[cu)( (77c X/ adjustedMax  adjustedMin range approxTickStep exponent mantissa  mantissaIndexitickStep physicalStep #.>OZan{ "(7:HSoy~#.>aOZ"  7HS~* , /exponent mantissa i /:FRikp   /:Fip+[/!" "/    /6757SSSSc/2313/GH EH/BC AC++++;/UVTVssss/YZ XZ/fg!eg/jk"ikKKKK[/[ikegXZTVEH;ACc5713 "y(<suikzW` GP.System.DrawingSystem.CollectionsSystem System.TextSystem.DiagnosticsNPlot/.4/home/carlosble/svns/nplot-gtk/lib/LinearGradient.csE GHI ,FI}}}}1rgb !(7>s !(7> 3 Q1ST -RT1WX .VX1de /ce1111A1hi 0giyyyy1uv 1tv1yz 2xz    1ixztvgiAceVXRTFI0SystemSystem.DrawingNPlot10./home/carlosble/svns/nplot-gtk/lib/LinePlot.csD.F4!4EF# # # # 3 3M.O4P;!5NPk k k k  3X.Z4[;\B!6Y\     3 shadowPenIdatatt numberPointsphysicala leftCutoff  rightCutoff shadowCorrection i dx1 dx2 dy1 dy2 p1a p2a hik lo&rDtLvSx^}_fu|(-<KT]d!EJ\l%- &^_f(|(--T]d-!EJ!Ag-  O   3  !B' ' ' ' G 3data_t%!C     3data_t%!D    357<!E47KKKK[3!73!83!9####33!:kkkk{3$%!;#%3()!<') 3AB!=@BCCCCS3EF!>DF3]^ !?\^3RT UXZ) )!@QZC3\^SQZDFS@B[47 ')#%{3 O  g Y\ NP3 EF2SystemSystem.DrawingSystem.DiagnosticsNPlot32-/home/carlosble/svns/nplot-gtk/lib/LogAxis.csdf$g*"Keg'5oq%r+"Lpr____w5{}&~,"M|~5a,GHJL"M*N,""YFN =5XZ[\]+"ZW]}}}}5 "[5 tLabelOffset] tBoundingBoxlargeTickPositionssmallTickPositionsoffset]bbilabeldira rr i ),8;@Gh".16hn{88@".{.{6h"\ %%Q5bigTickSpacing nSmallpos1 ipos jm pos1 i pos i j pos  dec pos1 ipos  #+7CQV_nz|  3?UX]gt "$%&+,-)-,/10;2U4e-k8v 7CVnzv?U]tv)v1eUe"]8:33w%5 dMyInterval dPower  dFixPower d5Region dMyMult @AB CDF#H2I7JBMGNUP`RvT}2BG`v}"^?TE5 roundTickDist first nToFirst mark val efh j+m6p=sDuTxhy}  +6Th"_c]55MagRange  roundTickDist nticks +;LW^ +;^LW"`q5&24@EP&24@EEP"a5lrange prop offseta3579;!?#A/E:FRGgJK#!#/:"b1K qq} 5t v ret Z] _#b>dEeRh_jaE_"cXj[ [ g   5"O!!!!!5"PI!I!I!I!Y!5 "Q !!!!!5  "R !!!!!5 "S!"!"!"!"1"5tu"Tsui"i"i"i"y"5xz {~# #"Uw"""""5"V!#!#!#!#1#5 # #"Wi#i#i#i##5"X#####5##1#"wy"su Xj# 1K1"! ! !Y!9uc?T8|~wpr'egW]EFN4SystemSystem.DrawingSystem.Collections System.TextNPlot54,/home/carlosble/svns/nplot-gtk/lib/Marker.cs &-4;#d&&&&8&7 &-4;#ep&p&p&p&&7 &-4;#f&&&&&7( *&+-,4-;.B#g).0'0'0'0'`'77 9&:-;4<;=B#h8='''''7G I&J-K4L;MC#iHM((((0(7     p1]p2]p3]pts]gpp1] p2] p3] pts] gp p1] p2] p3] pts]gpp1]p2]p3]p4]pts]gpp1]p2]p3]p4]pts]gpp1]p2]p3]p4]pts] gpZ^P_|`cdehik!mIpNqvsuz{|}~!)7BPUl|)QV~"+9GL\l|!A\l.>pwPN!INUUBPUUVVLLLL#xX!Wh(h((H*-7#j.....7#kP.P.P.P.`.7#l.....7#m.....7#n(/(/(/(/8/7#op/p/p/p//7#p/////7#q000007#rP0P0P0P0`07#s000007 #t000007 #u(1(1(1(1@17#vx1x1x1x117#w111117-X0(HM'8=`').&&8&11 0@1 0 `0 0 //8/..`..6SystemSystem.DrawingSystem.Drawing.Drawing2DNPlot760/home/carlosble/svns/nplot-gtk/lib/MarkerItem.csIKLMN,$yJN333339VXYZ[ $zW[%4%4%4%4M49dfg hi${ei444449prs tu'$|qu4444 59pointa1M$}~E5E5I5V5n59n5~ 5qu4eiM4W[3JN8SystemSystem.DrawingNPlot98=/home/carlosble/svns/nplot-gtk/lib/PageAlignedPhysicalAxis.csOQRS(U;W\XpYZ\]^adf\%~PfW6W6W6W66;pq#%oq7777/7;|~  (K  (%{g7g7g7g77;!%77777;77{/7oq6Pf:SystemSystem.CollectionsNPlot;:2/home/carlosble/svns/nplot-gtk/lib/PhysicalAxis.csTV&UV88888=_ab cd&`d 9 9 9 919=  scratchArea_giboundsmnpqr&lri9i9u999=}~&|~:::::=$&J:J:J:J:Z:=)&:::::=!"#$%&minc maxc tmp tmp half width  $4=P\aj} 4\a&:::3;;=&<<<<#<=&[<[<[<[<k<=&<<<<<=&<<<<<=&3=3=3=3=C==&{={={={===&======& > > > >>=$>#="=!C= <<k<#<);(:'Z:&:|~%9lr19`d8UV<SystemSystem.DrawingSystem.Drawing.Drawing2DSystem.CollectionsNPlot=<,/home/carlosble/svns/nplot-gtk/lib/PiAxis.csoqr 'pr??????y{| 'z|@@@@'@?'_@_@_@_@w@?'aDKMOQ"R)S+"'JS@@@@@?]^'\^-A-A-A-A=A?f'efuAuAuAuA}A?()*+,- tLabelOffset] tBoundingBoxstartendilabel+BUVY^qxUVV^'AAA BB?./0startendi "9LMOTmqxLMMxTm' CC C*CC?1C0B,w@+'@z|*?pr/}Aef.=A\^-@JS>SystemSystem.DrawingSystem.CollectionsNPlot?>-/home/carlosble/svns/nplot-gtk/lib/PiePlot.cs3/home/carlosble/svns/nplot-gtk/lib/PlotSurface2D.cs $*)DDDDEA1a<IKt&(RZ\^<Kt(R\)REREVE`EFA2 fontFamilyM !,7BU]hov})FFFFfGA34diag  scaleFactor (*0(**0)GGGGGA);H;H;H;HKHA )HHHHHA,- )+-HHHHHA5fraction :; <=1?E@_CEH)9H III&InIA6789:positionipxapLyapPOQ6TAXCZI[W[^^``fambtc{ffjkmnoqsuvxz}.:GR^jv{  ,8=IUaiu +7CSXiuf6AI`f.:Rv{aa8=aiu+SCSXiu)NXIIII!LA!-9DV ^ jv"#$ '-j9Dv)'MMMMNA;<=>?@ABCDEFGcb bottomIndentbb leftIndentbb topIndentscale  titleHeightnlCount i bb rightIndent bb 02496q8;<?ADEH-J7MINQPgRrSVZ[[]^_[`befj#l8pGqOtawk~ 1Vz-IrG8Ga). -*O*O^OP wQAHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghiscale x_center y_center  scaled_fontYxAxis1xAxis2yAxis1yAxis2pXAxis1@ pYAxis1@ pXAxis2@ pYAxis2@ oldXAxis2Height ilegendPosition]newXAxis2Height titleExtraOffset xt yt  scaledFontYnlCounti sq smoothSave legendDrawni_oizOrder drawablexapLyapP drawXAxis@ drawYAxis@! axisBounds%<S^lqx'/;COWZ]`czJO[#7BQV^ !#$')+#-&-)0.1C2X5f7y8<=>CEFILNORVXZ!['--]?_Rchdpexfhlmno{%^lqxJ[BQV^&?.'fyRh){"sQQRTXA)XXXXYA )GYGYGYGYWYAjindex !-9EKRXKR) YYYYYAklmnizpos fraction d +GKbfwwb) 7Z7ZGZqZZAopindexpL   ' .5)[[[/[_[AqrindexpP  '.5)[[[[[A " ")\\\\=\A)\\\\\A)\\\\\A)]]]]%]A)]]]]]]]]m]A)]]]]]A)]]]]]A  )  5^5^5^5^E^A)}^}^}^}^^A)^^^^^A())') _ _ _ __A45)35U_U_U_U_e_A@A)?A_____AMN)LN_____AQR)PR-`-`-`-`=`A]^)\^u`u`u`u``Aab)`b`````Ano)moaaaaaArs)qsMaMaMaMa]aA~ )}aaaaaA)aaaaaA)%b%b%b%b5bA )mbmbmbmbbA)bbbbbA)cccc=cA)ucucucuccA)cccccA)dddddA)MdMdMdMd]dA)dddddA)dddddA)%e%e%e%e5eA)memememe}eA)eeeeeA)*)(*eeee fA-.),.EfEfEfEfUfAVUf,.U f(*g[f_[TeeZdYS}eR5eQdPdcWYO]dNdbYaX{`Q._N'^MN]vI9H\H+-[HZKHYH2EXfGMcLcK=cJbIbH5bGaFa}E]aqsDamoC``bB`\^A=`PR@_LN?_?A>e_35=_')<^;^:E^  9]8]7m]6%]5\4\WPF3M\@SystemSystem.DrawingSystem.DiagnosticsSystem.CollectionsNPlotA@3/home/carlosble/svns/nplot-gtk/lib/PlotSurface3D.cs,/home/carlosble/svns/nplot-gtk/lib/PointD.csMNO+LOjjjjjCWX!+VXjjjjjCijVXhjLOBNPlotCB//home/carlosble/svns/nplot-gtk/lib/PointPlot.csDFG,EGkkkkk'MOP ,NPkkkkk'OPQRSTUVdata_t leftCutoff_  rightCutoff_ ixPosayPosayMinTyStarta[^_;aXaZc_efgijkmn=oMrasX_,Zs,l,lLllJm'Wdata_t|%,{mmmmm'Xdata_t%,nnnn.n'?D^?^,fnfnfnfnn',nnnnn',&o&o&o&o6o'n6on.nm{jmZskNPkEG&SystemSystem.DrawingNPlot'&6/home/carlosble/svns/nplot-gtk/lib/RectangleBrushes.csZ\]-[]HpHpHpHp`pEfg-`egpppppEqr -prpppppE|} -{}(q(q(q(q8qE -pqpqpqpqqE -qqqqqE -rrrrrE -HrHrHrHrXrE -rrrrrE -rrrrrE - s s s s0sE -hshshshsxsE -sssssE -sssstE -@t@t@t@tPtE -tttttE   -  tttttE -uuuu(uE!" - "`u`u`u`upuE,- -+-uuuuuE78 -68uuuuvEBC -AC8v8v8v8vHvEMN -LNvvvvvEXY -WYvvvvvEcd -bdwwww wEno -moXwXwXwXwhwEyz -xzwwwwwE -wwwwwE -0x0x0x0x@xE -xxxxxxxxxE -xxxxxE -yyyyyE -PyPyPyPy`yE -yyyyyE -yyyyyE -(z(z(z(z8zE -pzpzpzpzzE -zzzzzE -{{{{{E  - H{H{H{H{X{E -{{{{{E -{{{{{E)* -(* | | | |0|E45 -35h|h|h|h|x|E?@ ->@|||||EJK -IK||||}EUV -TV@}@}@}@}P}E`a -_a}}}}}Ekl -jl}}}}}Evw -uw~~~~(~E -`~`~`~`~p~E -~~~~~E -~~~~E -8888HE -E -E -  E - XXXXhE - E - E - 0000@E -xxxxE -ЁE -E -PPPP`E&' -%'E12 -02E<= -;=((((8EGH -FHppppERS -QSȃE]^ -\^Ehi -giHHHHXEst -rtE~ -}؄؄؄؄E -    0E -hhhhxE -E -E -@@@@PE - E -!ІІІІE -"(E -#````pE -$E -%E -&8888HE  -' E -(ȈȈȈȈ؈E#$ -)"$ E./ -*-/XXXXhE9: -+8:EDE -,CEEOP --NP0000@EZ[ -.Y[xxxxEef -/dfЊEpq -0oqE{| -1z|PPPP`E -2E -3E -4((((8E -5ppppE -6ȌE -7E -8HHHHXE -9E -:؍؍؍؍E -;    0E -<hhhhxE -=E   ->  E -?@@@@PE ! -@!E+, -A*,ЏЏЏЏE67 -B57(EAB -C@B````pELM -DKMEWX -EVXEbc -Fac8888HEmn -GlnExy -HwyȑȑȑȑؑE -I E -JXXXXhE -KE -LE -M0000@E -NxxxxE -OГE -PE -QPPPP`E -RE -SE -T((((8E -UppppE -VȕE -WE() -X')HHHHXE34 -Y24E>? -Z=?ؖؖؖؖEIJ -[HJ    0ETU -\SUhhhhxE_` -]^`Ejk -^ikEuv -_tv@@@@PE -aE-eE.-b((((8E.-cppppE.-dșE -f E-jXXXXhE.-gE.-hE.-i0000@E -kxxxxEstuvbrush relativeIntensities relativePositions blend "#$C%r&x'()*-o!* ЛЛ0xE56.-l46E@A.-m?AEKL.-nJL@@@@PEacd e-pbeEwxyzbrush relativeIntensities relativePositions blend nopCqrrxstuv-tmv @E.-qОE.-rE.-sPPPP`E `  О mvbePJL?A46x!*@h ș8Ptvik^`xSU0HJ=?24X')ȕ8`Г@h ؑwylnHacVXKMp@B(57*,!P  x0XȌ8`z|oqЊdfY[@NPCE8:h-/ "$؈ Hp(Px0}rtXgi\^ȃQSFH8;=02%'`Ё@h H~p~(~uw}jl}_aP}TV}IK|>@x|350|(*{{X{ {zz8zyy`yyxx@xwwxzhwmo wbdvWYvLN~HvAC}v68|u+-{pu "z(uyt  xtwPtvtustxss0srrqrpXrornqmql8q{}kpprpegj`p[]DSystemSystem.DrawingSystem.Drawing.Drawing2DNPlotED0/home/carlosble/svns/nplot-gtk/lib/RectangleD.csEFGHI.uDI5555]GRS.vQSGVW.wUWݪݪݪݪGab.x`b%%%%5Gef.ydfmmmm}Gpq.zoqūGtu.{su G.|EEEEUG.}GU suūoq}df5`bUWQS ]DIFSystemSystem.DrawingNPlotGF5/home/carlosble/svns/nplot-gtk/lib/SequenceAdapter.cs{|data9 rowsPSUXY.Z9\O^``qb}cdfhkmnortuvx {%}+2=HS^ijv&9K^pq  /ABGcepv'(:FQRWb } +2jvBqqB BBBcRpv(:RRRWW/~QZƭޭI#$ /"$ƱI}a-/ 01/,1 ,I~i<<>ACDE<F/;F ddhpI   /  I!/HHHHXIȲ;F,,1Ʊ"$X  ~QHSystemSystem.Collections System.DataNPlotIH//home/carlosble/svns/nplot-gtk/lib/StartStep.csHJK L0ILSSSSsKVW0UWKZ[0Y[Kfg0eg;;;;KKjk0ikK ikKegY[UWsILJSystemNPlotKJ./home/carlosble/svns/nplot-gtk/lib/StepPlot.csCE!F(1DF^^^^vMdatat leftCutoff  rightCutoff ip1Tp2Tp3Toffset offset  xPos1a yPos1a xPos2a yPos2a xPos3ayPos3amiddle width RUV,X:X<ZA[J]lbqdegijknopqr uwx1yAzQ}a~q/FWbX:Alqa/1P.̷ <Mdatatap1Tp2Tp3Tp4Toffset1 offset2 *18@HXhs{*1s1ԹԹSMdatat%1337D\M<1M1ܻܻܻܻM1$$$$4M1llll|M  1  ļM"# 1!# M ) )1DDDDlM./1-/ĽM23113 M?@1>@DDDDTMCD1BDMQR1PRԾԾԾԾMUV1TV,M-,TV,PR+BD*T>@) 13(Ľ-/& !#'|%ļ  $|1"#40\/.P!vDFLSystemSystem.DrawingNPlotML1/home/carlosble/svns/nplot-gtk/lib/Transform2D.csretIPR S 2HSOcef g2dg0000POru32quO?2~O28O!2ppppO-2O87685~4qu3Pdg2HSNSystemSystem.DrawingNPlotON+/home/carlosble/svns/nplot-gtk/lib/Utils.csQSUV3PVQc `abc 3_c#+KQnoG3moQz{G3y{Q +2= +23CQoe (*8FMRY`*FY3kQr e (*>RY^jw' ) +*Rj)3 Qie  "#$('*(>*R*T-Y/l1t4w68*:<*RYtw3<<<DTQdiradirNorm GH%IKKWOPW3FP<<D]QfsQguUsz nmZ[\]^_!`,3Y`;Qfinalijkmmooq"r>oBsXm\urvtrXX">3jv ssQCjvB;Y`AFP@<? >=S<y{;mo:K_c9PVPSystemSystem.DrawingSystem.Drawing.Drawing2D System.DataSystem.CollectionsNPlotQP2/home/carlosble/svns/nplot-gtk/lib/VerticalLine.csE&G,H34FHSP&R,S3T?4QTS\&^,_3`:4]`;;;;[Sik<4hkS4S4####3S,23?LXjv,3234 kkkkSyMinyMaxlength  lengthDiff  indentAmount xPos )2<GPV\u4 eSuv4tv Syz4xzEEEEUS4S4S4-S4eeeeuS4S4S 4 ====MS  4  S4S4%SR%QP  OM NMLuK-WVU3TJIHUxzG tvShkF[]`EQTDFHRSystemSystem.DrawingNPlotSR>/home/carlosble/svns/nplot-gtk/lib/Web.Design.PlotSurface2D.csplotxsyssw1output5UW X!X(Y.ZCZJ\P]V^^_y`abcdefg h i,j8kOlVm]ndokprry5PrL4WX4PrTSystemSystem.DrawingSystem.Drawing.Imaging System.IO System.Web.UISystem.Web.UI.WebControlsSystem.ComponentModelNPlotNPlotUT NPlot.WebVUNPlot.Web.DesignWV7/home/carlosble/svns/nplot-gtk/lib/Web.PlotSurface2D.cs] _6^_]]]]mZtoReturnmnopq1r=s?6lsZ{| 6z|((((8Z 6ppppZ6Z 6Z6HHHHXZ urlParams getParamName,iuu,i6ZrequestMresponse]bmps 8>Iou8>655E|Zbgi$/6d   ,7BRbmx !"#$%&/d 6&tt|wZ/0 6.0Z 6Z 6WWWWgZ 6Z 6Z 6////?Z 6wwwwZ 6Z 6Z 6OOOO_Z  6 Z 6Z!" 6 "''''7Z%& 6$&ooooZ56 646Z9: 68:ZIJ 6HJGGGGWZUV 6TVZab 6`bZqr 6pr/Zuv 6tvggggwZ 6Z 6Z 6????OZ 6Z 6Z?@ 6>@'ZCD 6BD____oZXY 6WYZ\] 6[]Zlm 6km7777GZ{| 6z|Z 6~Z 6Zyx~wz|vGkmu[]tWYsoBDr'>@.0&<qpoOnmlwtvk/prj`biTVhWHJg8:f46e$&d7 "cb a_`_^]?\[ZgX~}|{8z|zlsYm^_X SystemSystem.DrawingSystem.Drawing.Imaging System.Web.UISystem.Web.UI.WebControlsSystem.ComponentModel System.IOSystem.Collections System.TextNPlotYX NPlot.WebZY@ABCEWFGH7IJK'LMNOPOQST/UVW X_ Y Z [? ] ^ _ aw b c d_ e fo g' hoijkl+mnOopq'rostuGvwxygz{|?}~gr-!}!!8###%`%%&p&)++8,A]AAA5B}BB CUCCC-DuDDEMEEE%FmFFGMGGG-HuHHIMIII%JmJJJEKKKLeLLL=MMMN]NNN5O}OOP]PPP5Q}QQ RURR,-,//0246;0=>d>>?T??L@@XXCYYYZcZZ\a\\][^^_]_=^T``dddddz?{@^{A{B{C6|D~|E|F}GV}H}I}J.~K~L~MN&vOyPyQyRFzSzTf[\]݄^U_`abc?deߊfkgh]ijk`l6m(n#oyprsItuٛv!wxG}~HRNަ&nnyz² R R*r*rYұ2޸6@м`8ȾXֹf3{#kC[[gFfM- Qb:kkn6ojmm.nn*.)qI!iA9   T  ,tL$|<c; ![" #z$%&'()y*+,-.A/012i33 4 5 67839{:; <S=>?S@ AO B CD[E'KwLM!OY!P!Q!R1"Sy"T"U1#V#W#XEYZ[\]^u_`9a# b c8&d&e&f`'g'h0(i.j`.k.l.m8/n/o/p0q`0r0s0t@1u1v1w-x3yM4z4{ 5|n5}6~/777819#<k<<<C===>9:Z::;?'@w@@=A}ABCEM\\\%]m]]]E^^^_e___=```a]aaa5bbb=cccd]ddd5e}ee fUfPFfGHKHHHvIMNQXYWYYZ_[[jj`pp8qqqrXrrr0sxsstPttt(upuuvHvvv whwww@xxxy`yyy8zzz{X{{{0|x||}P}}}(~p~~H  h   @ Ё`8ȃX0xP !("p#$%H&'؈( )h*+,@-.Њ/0`123845Ȍ67X89:0;x<=>P?@A(BpCDEHFGؑH IhJKL@MNГOP`QRS8TUȕVWXXYZ0[x\]^P_p`a8bcșde fgh@ihjklmPnxopОqr`st]uvw5x}yūz {U|}~~XƱ,ȲsKv4|ļ |Ľ T,\P8KS;[ U-uM%34mg?_7W/wO'oG8X<%D *7g{/%%%)* +TE+R%XtXZc[[Q]] ]__ 0_,n,q )q L˙ M͝ ԢԢ Ԣ65B###SSS KKKK f&U) _T HQ!"!$%#%2X3$355%6'8g8&8S>C?'?CZD(DDD)6Dfi*6jjjjj+jj/kOk,\knoo-pȩ. լe/0#˵1/dt2p3 U4`]5l|6,%Wnplot-gtk-0.9.9.2/lib/NPlot.Gtk.dll.mdb0000644000175000017500000001265710512404273020103 0ustar carlosblecarlosble#&E'[2lxL{T'D007/home/carlosble/svns/nplot-gtk/lib/Gtk.PlotSurface2D.cs|||| !(!%&'*%$',,,,Dareag!bounds-+-./1A2P3b4dbP&*4||89:;<'7<3333[g!bounds-@A C DF#GDHPJoK|LDP|(?L RS )QSJJJJZWX *VX]^+\^bc,ac""""2gh -fhjjjjz . / lm kmBBBBRpq oqvw uwz{ y{* bbbbr     ::::J      " ZZZZj   2 2 2 2 B  z z z z       R R R R b      * * * * :  r r r r          J J J J Z         " " " " 2   j j j j z  ! !!"!! %% #%%BBBBR)) $))$))#R%%" !!!  z 2    Z    :   / b    B .j "   J r*y{uwoqRkm-zfh,2ac+\^*VX)ZQS(?L'[7<&*4%D$'!SystemSystem.CollectionsSystem.ComponentModel System.DataGtkSystem.DrawingNPlot NPlot.Gtk-/home/carlosble/svns/nplot-gtk/lib/sysdraw.cs  x_drawablex_offy_offdisplaygraphics}miargsrg!! #'%.&:'J(R)]*+-/0 30 YY}l0t0SystemSystem.ReflectionSystem.Runtime.InteropServicesGdkR*r J   " jB    b   :    Z   2 z  ! "R#$D%&['(Z)*+2,z-. /t3/D+nplot-gtk-0.9.9.2/lib/mf.exe.mdb0000644000175000017500000002734210512404275016732 0ustar carlosblecarlosble#&E'1% *I'}2Q.D-.../home/carlosble/svns/nplot-gtk/lib/MainForm.cs ssssmf?@A BC>C Nstart end xs ys it lp-gh i)oGpRr^ratfuvwryz{|~ ;GR^ffIIiU lp-myGridEmyAxisM "-8>ELXdto daub4_h daub4_g a t nsiiji j 'NU]`eqwz%+4>@e4w4%% "0 @ !"#$%fineGridEnptx y step ixmin xmax ymin ymax lp- loga] lp1- linMlxM +3;BEJZrx'3@ L Y ` hp %$5%@BJr%4 M&'()*+,-./012345mygridEnptx y step ixmin xmax ymin ymax lp- logax] logay] lp1-linxMlinyM+- ./02+3.456<9C9F;K<W=d9j>r?w@~ACDEFGJKLMNOP QR"T/UAVKWUXaYmZy[\^_`abefghijk l,n9oKpUq_rkswtuwyzCrKd)zB  6789:;<=>rma b mult imqppylp-legend !(+0PYej ")1Oer(0Yej~ %  [  ?@ABCDErmlena b isplp- "%*Jjy #0@Vfq"*y  91FGHIJKLMNsizexs ys ilp-linePen1afileim !#(Qz~"Bbny!(z  OPQRSTUVWXmygridE majorGridPen1pattern xs xs2 xs3 hphp2hp3 la #:AHTfy     )5AIR_ly!"#$%&'()*%,;-H.a/v13567 7 4GfYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~mygridEParticle_Numberx y alpha beta gamma emit da xmax xpmax randm i r ippylxMlyMxeli yeli a_rms b_rms g_rms e_rms lp-xeli2 yeli2 lp2-p21pattern range min max !Nbin"xbin #xh $j%i&j 'sp(ly2M<> ?@AG+H6LAMHNOO_RfSnT|VYY^_`abYee ghi0e6jBlRmYnaoipstuvwx{| )8NW`x '17@CH^u !,B0@1@H^ ;)\B rot sr cr brot npttheta ixr yr  8AJbilq 8iq  oozxave xsqave yave ysqave xyave sigmaxsq sigmaysq sigmaxy Npoints i i  '-6<BHNUX]iu6'U] lensrmippytp1laiff  ! - 3 5:cv  !#$%(&5'=(M*Z+l+o-t.+/0134567 8'9<:Q;m=>@BC3:vltC 4Xdsfiledtcpav10sd2_10sd_2_10datesi sum  j average  j av-top-bottom-frarrowIL MO!P*S7T=UDVOWZXeYpZ{[\_`abcceffhifjk lmm"o'psmyqrstuvcy z{|&}2CJS\hy$1>J 'sHL``| "myfiletokensmap ijip-"$),1RXaemx ""m)a)a1RD#D#\##X$y imqx ppylegend 05<^fqx*@]z<$$$%%dsfiledtcp  !*7=DOZep{!"$%&() )4&4&D&r&*'llp1-lp2-framI/2 34536D8Q9:>?@B DFG-H9JEKrLzMNPQSUVWZ,7-b'b'z''(fsMwailp- "027CGR]dly0R7C((($))ti'7N^u)))*z******id!(1C!(***+7+*<w+w+w+w+++?+*z*)(-*' )%x$ #H(C  7; f7  I ~ )z]%oef>C SystemSystem.DrawingSystem.Drawing.Drawing2DSystem.CollectionsSystem.ComponentModelGtk System.DataNPlot System.IOSystem.Reflection NPlotDemoeo]  I  f 7  ( #x$%*'()z**?++D+g-nplot-gtk-0.9.9.2/lib/test.exe.mdb0000644000175000017500000000264010512404276017302 0ustar carlosblecarlosble#&E'ӱrFC1ɠD$h */home/carlosble/svns/nplot-gtk/lib/test.cs daub4_h daub4_g a t nsiiji j'NU]`eqwz""##$##""''(()(('%'+*4+>,@e4w4% , "oo lpmyGrid!myAxis-034 57'8-94:;=B>ILTM`NhRoTUVZ/Zpp|2a lp^`bc$d*e1g<kClNmZnforpsty]yjjrwMplotY~"(.4;AF| ==EZ|]y2/Z8 ,Gtk NPlot.GtkNPlotSystem.DrawingSystem.Drawing.Imaging82D*nplot-gtk-0.9.9.2/lib/AdapterUtils.cs0000644000175000017500000005534710512404107020014 0ustar carlosblecarlosble/* NPlot - A charting library for .NET AdapterUtils.cs Copyright (C) 2003-2005 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.Collections; using System.Data; namespace NPlot { /// /// Encapsulates functionality relating to exposing data in various /// different data structures in a consistent way. /// /// It would be more efficient to have iterator style access /// to the data, rather than index based, and Count. public class AdapterUtils { #region AxisSuggesters /// /// Interface for classes that can suggest an axis for data they contain. /// public interface IAxisSuggester { /// /// Calculates a suggested axis for the data contained by the implementing class. /// /// the suggested axis Axis Get(); } /// /// Implements functionality for suggesting an axis suitable for charting /// data in multiple columns of a DataRowCollection. /// /// This is currently not used. public class AxisSuggester_MultiColumns : IAxisSuggester { DataRowCollection rows_; string abscissaName_; /// /// Constructor /// /// The DataRowCollection containing the data. /// the column with this name is not considered public AxisSuggester_MultiColumns(DataRowCollection rows, string abscissaName) { rows_ = rows; abscissaName_ = abscissaName; } /// /// Calculates a suggested axis for the DataRowCollection data. /// /// the suggested axis public Axis Get() { double t_min = double.MaxValue; double t_max = double.MinValue; System.Collections.IEnumerator en = rows_[0].Table.Columns.GetEnumerator(); while (en.MoveNext()) { string colName = ((DataColumn)en.Current).Caption; if (colName == abscissaName_) { continue; } double min; double max; if (Utils.RowArrayMinMax(rows_, out min, out max, colName)) { if (min < t_min) { t_min = min; } if (max > t_max) { t_max = max; } } } return new LinearAxis(t_min, t_max); } } /// /// This class gets an axis suitable for plotting the data contained in an IList. /// public class AxisSuggester_IList : IAxisSuggester { private IList data_; /// /// Constructor. /// /// the data we want to find a suitable axis for. public AxisSuggester_IList(IList data) { data_ = data; } /// /// Calculates a suggested axis for the IList data. /// /// the suggested axis public Axis Get() { double min; double max; if (Utils.ArrayMinMax(data_, out min, out max)) { if (data_[0] is DateTime) { return new DateTimeAxis(min, max); } else { return new LinearAxis(min, max); } // perhaps return LogAxis here if range large enough // + other constraints? } return new LinearAxis(0.0, 1.0); } } /// /// This class is responsible for supplying a default axis via the IAxisSuggester interface. /// public class AxisSuggester_Null : IAxisSuggester { /// /// Returns a default axis. /// /// the suggested axis public Axis Get() { return new LinearAxis(0.0, 1.0); } } /// /// This class gets an axis corresponding to a StartStep object. The data on /// the orthogonal axis is of course also needed to calculate this. /// public class AxisSuggester_StartStep : IAxisSuggester { StartStep abscissaData_; IList ordinateData_; /// /// Constructor /// /// StartStep object corresponding to axis of interest /// data of other axis (needed to get count value) public AxisSuggester_StartStep(StartStep axisOfInterest, IList otherAxisData) { ordinateData_ = otherAxisData; abscissaData_ = axisOfInterest; } /// /// Calculates a suggested axis given the data specified in the constructor. /// /// the suggested axis public Axis Get() { return new LinearAxis( abscissaData_.Start, abscissaData_.Start + (double)(ordinateData_.Count - 1) * abscissaData_.Step); } } /// /// Provides default axis if only data corresponding to orthogonal axis is provided. /// public class AxisSuggester_Auto : IAxisSuggester { IList ordinateData_; /// /// Constructor /// /// Data corresponding to orthogonal axis. public AxisSuggester_Auto(IList ordinateData) { ordinateData_ = ordinateData; } /// /// Calculates a suggested axis given the data specified in the constructor. /// /// the suggested axis public Axis Get() { return new LinearAxis(0, ordinateData_.Count - 1); } } /// /// Provides default axis if only data corresponding to orthogonal axis is provided. /// public class AxisSuggester_RowAuto : IAxisSuggester { DataRowCollection ordinateData_; /// /// Construbtor /// /// Data corresponding to orthogonal axis. public AxisSuggester_RowAuto(DataRowCollection ordinateData) { ordinateData_ = ordinateData; } /// /// Calculates a suggested axis given the data specified in the constructor. /// /// the suggested axis public Axis Get() { return new LinearAxis(0, ordinateData_.Count - 1); } } /// /// Provides axis for data in a given column of a DataRowCollection. /// public class AxisSuggester_Rows : IAxisSuggester { DataRowCollection rows_; string columnName_; /// /// Constructor /// /// DataRowCollection containing the data to suggest axis for. /// the column to get data. public AxisSuggester_Rows(DataRowCollection rows, string columnName) { rows_ = rows; columnName_ = columnName; } /// /// Calculates a suggested axis given the data specified in the constructor. /// /// the suggested axis public Axis Get() { double min; double max; if (Utils.RowArrayMinMax(rows_, out min, out max, columnName_)) { if ((rows_[0])[columnName_] is DateTime) { return new DateTimeAxis(min, max); } else { return new LinearAxis(min, max); } } return new LinearAxis(0.0, 1.0); } } /// /// Provides axis suggestion for data in a particular column of a DataView. /// public class AxisSuggester_DataView : IAxisSuggester { DataView data_; string columnName_; /// /// Constructor /// /// DataView that contains data to suggest axis for /// the column of interest in the DataView public AxisSuggester_DataView(DataView data, string columnName) { data_ = data; columnName_ = columnName; } /// /// Calculates a suggested axis given the data specified in the constructor. /// /// the suggested axis public Axis Get() { double min; double max; if (Utils.DataViewArrayMinMax(data_, out min, out max, columnName_)) { if ((data_[0])[columnName_] is DateTime) { return new DateTimeAxis(min, max); } else { return new LinearAxis(min, max); } } return new LinearAxis(0.0, 1.0); } } #endregion #region Counters /// /// Interface that enables a dataholding class to report how many data items it holds. /// public interface ICounter { /// /// Number of data items in container. /// /// Number of data items in container. int Count { get; } } /// /// Class that provides the number of items in an IList via the ICounter interface. /// public class Counter_IList : ICounter { private IList data_; /// /// Constructor /// /// the IList data to provide count of public Counter_IList(IList data) { data_ = data; } /// /// Number of data items in container. /// /// Number of data items in container. public int Count { get { return data_.Count; } } } /// /// Class that returns 0 via the ICounter interface. /// public class Counter_Null : ICounter { /// /// Number of data items in container. /// /// Number of data items in container. public int Count { get { return 0; } } } /// /// Class that provides the number of items in a DataRowCollection via the ICounter interface. /// public class Counter_Rows : ICounter { DataRowCollection rows_; /// /// Constructor /// /// the DataRowCollection data to provide count of number of rows of. public Counter_Rows(DataRowCollection rows) { rows_ = rows; } /// /// Number of data items in container. /// /// Number of data items in container. public int Count { get { return rows_.Count; } } } /// /// Class that provides the number of items in a DataView via the ICounter interface. /// public class Counter_DataView : ICounter { DataView dataView_; /// /// Constructor /// /// the DataBiew data to provide count of number of rows of. public Counter_DataView(DataView dataView) { dataView_ = dataView; } /// /// Number of data items in container. /// /// Number of data items in container. public int Count { get { return dataView_.Count; } } } #endregion #region DataGetters /// /// Interface for data holding classes that allows users to get the ith value. /// /// /// TODO: should change this to GetNext() and Reset() for more generality. /// public interface IDataGetter { /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. double Get(int i); } /// /// Provides data in an IList via the IDataGetter interface. /// public class DataGetter_IList : IDataGetter { private IList data_; /// /// Constructor /// /// IList that contains the data public DataGetter_IList(IList data) { data_ = data; } /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { return Utils.ToDouble(data_[i]); } } /// /// Provides data in an array of doubles via the IDataGetter interface. /// /// /// A speed-up version of DataDetter_IList; no boxing/unboxing overhead. /// public class DataGetter_DoublesArray : IDataGetter { private double[] data_; /// /// Constructor /// /// array of doubles that contains the data public DataGetter_DoublesArray(double[] data) { data_ = data; } /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { return data_[i]; } } /// /// Provides no data. /// public class DataGetter_Null : IDataGetter { /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { throw new NPlotException( "No Data!" ); } } /// /// Provides data points from a StartStep object via the IDataGetter interface. /// public class DataGetter_StartStep : IDataGetter { StartStep data_; /// /// Constructor /// /// StartStep to derive data from. public DataGetter_StartStep(StartStep data) { data_ = data; } /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { return data_.Start + (double)(i) * data_.Step; } } /// /// Provides the natural numbers (and 0) via the IDataGetter interface. /// public class DataGetter_Count : IDataGetter { /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { return (double)i; } } /// /// Provides data in a DataRowCollection via the IDataGetter interface. /// public class DataGetter_Rows : IDataGetter { private DataRowCollection rows_; private string columnName_; /// /// Constructor /// /// DataRowCollection to get data from /// Get data in this column public DataGetter_Rows(DataRowCollection rows, string columnName) { rows_ = rows; columnName_ = columnName; } /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { return Utils.ToDouble((rows_[i])[columnName_]); } } /// /// Provides data in a DataView via the IDataGetter interface. /// public class DataGetter_DataView : IDataGetter { private DataView data_; private string columnName_; /// /// Constructor /// /// DataView to get data from. /// Get data in this column public DataGetter_DataView(DataView data, string columnName) { data_ = data; columnName_ = columnName; } /// /// Gets the ith data value. /// /// sequence number of data to get. /// ith data value. public double Get(int i) { return Utils.ToDouble((data_[i])[columnName_]); } } /// /// Gets data /// /// Note: Does not implement IDataGetter... Currently this class is not used. public class DataGetter_MultiRows { DataRowCollection rows_; string abscissaName_; int abscissaColumnNumber_; /// /// Constructor /// /// DataRowCollection to get data from. /// don't get data from this column public DataGetter_MultiRows(DataRowCollection rows, string omitThisColumn ) { rows_ = rows; abscissaName_ = omitThisColumn; abscissaColumnNumber_ = rows_[0].Table.Columns.IndexOf( omitThisColumn ); if (abscissaColumnNumber_ < 0) throw new NPlotException( "invalid column name" ); } /// /// Number of data points /// public int Count { get { return rows_[0].Table.Columns.Count-1; } } /// /// Gets data at a given index, in the given series (column number). /// /// index in the series to get data for /// series number (column number) to get data for. /// the required data point. public double PointAt( int index, int seriesIndex ) { if (seriesIndex < abscissaColumnNumber_) return Utils.ToDouble( rows_[index][seriesIndex] ); else return Utils.ToDouble( rows_[index][seriesIndex+1] ); } } #endregion } } nplot-gtk-0.9.9.2/lib/BarPlot.cs0000644000175000017500000002007410512404107016743 0ustar carlosblecarlosble/* NPlot - A charting library for .NET BarPlot.cs Copyright (C) 2003 Matt Howlett Redistribution and use of NPlot or parts there-of in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Re-distributions in source form must retain at the head of each source file the above copyright notice, this list of conditions and the following disclaimer. 2. Any product ("the product") that makes use NPlot or parts there-of must either: (a) allow any user of the product to obtain a complete machine- readable copy of the corresponding source code for the product and the version of NPlot used for a charge no more than your cost of physically performing source distribution, on a medium customarily used for software interchange, or: (b) reproduce the following text in the documentation, about box or other materials intended to be read by human users of the product that is provided to every human user of the product: "This product includes software developed as part of the NPlot library project available from: http://www.nplot.com/" The words "This product" may optionally be replace with the actual name of the product. ------------------------------------------------------------------------ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 { /// /// Draws /// public class BarPlot : BasePlot, IPlot, IDrawable { /// /// Default Constructor /// public BarPlot() { } /// /// Gets or sets the data, or column name for the ordinate [y] axis. /// public object OrdinateDataTop { get { return this.ordinateDataTop_; } set { this.ordinateDataTop_ = value; } } private object ordinateDataTop_ = null; /// /// Gets or sets the data, or column name for the ordinate [y] axis. /// public object OrdinateDataBottom { get { return this.ordinateDataBottom_; } set { this.ordinateDataBottom_ = value; } } private object ordinateDataBottom_ = null; /// /// Gets or sets the data, or column name for the abscissa [x] axis. /// public object AbscissaData { get { return this.abscissaData_; } set { this.abscissaData_ = value; } } private object abscissaData_ = null; /// /// Draws the line 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 void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis ) { SequenceAdapter dataTop = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataTop, this.AbscissaData ); SequenceAdapter dataBottom = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataBottom, this.AbscissaData ); ITransform2D t = Transform2D.GetTransformer( xAxis, yAxis ); for (int i=0; i /// Returns an x-axis that is suitable for drawing this plot. /// /// A suitable x-axis. public Axis SuggestXAxis() { SequenceAdapter dataBottom_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataBottom, this.AbscissaData ); SequenceAdapter dataTop_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataTop, this.AbscissaData ); Axis axis = dataTop_.SuggestXAxis(); axis.LUB(dataBottom_.SuggestXAxis()); return axis; } /// /// Returns a y-axis that is suitable for drawing this plot. /// /// A suitable y-axis. public Axis SuggestYAxis() { SequenceAdapter dataBottom_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataBottom, this.AbscissaData ); SequenceAdapter dataTop_ = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataTop, this.AbscissaData ); Axis axis = dataTop_.SuggestYAxis(); axis.LUB(dataBottom_.SuggestYAxis()); return axis; } /// /// 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 virtual void DrawInLegend(Graphics g, Rectangle startEnd) { int smallerHeight = (int)(startEnd.Height * 0.5f); int heightToRemove = (int)(startEnd.Height * 0.5f); Rectangle newRectangle = new Rectangle( startEnd.Left, startEnd.Top + smallerHeight / 2, startEnd.Width, smallerHeight ); g.FillRectangle( rectangleBrush_.Get( newRectangle ), newRectangle ); g.DrawRectangle( borderPen_, newRectangle ); } /// /// The pen used to draw the plot /// public System.Drawing.Pen BorderPen { get { return borderPen_; } set { borderPen_ = value; } } private System.Drawing.Pen borderPen_ = new Pen(Color.Black); /// /// The color of the pen used to draw lines in this plot. /// public System.Drawing.Color BorderColor { set { if (borderPen_ != null) { borderPen_.Color = value; } else { borderPen_ = new Pen(value); } } get { return borderPen_.Color; } } /// /// Set/Get the fill brush /// public IRectangleBru