Represtents a point in two-dimensional space. Used for representation of points world coordinates.
예제 #1
0
파일: StepPlot.cs 프로젝트: nigelis/NPlotB
        /// <summary>
        /// Draws the step plot on a GDI+ surface against the provided x and y axes.
        /// </summary>
        /// <param name="g">The GDI+ surface on which to draw.</param>
        /// <param name="xAxis">The X-Axis to draw against.</param>
        /// <param name="yAxis">The Y-Axis to draw against.</param>
        public virtual void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis)
        {
            SequenceAdapter data =
                new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData);

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

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

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

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

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

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

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

                if (!this.hideHorizontalSegments_)
                {
                    if (scale_ != 1.0f)
                    {
                        float middle = (xPos2.X + xPos1.X) / 2.0f;
                        float width  = xPos2.X - xPos1.X;
                        width *= this.scale_;
                        g.DrawLine(Pen, (int)(middle - width / 2.0f), yPos1.Y, (int)(middle + width / 2.0f), yPos2.Y);
                    }
                    else
                    {
                        g.DrawLine(Pen, xPos1.X, yPos1.Y, xPos2.X, yPos2.Y);
                    }
                }

                if (!this.hideVerticalSegments_)
                {
                    g.DrawLine(Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y);
                }
            }
        }
예제 #2
0
 /// <summary>
 /// Transforms the given world point to physical coordinates
 /// </summary>
 /// <param name="worldPoint">the world point to transform</param>
 /// <returns>the corresponding physical point</returns>
 public PointF Transform(PointD worldPoint)
 {
     return(new PointF(
                xAxis_.WorldToPhysical(worldPoint.X, false).X,
                yAxis_.WorldToPhysical(worldPoint.Y, false).Y));
 }
예제 #3
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="position">The position the arrow points to.</param>
 /// <param name="angle">angle of arrow with respect to x axis.</param>
 public ArrowItem(PointD position, double angle)
 {
     to_    = position;
     angle_ = -angle;
     Init();
 }
예제 #4
0
 /// <summary>
 /// Default constructor :
 /// text = ""
 /// angle = 45 degrees anticlockwise from horizontal.
 /// </summary>
 /// <param name="position">The position the arrow points to.</param>
 public ArrowItem(PointD position)
 {
     to_ = position;
     Init();
 }
예제 #5
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="position">The position the text starts.</param>
 /// <param name="text">The text.</param>
 public TextItem(PointD position, string text)
 {
     start_ = position;
     text_  = text;
     Init();
 }
예제 #6
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(DataSource, DataMember, OrdinateData, 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_;
                    }
                    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 (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);
            }
        }
예제 #7
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);
                    }
                }
            }
        }