This class adds physical positioning information [PhysicalMin, PhysicalMax] and related functionality on top of a specific Axis class. It's an interesting question where to put this information. It belongs with every specific axis type, but on the other hand, users of the library as it is normally used should not see it because positioning of axes is handled internally by PlotSurface2D. Therefore it doesn't make sense to put it in the Axis class unless it is internal. But if this were done it would restrict use of this information outside the library always, which is not what is wanted. The main disadvantage with the method chosen is that there is a lot of passing of the positional information between physical axis and the underlying logical axis type. C# doesn't have templates. If it did, I might derive PhysicalAxis from the templated Axis type (LinearAxis etc). Instead, have used a has-a relationship with an Axis superclass.
 public void InitializeY(PhysicalAxis physicalAxis)
 {
     m_worldMinY = physicalAxis.Axis.WorldMin;
     double worldMax = physicalAxis.Axis.WorldMax;
     double worldLength = worldMax - m_worldMinY;
     m_pMinY = physicalAxis.PhysicalMin.Y;
     double pMax = physicalAxis.PhysicalMax.Y;
     double pLength = pMax - m_pMinY;
     m_divideWorldLengthTimesPLengthY = pLength / worldLength;
 }
        public override void ApplyConstraint(PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2)
        {
            double boreYMin, boreYMax, waveYMin, waveYMax;
            NPlot.Utils.ArrayMinMax(borePlot.OrdinateData as IList, out boreYMin, out boreYMax);
            NPlot.Utils.ArrayMinMax(waveformPlot.OrdinateData as IList, out waveYMin, out waveYMax);

            //we calculate the position of the bore plot first, indepedently of the waveform plot
            int borePlotHeight = AdjustBorePlot(pXAxis1, pYAxis1, boreYMax);

            AdjustWaveformPlot(pYAxis2, borePlotHeight, Math.Max(waveYMax, Math.Abs(waveYMin)));
        }
示例#3
0
        /// <summary>
        /// Constructs the optimal ITransform2D object for the supplied x and y axes.
        /// </summary>
        /// <param name="xAxis">The xAxis to use for the world to physical transform.</param>
        /// <param name="yAxis">The yAxis to use for the world to physical transform.</param>
        /// <returns>An ITransform2D derived object for converting from world to physical coordinates.</returns>
        public static ITransform2D GetTransformer(PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            ITransform2D ret = null;

            //			if (xAxis.Axis.IsLinear && yAxis.Axis.IsLinear && !xAxis.Axis.Reversed && !yAxis.Axis.Reversed)
            //				ret = new FastTransform2D( xAxis, yAxis );
            //			else
            //				ret = new DefaultTransform2D( xAxis, yAxis );

            ret = new DefaultTransform2D (xAxis, yAxis);
            return ret;
        }
示例#4
0
文件: AxisDrag.cs 项目: parnham/NPlot
        /// <summary>
        /// MouseDown method for AxisDrag interaction
        /// </summary>
        /// <param name="X">mouse X position</param>
        /// <param name="Y">mouse Y position</param>
        /// <param name="keys">mouse and keyboard modifiers</param>
        /// <param name="ps">the InteractivePlotSurface2D</param>
        public override bool DoMouseDown(int X, int Y, Modifier keys, InteractivePlotSurface2D ps)
        {
            // if the mouse is inside the plot area [the tick marks may be here,
                // and are counted as part of the axis], then don't invoke drag.
                if (ps.PlotAreaBoundingBoxCache.Contains(X,Y)) {
                    return false;
                }

                if ((keys & Modifier.Button1) != 0) {
                    // see if hit with axis. NB Only one axis object will be returned
                    ArrayList objects = ps.HitTest(new Point(X, Y));

                    foreach (object o in objects) {
                        if (o is NPlot.Axis) {
                            dragging_ = true;
                            axis_ = (Axis)o;

                            if (ps.PhysicalXAxis1Cache.Axis == axis_) {
                                physicalAxis_ = ps.PhysicalXAxis1Cache;
                                ps.plotCursor = CursorType.LeftRight;
                            }
                            else if (ps.PhysicalXAxis2Cache.Axis == axis_) {
                                physicalAxis_ = ps.PhysicalXAxis2Cache;
                                ps.plotCursor = CursorType.LeftRight;
                            }
                            else if (ps.PhysicalYAxis1Cache.Axis == axis_) {
                                physicalAxis_ = ps.PhysicalYAxis1Cache;
                                ps.plotCursor = CursorType.UpDown;
                            }
                            else if (ps.PhysicalYAxis2Cache.Axis == axis_) {
                                physicalAxis_ = ps.PhysicalYAxis2Cache;
                                ps.plotCursor = CursorType.UpDown;
                            }

                            startPoint_ = new Point(X, Y);	// don't combine these - Mono
                            lastPoint_ = startPoint_;		// bug #475205 prior to 2.4

                            // evaluate focusRatio about which axis is expanded
                            float  x = startPoint_.X - physicalAxis_.PhysicalMin.X;
                            float  y = startPoint_.Y - physicalAxis_.PhysicalMin.Y;
                            double r = Math.Sqrt(x*x + y*y);
                            focusRatio_ = r/physicalAxis_.PhysicalLength;

                            return false;
                        }
                    }
                }
                return false;
        }
        /// <summary>
        /// Adjusts the left y axis to ensure that the bore plot is placed at the top of the plot, and has a 1:1
        /// aspect ratio
        /// </summary>
        /// <param name="pXAxis1">The physical bottom x axis</param>
        /// <param name="pYAxis1">The physical left y axis</param>
        /// <param name="yMax">the actual max Y value of the bore</param>
        /// <returns>The physical height of the bore plot</returns>
        private int AdjustBorePlot(PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, double yMax)
        {
            double xDirPixelSize = pXAxis1.PixelWorldLength;
            //now calculate the required yWorldRange for a 1:1 aspect ratio
            double yWorldRange = xDirPixelSize * pYAxis1.PhysicalLength;

            //set the WorldMax of the axis to the top of the bore plot, plus 10 pixels for padding
            pYAxis1.Axis.WorldMax = yMax + 15 * xDirPixelSize;
            pYAxis1.Axis.WorldMin = pYAxis1.Axis.WorldMax - yWorldRange;

            //return the physical height of the bore plot.
            //this includes the height of the plot itself, plus 15 pixels padding on the top
            //and bottom
            return (int)(yMax * 2/xDirPixelSize) + 30;
        }
示例#6
0
        /// <summary>
        /// Construct from a fully-blown physical axis.
        /// </summary>
        /// <param name="physicalAxis">the physical axis to get initial values from.</param>
        public PageAlignedPhysicalAxis(PhysicalAxis physicalAxis)
        {
            worldMin_ = physicalAxis.Axis.WorldMin;
            worldMax_ = physicalAxis.Axis.WorldMax;
            worldLength_ = worldMax_ - worldMin_;

            if (physicalAxis.PhysicalMin.X == physicalAxis.PhysicalMax.X) {
                pMin_ = physicalAxis.PhysicalMin.Y;
                pMax_ = physicalAxis.PhysicalMax.Y;
            }
            else if (physicalAxis.PhysicalMin.Y == physicalAxis.PhysicalMax.Y) {
                pMin_ = physicalAxis.PhysicalMin.X;
                pMax_ = physicalAxis.PhysicalMax.X;
            }
            else {
                throw new NPlotException( "Physical axis is not page aligned" );
            }
            pLength_ = pMax_ - pMin_;
        }
        public override void ApplyConstraint(PhysicalAxis pXAxis1, PhysicalAxis pYAxis1, PhysicalAxis pXAxis2, PhysicalAxis pYAxis2)
        {
            double boreYMin, boreYMax;
            NPlot.Utils.ArrayMinMax(borePlot.OrdinateData as IList, out boreYMin, out boreYMax);

            double yPhysicalLength = ((boreYMax * 2)/pXAxis1.PixelWorldLength) + 15;

            double yWorldLength = yPhysicalLength * pXAxis1.PixelWorldLength;

            pYAxis1.Axis.WorldMin = -15 * pXAxis1.PixelWorldLength + boreYMin;
            pYAxis1.Axis.WorldMax = pYAxis1.Axis.WorldMin + yWorldLength;

            int change = (int)(pYAxis1.PhysicalLength - yPhysicalLength) / 2;

            pYAxis1.PhysicalMax = new Point(pYAxis1.PhysicalMax.X, pYAxis1.PhysicalMax.Y + change);
            pYAxis1.PhysicalMin = new Point(pYAxis1.PhysicalMin.X, pYAxis1.PhysicalMin.Y - change);

            pXAxis1.PhysicalMax = new Point(pXAxis1.PhysicalMax.X, pXAxis1.PhysicalMax.Y - change);
            pXAxis1.PhysicalMin = new Point(pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMin.Y - change);
        }
