This class does highly efficient world->physical and physical->world transforms for linear axes.
Пример #1
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);
                    }
                }
            }
        }
Пример #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)Pen.Clone();
                shadowPen.Color = ShadowColor;
            }

            SequenceAdapter data =
                new SequenceAdapter(DataSource, DataMember, OrdinateData, 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 + ShadowOffset.X,
                               physical.Y + ShadowOffset.Y,
                               physical.X + 0.5f + ShadowOffset.X,
                               physical.Y + 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);
                    }
                }
            }
        }
        /// <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>
        public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            try
            {



                double xVal, yVal;

                int pointCount = m_lineData.Count;
                if (pointCount == 0)
                    return;

                Stopwatch sw = StepTimer.Start("Transform");

                Transform2D t = new Transform2D(xAxis, yAxis);

                // clipping is now handled assigning a clip region in the
                // graphic object before this call
                if (pointCount == 1)
                {
                    m_lineData.Get(0, out xVal, out yVal);
                    PointF physical = t.Transform(xVal, yVal);
                    g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y);
                }
                else
                {
                    int index = 0;
                    PointF[] points = new PointF[pointCount];
                    PointF lastPoint = new PointF(Single.NaN, Single.NaN);
                    for (int i = 0; i < pointCount; ++i)
                    {
                        // check to see if any values null. If so, then continue.
                        m_lineData.Get(i, out xVal, out yVal);

                        if (!Double.IsNaN(xVal + yVal)) //Adding a NaN with anything yeilds NaN
                        {
                            const float GDIMax = 1000000000f;
                            const float GDIMin = -1000000000f;
                            PointF p1 = t.Transform(xVal, yVal);
                            if (p1.X > GDIMax)
                                p1.X = GDIMax;
                            if (p1.X < GDIMin)
                                p1.X = GDIMin;

                            if (p1.Y > GDIMax)
                                p1.Y = GDIMax;
                            if (p1.Y < GDIMin)
                                p1.Y = GDIMin;

                            if (!float.IsNaN(p1.X) && !float.IsNaN(p1.Y))
                            {
                                if (p1 != lastPoint)
                                {
                                    lastPoint = p1;
                                    points[index] = p1;
                                    index++;
                                }
                            }
                        }
                    }
                    //System.Drawing.Drawing2D.GraphicsPath graphicsPath = new System.Drawing.Drawing2D.GraphicsPath();
                    //graphicsPath.AddLines(points.ToArray());
                    //g.DrawPath(Pen, graphicsPath);
                    //g.CompositingQuality = CompositingQuality.HighQuality;
                    //g.SmoothingMode = SmoothingMode.HighQuality;
                    StepTimer.Stop(sw);

                    sw = StepTimer.Start("GDI+");
                    if (index == 0)
                        return;
                    else if (index == 1)
                    {
                        PointF physical = points[0];
                        g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y);
                        return;
                    }
                    if (index == points.Length)
                    {
                        g.DrawLines(Pen, points);
                    }
                    else
                    {
                        PointF[] newArray = new PointF[index];
                        Array.Copy(points, 0, newArray, 0, index);
                        g.DrawLines(Pen, newArray);
                    }
                    StepTimer.Stop(sw);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                throw;
            }
        }
Пример #4
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>
        public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            try
            {
                double xVal, yVal;

                int pointCount = m_lineData.Count;
                if (pointCount == 0)
                {
                    return;
                }

                Stopwatch sw = StepTimer.Start("Transform");

                Transform2D t = new Transform2D(xAxis, yAxis);

                // clipping is now handled assigning a clip region in the
                // graphic object before this call
                if (pointCount == 1)
                {
                    m_lineData.Get(0, out xVal, out yVal);
                    PointF physical = t.Transform(xVal, yVal);
                    g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y);
                }
                else
                {
                    int      index     = 0;
                    PointF[] points    = new PointF[pointCount];
                    PointF   lastPoint = new PointF(Single.NaN, Single.NaN);
                    for (int i = 0; i < pointCount; ++i)
                    {
                        // check to see if any values null. If so, then continue.
                        m_lineData.Get(i, out xVal, out yVal);

                        if (!Double.IsNaN(xVal + yVal)) //Adding a NaN with anything yeilds NaN
                        {
                            const float GDIMax = 1000000000f;
                            const float GDIMin = -1000000000f;
                            PointF      p1     = t.Transform(xVal, yVal);
                            if (p1.X > GDIMax)
                            {
                                p1.X = GDIMax;
                            }
                            if (p1.X < GDIMin)
                            {
                                p1.X = GDIMin;
                            }

                            if (p1.Y > GDIMax)
                            {
                                p1.Y = GDIMax;
                            }
                            if (p1.Y < GDIMin)
                            {
                                p1.Y = GDIMin;
                            }

                            if (!float.IsNaN(p1.X) && !float.IsNaN(p1.Y))
                            {
                                if (p1 != lastPoint)
                                {
                                    lastPoint     = p1;
                                    points[index] = p1;
                                    index++;
                                }
                            }
                        }
                    }
                    //System.Drawing.Drawing2D.GraphicsPath graphicsPath = new System.Drawing.Drawing2D.GraphicsPath();
                    //graphicsPath.AddLines(points.ToArray());
                    //g.DrawPath(Pen, graphicsPath);
                    //g.CompositingQuality = CompositingQuality.HighQuality;
                    //g.SmoothingMode = SmoothingMode.HighQuality;
                    StepTimer.Stop(sw);

                    sw = StepTimer.Start("GDI+");
                    if (index == 0)
                    {
                        return;
                    }
                    else if (index == 1)
                    {
                        PointF physical = points[0];
                        g.DrawLine(Pen, physical.X - 0.5f, physical.Y, physical.X + 0.5f, physical.Y);
                        return;
                    }
                    if (index == points.Length)
                    {
                        g.DrawLines(Pen, points);
                    }
                    else
                    {
                        PointF[] newArray = new PointF[index];
                        Array.Copy(points, 0, newArray, 0, index);
                        g.DrawLines(Pen, newArray);
                    }
                    StepTimer.Stop(sw);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                throw;
            }
        }