PhysicalToWorld() публичный Метод

Given a physical point on the graphics surface, returns the world value of it's projection onto the axis [i.e. closest point on the axis]. The function is implemented for axes of arbitrary orientation.
public PhysicalToWorld ( Point p, bool clip ) : double
p Point Physical point to find corresponding world value of.
clip bool if true, returns a world position outside WorldMin / WorldMax /// range if this is closer to the axis line. If false, such values will /// be clipped to be either WorldMin or WorldMax as appropriate.
Результат double
Пример #1
0
        /// <summary>
        /// Draws the line plot using the Context and Physical Axes provided
        /// </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>
        /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param>
        public void DrawLineOrShadow(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow)
        {
            SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, AbscissaData);

            ITransform2D t = Transform2D.GetTransformer (xAxis, yAxis);

            int numberPoints = data.Count;

            if (data.Count == 0) {
                return;
            }

            ctx.Save ();
            ctx.SetLineWidth (lineWidth_);

            // clipping is now handled assigning a clip region in the
            // graphic object before this call
            if (numberPoints == 1) {
                Point physical = t.Transform (data[0]);

                if (drawShadow) {
                    ctx.SetColor (shadowColor_);
                    ctx.MoveTo (physical.X - 0.5 + ShadowOffset.X, physical.Y + ShadowOffset.Y);
                    ctx.LineTo (physical.X + 0.5 + ShadowOffset.X, physical.Y + ShadowOffset.Y);
                    ctx.Stroke ();
                }
                else {
                    ctx.SetColor (lineColor_);
                    ctx.MoveTo (physical.X-0.5, physical.Y);
                    ctx.LineTo (physical.X+0.5, physical.Y);
                    ctx.Stroke ();
                }
            }
            else {
                // prepare for clipping
                double leftCutoff = xAxis.PhysicalToWorld (xAxis.PhysicalMin, false);
                double rightCutoff = xAxis.PhysicalToWorld (xAxis.PhysicalMax, false);
                if (leftCutoff > rightCutoff) {
                    Utils.Swap (ref leftCutoff, ref rightCutoff);
                }
                if (drawShadow) {
                    // correct cut-offs
                    double shadowCorrection =
                        xAxis.PhysicalToWorld (ShadowOffset, false) - xAxis.PhysicalToWorld (new Point(0,0), false);
                    leftCutoff -= shadowCorrection;
                    rightCutoff -= shadowCorrection;
                }

                for (int i = 1; i < numberPoints; ++i) {
                    // check to see if any values null. If so, then continue.
                    double dx1 = data[i-1].X;
                    double dx2 = data[i].X;
                    double dy1 = data[i-1].Y;
                    double dy2 = data[i].Y;
                    if (Double.IsNaN(dx1) || Double.IsNaN(dy1) || Double.IsNaN(dx2) || Double.IsNaN(dy2)) {
                        continue;
                    }

                    // do horizontal clipping here, to speed up
                    if ((dx1 < leftCutoff && dx2 < leftCutoff) || (rightCutoff < dx1 && rightCutoff < dx2)) {
                        continue;
                    }

                    // else draw line.
                    Point p1 = t.Transform (data[i-1]);
                    Point p2 = t.Transform (data[i]);

                    // when very far zoomed in, points can fall ontop of each other,
                    // and g.DrawLine throws an overflow exception
                    if (p1.Equals(p2)) {
                        continue;
                    }

                    if (drawShadow) {
                        ctx.SetColor (shadowColor_);
                        ctx.MoveTo (p1.X + ShadowOffset.X, p1.Y + ShadowOffset.Y);
                        ctx.LineTo (p2.X + ShadowOffset.X, p2.Y + ShadowOffset.Y);
                        ctx.Stroke ();
                    }
                    else {
                        ctx.SetColor (lineColor_);
                        ctx.MoveTo (p1.X, p1.Y);
                        ctx.LineTo (p2.X, p2.Y);
                        ctx.Stroke ();
                    }
                }
            }
            ctx.Restore ();
        }