示例#8
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));
        }
示例#9
0
        /// <summary>
        /// Updates the PlotSurface2D axes to compensate for the legend.
        /// </summary>
        /// <param name="pXAxis1">the bottom x axis</param>
        /// <param name="pYAxis1">the left y axis</param>
        /// <param name="pXAxis2">the top x axis</param>
        /// <param name="pYAxis2">the right y axis</param>
        /// <param name="plots">list of plots.</param>
        /// <param name="scale">scale parameter (for text and other)</param>
        /// <param name="padding">padding around plot within bounds.</param>
        /// <param name="bounds">graphics surface bounds</param>
        /// <param name="position">legend position</param>
        public void UpdateAxesPositions( 
			PhysicalAxis pXAxis1,
			PhysicalAxis pYAxis1,
			PhysicalAxis pXAxis2,
			PhysicalAxis pYAxis2,
			ArrayList plots,
			float scale, int padding, Rectangle bounds,
			out Point position )
        {
            int leftIndent = 0;
            int rightIndent = 0;
            int bottomIndent = 0;
            int topIndent = 0;

            position = new Point(0,0);

            // now determine if legend should change any of these (legend should be fully
            // visible at all times), and draw legend.

            Rectangle legendWidthHeight = this.GetBoundingBox( new Point(0,0), plots, scale );

            if (legendWidthHeight.Width > bounds.Width)
            {
                legendWidthHeight.Width = bounds.Width;
            }

            // (1) calculate legend position.

            // y
            position.Y = this.yOffset_;

            if ( this.xAttach_ == PlotSurface2D.XAxisPosition.Bottom )
            {
                position.Y += pYAxis1.PhysicalMin.Y;
                if ( this.horizontalEdgePlacement_ == Legend.Placement.Inside )
                {
                    position.Y -= legendWidthHeight.Height;
                }
            }
            else
            {
                position.Y += pYAxis1.PhysicalMax.Y;
                if ( this.horizontalEdgePlacement_ == Legend.Placement.Outside )
                {
                    position.Y -= legendWidthHeight.Height;
                }
            }

            // x
            position.X = this.xOffset_;

            if ( this.yAttach_ == PlotSurface2D.YAxisPosition.Left )
            {
                if ( this.verticalEdgePlacement_ == Legend.Placement.Outside )
                {
                    position.X -= legendWidthHeight.Width;
                }
                position.X += pXAxis1.PhysicalMin.X;
            }
            else
            {
                if ( this.verticalEdgePlacement_ == Legend.Placement.Inside )
                {
                    position.X -= legendWidthHeight.Width;
                }
                position.X += pXAxis1.PhysicalMax.X;
            }

            // determine update amounts for axes

            if ( !this.neverShiftAxes_ )
            {
                if ( position.X < padding )
                {
                    int changeAmount = -position.X + padding;
                    // only allow axes to move away from bounds.
                    if ( changeAmount > 0 )
                    {
                        leftIndent = changeAmount;
                    }
                    position.X += changeAmount;
                }

                if ( position.X + legendWidthHeight.Width > bounds.Right - padding )
                {
                    int changeAmount = (position.X - bounds.Right + legendWidthHeight.Width + padding );
                    // only allow axes to move away from bounds.
                    if ( changeAmount > 0.0f )
                    {
                        rightIndent = changeAmount;
                    }
                    position.X -= changeAmount;
                }

                if ( position.Y < padding )
                {
                    int changeAmount = -position.Y + padding;
                    // only allow axes to move away from bounds.
                    if ( changeAmount > 0.0f )
                    {
                        topIndent = changeAmount;
                    }
                    position.Y += changeAmount;
                }

                if ( position.Y + legendWidthHeight.Height > bounds.Bottom - padding )
                {
                    int changeAmount = (position.Y - bounds.Bottom + legendWidthHeight.Height + padding );
                    // only allow axes to move away from bounds.
                    if ( changeAmount > 0.0f )
                    {
                        bottomIndent = changeAmount;
                    }
                    position.Y -= changeAmount;
                }

                // update axes.

                pXAxis1.PhysicalMin = new Point( pXAxis1.PhysicalMin.X + leftIndent, pXAxis1.PhysicalMin.Y - bottomIndent );
                pXAxis1.PhysicalMax = new Point( pXAxis1.PhysicalMax.X - rightIndent, pXAxis1.PhysicalMax.Y - bottomIndent );
                pYAxis1.PhysicalMin = new Point( pYAxis1.PhysicalMin.X + leftIndent, pYAxis1.PhysicalMin.Y - bottomIndent );
                pYAxis1.PhysicalMax = new Point( pYAxis1.PhysicalMax.X + leftIndent, pYAxis1.PhysicalMax.Y + topIndent );

                pXAxis2.PhysicalMin = new Point( pXAxis2.PhysicalMin.X + leftIndent, pXAxis2.PhysicalMin.Y + topIndent );
                pXAxis2.PhysicalMax = new Point( pXAxis2.PhysicalMax.X - rightIndent, pXAxis2.PhysicalMax.Y + topIndent );
                pYAxis2.PhysicalMin = new Point( pYAxis2.PhysicalMin.X - rightIndent, pYAxis2.PhysicalMin.Y - bottomIndent );
                pYAxis2.PhysicalMax = new Point( pYAxis2.PhysicalMax.X - rightIndent, pYAxis2.PhysicalMax.Y + topIndent );
            }
        }
