WorldToPhysical() public method

Given a world coordinate value, returns the physical position of the coordinate along the axis.
public WorldToPhysical ( double coord, bool clip ) : PointF
coord double the world coordinate
clip bool 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.
return PointF
Example #1
0
        /// <summary>
        /// Draws the point plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public virtual void Draw(IGraphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            SequenceAdapter data_ =
                new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData);

            float leftCutoff_  = xAxis.PhysicalMin.X - Marker.Size;
            float rightCutoff_ = xAxis.PhysicalMax.X + Marker.Size;

            for (int i = 0; i < data_.Count; ++i)
            {
                if (!Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y))
                {
                    PointF xPos = xAxis.WorldToPhysical(data_[i].X, false);
                    if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X)
                    {
                        continue;
                    }

                    PointF yPos = yAxis.WorldToPhysical(data_[i].Y, false);
                    Marker.Draw(g, (int)xPos.X, (int)yPos.Y);
                    if (Marker.DropLine)
                    {
                        PointD yMin   = new PointD(data_[i].X, Math.Max(0.0f, yAxis.Axis.WorldMin));
                        PointF yStart = yAxis.WorldToPhysical(yMin.Y, false);
                        g.DrawLine(Marker.Pen, new Point((int)xPos.X, (int)yStart.Y), new Point((int)xPos.X, (int)yPos.Y));
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Draws the point plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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 < data_.Count; ++i)
            {
                var p1 = data_[i];

                if (!Double.IsNaN(p1.X) && !Double.IsNaN(p1.Y))
                {
                    PointF xPos = xAxis.WorldToPhysical(p1.X, false);
                    if (float.IsNaN(xPos.X) || xPos.X < leftCutoff_ || rightCutoff_ < xPos.X)
                    {
                        continue;
                    }

                    PointF yPos = yAxis.WorldToPhysical(p1.Y, false);
                    if (float.IsNaN(yPos.Y))
                    {
                        continue;
                    }
                    marker_.Draw(g, (int)xPos.X, (int)yPos.Y);
                    if (marker_.DropLine)
                    {
                        PointD yMin   = new PointD(p1.X, Math.Max(0.0f, yAxis.Axis.WorldMin));
                        PointF yStart = yAxis.WorldToPhysical(yMin.Y, false);
                        g.DrawLine(marker_.Pen, new Point((int)xPos.X, (int)yStart.Y), new Point((int)xPos.X, (int)yPos.Y));
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Calculates the physical (not world) separation between abscissa values.
        /// </summary>
        /// <param name="cd">Candle adapter containing data</param>
        /// <param name="xAxis">Physical x axis the data is plotted against.</param>
        /// <returns>physical separation between abscissa values.</returns>
        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);
        }
Example #4
0
        /// <summary>
        /// Draws the marker on a plot surface.
        /// </summary>
        /// <param name="g">graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(IGraphics 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);
        }
Example #5
0
        /// <summary>
        /// Draws the text on a plot surface.
        /// </summary>
        /// <param name="g">graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(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);
        }
Example #6
0
        /// <summary>
        /// Draws the plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public override void Draw(IGraphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            SequenceAdapter data =
                new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData);

            TextDataAdapter textData =
                new TextDataAdapter(DataSource, DataMember, TextData);

            // first plot the marker
            // we can do this cast, since the constructor accepts only this type!
            for (int i = 0; i < data.Count; ++i)
            {
                try
                {
                    PointD pt = data[i];
                    if (!Double.IsNaN(pt.X) && !Double.IsNaN(pt.Y))
                    {
                        PointF xPos = xAxis.WorldToPhysical(pt.X, false);
                        PointF yPos = yAxis.WorldToPhysical(pt.Y, false);
                        Marker.Draw(g, (int)xPos.X, (int)yPos.Y);
                        if (textData[i] != "")
                        {
                            SizeF size = g.MeasureString(textData[i], Font);
                            switch (LabelTextPosition)
                            {
                            case LabelPositions.Above:
                                g.DrawString(textData[i], Font, Brushes.Black,
                                             new PointF(xPos.X - size.Width / 2, yPos.Y - size.Height - Marker.Size * 2 / 3));
                                break;

                            case LabelPositions.Below:
                                g.DrawString(textData[i], Font, Brushes.Black, new PointF(xPos.X - size.Width / 2, yPos.Y + Marker.Size * 2 / 3));
                                break;

                            case LabelPositions.Left:
                                g.DrawString(textData[i], Font, Brushes.Black,
                                             new PointF(xPos.X - size.Width - Marker.Size * 2 / 3, yPos.Y - size.Height / 2));
                                break;

                            case LabelPositions.Right:
                                g.DrawString(textData[i], Font, Brushes.Black, new PointF(xPos.X + Marker.Size * 2 / 3, yPos.Y - size.Height / 2));
                                break;
                            }
                        }
                    }
                }
                catch
                {
                    throw new NPlotException("Error in TextPlot.Draw");
                }
            }
        }
Example #7
0
        /// <summary>
        /// Draws the vertical line plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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.
        }
Example #8
0
        /// <summary>
        /// Draws the horizontal line plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(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 Point(xMin, yPos), new Point(xMax, yPos));

            // todo:  clip and proper logic for flipped axis min max.
        }
Example #9
0
        /// <summary>
        /// Draws the vertical line plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(IGraphics 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 * LengthScale;
            float indentAmount = lengthDiff / 2;

            yMin -= (int)indentAmount;
            yMax += (int)indentAmount;

            int xPos = (int)xAxis.WorldToPhysical(AbscissaValue, false).X;

            g.DrawLine(Pen, new Point(xPos, yMin), new Point(xPos, yMax));

            // todo:  clip and proper logic for flipped axis min max.
        }
Example #10
0
 /// <summary>
 /// Does all the work in drawing grid lines.
 /// </summary>
 /// <param name="g">The graphics surface on which to render.</param>
 /// <param name="axis">TODO</param>
 /// <param name="orthogonalAxis">TODO</param>
 /// <param name="a">the list of world values to draw grid lines at.</param>
 /// <param name="horizontal">true if want horizontal lines, false otherwise.</param>
 /// <param name="p">the pen to use to draw the grid lines.</param>
 private void DrawGridLines(
     Graphics g, PhysicalAxis axis, PhysicalAxis orthogonalAxis,
     System.Collections.ArrayList a, bool horizontal, Pen p)
 {
     for (int i = 0; i < a.Count; ++i)
     {
         PointF p1 = axis.WorldToPhysical((double)a[i], true);
         PointF p2 = p1;
         PointF p3 = orthogonalAxis.PhysicalMax;
         PointF p4 = orthogonalAxis.PhysicalMin;
         if (horizontal)
         {
             p1.Y = p4.Y;
             p2.Y = p3.Y;
         }
         else
         {
             p1.X = p4.X;
             p2.X = p3.X;
         }
         // note: casting all drawing was necessary for sane display. why?
         g.DrawLine(p, (int)p1.X, (int)p1.Y, (int)p2.X, (int)p2.Y);
     }
 }
Example #11
0
        /// <summary>
        /// Draws the arrow on a plot surface.
        /// </summary>
        /// <param name="g">graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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) );
        }