Пример #2
0
        /// <summary>
        /// Draws the 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>
        /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param>
        public void DrawLineOrShadow( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow )
        {
            Pen shadowPen = null;
            if (drawShadow)
            {
                shadowPen = (Pen)this.Pen.Clone();
                shadowPen.Color = this.ShadowColor;
            }

            SequenceAdapter data =
                new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData );

            ITransform2D t = Transform2D.GetTransformer( xAxis, yAxis );

            int numberPoints = data.Count;

            if (data.Count == 0)
            {
                return;
            }

            // clipping is now handled assigning a clip region in the
            // graphic object before this call
            if (numberPoints == 1)
            {
                PointF physical = t.Transform( data[0] );

                if (drawShadow)
                {
                    g.DrawLine( shadowPen,
                        physical.X - 0.5f + this.ShadowOffset.X,
                        physical.Y + this.ShadowOffset.Y,
                        physical.X + 0.5f + this.ShadowOffset.X,
                        physical.Y + this.ShadowOffset.Y );
                }
                else
                {
                    g.DrawLine( Pen, physical.X-0.5f, physical.Y, physical.X+0.5f, physical.Y);
                }
            }
            else
            {

                // prepare for clipping
                double leftCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false);
                double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false);
                if (leftCutoff > rightCutoff)
                {
                    Utils.Swap(ref leftCutoff, ref rightCutoff);
                }
                if (drawShadow)
                {
                    // correct cut-offs
                    double shadowCorrection =
                        xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0,0), false);
                    leftCutoff -= shadowCorrection;
                    rightCutoff -= shadowCorrection;
                }

                for (int i = 1; i < numberPoints; ++i)
                {
                    // check to see if any values null. If so, then continue.
                    double dx1 = data[i-1].X;
                    double dx2 = data[i].X;
                    double dy1 = data[i-1].Y;
                    double dy2 = data[i].Y;
                    if ( Double.IsNaN(dx1) || Double.IsNaN(dy1) ||
                        Double.IsNaN(dx2) || Double.IsNaN(dy2) )
                    {
                        continue;
                    }

                    // do horizontal clipping here, to speed up
                    if ((dx1 < leftCutoff || rightCutoff < dx1) &&
                        (dx2 < leftCutoff || rightCutoff < dx2))
                    {
                        continue;
                    }

                    // else draw line.
                    PointF p1 = t.Transform( data[i-1] );
                    PointF p2 = t.Transform( data[i] );

                    // when very far zoomed in, points can fall ontop of each other,
                    // and g.DrawLine throws an overflow exception
                    if (p1.Equals(p2))
                        continue;

                    if (drawShadow)
                    {
                        g.DrawLine( shadowPen,
                            p1.X + ShadowOffset.X,
                            p1.Y + ShadowOffset.Y,
                            p2.X + ShadowOffset.X,
                            p2.Y + ShadowOffset.Y );
                    }
                    else
                    {
                        g.DrawLine( Pen, p1.X, p1.Y, p2.X, p2.Y );
                    }
                }
            }
        }
Пример #3
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);
                }
            }
        }