示例#10
0
            /// <summary>
            /// Applies the constraint to the axes.
            /// </summary>
            /// <param name="pXAxis1">The bottom x-axis.</param>
            /// <param name="pYAxis1">The left y-axis.</param>
            /// <param name="pXAxis2">The top x-axis.</param>
            /// <param name="pYAxis2">The right y-axis.</param>
            public override void ApplyConstraint(
                PhysicalAxis pXAxis1, PhysicalAxis pYAxis1,
                PhysicalAxis pXAxis2, PhysicalAxis pYAxis2)
            {
                double xWorldRange    = Math.Abs(pXAxis1.Axis.WorldMax - pXAxis1.Axis.WorldMin);
                double xPhysicalRange = Math.Abs(pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X);
                double xDirPixelSize  = xWorldRange / xPhysicalRange;

                double yWorldRange    = Math.Abs(pYAxis1.Axis.WorldMax - pYAxis1.Axis.WorldMin);
                double yPhysicalRange = Math.Abs(pYAxis1.PhysicalMax.Y - pYAxis1.PhysicalMin.Y);
                double yDirPixelSize  = yWorldRange / yPhysicalRange;

                double currentAspectRatio = yDirPixelSize / xDirPixelSize;

                // we want to change the current aspect ratio to be the desired.
                // to do this, we may only add the world pixel lengths.

                if (a_ > currentAspectRatio)
                {
                    // want to increase aspect ratio. Therefore, want to add some amount
                    // to yDirPixelSize (numerator).

                    double toAdd     = (a_ - currentAspectRatio) * xDirPixelSize;
                    int    newHeight =
                        (int)(Math.Abs(pYAxis1.Axis.WorldMax - pYAxis1.Axis.WorldMin) / (yDirPixelSize + toAdd));
                    int changeInHeight = (int)yPhysicalRange - newHeight;

                    int changeBottom = changeInHeight / 2;
                    int changeTop    = changeInHeight / 2;
                    if (holdFixedX_ != null)
                    {
                        if ((PlotSurface2D.XAxisPosition)holdFixedX_ == PlotSurface2D.XAxisPosition.Bottom)
                        {
                            changeBottom = 0;
                            changeTop    = changeInHeight;
                        }
                        else
                        {
                            changeBottom = changeInHeight;
                            changeTop    = 0;
                        }
                    }

                    pYAxis1.PhysicalMin = new Point(pYAxis1.PhysicalMin.X, pYAxis1.PhysicalMin.Y - changeBottom);
                    pYAxis1.PhysicalMax = new Point(pYAxis1.PhysicalMax.X, pYAxis1.PhysicalMax.Y + changeTop);
                    pYAxis2.PhysicalMin = new Point(pYAxis2.PhysicalMin.X, pYAxis2.PhysicalMin.Y - changeBottom);
                    pYAxis2.PhysicalMax = new Point(pYAxis2.PhysicalMax.X, pYAxis2.PhysicalMax.Y + changeTop);

                    pXAxis1.PhysicalMin = new Point(pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMin.Y - changeBottom);
                    pXAxis1.PhysicalMax = new Point(pXAxis1.PhysicalMax.X, pXAxis1.PhysicalMax.Y - changeBottom);
                    pXAxis2.PhysicalMin = new Point(pXAxis2.PhysicalMin.X, pXAxis2.PhysicalMin.Y + changeTop);
                    pXAxis2.PhysicalMax = new Point(pXAxis2.PhysicalMax.X, pXAxis2.PhysicalMax.Y + changeTop);
                }

                else
                {
                    // want to decrease aspect ratio. Therefore, want to add some amount
                    // to xDirPixelSize (denominator).

                    double toAdd    = yDirPixelSize / a_ - xDirPixelSize;
                    int    newWidth =
                        (int)(Math.Abs(pXAxis1.Axis.WorldMax - pXAxis1.Axis.WorldMin) / (xDirPixelSize + toAdd));
                    int changeInWidth = (int)xPhysicalRange - newWidth;

                    int changeLeft  = changeInWidth / 2;
                    int changeRight = changeInWidth / 2;
                    if (holdFixedY_ != null)
                    {
                        if ((PlotSurface2D.YAxisPosition)holdFixedY_ == PlotSurface2D.YAxisPosition.Left)
                        {
                            changeLeft  = 0;
                            changeRight = changeInWidth;
                        }
                        else
                        {
                            changeLeft  = changeInWidth;
                            changeRight = 0;
                        }
                    }

                    pXAxis1.PhysicalMin = new Point(pXAxis1.PhysicalMin.X + changeLeft, pXAxis1.PhysicalMin.Y);
                    pXAxis1.PhysicalMax = new Point(pXAxis1.PhysicalMax.X - changeRight, pXAxis1.PhysicalMax.Y);
                    pXAxis2.PhysicalMin = new Point(pXAxis2.PhysicalMin.X + changeLeft, pXAxis2.PhysicalMin.Y);
                    pXAxis2.PhysicalMax = new Point(pXAxis2.PhysicalMax.X - changeRight, pXAxis2.PhysicalMax.Y);

                    pYAxis1.PhysicalMin = new Point(pYAxis1.PhysicalMin.X + changeLeft, pYAxis1.PhysicalMin.Y);
                    pYAxis1.PhysicalMax = new Point(pYAxis1.PhysicalMax.X + changeLeft, pYAxis1.PhysicalMax.Y);
                    pYAxis2.PhysicalMin = new Point(pYAxis2.PhysicalMin.X - changeRight, pYAxis2.PhysicalMin.Y);
                    pYAxis2.PhysicalMax = new Point(pYAxis2.PhysicalMax.X - changeRight, pYAxis2.PhysicalMax.Y);
                }
            }
        /// <summary>
        /// Draws the grid
        /// </summary>
        /// <param name="g">The graphics surface on which to draw</param>
        /// <param name="xAxis">The physical x axis to draw horizontal lines parallel to.</param>
        /// <param name="yAxis">The physical y axis to draw vertical lines parallel to.</param>
        public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            List<double> xLargePositions = null;
            List<double> yLargePositions = null;
            List<double> xSmallPositions = null;
            List<double> ySmallPositions = null;

            if (this.horizontalGridType_ != GridType.None)
            {
                xAxis.Axis.WorldTickPositions_FirstPass(xAxis.PhysicalMin, xAxis.PhysicalMax, out xLargePositions, out xSmallPositions);
                DrawGridLines(g, xAxis, yAxis, xLargePositions, true, this.MajorGridPen);
            }

            if (this.verticalGridType_ != GridType.None)
            {
                yAxis.Axis.WorldTickPositions_FirstPass(yAxis.PhysicalMin, yAxis.PhysicalMax, out yLargePositions, out ySmallPositions);
                DrawGridLines(g, yAxis, xAxis, yLargePositions, false, this.MajorGridPen);
            }


            if (this.horizontalGridType_ == GridType.Fine)
            {
                xAxis.Axis.WorldTickPositions_SecondPass(xAxis.PhysicalMin, xAxis.PhysicalMax, xLargePositions, ref xSmallPositions);
                DrawGridLines(g, xAxis, yAxis, xSmallPositions, true, this.MinorGridPen);
            }

            if (this.verticalGridType_ == GridType.Fine)
            {
                yAxis.Axis.WorldTickPositions_SecondPass(yAxis.PhysicalMin, yAxis.PhysicalMax, yLargePositions, ref ySmallPositions);
                DrawGridLines(g, yAxis, xAxis, ySmallPositions, false, this.MinorGridPen);
            }
        }
示例#12
0
        /// <summary>
        /// Draw the filled region
        /// </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 )
        {
            ITransform2D t = Transform2D.GetTransformer(xAxis, yAxis);

            Brush b = brush_;
            if (b == null)
            {
                b = areaBrush_.Get(new Rectangle(xAxis.PhysicalMin.X, yAxis.PhysicalMax.Y, xAxis.PhysicalLength, yAxis.PhysicalLength));
            }

            if (hl1_ != null && hl2_ != null)
            {
                PointF[] points = new PointF[4];
                points[0] = t.Transform(xAxis.Axis.WorldMin, hl1_.OrdinateValue);
                points[1] = t.Transform(xAxis.Axis.WorldMax, hl1_.OrdinateValue);
                points[2] = t.Transform(xAxis.Axis.WorldMax, hl2_.OrdinateValue);
                points[3] = t.Transform(xAxis.Axis.WorldMin, hl2_.OrdinateValue);

                g.FillPolygon(b, points);
            }
            else if (vl1_ != null && vl2_ != null)
            {
                PointF[] points = new PointF[4];
                points[0] = t.Transform(vl1_.AbscissaValue, yAxis.Axis.WorldMin);
                points[1] = t.Transform(vl1_.AbscissaValue, yAxis.Axis.WorldMax);
                points[2] = t.Transform(vl2_.AbscissaValue, yAxis.Axis.WorldMax);
                points[3] = t.Transform(vl2_.AbscissaValue, yAxis.Axis.WorldMin);

                g.FillPolygon(b, points);
            }
            else if (lp1_ != null && lp2_ != null)
            {
                SequenceAdapter a1 = new SequenceAdapter(lp1_.DataSource, lp1_.DataMember, lp1_.OrdinateData, lp1_.AbscissaData);
                SequenceAdapter a2 = new SequenceAdapter(lp2_.DataSource, lp2_.DataMember, lp2_.OrdinateData, lp2_.AbscissaData);

                int count = a1.Count + a2.Count;
                PointF[] points = new PointF[count];
                for (int i = 0; i < a1.Count; ++i)
                {
                    points[i] = t.Transform(a1[i]);
                }
                for (int i = 0; i < a2.Count; ++i)
                {
                    points[i + a1.Count] = t.Transform(a2[a2.Count - i - 1]);
                }

                g.FillPolygon(b, points);
            }
            else
            {
                throw new NPlotException("One of bounds was set to null");
            }
        }
示例#13
0
文件: LinePlot.cs 项目: parnham/NPlot
 /// <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>
 public void Draw(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis)
 {
     if (shadow_) {
         DrawLineOrShadow (ctx, xAxis, yAxis, true);
     }
     DrawLineOrShadow (ctx, xAxis, yAxis, false);
 }
示例#14
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 );
                        }
                    }
                }
            }
        }
示例#15
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.
		}