Example #12
0
        /// <summary>
        /// Draws the point plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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 < data_.Count; ++i)
            {
                var pointMarker = marker_;

                if (MarkerCallback != null)
                {
                    pointMarker = MarkerCallback(data_[i].X, data_[i].Y);
                }

                if (!Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y))
                {
                    PointF xPos = xAxis.WorldToPhysical(data_[i].X, false);
                    if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X)
                    {
                        continue;
                    }

                    PointF yPos = yAxis.WorldToPhysical(data_[i].Y, false);
                    pointMarker.Draw(g, (int)xPos.X, (int)yPos.Y);
                    if (pointMarker.DropLine)
                    {
                        PointD yMin   = new PointD(data_[i].X, Math.Max(0.0f, yAxis.Axis.WorldMin));
                        PointF yStart = yAxis.WorldToPhysical(yMin.Y, false);
                        g.DrawLine(pointMarker.Pen, new Point((int)xPos.X, (int)yStart.Y), new Point((int)xPos.X, (int)yPos.Y));
                    }

                    if (LabelFont != null)
                    {
                        var markerHalfSize = (float)pointMarker.Size / 2.0f;

                        // Top-left corner
                        var yText     = data_[i].Y.ToString();
                        var textSize  = g.MeasureString(yText, LabelFont);
                        var labelRect = new RectangleF(xPos.X, yPos.Y,
                                                       textSize.Width + LabelPadding + LabelPadding,
                                                       textSize.Height + LabelPadding + LabelPadding);

                        if (!g.ClipBounds.Contains(labelRect))
                        {
                            // Try bottom-left corner
                            labelRect.Y = yPos.Y - labelRect.Height;
                        }

                        if (!g.ClipBounds.Contains(labelRect))
                        {
                            // Try bottom-right corner
                            labelRect.X = xPos.X - labelRect.Width;
                        }

                        if (!g.ClipBounds.Contains(labelRect))
                        {
                            // Try top-right corner
                            labelRect.Y = yPos.Y;
                        }

                        g.FillRectangle(Brushes.White, labelRect);
                        g.DrawRectangle(Pens.Black, labelRect.X, labelRect.Y,
                                        labelRect.Width, labelRect.Height);

                        g.DrawString(yText, LabelFont, pointMarker.FillBrush,
                                     labelRect.X + LabelPadding, labelRect.Y + LabelPadding);
                    }
                }
            }
        }
Example #13
0
        /// <summary>
        /// Draws the candle plot with the specified Drawing Context and X,Y axes
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw</param>
        /// <param name="xAxis">The physical X-Axis to draw against</param>
        /// <param name="yAxis">The physical Y-Axis to draw against</param>
        public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            CandleDataAdapter cd = new CandleDataAdapter (DataSource, DataMember,
                AbscissaData, OpenData, LowData, HighData, CloseData);

            double offset = 0;
            if (Centered) {
                offset = CalculatePhysicalSeparation (cd,xAxis)/2;
            }

            double addAmount = StickWidth/2;
            double stickWidth = StickWidth;

            if (StickWidth == AutoScaleStickWidth) {
                // default
                addAmount = 2;
                stickWidth = 4;

                double minDist = CalculatePhysicalSeparation (cd, xAxis);

                addAmount = minDist / 3;
                stickWidth = addAmount * 2;
            }

            ctx.Save ();
            ctx.SetLineWidth (1);

            /*
            // brant hyatt proposed.
            if (Style == Styles.Stick)
            {
                p.Width = stickWidth;
                addAmount = stickWidth + 2;
            }
            */

            for (int i=0; i<cd.Count; ++i) {

                PointOLHC point = (PointOLHC)cd [i];
                if ((!double.IsNaN (point.Open)) && (!double.IsNaN(point.High))
                 && (!double.IsNaN (point.Low)) && (!double.IsNaN(point.Close))) {
                    double xPos = (xAxis.WorldToPhysical (point.X, false)).X;

                    if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount) {
                        continue;
                    }

                    double yLo  = (yAxis.WorldToPhysical (point.Low,  false)).Y;
                    double yHi  = (yAxis.WorldToPhysical (point.High, false)).Y;
                    double yOpn = (yAxis.WorldToPhysical (point.Open, false)).Y;
                    double yCls = (yAxis.WorldToPhysical (point.Close,false)).Y;

                    if (Style == Styles.Stick) {
                        /*
                        // brant hyatt proposed.
                        if (i > 0)
                        {
                            if ( ((PointOLHC)cd[i]).Close > ((PointOLHC)cd[i-1]).Close)
                            {
                                p.Color = BullishColor;
                            }
                            else
                            {
                                p.Color = BearishColor;
                            }
                        }
                        */
                        ctx.SetColor (Color);
                        ctx.MoveTo (xPos+offset, yLo);
                        ctx.LineTo (xPos+offset, yHi);		// Low to High line

                        ctx.MoveTo (xPos-addAmount+offset, yOpn);
                        ctx.LineTo (xPos+offset, yOpn);		// Open line

                        ctx.MoveTo (xPos+addAmount+offset, yCls);
                        ctx.LineTo (xPos+offset, yCls);		// Close line
                        ctx.Stroke ();
                    }
                    else if (Style == Styles.Filled) {
                        ctx.MoveTo (xPos+offset, yLo);
                        ctx.LineTo (xPos+offset, yHi);
                        ctx.Stroke ();
                        if (yOpn > yCls) {
                            ctx.SetColor (BullishColor);
                            ctx.Rectangle (xPos-addAmount+offset, yCls, stickWidth, yOpn - yCls);
                            ctx.FillPreserve ();
                            ctx.SetColor (Color);
                            ctx.Stroke ();
                        }
                        else if (yOpn < yCls) {
                            ctx.SetColor (BearishColor);
                            ctx.Rectangle (xPos-addAmount+offset, yOpn, stickWidth, yCls - yOpn);
                            ctx.FillPreserve ();
                            ctx.SetColor (Color);
                            ctx.Stroke ();
                        }
                        else {	// Cls == Opn
                            ctx.MoveTo (xPos-addAmount+offset, yOpn);
                            ctx.LineTo (xPos-addAmount+stickWidth+offset, yCls);
                            ctx.Stroke ();
                        }
                    }
                }
            }
            ctx.Restore ();
        }
Example #14
0
 /// <summary>
 /// Transforms the given world point to physical coordinates
 /// </summary>
 /// <param name="x">x coordinate of world point to transform.</param>
 /// <param name="y">y coordinate of world point to transform.</param>
 /// <returns>the corresponding physical point.</returns>
 public PointF Transform(double x, double y)
 {
     return(new PointF(
                xAxis_.WorldToPhysical(x, false).X,
                yAxis_.WorldToPhysical(y, false).Y));
 }