Пример #4
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 );
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Draws the 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>
        /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param>
        public void DrawLineOrShadow(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow)
        {
            Pen shadowPen = null;

            if (drawShadow)
            {
                shadowPen       = (Pen)this.Pen.Clone();
                shadowPen.Color = this.ShadowColor;
            }

            SequenceAdapter data =
                new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData);

            ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis);

            int numberPoints = data.Count;

            if (data.Count == 0)
            {
                return;
            }

            // clipping is now handled assigning a clip region in the
            // graphic object before this call
            if (numberPoints == 1)
            {
                PointF physical = t.Transform(data[0]);

                if (drawShadow)
                {
                    g.DrawLine(shadowPen,
                               physical.X - 0.5f + this.ShadowOffset.X,
                               physical.Y + this.ShadowOffset.Y,
                               physical.X + 0.5f + this.ShadowOffset.X,
                               physical.Y + this.ShadowOffset.Y);
                }
                else
                {
                    g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y);
                }
            }
            else
            {
                // prepare for clipping
                double leftCutoff  = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false);
                double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false);
                if (leftCutoff > rightCutoff)
                {
                    Utils.Swap(ref leftCutoff, ref rightCutoff);
                }
                if (drawShadow)
                {
                    // correct cut-offs
                    double shadowCorrection =
                        xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0, 0), false);
                    leftCutoff  -= shadowCorrection;
                    rightCutoff -= shadowCorrection;
                }

                for (int i = 1; i < numberPoints; ++i)
                {
                    // check to see if any values null. If so, then continue.
                    double dx1 = data[i - 1].X;
                    double dx2 = data[i].X;
                    double dy1 = data[i - 1].Y;
                    double dy2 = data[i].Y;
                    if (Double.IsNaN(dx1) || Double.IsNaN(dy1) ||
                        Double.IsNaN(dx2) || Double.IsNaN(dy2))
                    {
                        continue;
                    }

                    // do horizontal clipping here, to speed up
                    if ((dx1 < leftCutoff && dx2 < leftCutoff) ||
                        (rightCutoff < dx1 && rightCutoff < dx2))
                    {
                        continue;
                    }

                    // else draw line.
                    PointF p1 = t.Transform(data[i - 1]);
                    PointF p2 = t.Transform(data[i]);

                    // when very far zoomed in, points can fall ontop of each other,
                    // and g.DrawLine throws an overflow exception
                    if (p1.Equals(p2))
                    {
                        continue;
                    }

                    if (drawShadow)
                    {
                        g.DrawLine(shadowPen,
                                   p1.X + ShadowOffset.X,
                                   p1.Y + ShadowOffset.Y,
                                   p2.X + ShadowOffset.X,
                                   p2.Y + ShadowOffset.Y);
                    }
                    else
                    {
                        g.DrawLine(Pen, p1.X, p1.Y, p2.X, p2.Y);
                    }
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Draws the 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>
        /// <param name="drawShadow">If true draw the shadow for the line. If false, draw line.</param>
        public void DrawLineOrShadow(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis, bool drawShadow)
        {
            Pen shadowPen = null;

            if (drawShadow)
            {
                shadowPen       = (Pen)this.Pen.Clone();
                shadowPen.Color = this.ShadowColor;
            }

            SequenceAdapter data =
                new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData);

            int numberPoints = data.Count;

            if (data.Count == 0)
            {
                return;
            }

            // clipping is now handled assigning a clip region in the
            // graphic object before this call
            if (numberPoints == 1)
            {
                PointF physical = Transform2D.GetTransformer(xAxis, yAxis).Transform(data[0]);

                if (drawShadow)
                {
                    g.DrawLine(shadowPen,
                               physical.X - 0.5f + this.ShadowOffset.X,
                               physical.Y + this.ShadowOffset.Y,
                               physical.X + 0.5f + this.ShadowOffset.X,
                               physical.Y + this.ShadowOffset.Y);
                }
                else
                {
                    g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y);
                }
            }
            else
            {
                // prepare for clipping
                double leftCutoff  = xAxis.PhysicalToWorld(xAxis.PhysicalMin, false);
                double rightCutoff = xAxis.PhysicalToWorld(xAxis.PhysicalMax, false);
                if (leftCutoff > rightCutoff)
                {
                    double temp = leftCutoff;
                    leftCutoff  = rightCutoff;
                    rightCutoff = temp;
                }
                if (drawShadow)
                {
                    // correct cut-offs
                    double shadowCorrection =
                        xAxis.PhysicalToWorld(ShadowOffset, false) - xAxis.PhysicalToWorld(new Point(0, 0), false);
                    leftCutoff  -= shadowCorrection;
                    rightCutoff -= shadowCorrection;
                }

                // determine which points to plot
                double        tradingTimeOffset = 0;
                List <PointD> plotPoints        = new List <PointD>(numberPoints);
                PointD        d1 = data[0];
                PointD        d2 = d1;
                if ((d1.X >= leftCutoff) && (d1.X <= rightCutoff))
                {
                    plotPoints.Add(d1);
                }
                DateTime prevTime = (DateTime)((System.Data.DataTable) this.DataSource).Rows[0][(string)this.AbscissaData];
                for (int i = 1; i < numberPoints; ++i)
                {
                    // check to see if any values null. If so, then continue.
                    d1 = d2;
                    d2 = data[i];
                    if (Double.IsNaN(d1.X) || Double.IsNaN(d1.Y) ||
                        Double.IsNaN(d2.X) || Double.IsNaN(d2.Y))
                    {
                        continue;
                    }

                    // Get the X axis offset to strip out the non-trading time
                    d1.X -= tradingTimeOffset;
                    DateTime nextTime = (DateTime)((System.Data.DataTable) this.DataSource).Rows[i][(string)this.AbscissaData];
                    if (nextTime.TimeOfDay < prevTime.TimeOfDay)
                    {
                        tradingTimeOffset += (double)(nextTime - prevTime).Ticks;
                    }
                    prevTime = nextTime;
                    d2.X    -= tradingTimeOffset;

                    // do horizontal clipping here, to speed up
                    if ((d1.X < leftCutoff && d2.X < leftCutoff) ||
                        (rightCutoff < d1.X && rightCutoff < d2.X))
                    {
                        continue;
                    }

                    // Add a point to plot
                    plotPoints.Add(d2);
                }

                // create a transform, which takes into account the skipped time
                PhysicalAxis shunkAxis = new PhysicalAxis(new DateTimeAxis(xAxis.Axis.WorldMin, xAxis.Axis.WorldMax - tradingTimeOffset), xAxis.PhysicalMin, xAxis.PhysicalMax);
                ITransform2D t         = Transform2D.GetTransformer(shunkAxis, yAxis);

                // plot those points
                for (int i = 1; i < plotPoints.Count; i++)
                {
                    // else draw line.
                    PointF p1 = t.Transform(plotPoints[i - 1]);
                    PointF p2 = t.Transform(plotPoints[i]);

                    // when very far zoomed in, points can fall ontop of each other,
                    // and g.DrawLine throws an overflow exception
                    if (p1.Equals(p2))
                    {
                        continue;
                    }

                    if (drawShadow)
                    {
                        g.DrawLine(shadowPen,
                                   p1.X + ShadowOffset.X,
                                   p1.Y + ShadowOffset.Y,
                                   p2.X + ShadowOffset.X,
                                   p2.Y + ShadowOffset.Y);
                    }
                    else
                    {
                        g.DrawLine(Pen, p1.X, p1.Y, p2.X, p2.Y);
                    }
                }
            }
        }
Пример #7
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 ();
            }
        }
Пример #8
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 );
                }

            }
        }
Пример #9
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 );
        }