示例#16
0
        /// <summary>
        /// Draw the the PlotSurface2D and all contents [axes, drawables, and legend] on the 
        /// supplied graphics surface.
        /// </summary>
        /// <param name="g">The graphics surface on which to draw.</param>
        /// <param name="bounds">A bounding box on this surface that denotes the area on the
        /// surface to confine drawing to.</param>
        public void Draw( Graphics g, Rectangle bounds )
        {
            // determine font sizes and tick scale factor.
            float scale = DetermineScaleFactor( bounds.Width, bounds.Height );

            // if there is nothing to plot, return.
            if ( drawables_.Count == 0 )
            {
                // draw title
                float x_center = (bounds.Left + bounds.Right)/2.0f;
                float y_center = (bounds.Top + bounds.Bottom)/2.0f;
                Font scaled_font;
                if (this.AutoScaleTitle)
                {
                    scaled_font = Utils.ScaleFont( titleFont_, scale );
                }
                else
                {
                    scaled_font = titleFont_;
                }
                g.DrawString( title_, scaled_font, this.titleBrush_, new PointF(x_center,y_center), titleDrawFormat_ );

                return;
            }

            // determine the [non physical] axes to draw based on the axis properties set.
            Axis xAxis1 = null;
            Axis xAxis2 = null;
            Axis yAxis1 = null;
            Axis yAxis2 = null;
            this.DetermineAxesToDraw( out xAxis1, out xAxis2, out yAxis1, out yAxis2 );

            // apply scale factor to axes as desired.

            if (xAxis1.AutoScaleTicks)
                xAxis1.TickScale = scale;
            if (xAxis1.AutoScaleText)
                xAxis1.FontScale = scale;
            if (yAxis1.AutoScaleTicks)
                yAxis1.TickScale = scale;
            if (yAxis1.AutoScaleText)
                yAxis1.FontScale = scale;
            if (xAxis2.AutoScaleTicks)
                xAxis2.TickScale = scale;
            if (xAxis2.AutoScaleText)
                xAxis2.FontScale = scale;
            if (yAxis2.AutoScaleTicks)
                yAxis2.TickScale = scale;
            if (yAxis2.AutoScaleText)
                yAxis2.FontScale = scale;

            // determine the default physical positioning of those axes.
            PhysicalAxis pXAxis1 = null;
            PhysicalAxis pYAxis1 = null;
            PhysicalAxis pXAxis2 = null;
            PhysicalAxis pYAxis2 = null;
            this.DeterminePhysicalAxesToDraw(
                bounds, xAxis1, xAxis2, yAxis1, yAxis2,
                out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2 );

            float oldXAxis2Height = pXAxis2.PhysicalMin.Y;

            // Apply axes constraints
            for (int i=0; i<axesConstraints_.Count; ++i)
            {
                ((AxesConstraint)axesConstraints_[i]).ApplyConstraint(
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2 );
            }

            /////////////////////////////////////////////////////////////////////////
            // draw legend if have one.
            // Note: this will update axes if necessary.

            Point legendPosition = new Point(0,0);
            if (this.legend_ != null)
            {
                legend_.UpdateAxesPositions(
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2,
                    this.drawables_, scale, this.padding_, bounds,
                    out legendPosition );
            }

            float newXAxis2Height = pXAxis2.PhysicalMin.Y;

            float titleExtraOffset = oldXAxis2Height - newXAxis2Height;

            // now we are ready to define the bounding box for the plot area (to use in clipping
            // operations.
            plotAreaBoundingBoxCache_ = new Rectangle(
                Math.Min( pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMax.X ),
                Math.Min( pYAxis1.PhysicalMax.Y, pYAxis1.PhysicalMin.Y ),
                Math.Abs( pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X + 1 ),
                Math.Abs( pYAxis1.PhysicalMin.Y - pYAxis1.PhysicalMax.Y + 1 )
            );
            bbXAxis1Cache_ = pXAxis1.GetBoundingBox();
            bbXAxis2Cache_ = pXAxis2.GetBoundingBox();
            bbYAxis1Cache_ = pYAxis1.GetBoundingBox();
            bbYAxis2Cache_ = pYAxis2.GetBoundingBox();

            // Fill in the background.
            if ( this.plotBackColor_ != null )
            {
                g.FillRectangle(
                    new System.Drawing.SolidBrush( (Color)this.plotBackColor_ ),
                    (Rectangle)plotAreaBoundingBoxCache_ );
            }
            else if (this.plotBackBrush_ != null)
            {
                g.FillRectangle(
                    this.plotBackBrush_.Get( (Rectangle)plotAreaBoundingBoxCache_ ),
                    (Rectangle)plotAreaBoundingBoxCache_ );
            }
            else if (this.plotBackImage_ != null)
            {
                g.DrawImage(
                    Utils.TiledImage( this.plotBackImage_ , new Size(
                        ((Rectangle)plotAreaBoundingBoxCache_).Width,
                        ((Rectangle)plotAreaBoundingBoxCache_).Height ) ),
                    (Rectangle)plotAreaBoundingBoxCache_ );
            }

            // draw title
            float xt = (pXAxis2.PhysicalMax.X + pXAxis2.PhysicalMin.X)/2.0f;
            float yt = bounds.Top + this.padding_ - titleExtraOffset;
            Font scaledFont;
            if (this.AutoScaleTitle)
            {
                scaledFont = Utils.ScaleFont( titleFont_, scale );
            }
            else
            {
                scaledFont = titleFont_;
            }
            g.DrawString( title_, scaledFont, this.titleBrush_,	new PointF(xt,yt), titleDrawFormat_ );

            //count number of new lines in title.
            int nlCount = 0;
            for (int i=0; i<title_.Length; ++i)
            {
                if (title_[i] == '\n')
                    nlCount += 1;
            }

            SizeF s = g.MeasureString(title_,scaledFont);
            bbTitleCache_ = new Rectangle( (int)(xt-s.Width/2), (int)(yt), (int)(s.Width), (int)(s.Height)*(nlCount+1) );

            // draw drawables..
            System.Drawing.Drawing2D.SmoothingMode smoothSave = g.SmoothingMode;

            g.SmoothingMode = this.smoothingMode_;

            bool legendDrawn = false;

            for ( int i_o = 0; i_o < ordering_.Count; ++i_o )
            {

                int i = (int)ordering_.GetByIndex(i_o);
                double zOrder = (double)ordering_.GetKey( i_o );
                if (zOrder > this.legendZOrder_)
                {
                    // draw legend.
                    if ( !legendDrawn && this.legend_ != null )
                    {
                        legend_.Draw( g, legendPosition, this.drawables_, scale );
                        legendDrawn = true;
                    }
                }

                IDrawable drawable = (IDrawable)drawables_[i];
                XAxisPosition xap = (XAxisPosition)xAxisPositions_[i];
                YAxisPosition yap = (YAxisPosition)yAxisPositions_[i];

                PhysicalAxis drawXAxis;
                PhysicalAxis drawYAxis;

                if ( xap == XAxisPosition.Bottom )
                {
                    drawXAxis = pXAxis1;
                }
                else
                {
                    drawXAxis = pXAxis2;
                }

                if ( yap == YAxisPosition.Left )
                {
                    drawYAxis = pYAxis1;
                }
                else
                {
                    drawYAxis = pYAxis2;
                }

                // set the clipping region.. (necessary for zoom)
                g.Clip = new Region((Rectangle)plotAreaBoundingBoxCache_);
                // plot.
                drawable.Draw( g, drawXAxis, drawYAxis );
                // reset it..
                g.ResetClip();
            }

            if ( !legendDrawn && this.legend_ != null )
            {
                legend_.Draw( g, legendPosition, this.drawables_, scale );
            }

            // cache the physical axes we used on this draw;
            this.pXAxis1Cache_ = pXAxis1;
            this.pYAxis1Cache_ = pYAxis1;
            this.pXAxis2Cache_ = pXAxis2;
            this.pYAxis2Cache_ = pYAxis2;

            g.SmoothingMode = smoothSave;

            // now draw axes.
            Rectangle axisBounds;
            pXAxis1.Draw( g, out axisBounds );
            pXAxis2.Draw( g, out axisBounds );
            pYAxis1.Draw( g, out axisBounds );
            pYAxis2.Draw( g, out axisBounds );

            #if DEBUG_BOUNDING_BOXES
            g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbXAxis1Cache_ );
            g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbXAxis2Cache_ );
            g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbYAxis1Cache_ );
            g.DrawRectangle( new Pen(Color.Orange), (Rectangle) bbYAxis2Cache_ );
            g.DrawRectangle( new Pen(Color.Red,5.0F),(Rectangle) plotAreaBoundingBoxCache_);
            //if(this.ShowLegend)g.DrawRectangle( new Pen(Color.Chocolate, 3.0F), (Rectangle) bbLegendCache_);
            g.DrawRectangle( new Pen(Color.DeepPink,2.0F), (Rectangle) bbTitleCache_);
            #endif
        }
示例#17
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);
                    }
                }
            }
        }
                /// <summary>
                /// 
                /// </summary>
                /// <param name="e"></param>
                /// <param name="ctr"></param>
                public override bool DoMouseUp(MouseEventArgs e, Control ctr)
                {
                    if (doing_)
                    {
                        doing_ = false;
                        axis_ = null;
                        physicalAxis_ = null;
                        lastPoint_ = new Point();
                    }

                    return false;
                }