Example #15
0
        /// <summary>
        /// Draws the candle plot on a GDI+ surface agains the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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 < cd.Count; ++i)
            {
                PointOLHC point = (PointOLHC)cd[i];
                if ((!double.IsNaN(point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN(point.Low)) && (!double.IsNaN(point.Close)))
                {
                    int xPos = (int)(xAxis.WorldToPhysical(point.X, false)).X;

                    if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount)
                    {
                        continue;
                    }

                    int yPos1 = (int)(yAxis.WorldToPhysical(point.Low, false)).Y;
                    int yPos2 = (int)(yAxis.WorldToPhysical(point.High, false)).Y;
                    int yPos3 = (int)(yAxis.WorldToPhysical(point.Open, false)).Y;
                    int yPos4 = (int)(yAxis.WorldToPhysical(point.Close, false)).Y;

                    if (this.Style == Styles.Stick)
                    {
                        /*
                         * // brant hyatt proposed.
                         * if (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);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Renders the histogram.
        /// </summary>
        /// <param name="g">The Graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<data.Count; ++i )
            {

                // (1) determine the top left hand point of the bar (assuming not centered)
                PointD p1 = data[i];
                if ( double.IsNaN(p1.X) || double.IsNaN(p1.Y) )
                    continue;

                // (2) determine the top right hand point of the bar (assuming not centered)
                PointD p2;
                if (i+1 != data.Count)
                {
                    p2 = data[i+1];
                    if ( double.IsNaN(p2.X) || double.IsNaN(p2.Y) )
                        continue;
                    p2.Y = p1.Y;
                }
                else if (i != 0)
                {
                    p2 = data[i-1];
                    if ( double.IsNaN(p2.X) || double.IsNaN(p2.Y) )
                        continue;
                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                }
                else
                {
                    double offset = 1.0f;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                }

                // (3) now account for plots this may be stacked on top of.
                HistogramPlot currentPlot = this;
                yoff = 0.0f;
                double yval = 0.0f;
                while (currentPlot.isStacked_)
                {
                    SequenceAdapter stackedToData = new SequenceAdapter(
                        currentPlot.stackedTo_.DataSource,
                        currentPlot.stackedTo_.DataMember,
                        currentPlot.stackedTo_.OrdinateData,
                        currentPlot.stackedTo_.AbscissaData );

                    yval += stackedToData[i].Y;
                    yoff = yAxis.WorldToPhysical( yval, false ).Y;
                    p1.Y += stackedToData[i].Y;
                    p2.Y += stackedToData[i].Y;
                    currentPlot = currentPlot.stackedTo_;
                }

                // (4) now account for centering
                if ( center_ )
                {
                    double offset = ( p2.X - p1.X ) / 2.0f;
                    p1.X -= offset;
                    p2.X -= offset;
                }

                // (5) now account for BaseOffset (shift of bar sideways).
                p1.X += baseOffset_;
                p2.X += baseOffset_;

                // (6) now get physical coordinates of top two points.
                PointF xPos1 = xAxis.WorldToPhysical( p1.X, false );
                PointF yPos1 = yAxis.WorldToPhysical( p1.Y, false );
                PointF xPos2 = xAxis.WorldToPhysical( p2.X, false );
                PointF yPos2 = yAxis.WorldToPhysical( p2.Y, false );

                if (isStacked_)
                {
                    currentPlot = this;
                    while (currentPlot.isStacked_)
                    {
                        currentPlot = currentPlot.stackedTo_;
                    }
                    this.baseWidth_ = currentPlot.baseWidth_;
                }

                float width = xPos2.X - xPos1.X;
                float height;
                if (isStacked_)
                {
                    height = -yPos1.Y+yoff;
                }
                else
                {
                    height = -yPos1.Y+yAxis.PhysicalMin.Y;
                }

                float xoff = (1.0f - baseWidth_)/2.0f*width;
                Rectangle r = new Rectangle( (int)(xPos1.X+xoff), (int)yPos1.Y, (int)(width-2*xoff), (int)height );

                if (this.Filled)
                {
                    if (r.Height != 0 && r.Width != 0)
                    {
                        // room for optimization maybe.
                        g.FillRectangle( rectangleBrush_.Get(r), r );
                    }
                }

                g.DrawRectangle( Pen, r.X, r.Y, r.Width, r.Height );

            }
        }
Example #17
0
        /// <summary>
        /// Draws the arrow on a plot surface.
        /// </summary>
        /// <param name="ctx">the Drawing Context with which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis )
        {
            if (To.X > xAxis.Axis.WorldMax || To.X < xAxis.Axis.WorldMin) {
                return;
            }
            if (To.Y > yAxis.Axis.WorldMax || To.Y < yAxis.Axis.WorldMin) {
                return;
            }

            ctx.Save ();

            TextLayout layout = new TextLayout ();
            layout.Font = textFont_;
            layout.Text = text_;

            double angle = angle_;
            if (angle_ < 0.0) {
                int mul = -(int)(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 (
                xAxis.WorldToPhysical (to_.X, true).X,
                yAxis.WorldToPhysical (to_.Y, true).Y);

            double xDir = Math.Cos (normAngle * 2.0 * Math.PI / 360.0);
            double yDir = Math.Sin (normAngle * 2.0 * Math.PI / 360.0);

            toPoint.X += xDir*headOffset_;
            toPoint.Y += yDir*headOffset_;

            double xOff = physicalLength_ * xDir;
            double yOff = physicalLength_ * yDir;

            Point fromPoint = new Point(
                (int)(toPoint.X + xOff),
                (int)(toPoint.Y + yOff) );

            ctx.SetLineWidth (1);
            ctx.SetColor (arrowColor_);
            ctx.MoveTo (fromPoint);
            ctx.LineTo (toPoint);
            ctx.Stroke ();

            xOff = headSize_ * Math.Cos ((normAngle-headAngle_/2) * 2.0 * Math.PI / 360.0);
            yOff = headSize_ * Math.Sin ((normAngle-headAngle_/2) * 2.0 * Math.PI / 360.0);

            ctx.LineTo (toPoint.X + xOff, toPoint.Y + yOff);

            double xOff2 = headSize_ * Math.Cos ((normAngle+headAngle_/2) * 2.0 * Math.PI / 360.0);
            double yOff2 = headSize_ * Math.Sin ((normAngle+headAngle_/2) * 2.0 * Math.PI / 360.0);

            ctx.LineTo (toPoint.X + xOff2, toPoint.Y + yOff2);
            ctx.LineTo (toPoint);
            ctx.ClosePath ();
            ctx.SetColor (arrowColor_);
            ctx.Fill ();

            Size textSize = layout.GetSize ();
            Size halfSize = new Size (textSize.Width/2, textSize.Height/2);

            double quadrantSlideLength = halfSize.Width + halfSize.Height;

            double quadrantD = normAngle / 90.0;		// integer part gives quadrant.
            int quadrant = (int)quadrantD;				// quadrant in.
            double prop = quadrantD - (double)quadrant;	// proportion of way through this qadrant.
            double 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.
            Point offsetFromMiddle = new Point (0, 0);
            switch (quadrant) {
            case 0:
                if (dist > halfSize.Height) {
                    dist -= halfSize.Height;
                    offsetFromMiddle = new Point ( -halfSize.Width + dist, halfSize.Height );
                }
                else {
                    offsetFromMiddle = new Point ( -halfSize.Width, - dist );
                }
                break;
            case 1:
                if (dist > halfSize.Width) {
                    dist -= halfSize.Width;
                    offsetFromMiddle = new Point ( halfSize.Width, halfSize.Height - dist );
                }
                else {
                    offsetFromMiddle = new Point ( dist, halfSize.Height );
                }
                break;
            case 2:
                if (dist > halfSize.Height) {
                    dist -= halfSize.Height;
                    offsetFromMiddle = new Point ( halfSize.Width - dist, -halfSize.Height );
                }
                else {
                    offsetFromMiddle = new Point ( halfSize.Width, -dist );
                }
                break;
            case 3:
                if (dist > halfSize.Width) {
                    dist -= halfSize.Width;
                    offsetFromMiddle = new Point ( -halfSize.Width, -halfSize.Height + dist );
                }
                else {
                    offsetFromMiddle = new Point ( -dist, -halfSize.Height );
                }
                break;
            default:
                throw new NPlotException( "Programmer error." );
            }

            ctx.SetColor (textColor_);
            double x = fromPoint.X - halfSize.Width - offsetFromMiddle.X;
            double y = fromPoint.Y - halfSize.Height + offsetFromMiddle.Y;
            ctx.DrawTextLayout (layout, x, y);

            ctx.Restore ();
        }
Example #18
0
        /// <summary>
        /// Draws the step plot using a Drawing Context against the provided x and y axes.
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public virtual void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis )
        {
            SequenceAdapter data =
                new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData);

            double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false);
            double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false);

            for (int i=0; i<data.Count; ++i) {
                Point p1 = data[i];
                if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y)) {
                    continue;
                }

                Point p2;
                Point p3;
                if (i+1 != data.Count) {
                    p2 = data[i+1];
                    if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y)) {
                        continue;
                    }
                    p2.Y = p1.Y;
                    p3 = data[i+1];
                }
                else {
                    // Check that we are not dealing with a DataSource of 1 point.
                    // This check is done here so it is only checked on the end
                    // condition and not for every point in the DataSource.
                    if (data.Count > 1) {
                        p2 = data[i - 1];
                    }
                    else {
                        // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense.
                        p2 = p1;
                    }

                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                    p3 = p2;
                }

                if (center_) {
                    double offset = ( p2.X - p1.X ) / 2.0;
                    p1.X -= offset;
                    p2.X -= offset;
                    p3.X -= offset;
                }

                Point xPos1 = xAxis.WorldToPhysical (p1.X, false);
                Point yPos1 = yAxis.WorldToPhysical (p1.Y, false);
                Point xPos2 = xAxis.WorldToPhysical (p2.X, false);
                Point yPos2 = yAxis.WorldToPhysical (p2.Y, false);
                Point xPos3 = xAxis.WorldToPhysical (p3.X, false);
                Point yPos3 = yAxis.WorldToPhysical (p3.Y, false);

                // do horizontal clipping here, to speed up
                if ((p1.X<leftCutoff && p2.X<leftCutoff && p3.X<leftCutoff) || (p1.X>rightCutoff && p2.X>rightCutoff && p3.X>rightCutoff)) {
                    continue;
                }

                ctx.Save ();
                ctx.SetColor (Color);
                ctx.SetLineWidth (1);
                if (!this.hideHorizontalSegments_) {
                    if (scale_ != 1) {
                        double middle = (xPos2.X + xPos1.X) / 2;
                        double width = xPos2.X - xPos1.X;
                        width *= this.scale_;
                        ctx.MoveTo (middle-width/2, yPos1.Y);
                        ctx.LineTo (middle+width/2, yPos2.Y);
                    }
                    else {
                        ctx.MoveTo (xPos1.X, yPos1.Y);
                        ctx.LineTo (xPos2.X, yPos2.Y);
                    }
                    ctx.Stroke ();
                }

                if (!this.hideVerticalSegments_) {
                    ctx.MoveTo (xPos2.X, yPos2.Y);
                    ctx.LineTo (xPos3.X, yPos3.Y);
                    ctx.Stroke ();
                }
                ctx.Restore ();
            }
        }
Example #19
0
        /// <summary>
        /// Draws the vertical line using the Context and the x and y axes specified
        /// </summary>
        /// <param name="ctx">The Context with which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            double yMin = yAxis.PhysicalMin.Y;
            double yMax = yAxis.PhysicalMax.Y;

            yMin -= PixelIndent;
            yMax += PixelIndent;

            double length = Math.Abs (yMax - yMin);
            double lengthDiff = length - length*LengthScale;
            double indentAmount = lengthDiff/2;

            yMin -= indentAmount;
            yMax += indentAmount;

            double xPos = xAxis.WorldToPhysical (AbscissaValue, false).X;

            ctx.Save ();
            ctx.SetLineWidth (1);
            ctx.SetColor (Color);
            ctx.MoveTo (xPos, yMin);
            ctx.LineTo (xPos, yMax);
            ctx.Stroke ();
            ctx.Restore ();
            // todo:  clip and proper logic for flipped axis min max.
        }
Example #20
0
        /// <summary>
        /// Draws the step plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<data.Count; ++i)
            {
                PointD p1 = data[i];
                if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y))
                {
                    continue;
                }

                PointD p2;
                PointD p3;
                if (i+1 != data.Count)
                {
                    p2 = data[i+1];
                    if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y))
                    {
                        continue;
                    }
                    p2.Y = p1.Y;
                    p3 = data[i+1];
                }
                else
                {
                    p2 = data[i-1];
                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                    p3 = p2;
                }

                if ( this.center_ )
                {
                    double offset = ( p2.X - p1.X ) / 2.0f;
                    p1.X -= offset;
                    p2.X -= offset;
                    p3.X -= offset;
                }

                PointF xPos1 = xAxis.WorldToPhysical( p1.X, false );
                PointF yPos1 = yAxis.WorldToPhysical( p1.Y, false );
                PointF xPos2 = xAxis.WorldToPhysical( p2.X, false );
                PointF yPos2 = yAxis.WorldToPhysical( p2.Y, false );
                PointF xPos3 = xAxis.WorldToPhysical( p3.X, false );
                PointF yPos3 = yAxis.WorldToPhysical( p3.Y, false );

                // do horizontal clipping here, to speed up
                if ((p1.X < leftCutoff || p1.X > 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 );
                }

            }
        }
Example #21
0
        /// <summary>
        /// Draws the marker on a plot surface.
        /// </summary>
        /// <param name="g">graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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 );
        }
Example #22
0
        /// <summary>
        /// Does all the work in drawing grid lines.
        /// </summary>
        /// <param name="ctx">The graphics context with which to draw</param>
        /// <param name="axis">TODO</param>
        /// <param name="orthogonalAxis">TODO</param>
        /// <param name="a">the list of world values to draw grid lines at.</param>
        /// <param name="horizontal">true if want horizontal lines, false otherwise.</param>
        /// <param name="color">the color to draw the grid lines.</param>
        private void DrawGridLines(Context ctx,
			PhysicalAxis axis, PhysicalAxis orthogonalAxis,
			System.Collections.ArrayList a, bool horizontal)
        {
            for (int i=0; i<a.Count; ++i) {
                Point p1 = axis.WorldToPhysical ((double)a[i], true);
                Point p2 = p1;
                Point p3 = orthogonalAxis.PhysicalMax;
                Point p4 = orthogonalAxis.PhysicalMin;
                if (horizontal) {
                    p1.Y = p4.Y;
                    p2.Y = p3.Y;
                }
                else {
                    p1.X = p4.X;
                    p2.X = p3.X;
                }
                ctx.MoveTo (p1);
                ctx.LineTo (p2);
                // note: casting all drawing was necessary for sane display. why?
                //g.DrawLine( p, (int)p1.X, (int)p1.Y, (int)p2.X, (int)p2.Y );
            }
            ctx.SetLineWidth (1);
            ctx.SetColor (gridColor);
            ctx.SetLineDash (0, gridDash);
            ctx.Stroke ();
        }
Example #23
0
        /// <summary>
        /// Draws the plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<data.Count; ++i)
            {
                try
                {
                    PointD pt = data[i];
                    if ( !Double.IsNaN(pt.X) && !Double.IsNaN(pt.Y) )
                    {
                        PointF xPos = xAxis.WorldToPhysical( pt.X, false);
                        PointF yPos = yAxis.WorldToPhysical( pt.Y, false);
                        Marker.Draw( g, (int)xPos.X, (int)yPos.Y );
                        if ( textData[i] != "" )
                        {
                            SizeF size = g.MeasureString( textData[i], this.Font );
                            switch (labelTextPosition_)
                            {
                                case LabelPositions.Above:
                                    g.DrawString( textData[i], font_, Brushes.Black, new PointF(xPos.X-size.Width/2,yPos.Y-size.Height-Marker.Size*2/3));
                                    break;
                                case LabelPositions.Below:
                                    g.DrawString( textData[i], font_, Brushes.Black, new PointF(xPos.X-size.Width/2,yPos.Y+Marker.Size*2/3));
                                    break;
                                case LabelPositions.Left:
                                    g.DrawString( textData[i], font_, Brushes.Black, new PointF(xPos.X-size.Width-Marker.Size*2/3,yPos.Y-size.Height/2));
                                    break;
                                case LabelPositions.Right:
                                    g.DrawString( textData[i], font_, Brushes.Black, new PointF(xPos.X+Marker.Size*2/3,yPos.Y-size.Height/2));
                                    break;
                            }
                        }
                    }
                }
                catch
                {
                    throw new NPlotException("Error in TextPlot.Draw");
                }
            }
        }
Example #24
0
        /// <summary>
        /// Draws the step plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<data.Count; ++i)
            {
                PointD p1 = data[i];
                if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y))
                {
                    continue;
                }

                PointD p2;
                PointD p3;
                if (i+1 != data.Count)
                {
                    p2 = data[i+1];
                    if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y))
                    {
                        continue;
                    }
                    p2.Y = p1.Y;
                    p3 = data[i+1];
                }
                else
                {
                    // Check that we are not dealing with a DataSource of 1 point.
                    // This check is done here so it is only checked on the end
                    // condition and not for every point in the DataSource.
                    if (data.Count > 1)
                    {
                        p2 = data[i - 1];
                    }
                    else
                    {
                        // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense.
                        p2 = p1;
                    }

                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                    p3 = p2;
                }

                if ( this.center_ )
                {
                    double offset = ( p2.X - p1.X ) / 2.0f;
                    p1.X -= offset;
                    p2.X -= offset;
                    p3.X -= offset;
                }

                PointF xPos1 = xAxis.WorldToPhysical( p1.X, false );
                PointF yPos1 = yAxis.WorldToPhysical( p1.Y, false );
                PointF xPos2 = xAxis.WorldToPhysical( p2.X, false );
                PointF yPos2 = yAxis.WorldToPhysical( p2.Y, false );
                PointF xPos3 = xAxis.WorldToPhysical( p3.X, false );
                PointF yPos3 = yAxis.WorldToPhysical( p3.Y, false );

                // do horizontal clipping here, to speed up
                if ((p1.X < leftCutoff && p2.X < leftCutoff && p3.X < leftCutoff) ||
                    (p1.X > rightCutoff && p2.X > rightCutoff && 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 );
                }
            }
        }
Example #25
0
        /// <summary>
        /// Draws the point plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<data_.Count; ++i)
            {
                if ( !Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y) )
                {
                    PointF xPos = xAxis.WorldToPhysical( data_[i].X, false);
                    if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X)
                    {
                        continue;
                    }

                    PointF yPos = yAxis.WorldToPhysical( data_[i].Y, false);
                    marker_.Draw( g, (int)xPos.X, (int)yPos.Y );
                    if (marker_.DropLine)
                    {
                        PointD yMin = new PointD( data_[i].X, Math.Max( 0.0f, yAxis.Axis.WorldMin ) );
                        PointF yStart = yAxis.WorldToPhysical( yMin.Y, false );
                        g.DrawLine( marker_.Pen, new Point((int)xPos.X,(int)yStart.Y), new Point((int)xPos.X,(int)yPos.Y) );
                    }
                }
            }
        }
Example #26
0
        /// <summary>
        /// Renders the histogram.
        /// </summary>
        /// <param name="g">The Graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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 < data.Count; ++i)
            {
                // (1) determine the top left hand point of the bar (assuming not centered)
                PointD p1 = data[i];
                if (double.IsNaN(p1.X) || double.IsNaN(p1.Y))
                {
                    continue;
                }

                // (2) determine the top right hand point of the bar (assuming not centered)
                PointD p2;
                if (i + 1 != data.Count)
                {
                    p2 = data[i + 1];
                    if (double.IsNaN(p2.X) || double.IsNaN(p2.Y))
                    {
                        continue;
                    }
                    p2.Y = p1.Y;
                }
                else if (i != 0)
                {
                    p2 = data[i - 1];
                    if (double.IsNaN(p2.X) || double.IsNaN(p2.Y))
                    {
                        continue;
                    }
                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                }
                else
                {
                    double offset = 1.0f;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                }

                // (3) now account for plots this may be stacked on top of.
                HistogramPlot currentPlot = this;
                yoff = 0.0f;
                double yval = 0.0f;
                while (currentPlot.isStacked_)
                {
                    SequenceAdapter stackedToData = new SequenceAdapter(
                        currentPlot.stackedTo_.DataSource,
                        currentPlot.stackedTo_.DataMember,
                        currentPlot.stackedTo_.OrdinateData,
                        currentPlot.stackedTo_.AbscissaData);

                    yval       += stackedToData[i].Y;
                    yoff        = yAxis.WorldToPhysical(yval, false).Y;
                    p1.Y       += stackedToData[i].Y;
                    p2.Y       += stackedToData[i].Y;
                    currentPlot = currentPlot.stackedTo_;
                }

                // (4) now account for centering
                if (center_)
                {
                    double offset = (p2.X - p1.X) / 2.0f;
                    p1.X -= offset;
                    p2.X -= offset;
                }

                // (5) now account for BaseOffset (shift of bar sideways).
                p1.X += baseOffset_;
                p2.X += baseOffset_;

                // (6) now get physical coordinates of top two points.
                PointF xPos1 = xAxis.WorldToPhysical(p1.X, false);
                PointF yPos1 = yAxis.WorldToPhysical(p1.Y, false);
                PointF xPos2 = xAxis.WorldToPhysical(p2.X, false);
                PointF yPos2 = yAxis.WorldToPhysical(p2.Y, false);

                if (isStacked_)
                {
                    currentPlot = this;
                    while (currentPlot.isStacked_)
                    {
                        currentPlot = currentPlot.stackedTo_;
                    }
                    this.baseWidth_ = currentPlot.baseWidth_;
                }

                float width = xPos2.X - xPos1.X;
                float height;
                if (isStacked_)
                {
                    height = -yPos1.Y + yoff;
                }
                else
                {
                    height = -yPos1.Y + yAxis.PhysicalMin.Y;
                }

                float     xoff = (1.0f - baseWidth_) / 2.0f * width;
                Rectangle r    = new Rectangle((int)(xPos1.X + xoff), (int)yPos1.Y, (int)(width - 2 * xoff), (int)height);

                if (this.Filled)
                {
                    if (r.Height != 0 && r.Width != 0)
                    {
                        // room for optimization maybe.
                        g.FillRectangle(rectangleBrush_.Get(r), r);
                    }
                }

                g.DrawRectangle(Pen, r.X, r.Y, r.Width, r.Height);
            }
        }
Example #27
0
        /// <summary>
        /// Draws the horizontal line plot using the Context and the x and y axes specified
        /// </summary>
        /// <param name="ctx">The Context with which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            double xMin = xAxis.PhysicalMin.X;
            double xMax = xAxis.PhysicalMax.X;

            xMin += pixelIndent_;
            xMax -= pixelIndent_;

            double length = Math.Abs (xMax - xMin);
            double lengthDiff = length - length*scale_;
            double indentAmount = lengthDiff/2;

            xMin += indentAmount;
            xMax -= indentAmount;

            double yPos = yAxis.WorldToPhysical (value_, false).Y;

            ctx.Save ();
            ctx.SetLineWidth (1);
            ctx.SetColor (color_);
            ctx.MoveTo (xMin, yPos);
            ctx.LineTo (xMax, yPos);
            ctx.Stroke ();
            ctx.Restore ();

            // todo:  clip and proper logic for flipped axis min max.
        }
Example #28
0
        /// <summary>
        /// Draws the point plot using the Drawing Context and x and y axes supplied
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public virtual void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            SequenceAdapter data_ = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData );

            double leftCutoff_ = xAxis.PhysicalMin.X - marker.Size;
            double rightCutoff_ = xAxis.PhysicalMax.X + marker.Size;

            ctx.Save ();
            ctx.SetColor (marker.LineColor);
            ctx.SetLineWidth (marker.LineWidth);

            for (int i=0; i<data_.Count; ++i) {
                if (!Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y)) {
                    Point xPos = xAxis.WorldToPhysical (data_[i].X, false);
                    if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X) {
                        continue;
                    }

                    Point yPos = yAxis.WorldToPhysical (data_[i].Y, false);
                    marker.Draw (ctx, xPos.X, yPos.Y);
                    if (marker.DropLine) {
                        Point yMin = new Point (data_[i].X, Math.Max (0.0, yAxis.Axis.WorldMin));
                        Point yStart = yAxis.WorldToPhysical (yMin.Y, false);
                        ctx.MoveTo (xPos.X, yStart.Y);
                        ctx.LineTo (xPos.X, yPos.Y);
                        ctx.Stroke ();
                    }
                }
            }
            ctx.Restore ();
        }
Example #29
0
		/// <summary>
		/// Draws the horizontal line plot on a GDI+ surface against the provided x and y axes.
		/// </summary>
		/// <param name="g">The GDI+ surface on which to draw.</param>
		/// <param name="xAxis">The X-Axis to draw against.</param>
		/// <param name="yAxis">The Y-Axis to draw against.</param>
		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.
		}
Example #30
0
        /// <summary>
        /// Draws the candle plot on a GDI+ surface agains the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<cd.Count; ++i)
            {

                PointOLHC point = (PointOLHC)cd[i];
                if ( (!double.IsNaN (point.Open)) && (!double.IsNaN(point.High)) && (!double.IsNaN (point.Low)) && (!double.IsNaN(point.Close)) )
                {
                    int xPos = (int)(xAxis.WorldToPhysical( point.X, false )).X;

                    if (xPos + offset + addAmount < xAxis.PhysicalMin.X || xAxis.PhysicalMax.X < xPos + offset - addAmount)
                    {
                        continue;
                    }

                    int yPos1 = (int)(yAxis.WorldToPhysical( point.Low, false )).Y;
                    int yPos2 = (int)(yAxis.WorldToPhysical( point.High, false )).Y;
                    int yPos3 = (int)(yAxis.WorldToPhysical( point.Open, false )).Y;
                    int yPos4 = (int)(yAxis.WorldToPhysical( point.Close, false )).Y;

                    if (this.Style == Styles.Stick)
                    {
                        /*
                        // brant hyatt proposed.
                        if (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 );
                        }
                    }
                }
            }
        }
Example #31
0
        /// <summary>
        /// Draws the histogram.
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            double yoff;
            SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData);

            ctx.Save ();
            ctx.SetLineWidth (1);

            for (int i=0; i<data.Count; ++i ) {

                // (1) determine the top left hand point of the bar (assuming not centered)
                Point p1 = data[i];
                if (double.IsNaN(p1.X) || double.IsNaN(p1.Y)) {
                    continue;
                }

                // (2) determine the top right hand point of the bar (assuming not centered)
                Point p2 = Point.Zero;;
                if (i+1 != data.Count) {
                    p2 = data[i+1];
                    if (double.IsNaN(p2.X) || double.IsNaN(p2.Y)) {
                        continue;
                    }
                    p2.Y = p1.Y;
                }
                else if (i != 0) {
                    p2 = data[i-1];
                    if (double.IsNaN(p2.X) || double.IsNaN(p2.Y)) {
                        continue;
                    }
                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                }
                else {
                    double offset = 1.0;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                }

                // (3) now account for plots this may be stacked on top of.
                HistogramPlot currentPlot = this;
                yoff = 0.0;
                double yval = 0.0;
                while (currentPlot.isStacked_) {
                    SequenceAdapter stackedToData = new SequenceAdapter (
                        currentPlot.stackedTo_.DataSource,
                        currentPlot.stackedTo_.DataMember,
                        currentPlot.stackedTo_.OrdinateData,
                        currentPlot.stackedTo_.AbscissaData );

                    yval += stackedToData[i].Y;
                    yoff = yAxis.WorldToPhysical (yval, false).Y;
                    p1.Y += stackedToData[i].Y;
                    p2.Y += stackedToData[i].Y;
                    currentPlot = currentPlot.stackedTo_;
                }

                // (4) now account for centering
                if (center_) {
                    double offset = (p2.X - p1.X) / 2.0;
                    p1.X -= offset;
                    p2.X -= offset;
                }

                // (5) now account for BaseOffset (shift of bar sideways).
                p1.X += baseOffset_;
                p2.X += baseOffset_;

                // (6) now get physical coordinates of top two points.
                Point xPos1 = xAxis.WorldToPhysical (p1.X, false);
                Point yPos1 = yAxis.WorldToPhysical (p1.Y, false);
                Point xPos2 = xAxis.WorldToPhysical (p2.X, false);

                if (isStacked_) {
                    currentPlot = this;
                    while (currentPlot.isStacked_) {
                        currentPlot = currentPlot.stackedTo_;
                    }
                    baseWidth_ = currentPlot.baseWidth_;
                }

                double width = xPos2.X - xPos1.X;
                double height;
                if (isStacked_) {
                    height = -yPos1.Y+yoff;
                }
                else {
                    height = -yPos1.Y+yAxis.PhysicalMin.Y;
                }

                double xoff = (1.0 - baseWidth_)/2.0*width;
                Rectangle r = new Rectangle (xPos1.X+xoff, yPos1.Y, width-2*xoff, height);

                ctx.Rectangle (r);
                if (Filled) {
                    if (r.Height != 0 && r.Width != 0) {
                        // room for optimization maybe.
                        ctx.SetColor (fillColor);
                        ctx.FillPreserve ();
                    }
                }
                ctx.SetColor (borderColor);
                ctx.Stroke ();
            }
            ctx.Restore ();
        }
Example #32
0
        public void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            int physicalX = (int)xAxis.WorldToPhysical(x, false).X;

            g.DrawLine(pen, new Point(physicalX, yAxis.PhysicalMin.Y), new Point(physicalX, yAxis.PhysicalMax.Y));
        }
Example #33
0
        /// <summary>
        /// Draws the vertical line plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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.
        }
Example #34
0
        /// <summary>
        /// Calculates the physical (not world) separation between abscissa values.
        /// </summary>
        /// <param name="cd">Candle adapter containing data</param>
        /// <param name="xAxis">Physical x axis the data is plotted against.</param>
        /// <returns>physical separation between abscissa values.</returns>
        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;
        }
Example #35
0
        /// <summary>
        /// Draws the marker on a plot surface.
        /// </summary>
        /// <param name="ctx">The Drawing Context with which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            Point point = new Point (
                xAxis.WorldToPhysical (x_, true).X,
                yAxis.WorldToPhysical (y_, true ).Y);

            marker_.Draw (ctx, point.X, point.Y );
        }
 /// <summary>
 /// Does all the work in drawing grid lines.
 /// </summary>
 /// <param name="g">The graphics surface on which to render.</param>
 /// <param name="axis">TODO</param>
 /// <param name="orthogonalAxis">TODO</param>
 /// <param name="a">the list of world values to draw grid lines at.</param>
 /// <param name="horizontal">true if want horizontal lines, false otherwise.</param>
 /// <param name="p">the pen to use to draw the grid lines.</param>
 private void DrawGridLines(
     Graphics g, PhysicalAxis axis, PhysicalAxis orthogonalAxis,
     List<double> a, bool horizontal, Pen p)
 {
     for (int i = 0; i < a.Count; ++i)
     {
         PointF p1 = axis.WorldToPhysical((double)a[i], true);
         PointF p2 = p1;
         PointF p3 = orthogonalAxis.PhysicalMax;
         PointF p4 = orthogonalAxis.PhysicalMin;
         if (horizontal)
         {
             p1.Y = p4.Y;
             p2.Y = p3.Y;
         }
         else
         {
             p1.X = p4.X;
             p2.X = p3.X;
         }
         // note: casting all drawing was necessary for sane display. why?
         g.DrawLine(p, (int)p1.X, (int)p1.Y, (int)p2.X, (int)p2.Y);
     }
 }
Example #37
0
		/// <summary>
		/// Draws the text on a plot surface.
		/// </summary>
		/// <param name="g">graphics surface on which to draw</param>
		/// <param name="xAxis">The X-Axis to draw against.</param>
		/// <param name="yAxis">The Y-Axis to draw against.</param>
		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);
		}
Example #38
0
		/// <summary>
		/// Draw on to the supplied graphics surface against the supplied axes.
		/// </summary>
		/// <param name="g">The graphics surface on which to draw.</param>
		/// <param name="xAxis">The X-Axis to draw against.</param>
		/// <param name="yAxis">The Y-Axis to draw against.</param>
		/// <remarks>TODO: block positions may be off by a pixel or so. maybe. Re-think calculations</remarks>
		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<data_.GetLength(0); ++i)
			{
				for (int j=0; j<data_.GetLength(1); ++j)
				{
					double wX = (double)j*this.xStep_ + xStart_;
					double wY = (double)i*this.yStep_ + yStart_;
					if ( !hPositive )
					{
						wY += yStep_;
					}
					if (!wPositive )
					{
						wX += xStep_;
					}

					if (this.center_)
					{
						wX -= this.xStep_/2.0;
						wY -= this.yStep_/2.0;
					}
					Pen p = new Pen( this.Gradient.GetColor( (data_[i,j]-this.dataMin_)/(this.dataMax_-this.dataMin_) ) );
					int x = (int)xAxis.WorldToPhysical(wX,false).X;
					int y = (int)yAxis.WorldToPhysical(wY,false).Y;
					g.FillRectangle( p.Brush,
						x,
						y, 
						(int)blockWidth,
						(int)blockHeight);
					//g.DrawRectangle(Pens.White,x,y,(int)blockWidth,(int)blockHeight);
				}
			}
		}
Example #39
0
        /// <summary>
        /// Draws the point plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        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<data_.Count; ++i)
            {
                var pointMarker = marker_;

                if (MarkerCallback != null)
                {
                    pointMarker = MarkerCallback(data_[i].X, data_[i].Y);
                }

                if ( !Double.IsNaN(data_[i].X) && !Double.IsNaN(data_[i].Y) )
                {
                    PointF xPos = xAxis.WorldToPhysical( data_[i].X, false);
                    if (xPos.X < leftCutoff_ || rightCutoff_ < xPos.X)
                        continue;

                    PointF yPos = yAxis.WorldToPhysical( data_[i].Y, false);
                    pointMarker.Draw(g, (int)xPos.X, (int)yPos.Y);
                    if (pointMarker.DropLine)
                    {
                        PointD yMin = new PointD( data_[i].X, Math.Max( 0.0f, yAxis.Axis.WorldMin ) );
                        PointF yStart = yAxis.WorldToPhysical( yMin.Y, false );
                        g.DrawLine(pointMarker.Pen, new Point((int)xPos.X, (int)yStart.Y), new Point((int)xPos.X, (int)yPos.Y));
                    }

                    if (LabelFont != null)
                    {
                        var markerHalfSize = (float)pointMarker.Size / 2.0f;

                        // Top-left corner
                        var yText = data_[i].Y.ToString();
                        var textSize = g.MeasureString(yText, LabelFont);
                        var labelRect = new RectangleF(xPos.X, yPos.Y,
                            textSize.Width + LabelPadding + LabelPadding,
                            textSize.Height + LabelPadding + LabelPadding);

                        if (!g.ClipBounds.Contains(labelRect))
                        {
                            // Try bottom-left corner
                            labelRect.Y = yPos.Y - labelRect.Height;
                        }

                        if (!g.ClipBounds.Contains(labelRect))
                        {
                            // Try bottom-right corner
                            labelRect.X = xPos.X - labelRect.Width;
                        }

                        if (!g.ClipBounds.Contains(labelRect))
                        {
                            // Try top-right corner
                            labelRect.Y = yPos.Y;
                        }

                        g.FillRectangle(Brushes.White, labelRect);
                        g.DrawRectangle(Pens.Black, labelRect.X, labelRect.Y,
                            labelRect.Width, labelRect.Height);

                        g.DrawString(yText, LabelFont, pointMarker.FillBrush,
                            labelRect.X + LabelPadding, labelRect.Y + LabelPadding);
                    }
                }
            }
        }
Example #40
0
        /// <summary>
        /// Draws the step plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public virtual void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            SequenceAdapter data =
                new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData);

            double leftCutoff  = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false);
            double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false);

            for (int i = 0; i < data.Count; ++i)
            {
                PointD p1 = data[i];
                if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y))
                {
                    continue;
                }

                PointD p2;
                PointD p3;
                if (i + 1 != data.Count)
                {
                    p2 = data[i + 1];
                    if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y))
                    {
                        continue;
                    }
                    p2.Y = p1.Y;
                    p3   = data[i + 1];
                }
                else
                {
                    // Check that we are not dealing with a DataSource of 1 point.
                    // This check is done here so it is only checked on the end
                    // condition and not for every point in the DataSource.
                    if (data.Count > 1)
                    {
                        p2 = data[i - 1];
                    }
                    else
                    {
                        // TODO: Once log4net is set up post a message to the user that a step-plot of 1 really does not make any sense.
                        p2 = p1;
                    }

                    double offset = p1.X - p2.X;
                    p2.X = p1.X + offset;
                    p2.Y = p1.Y;
                    p3   = p2;
                }

                if (center_)
                {
                    double offset = (p2.X - p1.X) / 2.0f;
                    p1.X -= offset;
                    p2.X -= offset;
                    p3.X -= offset;
                }

                PointF xPos1 = xAxis.WorldToPhysical(p1.X, false);
                PointF yPos1 = yAxis.WorldToPhysical(p1.Y, false);
                PointF xPos2 = xAxis.WorldToPhysical(p2.X, false);
                PointF yPos2 = yAxis.WorldToPhysical(p2.Y, false);
                PointF xPos3 = xAxis.WorldToPhysical(p3.X, false);
                PointF yPos3 = yAxis.WorldToPhysical(p3.Y, false);

                // do horizontal clipping here, to speed up
                if ((p1.X < leftCutoff || p1.X > rightCutoff) &&
                    (p2.X < leftCutoff || p2.X > rightCutoff) &&
                    (p3.X < leftCutoff || p3.X > rightCutoff))
                {
                    continue;
                }

                if (!hideHorizontalSegments_)
                {
                    if (scale_ != 1.0f)
                    {
                        float middle = (xPos2.X + xPos1.X) / 2.0f;
                        float width  = xPos2.X - xPos1.X;
                        width *= 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 (!hideVerticalSegments_)
                {
                    g.DrawLine(Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y);
                }
            }
        }
Example #41
0
        /// <summary>
        /// Draw on to the supplied graphics surface against the supplied axes.
        /// </summary>
        /// <param name="g">The graphics surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        /// <remarks>TODO: block positions may be off by a pixel or so. maybe. Re-think calculations</remarks>
        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 < data_.GetLength(0); ++i)
            {
                for (int j = 0; j < data_.GetLength(1); ++j)
                {
                    double wX = (double)j * this.xStep_ + xStart_;
                    double wY = (double)i * this.yStep_ + yStart_;
                    if (!hPositive)
                    {
                        wY += yStep_;
                    }
                    if (!wPositive)
                    {
                        wX += xStep_;
                    }

                    if (this.center_)
                    {
                        wX -= this.xStep_ / 2.0;
                        wY -= this.yStep_ / 2.0;
                    }
                    Pen p = new Pen(this.Gradient.GetColor((data_[i, j] - this.dataMin_) / (this.dataMax_ - this.dataMin_)));
                    int x = (int)xAxis.WorldToPhysical(wX, false).X;
                    int y = (int)yAxis.WorldToPhysical(wY, false).Y;
                    g.FillRectangle(p.Brush,
                                    x,
                                    y,
                                    (int)blockWidth,
                                    (int)blockHeight);
                    //g.DrawRectangle(Pens.White,x,y,(int)blockWidth,(int)blockHeight);
                }
            }
        }
Example #42
0
        /// <summary>
        /// Draws the arrow on a plot surface.
        /// </summary>
        /// <param name="g">graphics surface on which to draw</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            if (To.X > xAxis.Axis.WorldMax || To.X < xAxis.Axis.WorldMin)
            {
                return;
            }

            if (To.Y > yAxis.Axis.WorldMax || To.Y < yAxis.Axis.WorldMin)
            {
                return;
            }

            double angle = angle_;

            if (angle_ < 0.0)
            {
                int mul = -(int)(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));
        }
Example #43
0
        /// <summary>
        /// Draws the scale division label on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        /// 
        public void Draw(System.Drawing.Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            ArrayList yLargePositions = null;
            ArrayList ySmallPositions = null;

            yAxis.Axis.WorldTickPositions_FirstPass( yAxis.PhysicalMin, yAxis.PhysicalMax, out yLargePositions, out ySmallPositions );

            // test if we have enough y ticks
            if (yLargePositions.Count <= this.YPosition) {
                if (yLargePositions.Count > 1)
                    this.YPosition = yLargePositions.Count - 1;
                else return;
            }

            double minX = xAxis.PhysicalToWorld(xAxis.PhysicalMin,false);
            double maxX = xAxis.PhysicalToWorld(xAxis.PhysicalMax,false);

            double xOffset = this.XPosition;
            double xRef = xAxis.PhysicalMin.X;
            if (xOffset < 0)
                xRef = xAxis.PhysicalMax.X;

            if (xOffset < 1 && xOffset > 0)
                xOffset = (xAxis.PhysicalMax.X - xAxis.PhysicalMin.X) * this.XPosition;

            //*P8 	P3*==*P2==*P4
            //		 	||
            //		 	||
            //		 	|| *P7
            //       	||
            //       	||
            //  	P5*==*P1==*P6

            //Points for the main-line
            PointF p1 = new PointF(Convert.ToSingle(xRef + xOffset), 0.0f);
            PointF p2 = p1;

            PointF yTick1 = yAxis.WorldToPhysical((double)yLargePositions[yLargePositions.Count-this.YPosition],false);
            PointF yTick0 = yAxis.WorldToPhysical((double)yLargePositions[yLargePositions.Count-(this.YPosition+1)],false);

            p1.Y = yTick0.Y;
            p2.Y = yTick1.Y;

            //Points for the upper line
            PointF p3 = yTick1;
            PointF p4 = p3;
            p3.X = Convert.ToSingle(xRef + xOffset - 3);
            p4.X = Convert.ToSingle(xRef + xOffset + 3);

            //Points for the lower line
            PointF p5 = p3;
            PointF p6 = p4;
            p5.Y = yTick0.Y;
            p6.Y = yTick0.Y;

            //Label-point
            PointF p7 = p6;
            p7.Y = p7.Y + (p2.Y - p1.Y)/2;

            //Background-point
            PointF p8 = p3;
            p8.X = Convert.ToSingle((xRef + xOffset) - 14);

            double labelValue = (double)yLargePositions[yLargePositions.Count-this.YPosition] -
                (double)yLargePositions[yLargePositions.Count-(this.YPosition+1)];

            StringBuilder label = new StringBuilder();
            label.AppendFormat(this.NumberFormat, labelValue);
            float labelLength = g.MeasureString (label.ToString(), this.LabelFont).Width;

            float width = Convert.ToSingle((xRef + xOffset) + 14) - p8.X;
            float widthMin = (p7.X - p8.X) + labelLength + 2;
            if (widthMin > width)
                width = widthMin;

            float height = p1.Y-p2.Y;

            RectangleF bgRect = new RectangleF (p8.X, p8.Y, width, height);
            g.FillPath(this.BackgroundBrush, bgRect.RoundCorners(this.BackgroundCornerRadius));
            g.DrawString(label.ToString(), this.LabelFont, this.ValueBrush, p7);
            g.DrawLine( this.LinePen, (int)p1.X, (int)p1.Y, (int)p2.X, (int)p2.Y );
            g.DrawLine( this.LinePen, (int)p3.X, (int)p3.Y, (int)p4.X, (int)p4.Y );
            g.DrawLine( this.LinePen, (int)p5.X, (int)p5.Y, (int)p6.X, (int)p6.Y );
        }