示例#19
0
        /// <summary>
        /// Draw the the PlotSurface2D and all contents [axes, drawables, and legend] on the
        /// supplied graphics surface.
        /// </summary>
        /// <param name="g">The graphics surface on which to draw.</param>
        /// <param name="bounds">A bounding box on this surface that denotes the area on the
        /// surface to confine drawing to.</param>
        public void Draw(Graphics g, Rectangle bounds)
        {
            // determine font sizes and tick scale factor.
            float scale = DetermineScaleFactor(bounds.Width, bounds.Height);

            // if there is nothing to plot, return.
            if (drawables_.Count == 0)
            {
                // draw title
                float x_center = (bounds.Left + bounds.Right) / 2.0f;
                float y_center = (bounds.Top + bounds.Bottom) / 2.0f;
                Font  scaled_font;
                if (AutoScaleTitle)
                {
                    scaled_font = Utils.ScaleFont(titleFont_, scale);
                }
                else
                {
                    scaled_font = titleFont_;
                }
                g.DrawString(title_, scaled_font, titleBrush_, new PointF(x_center, y_center), titleDrawFormat_);

                return;
            }

            // determine the [non physical] axes to draw based on the axis properties set.
            Axis xAxis1 = null;
            Axis xAxis2 = null;
            Axis yAxis1 = null;
            Axis yAxis2 = null;

            DetermineAxesToDraw(out xAxis1, out xAxis2, out yAxis1, out yAxis2);

            // apply scale factor to axes as desired.

            if (xAxis1.AutoScaleTicks)
            {
                xAxis1.TickScale = scale;
            }
            if (xAxis1.AutoScaleText)
            {
                xAxis1.FontScale = scale;
            }
            if (yAxis1.AutoScaleTicks)
            {
                yAxis1.TickScale = scale;
            }
            if (yAxis1.AutoScaleText)
            {
                yAxis1.FontScale = scale;
            }
            if (xAxis2.AutoScaleTicks)
            {
                xAxis2.TickScale = scale;
            }
            if (xAxis2.AutoScaleText)
            {
                xAxis2.FontScale = scale;
            }
            if (yAxis2.AutoScaleTicks)
            {
                yAxis2.TickScale = scale;
            }
            if (yAxis2.AutoScaleText)
            {
                yAxis2.FontScale = scale;
            }

            // determine the default physical positioning of those axes.
            PhysicalAxis pXAxis1 = null;
            PhysicalAxis pYAxis1 = null;
            PhysicalAxis pXAxis2 = null;
            PhysicalAxis pYAxis2 = null;

            DeterminePhysicalAxesToDraw(
                bounds, xAxis1, xAxis2, yAxis1, yAxis2,
                out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2);

            float oldXAxis2Height = pXAxis2.PhysicalMin.Y;

            // Apply axes constraints
            for (int i = 0; i < axesConstraints_.Count; ++i)
            {
                ((AxesConstraint)axesConstraints_[i]).ApplyConstraint(
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2);
            }

            /////////////////////////////////////////////////////////////////////////
            // draw legend if have one.
            // Note: this will update axes if necessary.

            Point legendPosition = new Point(0, 0);

            if (legend_ != null)
            {
                legend_.UpdateAxesPositions(
                    pXAxis1, pYAxis1, pXAxis2, pYAxis2,
                    drawables_, scale, padding_, bounds,
                    out legendPosition);
            }

            float newXAxis2Height = pXAxis2.PhysicalMin.Y;

            float titleExtraOffset = oldXAxis2Height - newXAxis2Height;

            // now we are ready to define the bounding box for the plot area (to use in clipping
            // operations.
            plotAreaBoundingBoxCache_ = new Rectangle(
                Math.Min(pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMax.X),
                Math.Min(pYAxis1.PhysicalMax.Y, pYAxis1.PhysicalMin.Y),
                Math.Abs(pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X + 1),
                Math.Abs(pYAxis1.PhysicalMin.Y - pYAxis1.PhysicalMax.Y + 1)
                );
            bbXAxis1Cache_ = pXAxis1.GetBoundingBox();
            bbXAxis2Cache_ = pXAxis2.GetBoundingBox();
            bbYAxis1Cache_ = pYAxis1.GetBoundingBox();
            bbYAxis2Cache_ = pYAxis2.GetBoundingBox();

            // Fill in the background.
            if (plotBackColor_ != null)
            {
                g.FillRectangle(
                    new System.Drawing.SolidBrush((Color)plotBackColor_),
                    (Rectangle)plotAreaBoundingBoxCache_);
            }
            else if (plotBackBrush_ != null)
            {
                g.FillRectangle(
                    plotBackBrush_.Get((Rectangle)plotAreaBoundingBoxCache_),
                    (Rectangle)plotAreaBoundingBoxCache_);
            }
            else if (plotBackImage_ != null)
            {
                g.DrawImage(
                    Utils.TiledImage(plotBackImage_, new Size(
                                         ((Rectangle)plotAreaBoundingBoxCache_).Width,
                                         ((Rectangle)plotAreaBoundingBoxCache_).Height)),
                    (Rectangle)plotAreaBoundingBoxCache_);
            }

            // draw title
            float xt = (pXAxis2.PhysicalMax.X + pXAxis2.PhysicalMin.X) / 2.0f;
            float yt = bounds.Top + padding_ - titleExtraOffset;
            Font  scaledFont;

            if (AutoScaleTitle)
            {
                scaledFont = Utils.ScaleFont(titleFont_, scale);
            }
            else
            {
                scaledFont = titleFont_;
            }
            g.DrawString(title_, scaledFont, titleBrush_, new PointF(xt, yt), titleDrawFormat_);

            //count number of new lines in title.
            int nlCount = 0;

            for (int i = 0; i < title_.Length; ++i)
            {
                if (title_[i] == '\n')
                {
                    nlCount += 1;
                }
            }

            SizeF s = g.MeasureString(title_, scaledFont);

            bbTitleCache_ = new Rectangle((int)(xt - s.Width / 2), (int)(yt), (int)(s.Width), (int)(s.Height) * (nlCount + 1));

            // draw drawables..
            System.Drawing.Drawing2D.SmoothingMode smoothSave = g.SmoothingMode;

            g.SmoothingMode = smoothingMode_;

            bool legendDrawn = false;

            for (int i_o = 0; i_o < ordering_.Count; ++i_o)
            {
                int    i      = (int)ordering_.GetByIndex(i_o);
                double zOrder = (double)ordering_.GetKey(i_o);
                if (zOrder > legendZOrder_)
                {
                    // draw legend.
                    if (!legendDrawn && legend_ != null)
                    {
                        legend_.Draw(g, legendPosition, drawables_, scale);
                        legendDrawn = true;
                    }
                }

                IDrawable     drawable = (IDrawable)drawables_[i];
                XAxisPosition xap      = (XAxisPosition)xAxisPositions_[i];
                YAxisPosition yap      = (YAxisPosition)yAxisPositions_[i];

                PhysicalAxis drawXAxis;
                PhysicalAxis drawYAxis;

                if (xap == XAxisPosition.Bottom)
                {
                    drawXAxis = pXAxis1;
                }
                else
                {
                    drawXAxis = pXAxis2;
                }

                if (yap == YAxisPosition.Left)
                {
                    drawYAxis = pYAxis1;
                }
                else
                {
                    drawYAxis = pYAxis2;
                }

                // set the clipping region.. (necessary for zoom)
                g.Clip = new Region((Rectangle)plotAreaBoundingBoxCache_);
                // plot.
                drawable.Draw(g, drawXAxis, drawYAxis);
                // reset it..
                g.ResetClip();
            }

            if (!legendDrawn && legend_ != null)
            {
                legend_.Draw(g, legendPosition, drawables_, scale);
            }

            // cache the physical axes we used on this draw;
            pXAxis1Cache_ = pXAxis1;
            pYAxis1Cache_ = pYAxis1;
            pXAxis2Cache_ = pXAxis2;
            pYAxis2Cache_ = pYAxis2;

            g.SmoothingMode = smoothSave;

            // now draw axes.
            Rectangle axisBounds;

            pXAxis1.Draw(g, out axisBounds);
            pXAxis2.Draw(g, out axisBounds);
            pYAxis1.Draw(g, out axisBounds);
            pYAxis2.Draw(g, out axisBounds);

#if DEBUG_BOUNDING_BOXES
            g.DrawRectangle(new Pen(Color.Orange), (Rectangle)bbXAxis1Cache_);
            g.DrawRectangle(new Pen(Color.Orange), (Rectangle)bbXAxis2Cache_);
            g.DrawRectangle(new Pen(Color.Orange), (Rectangle)bbYAxis1Cache_);
            g.DrawRectangle(new Pen(Color.Orange), (Rectangle)bbYAxis2Cache_);
            g.DrawRectangle(new Pen(Color.Red, 5.0F), (Rectangle)plotAreaBoundingBoxCache_);
            //if(this.ShowLegend)g.DrawRectangle( new Pen(Color.Chocolate, 3.0F), (Rectangle) bbLegendCache_);
            g.DrawRectangle(new Pen(Color.DeepPink, 2.0F), (Rectangle)bbTitleCache_);
#endif
        }
示例#20
0
        private void DeterminePhysicalAxesToDraw(Rectangle bounds,
                                                 Axis xAxis1, Axis xAxis2, Axis yAxis1, Axis yAxis2,
                                                 out PhysicalAxis pXAxis1, out PhysicalAxis pXAxis2,
                                                 out PhysicalAxis pYAxis1, out PhysicalAxis pYAxis2)
        {
            System.Drawing.Rectangle cb = bounds;

            pXAxis1 = new PhysicalAxis(xAxis1,
                                       new Point(cb.Left, cb.Bottom), new Point(cb.Right, cb.Bottom));
            pYAxis1 = new PhysicalAxis(yAxis1,
                                       new Point(cb.Left, cb.Bottom), new Point(cb.Left, cb.Top));
            pXAxis2 = new PhysicalAxis(xAxis2,
                                       new Point(cb.Left, cb.Top), new Point(cb.Right, cb.Top));
            pYAxis2 = new PhysicalAxis(yAxis2,
                                       new Point(cb.Right, cb.Bottom), new Point(cb.Right, cb.Top));

            int bottomIndent = padding_;

            if (!pXAxis1.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pXAxis1.GetBoundingBox();
                // finally determine its indentation from the bottom
                bottomIndent = bottomIndent + bb.Bottom - cb.Bottom;
            }

            int leftIndent = padding_;

            if (!pYAxis1.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pYAxis1.GetBoundingBox();
                // finally determine its indentation from the left
                leftIndent = leftIndent - bb.Left + cb.Left;
            }

            int   topIndent = padding_;
            float scale     = DetermineScaleFactor(bounds.Width, bounds.Height);
            int   titleHeight;

            if (AutoScaleTitle)
            {
                titleHeight = Utils.ScaleFont(titleFont_, scale).Height;
            }
            else
            {
                titleHeight = titleFont_.Height;
            }

            //count number of new lines in title.
            int nlCount = 0;

            for (int i = 0; i < title_.Length; ++i)
            {
                if (title_[i] == '\n')
                {
                    nlCount += 1;
                }
            }
            titleHeight = (int)(((float)nlCount * 0.75 + 1.0f) * (float)titleHeight);

            if (!pXAxis2.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pXAxis2.GetBoundingBox();
                topIndent = topIndent - bb.Top + cb.Top;

                // finally determine its indentation from the top
                // correct top indendation to take into account plot title
                if (title_ != "")
                {
                    topIndent += (int)(titleHeight * 1.3f);
                }
            }

            int rightIndent = padding_;

            if (!pYAxis2.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pYAxis2.GetBoundingBox();

                // finally determine its indentation from the right
                rightIndent = (int)(rightIndent + bb.Right - cb.Right);
            }

            // now we have all the default calculated positions and we can proceed to
            // "move" the axes to their right places

            // primary axes (bottom, left)
            pXAxis1.PhysicalMin = new Point(cb.Left + leftIndent, cb.Bottom - bottomIndent);
            pXAxis1.PhysicalMax = new Point(cb.Right - rightIndent, cb.Bottom - bottomIndent);
            pYAxis1.PhysicalMin = new Point(cb.Left + leftIndent, cb.Bottom - bottomIndent);
            pYAxis1.PhysicalMax = new Point(cb.Left + leftIndent, cb.Top + topIndent);

            // secondary axes (top, right)
            pXAxis2.PhysicalMin = new Point(cb.Left + leftIndent, cb.Top + topIndent);
            pXAxis2.PhysicalMax = new Point(cb.Right - rightIndent, cb.Top + topIndent);
            pYAxis2.PhysicalMin = new Point(cb.Right - rightIndent, cb.Bottom - bottomIndent);
            pYAxis2.PhysicalMax = new Point(cb.Right - rightIndent, cb.Top + topIndent);
        }
示例#21
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="xAxis">The x-axis to use for transforms</param>
 /// <param name="yAxis">The y-axis to use for transforms</param>
 public DefaultTransform2D(PhysicalAxis xAxis, PhysicalAxis yAxis)
 {
     xAxis_ = xAxis;
     yAxis_ = yAxis;
 }
示例#22
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="xAxis">The x-axis to use for transforms</param>
 /// <param name="yAxis">The y-axis to use for transforms</param>
 public FastTransform2D(PhysicalAxis xAxis, PhysicalAxis yAxis)
 {
     xAxis_ = new PageAlignedPhysicalAxis(xAxis);
     yAxis_ = new PageAlignedPhysicalAxis(yAxis);
 }
示例#23
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 );
                    }
                }
            }
        }
示例#24
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);
                    }
                }
            }
        }
示例#25
0
        private void Init()
        {
            drawables_ = new ArrayList();
            xAxisPositions_ = new ArrayList();
            yAxisPositions_ = new ArrayList();
            zPositions_ = new ArrayList();
            ordering_ = new SortedList();
            FontFamily fontFamily = new FontFamily("Arial");
            TitleFont = new Font(fontFamily, 14, FontStyle.Regular, GraphicsUnit.Pixel);
            padding_ = 10;
            title_ = "";
            autoScaleTitle_ = false;
            autoScaleAutoGeneratedAxes_ = false;
            xAxis1_ = null;
            xAxis2_ = null;
            yAxis1_ = null;
            yAxis2_ = null;
            pXAxis1Cache_ = null;
            pYAxis1Cache_ = null;
            pXAxis2Cache_ = null;
            pYAxis2Cache_ = null;
            titleBrush_ = new SolidBrush( Color.Black );
            plotBackColor_ = Color.White;

            this.legend_ = null;

            smoothingMode_ = System.Drawing.Drawing2D.SmoothingMode.None;

            axesConstraints_ = new ArrayList();
        }
示例#26
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="xAxis">The x-axis to use for transforms</param>
 /// <param name="yAxis">The y-axis to use for transforms</param>
 public Transform2D(PhysicalAxis xAxis, PhysicalAxis yAxis)
 {
     InitializeX(xAxis);
     InitializeY(yAxis);
 }
示例#27
0
        private void DeterminePhysicalAxesToDraw( Rectangle bounds, 
			Axis xAxis1, Axis xAxis2, Axis yAxis1, Axis yAxis2,
			out PhysicalAxis pXAxis1, out PhysicalAxis pXAxis2, 
			out PhysicalAxis pYAxis1, out PhysicalAxis pYAxis2 )
        {
            System.Drawing.Rectangle cb = bounds;

            pXAxis1 = new PhysicalAxis( xAxis1,
                new Point( cb.Left, cb.Bottom ), new Point( cb.Right, cb.Bottom ) );
            pYAxis1 = new PhysicalAxis( yAxis1,
                new Point( cb.Left, cb.Bottom ), new Point( cb.Left, cb.Top ) );
            pXAxis2 = new PhysicalAxis( xAxis2,
                new Point( cb.Left, cb.Top), new Point( cb.Right, cb.Top) );
            pYAxis2 = new PhysicalAxis( yAxis2,
                new Point( cb.Right, cb.Bottom ), new Point( cb.Right, cb.Top ) );

            int bottomIndent = padding_;
            if (!pXAxis1.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pXAxis1.GetBoundingBox();
                // finally determine its indentation from the bottom
                bottomIndent = bottomIndent + bb.Bottom - cb.Bottom;
            }

            int leftIndent = padding_;
            if (!pYAxis1.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pYAxis1.GetBoundingBox();
                // finally determine its indentation from the left
                leftIndent = leftIndent - bb.Left + cb.Left;
            }

            int topIndent = padding_;
            float scale = this.DetermineScaleFactor( bounds.Width, bounds.Height );
            int titleHeight;
            if (this.AutoScaleTitle)
            {
                titleHeight = Utils.ScaleFont(titleFont_, scale).Height;
            }
            else
            {
                titleHeight = titleFont_.Height;
            }

            //count number of new lines in title.
            int nlCount = 0;
            for (int i=0; i<title_.Length; ++i)
            {
                if (title_[i] == '\n')
                    nlCount += 1;
            }
            titleHeight = (int)( ((float)nlCount*0.75 + 1.0f) * (float)titleHeight);

            if (!pXAxis2.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pXAxis2.GetBoundingBox();
                topIndent = topIndent - bb.Top + cb.Top;

                // finally determine its indentation from the top
                // correct top indendation to take into account plot title
                if (title_ != "" )
                {
                    topIndent += (int)(titleHeight * 1.3f);
                }
            }

            int rightIndent = padding_;
            if (!pYAxis2.Axis.Hidden)
            {
                // evaluate its bounding box
                Rectangle bb = pYAxis2.GetBoundingBox();

                // finally determine its indentation from the right
                rightIndent = (int)(rightIndent + bb.Right-cb.Right);
            }

            // now we have all the default calculated positions and we can proceed to
            // "move" the axes to their right places

            // primary axes (bottom, left)
            pXAxis1.PhysicalMin = new Point( cb.Left+leftIndent, cb.Bottom-bottomIndent );
            pXAxis1.PhysicalMax = new Point( cb.Right-rightIndent, cb.Bottom-bottomIndent );
            pYAxis1.PhysicalMin = new Point( cb.Left+leftIndent, cb.Bottom-bottomIndent );
            pYAxis1.PhysicalMax = new Point( cb.Left+leftIndent, cb.Top+topIndent );

            // secondary axes (top, right)
            pXAxis2.PhysicalMin = new Point( cb.Left+leftIndent, cb.Top+topIndent );
            pXAxis2.PhysicalMax = new Point( cb.Right-rightIndent, cb.Top+topIndent );
            pYAxis2.PhysicalMin = new Point( cb.Right-rightIndent, cb.Bottom-bottomIndent );
            pYAxis2.PhysicalMax = new Point( cb.Right-rightIndent, cb.Top+topIndent );
        }
示例#28
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);
                    }
                }
            }
        }
示例#29
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));
        }
示例#30
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);
                }
            }
        }
示例#31
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;
        }
示例#32
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);
                }
            }
        }
示例#33
0
文件: LinePlot.cs 项目: parnham/NPlot
        /// <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 ();
        }
示例#34
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;
            }
        }
 /// <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);
     }
 }
示例#36
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 ();
        }
示例#37
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);
				}
			}
		}
示例#38
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);
            }
        }
示例#39
0
 /// <summary>
 /// Applies the constraint to the axes. Must be overriden.
 /// </summary>
 /// <param name="pXAxis1">The bottom x-axis.</param>
 /// <param name="pYAxis1">The left y-axis.</param>
 /// <param name="pXAxis2">The top x-axis.</param>
 /// <param name="pYAxis2">The right y-axis.</param>
 public abstract void ApplyConstraint(
     PhysicalAxis pXAxis1, PhysicalAxis pYAxis1,
     PhysicalAxis pXAxis2, PhysicalAxis pYAxis2);
示例#40
0
文件: Legend.cs 项目: oamist/NPlot
        /// <summary>
        /// Updates the PlotSurface2D axes to compensate for the legend.
        /// </summary>
        /// <param name="pXAxis1">the bottom x axis</param>
        /// <param name="pYAxis1">the left y axis</param>
        /// <param name="pXAxis2">the top x axis</param>
        /// <param name="pYAxis2">the right y axis</param>
        /// <param name="plots">list of plots.</param>
        /// <param name="scale">scale parameter (for text and other)</param>
        /// <param name="padding">padding around plot within bounds.</param>
        /// <param name="bounds">graphics surface bounds</param>
        /// <param name="position">legend position</param>
        public void UpdateAxesPositions(
            PhysicalAxis pXAxis1,
            PhysicalAxis pYAxis1,
            PhysicalAxis pXAxis2,
            PhysicalAxis pYAxis2,
            ArrayList plots,
            float scale, int padding, Rectangle bounds,
            out Point position)
        {
            int leftIndent   = 0;
            int rightIndent  = 0;
            int bottomIndent = 0;
            int topIndent    = 0;

            position = new Point(0, 0);

            // now determine if legend should change any of these (legend should be fully
            // visible at all times), and draw legend.

            Rectangle legendWidthHeight = GetBoundingBox(new Point(0, 0), plots, scale);

            if (legendWidthHeight.Width > bounds.Width)
            {
                legendWidthHeight.Width = bounds.Width;
            }

            // (1) calculate legend position.

            // y

            position.Y = yOffset_;

            if (xAttach_ == PlotSurface2D.XAxisPosition.Bottom)
            {
                position.Y += pYAxis1.PhysicalMin.Y;
                if (horizontalEdgePlacement_ == Placement.Inside)
                {
                    position.Y -= legendWidthHeight.Height;
                }
            }
            else
            {
                position.Y += pYAxis1.PhysicalMax.Y;
                if (horizontalEdgePlacement_ == Placement.Outside)
                {
                    position.Y -= legendWidthHeight.Height;
                }
            }

            // x

            position.X = xOffset_;

            if (yAttach_ == PlotSurface2D.YAxisPosition.Left)
            {
                if (verticalEdgePlacement_ == Placement.Outside)
                {
                    position.X -= legendWidthHeight.Width;
                }
                position.X += pXAxis1.PhysicalMin.X;
            }
            else
            {
                if (verticalEdgePlacement_ == Placement.Inside)
                {
                    position.X -= legendWidthHeight.Width;
                }
                position.X += pXAxis1.PhysicalMax.X;
            }

            // determine update amounts for axes

            if (!neverShiftAxes_)
            {
                if (position.X < padding)
                {
                    int changeAmount = -position.X + padding;
                    // only allow axes to move away from bounds.
                    if (changeAmount > 0)
                    {
                        leftIndent = changeAmount;
                    }
                    position.X += changeAmount;
                }

                if (position.X + legendWidthHeight.Width > bounds.Right - padding)
                {
                    int changeAmount = (position.X - bounds.Right + legendWidthHeight.Width + padding);
                    // only allow axes to move away from bounds.
                    if (changeAmount > 0.0f)
                    {
                        rightIndent = changeAmount;
                    }
                    position.X -= changeAmount;
                }

                if (position.Y < padding)
                {
                    int changeAmount = -position.Y + padding;
                    // only allow axes to move away from bounds.
                    if (changeAmount > 0.0f)
                    {
                        topIndent = changeAmount;
                    }
                    position.Y += changeAmount;
                }

                if (position.Y + legendWidthHeight.Height > bounds.Bottom - padding)
                {
                    int changeAmount = (position.Y - bounds.Bottom + legendWidthHeight.Height + padding);
                    // only allow axes to move away from bounds.
                    if (changeAmount > 0.0f)
                    {
                        bottomIndent = changeAmount;
                    }
                    position.Y -= changeAmount;
                }

                // update axes.

                pXAxis1.PhysicalMin = new Point(pXAxis1.PhysicalMin.X + leftIndent, pXAxis1.PhysicalMin.Y - bottomIndent);
                pXAxis1.PhysicalMax = new Point(pXAxis1.PhysicalMax.X - rightIndent, pXAxis1.PhysicalMax.Y - bottomIndent);
                pYAxis1.PhysicalMin = new Point(pYAxis1.PhysicalMin.X + leftIndent, pYAxis1.PhysicalMin.Y - bottomIndent);
                pYAxis1.PhysicalMax = new Point(pYAxis1.PhysicalMax.X + leftIndent, pYAxis1.PhysicalMax.Y + topIndent);

                pXAxis2.PhysicalMin = new Point(pXAxis2.PhysicalMin.X + leftIndent, pXAxis2.PhysicalMin.Y + topIndent);
                pXAxis2.PhysicalMax = new Point(pXAxis2.PhysicalMax.X - rightIndent, pXAxis2.PhysicalMax.Y + topIndent);
                pYAxis2.PhysicalMin = new Point(pYAxis2.PhysicalMin.X - rightIndent, pYAxis2.PhysicalMin.Y - bottomIndent);
                pYAxis2.PhysicalMax = new Point(pYAxis2.PhysicalMax.X - rightIndent, pYAxis2.PhysicalMax.Y + topIndent);
            }
        }
示例#41
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.
        }
        /// <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 );

            }
        }
                /// <summary>
                /// 
                /// </summary>
                /// <param name="e"></param>
                /// <param name="ctr"></param>
                public override bool DoMouseDown(MouseEventArgs e, Control ctr)
                {
                    // if the mouse is inside the plot area [the tick marks are here and part of the
                    // axis], then don't invoke drag.
                    NPlot.PlotSurface2D ps = ((Windows.PlotSurface2D)ctr).Inner;
                    if (e.X > ps.PlotAreaBoundingBoxCache.Left && e.X < ps.PlotAreaBoundingBoxCache.Right &&
                        e.Y > ps.PlotAreaBoundingBoxCache.Top && e.Y < ps.PlotAreaBoundingBoxCache.Bottom)
                    {
                        return false;
                    }

                    if ((e.Button == MouseButtons.Left))
                    {
                        // see if hit with axis.
                        ArrayList objects = ps.HitTest(new Point(e.X, e.Y));

                        foreach (object o in objects)
                        {
                            if (o is NPlot.Axis)
                            {
                                doing_ = true;
                                axis_ = (Axis)o;

                                PhysicalAxis[] physicalAxisList = new PhysicalAxis[] { ps.PhysicalXAxis1Cache, ps.PhysicalXAxis2Cache, ps.PhysicalYAxis1Cache, ps.PhysicalYAxis2Cache };

                                if (ps.PhysicalXAxis1Cache.Axis == axis_)
                                    physicalAxis_ = ps.PhysicalXAxis1Cache;
                                else if (ps.PhysicalXAxis2Cache.Axis == axis_)
                                    physicalAxis_ = ps.PhysicalXAxis2Cache;
                                else if (ps.PhysicalYAxis1Cache.Axis == axis_)
                                    physicalAxis_ = ps.PhysicalYAxis1Cache;
                                else if (ps.PhysicalYAxis2Cache.Axis == axis_)
                                    physicalAxis_ = ps.PhysicalYAxis2Cache;

                                lastPoint_ = startPoint_ = new Point(e.X, e.Y);

                                return false;
                            }
                        }

                    }

                    return false;
                }
示例#44
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);
                        }
                    }
                }
            }
        }
示例#45
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 )
        {
            if (this.shadow_)
            {
                this.DrawLineOrShadow( g, xAxis, yAxis, true );
            }

            this.DrawLineOrShadow( g, xAxis, yAxis, false );
        }
示例#46
0
文件: AxisDrag.cs 项目: sanyu1/NPlot
 /// <summary>
 /// MouseUp method for AxisDrag interaction
 /// </summary>
 /// <param name="X">mouse X position</param>
 /// <param name="Y"> mouse Y position</param>
 /// <param name="keys"> mouse and keyboard modifiers</param>
 /// <param name="ps">the InteractivePlotSurface2D</param>
 public override bool DoMouseUp( int X, int Y, Modifier keys, InteractivePlotSurface2D ps )
 {
     if (dragging_) {
         dragging_ = false;
         axis_ = null;
         physicalAxis_ = null;
         lastPoint_ = new Point();
         ps.plotCursor = CursorType.LeftPointer;
     }
     return false;
 }
示例#47
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 )
        {
            SequenceAdapter dataTop =
                new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataTop, this.AbscissaData );

            SequenceAdapter dataBottom =
                new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateDataBottom, this.AbscissaData );

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

            for (int i=0; i<dataTop.Count; ++i)
            {
                PointF physicalBottom = t.Transform( dataBottom[i] );
                PointF physicalTop = t.Transform( dataTop[i] );

                if (physicalBottom != physicalTop)
                {
                    Rectangle r = new Rectangle( (int)(physicalBottom.X - BarWidth/2), (int)physicalTop.Y,
                        (int)BarWidth, (int)(physicalBottom.Y - physicalTop.Y) );

                    g.FillRectangle( this.rectangleBrush_.Get(r), r );
                    g.DrawRectangle( borderPen_, r );
                }
            }
        }
示例#48
0
        /// <summary>
        /// Draw the the PlotSurface2D and all contents [axes, drawables] on the
        /// supplied graphics surface.
        /// </summary>
        /// <param name="g">The graphics surface on which to draw.</param>
        /// <param name="bounds">A bounding box on this surface that denotes the area on the
        /// surface to confine drawing to.</param>
        public void Draw(Graphics g, Rectangle bounds)
        {
            // determine font sizes and tick scale factor.
            float scale = DetermineScaleFactor(bounds.Width, bounds.Height);

            // if there is nothing to plot, return.
            if (m_drawables.Count == 0)
            {
                // draw title
                float x_center = (bounds.Left + bounds.Right) / 2.0f;
                float y_center = (bounds.Top + bounds.Bottom) / 2.0f;
                Font  scaled_font;
                if (AutoScaleTitle)
                {
                    scaled_font = Utils.ScaleFont(m_titleFont, scale);
                }
                else
                {
                    scaled_font = m_titleFont;
                }
                g.DrawString(m_title, scaled_font, this.m_titleBrush, new PointF(x_center, y_center), m_titleDrawFormat);

                return;
            }

            Stopwatch sw = StepTimer.Start("Determine Axis");

            // determine the [non physical] axes to draw based on the axis properties set.
            Axis xAxis1, xAxis2, yAxis1, yAxis2;

            DetermineAxesToDraw(out xAxis1, out xAxis2, out yAxis1, out yAxis2);

            // apply scale factor to axes as desired.
            if (xAxis1.AutoScaleTicks)
            {
                xAxis1.TickScale = scale;
            }
            if (xAxis1.AutoScaleText)
            {
                xAxis1.FontScale = scale;
            }
            if (yAxis1.AutoScaleTicks)
            {
                yAxis1.TickScale = scale;
            }
            if (yAxis1.AutoScaleText)
            {
                yAxis1.FontScale = scale;
            }
            if (xAxis2.AutoScaleTicks)
            {
                xAxis2.TickScale = scale;
            }
            if (xAxis2.AutoScaleText)
            {
                xAxis2.FontScale = scale;
            }
            if (yAxis2.AutoScaleTicks)
            {
                yAxis2.TickScale = scale;
            }
            if (yAxis2.AutoScaleText)
            {
                yAxis2.FontScale = scale;
            }

            // determine the default physical positioning of those axes.
            PhysicalAxis pXAxis1, pYAxis1, pXAxis2, pYAxis2;

            DeterminePhysicalAxesToDraw(bounds, xAxis1, xAxis2, yAxis1, yAxis2, out pXAxis1, out pXAxis2, out pYAxis1, out pYAxis2);

            StepTimer.Stop(sw);

            float oldXAxis2Height = pXAxis2.PhysicalMin.Y;

            // Apply axes constraints
            for (int i = 0; i < m_axesConstraints.Count; ++i)
            {
                (m_axesConstraints[i]).ApplyConstraint(pXAxis1, pYAxis1, pXAxis2, pYAxis2);
            }

            float newXAxis2Height = pXAxis2.PhysicalMin.Y;

            float titleExtraOffset = oldXAxis2Height - newXAxis2Height;

            sw = StepTimer.Start("Draw Axis");

            // now we are ready to define the bounding box for the plot area (to use in clipping
            // operations.
            m_plotAreaBoundingBoxCache = new Rectangle(
                Math.Min(pXAxis1.PhysicalMin.X, pXAxis1.PhysicalMax.X),
                Math.Min(pYAxis1.PhysicalMax.Y, pYAxis1.PhysicalMin.Y),
                Math.Abs(pXAxis1.PhysicalMax.X - pXAxis1.PhysicalMin.X + 1),
                Math.Abs(pYAxis1.PhysicalMin.Y - pYAxis1.PhysicalMax.Y + 1)
                );
            m_bbXAxis1Cache = pXAxis1.GetBoundingBox();
            m_bbXAxis2Cache = pXAxis2.GetBoundingBox();
            m_bbYAxis1Cache = pYAxis1.GetBoundingBox();
            m_bbYAxis2Cache = pYAxis2.GetBoundingBox();

            // Fill in the background.
            g.FillRectangle(new SolidBrush(m_plotBackColor), m_plotAreaBoundingBoxCache);

            // draw title
            float xt = (pXAxis2.PhysicalMax.X + pXAxis2.PhysicalMin.X) / 2.0f;
            float yt = bounds.Top + m_padding - titleExtraOffset;
            Font  scaledFont;

            if (AutoScaleTitle)
            {
                scaledFont = Utils.ScaleFont(m_titleFont, scale);
            }
            else
            {
                scaledFont = m_titleFont;
            }
            g.DrawString(m_title, scaledFont, m_titleBrush, new PointF(xt, yt), m_titleDrawFormat);

            //count number of new lines in title.
            int nlCount = 0;

            for (int i = 0; i < m_title.Length; ++i)
            {
                if (m_title[i] == '\n')
                {
                    nlCount += 1;
                }
            }

            SizeF s = g.MeasureString(m_title, scaledFont);

            m_bbTitleCache = new Rectangle((int)(xt - s.Width / 2), (int)(yt), (int)(s.Width), (int)(s.Height) * (nlCount + 1));

            StepTimer.Stop(sw);

            //sw = StepTimer.Start("Draw IDrawables");

            // draw drawables..
            SmoothingMode smoothSave = g.SmoothingMode;

            g.SmoothingMode = m_smoothingMode;

            for (int i_o = 0; i_o < m_ordering.Count; ++i_o)
            {
                int i = m_ordering.Values[i_o];

                IDrawable drawable = m_drawables[i];

                PhysicalAxis drawXAxis;
                PhysicalAxis drawYAxis;

                drawXAxis = pXAxis1;
                drawYAxis = pYAxis1;

                // set the clipping region.. (necessary for zoom)
                g.Clip = new Region(m_plotAreaBoundingBoxCache);
                // plot.
                drawable.Draw(g, drawXAxis, drawYAxis);
                // reset it..
                g.ResetClip();
            }

            //StepTimer.Stop(sw);

            // cache the physical axes we used on this draw;
            m_pXAxis1Cache = pXAxis1;
            m_pYAxis1Cache = pYAxis1;
            m_pXAxis2Cache = pXAxis2;
            m_pYAxis2Cache = pYAxis2;

            g.SmoothingMode = smoothSave;

            sw = StepTimer.Start("Draw Axis Final");
            // now draw axes.
            Rectangle axisBounds;

            pXAxis1.Draw(g, out axisBounds);
            pXAxis2.Draw(g, out axisBounds);
            pYAxis1.Draw(g, out axisBounds);
            pYAxis2.Draw(g, out axisBounds);

            StepTimer.Stop(sw);
        }