public void Render(Axis axis)
        {
            if (axis == null)
                return;

            axis.GetTickValues(out majorTickValues, out minorTickValues);

            CreatePens(axis);

            if (axis.IsHorizontal())
            {
                RenderHorizontalAxis(axis, Plot.DefaultYAxis);
            }
            if (axis.IsVertical())
            {
                RenderVerticalAxis(axis, Plot.DefaultXAxis);
            }
            if (axis.Position == AxisPosition.Angle)
            {
                RenderAngleAxis(axis, Plot.DefaultMagnitudeAxis);
            }
            if (axis.Position == AxisPosition.Magnitude)
            {
                RenderMagnitudeAxis(axis, Plot.DefaultAngleAxis);
            }
        }
        /// <summary>
        /// The render.
        /// </summary>
        /// <param name="axis">
        /// The axis.
        /// </param>
        /// <param name="pass">
        /// The render pass.
        /// </param>
        public override void Render(Axis axis, int pass)
        {
            base.Render(axis, pass);

            double totalShift = axis.PositionTierMinShift;
            double tierSize = axis.PositionTierSize - this.Plot.AxisTierDistance;

            // store properties locally for performance
            double plotAreaLeft = this.Plot.PlotArea.Left;
            double plotAreaRight = this.Plot.PlotArea.Right;
            double plotAreaTop = this.Plot.PlotArea.Top;
            double plotAreaBottom = this.Plot.PlotArea.Bottom;

            // Axis position (x or y screen coordinate)
            double axisPosition = 0;
            double titlePosition = 0;

            switch (axis.Position)
            {
                case AxisPosition.Left:
                    axisPosition = plotAreaLeft - totalShift;
                    titlePosition = axisPosition - tierSize;
                    break;
                case AxisPosition.Right:
                    axisPosition = plotAreaRight + totalShift;
                    titlePosition = axisPosition + tierSize;
                    break;
                case AxisPosition.Top:
                    axisPosition = plotAreaTop - totalShift;
                    titlePosition = axisPosition - tierSize;
                    break;
                case AxisPosition.Bottom:
                    axisPosition = plotAreaBottom + totalShift;
                    titlePosition = axisPosition + tierSize;
                    break;
            }

            if (axis.PositionAtZeroCrossing)
            {
                var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis;
                axisPosition = perpendicularAxis.Transform(0);
            }

            if (pass == 0)
            {
                this.RenderMinorItems(axis, axisPosition);
            }

            if (pass == 1)
            {
                this.RenderMajorItems(axis, axisPosition, titlePosition);
            }
        }
 /// <summary>
 /// The get tick positions.
 /// </summary>
 /// <param name="axis">
 /// The axis.
 /// </param>
 /// <param name="glt">
 /// The glt.
 /// </param>
 /// <param name="ticksize">
 /// The ticksize.
 /// </param>
 /// <param name="position">
 /// The position.
 /// </param>
 /// <param name="x0">
 /// The x 0.
 /// </param>
 /// <param name="x1">
 /// The x 1.
 /// </param>
 protected void GetTickPositions(
     Axis axis, TickStyle glt, double ticksize, AxisPosition position, out double x0, out double x1)
 {
     x0 = 0;
     x1 = 0;
     bool isTopOrLeft = position == AxisPosition.Top || position == AxisPosition.Left;
     double sign = isTopOrLeft ? -1 : 1;
     switch (glt)
     {
         case TickStyle.Crossing:
             x0 = -ticksize * sign * 0.75;
             x1 = ticksize * sign * 0.75;
             break;
         case TickStyle.Inside:
             x0 = -ticksize * sign;
             break;
         case TickStyle.Outside:
             x1 = ticksize * sign;
             break;
     }
 }
        /// <summary>
        /// The render.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="pass">The render pass.</param>
        public virtual void Render(Axis axis, int pass)
        {
            if (axis == null)
            {
                return;
            }

            axis.GetTickValues(out this.MajorLabelValues, out this.MajorTickValues, out this.MinorTickValues);
            this.CreatePens(axis);
        }
 /// <summary>
 /// Checks if the specified value is valid.
 /// </summary>
 /// <param name="v">
 /// The value.
 /// </param>
 /// <param name="yaxis">
 /// The y axis.
 /// </param>
 /// <returns>
 /// True if the value is valid.
 /// </returns>
 public virtual bool IsValidPoint(double v, Axis yaxis)
 {
     return !double.IsNaN(v) && !double.IsInfinity(v);
 }
 /// <summary>
 /// Transforms the specified point to screen coordinates.
 /// </summary>
 /// <param name="p">
 /// The point.
 /// </param>
 /// <param name="xaxis">
 /// The x axis.
 /// </param>
 /// <param name="yaxis">
 /// The y axis.
 /// </param>
 /// <returns>
 /// The transformed point.
 /// </returns>
 public static ScreenPoint Transform(IDataPoint p, Axis xaxis, Axis yaxis)
 {
     return xaxis.Transform(p.X, p.Y, yaxis);
 }
        /// <summary>
        /// Transforms the specified point to screen coordinates.
        /// </summary>
        /// <param name="x">
        /// The x value (for the current axis).
        /// </param>
        /// <param name="y">
        /// The y value.
        /// </param>
        /// <param name="yaxis">
        /// The y axis.
        /// </param>
        /// <returns>
        /// The transformed point.
        /// </returns>
        public virtual ScreenPoint Transform(double x, double y, Axis yaxis)
        {
            if (yaxis == null)
            {
                throw new NullReferenceException("Y axis should not be null when transforming.");
            }

            return new ScreenPoint(this.Transform(x), yaxis.Transform(y));
        }
        /// <summary>
        /// Gets the axis for the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="defaultAxis">The default axis.</param>
        /// <returns>The axis, or the defaultAxis if the key is not found.</returns>
        public Axis GetAxisOrDefault(string key, Axis defaultAxis)
        {
            if (key != null)
            {
                return this.Axes.FirstOrDefault(a => a.Key == key) ?? defaultAxis;
            }

            return defaultAxis;
        }
        /// <summary>
        /// Renders the major items.
        /// </summary>
        /// <param name="axis">
        /// The axis.
        /// </param>
        /// <param name="axisPosition">
        /// The axis position.
        /// </param>
        /// <param name="titlePosition">
        /// The title position.
        /// </param>
        private void RenderMajorItems(Axis axis, double axisPosition, double titlePosition)
        {
            double eps = axis.ActualMinorStep * 1e-3;

            double actualMinimum = axis.ActualMinimum;
            double actualMaximum = axis.ActualMaximum;

            double plotAreaLeft = this.Plot.PlotArea.Left;
            double plotAreaRight = this.Plot.PlotArea.Right;
            double plotAreaTop = this.Plot.PlotArea.Top;
            double plotAreaBottom = this.Plot.PlotArea.Bottom;
            bool isHorizontal = axis.IsHorizontal();

            double a0;
            double a1;
            var majorSegments = new List<ScreenPoint>();
            var majorTickSegments = new List<ScreenPoint>();
            this.GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1);

            foreach (double value in this.MajorTickValues)
            {
                if (value < actualMinimum - eps || value > actualMaximum + eps)
                {
                    continue;
                }

                if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
                {
                    continue;
                }

                double transformedValue = axis.Transform(value);
                if (isHorizontal)
                {
                    SnapTo(plotAreaLeft, ref transformedValue);
                    SnapTo(plotAreaRight, ref transformedValue);
                }
                else
                {
                    SnapTo(plotAreaTop, ref transformedValue);
                    SnapTo(plotAreaBottom, ref transformedValue);
                }

                if (this.MajorPen != null)
                {
                    if (isHorizontal)
                    {
                        majorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop));
                        majorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom));
                    }
                    else
                    {
                        majorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue));
                        majorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue));
                    }
                }

                if (axis.TickStyle != TickStyle.None)
                {
                    if (isHorizontal)
                    {
                        majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0));
                        majorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1));
                    }
                    else
                    {
                        majorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue));
                        majorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue));
                    }
                }
            }

            // Render the axis labels (numbers or category names)
            foreach (double value in this.MajorLabelValues)
            {
                if (value < actualMinimum - eps || value > actualMaximum + eps)
                {
                    continue;
                }

                if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
                {
                    continue;
                }

                double transformedValue = axis.Transform(value);
                if (isHorizontal)
                {
                    SnapTo(plotAreaLeft, ref transformedValue);
                    SnapTo(plotAreaRight, ref transformedValue);
                }
                else
                {
                    SnapTo(plotAreaTop, ref transformedValue);
                    SnapTo(plotAreaBottom, ref transformedValue);
                }

                var pt = new ScreenPoint();
                var ha = HorizontalTextAlign.Right;
                var va = VerticalTextAlign.Middle;
                switch (axis.Position)
                {
                    case AxisPosition.Left:
                        pt = new ScreenPoint(axisPosition + a1 - axis.AxisTickToLabelDistance, transformedValue);
                        this.GetRotatedAlignments(
                            axis.Angle, HorizontalTextAlign.Right, VerticalTextAlign.Middle, out ha, out va);
                        break;
                    case AxisPosition.Right:
                        pt = new ScreenPoint(axisPosition + a1 + axis.AxisTickToLabelDistance, transformedValue);
                        this.GetRotatedAlignments(
                            axis.Angle, HorizontalTextAlign.Left, VerticalTextAlign.Middle, out ha, out va);
                        break;
                    case AxisPosition.Top:
                        pt = new ScreenPoint(transformedValue, axisPosition + a1 - axis.AxisTickToLabelDistance);
                        this.GetRotatedAlignments(
                            axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Bottom, out ha, out va);
                        break;
                    case AxisPosition.Bottom:
                        pt = new ScreenPoint(transformedValue, axisPosition + a1 + axis.AxisTickToLabelDistance);
                        this.GetRotatedAlignments(
                            axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Top, out ha, out va);
                        break;
                }

                string text = axis.FormatValue(value);
                this.rc.DrawMathText(
                    pt, 
                    text, 
                    axis.ActualTextColor, 
                    axis.ActualFont, 
                    axis.ActualFontSize, 
                    axis.ActualFontWeight, 
                    axis.Angle, 
                    ha, 
                    va);
            }

            // Draw the zero crossing line
            if (axis.PositionAtZeroCrossing && this.ZeroPen != null)
            {
                double t0 = axis.Transform(0);
                if (isHorizontal)
                {
                    this.rc.DrawLine(t0, plotAreaTop, t0, plotAreaBottom, this.ZeroPen);
                }
                else
                {
                    this.rc.DrawLine(plotAreaLeft, t0, plotAreaRight, t0, this.ZeroPen);
                }
            }

            // Draw extra grid lines
            if (axis.ExtraGridlines != null && this.ExtraPen != null)
            {
                foreach (double value in axis.ExtraGridlines)
                {
                    if (!this.IsWithin(value, actualMinimum, actualMaximum))
                    {
                        continue;
                    }

                    double transformedValue = axis.Transform(value);
                    if (isHorizontal)
                    {
                        this.rc.DrawLine(transformedValue, plotAreaTop, transformedValue, plotAreaBottom, this.ExtraPen);
                    }
                    else
                    {
                        this.rc.DrawLine(plotAreaLeft, transformedValue, plotAreaRight, transformedValue, this.ExtraPen);
                    }
                }
            }

            // Draw the axis line (across the tick marks)
            if (isHorizontal)
            {
                this.rc.DrawLine(
                    axis.Transform(actualMinimum), 
                    axisPosition, 
                    axis.Transform(actualMaximum), 
                    axisPosition, 
                    this.AxislinePen);
            }
            else
            {
                this.rc.DrawLine(
                    axisPosition, 
                    axis.Transform(actualMinimum), 
                    axisPosition, 
                    axis.Transform(actualMaximum), 
                    this.AxislinePen);
            }

            // Draw the axis title
            if (!string.IsNullOrEmpty(axis.ActualTitle))
            {
                this.RenderAxisTitle(axis, titlePosition);
            }

            if (this.MajorPen != null)
            {
                this.rc.DrawLineSegments(majorSegments, this.MajorPen);
            }

            if (this.MajorTickPen != null)
            {
                this.rc.DrawLineSegments(majorTickSegments, this.MajorTickPen);
            }
        }
        /// <summary>
        /// Renders the axis title.
        /// </summary>
        /// <param name="axis">
        /// The axis.
        /// </param>
        /// <param name="titlePosition">
        /// The title position.
        /// </param>
        private void RenderAxisTitle(Axis axis, double titlePosition)
        {
            bool isHorizontal = axis.IsHorizontal();

            OxySize? maxSize = null;

            if (axis.ClipTitle)
            {
                // Calculate the title clipping dimensions
                double screenLength = isHorizontal
                                          ? Math.Abs(axis.ScreenMax.X - axis.ScreenMin.X)
                                          : Math.Abs(axis.ScreenMax.Y - axis.ScreenMin.Y);

                maxSize = new OxySize(screenLength * axis.TitleClippingLength, double.MaxValue);
            }

            double angle = -90;

            var halign = HorizontalTextAlign.Center;
            var valign = VerticalTextAlign.Top;

            var lpt = this.GetAxisTitlePositionAndAlignment(axis, titlePosition, ref angle, ref halign, ref valign);

            this.rc.SetToolTip(axis.ToolTip);
            this.rc.DrawText(
                lpt, 
                axis.ActualTitle, 
                axis.ActualTitleColor, 
                axis.ActualTitleFont, 
                axis.ActualTitleFontSize, 
                axis.ActualTitleFontWeight, 
                angle, 
                halign, 
                valign, 
                maxSize);
            this.rc.SetToolTip(null);
        }
        /// <summary>
        /// Gets the axis title position, rotation and alignment.
        /// </summary>
        /// <param name="axis">
        /// The axis.
        /// </param>
        /// <param name="titlePosition">
        /// The title position.
        /// </param>
        /// <param name="angle">
        /// The angle.
        /// </param>
        /// <param name="halign">
        /// The horizontal alignment.
        /// </param>
        /// <param name="valign">
        /// The vertical alignment.
        /// </param>
        /// <returns>
        /// The <see cref="ScreenPoint"/>.
        /// </returns>
        protected virtual ScreenPoint GetAxisTitlePositionAndAlignment(
            Axis axis, 
            double titlePosition, 
            ref double angle, 
            ref HorizontalTextAlign halign, 
            ref VerticalTextAlign valign)
        {
            double middle = axis.IsHorizontal()
                                ? Lerp(axis.ScreenMin.X, axis.ScreenMax.X, axis.TitlePosition)
                                : Lerp(axis.ScreenMax.Y, axis.ScreenMin.Y, axis.TitlePosition);

            if (axis.PositionAtZeroCrossing)
            {
                var perpendicularAxis = axis.IsHorizontal() ? this.Plot.DefaultYAxis : this.Plot.DefaultXAxis;
                middle = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);
            }

            switch (axis.Position)
            {
                case AxisPosition.Left:
                    return new ScreenPoint(titlePosition, middle);
                case AxisPosition.Right:
                    valign = VerticalTextAlign.Bottom;
                    return new ScreenPoint(titlePosition, middle);
                case AxisPosition.Top:
                    halign = HorizontalTextAlign.Center;
                    valign = VerticalTextAlign.Top;
                    angle = 0;
                    return new ScreenPoint(middle, titlePosition);
                case AxisPosition.Bottom:
                    halign = HorizontalTextAlign.Center;
                    valign = VerticalTextAlign.Bottom;
                    angle = 0;
                    return new ScreenPoint(middle, titlePosition);
                default:
                    throw new ArgumentOutOfRangeException("axis");
            }
        }
 /// <summary>
 /// Determines whether the specified point is valid.
 /// </summary>
 /// <param name="pt">
 /// The pointt.
 /// </param>
 /// <param name="xaxis">
 /// The x axis.
 /// </param>
 /// <param name="yaxis">
 /// The y axis.
 /// </param>
 /// <returns>
 /// <c>true</c> if the point is valid; otherwise, <c>false</c> .
 /// </returns>
 protected virtual bool IsValidPoint(IDataPoint pt, Axis xaxis, Axis yaxis)
 {
     return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.Y) && !double.IsInfinity(pt.Y)
            && (xaxis != null && xaxis.IsValidValue(pt.X)) && (yaxis != null && yaxis.IsValidValue(pt.Y));
 }
 /// <summary>
 /// Check if the data series is using the specified axis.
 /// </summary>
 /// <param name="axis">
 /// An axis.
 /// </param>
 /// <returns>
 /// True if the axis is in use.
 /// </returns>
 protected internal override bool IsUsing(Axis axis)
 {
     return false;
 }
        public override void Render(Axis axis)
        {
            base.Render(axis);

            var perpendicularAxis = Plot.DefaultXAxis;
            bool isHorizontal = true;

            // Axis position (x or y screen coordinate)
            double apos = 0;

            switch (axis.Position)
            {
                case AxisPosition.Left:
                    apos = Plot.PlotArea.Left;
                    isHorizontal = false;
                    break;
                case AxisPosition.Right:
                    apos = Plot.PlotArea.Right;
                    isHorizontal = false;
                    break;
                case AxisPosition.Top:
                    apos = Plot.PlotArea.Top;
                    perpendicularAxis = Plot.DefaultYAxis;
                    break;
                case AxisPosition.Bottom:
                    apos = Plot.PlotArea.Bottom;
                    perpendicularAxis = Plot.DefaultYAxis;
                    break;
            }

            if (axis.PositionAtZeroCrossing)
            {
                apos = perpendicularAxis.Transform(0);
            }

            double a0, a1;

            if (axis.ShowMinorTicks)
            {
                GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1);

                foreach (double value in MinorTickValues)
                {
                    if (value < axis.ActualMinimum || value > axis.ActualMaximum)
                    {
                        continue;
                    }

                    if (MajorTickValues.Contains(value))
                    {
                        continue;
                    }

                    double transformedValue = axis.Transform(value);

                    if (MinorPen != null)
                    {
                        if (isHorizontal)
                        {
                            rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MinorPen);

                        }
                        else
                        {
                            rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MinorPen);
                        }
                    }
                    if (isHorizontal)
                    {
                        rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MinorTickPen);

                    }
                    else
                    {
                        rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MinorTickPen);
                    }
                }
            }

            GetTickPositions(axis, axis.TickStyle, axis.MajorTickSize, axis.Position, out a0, out a1);

            double maxWidth = 0;
            double maxHeight = 0;

            foreach (double value in MajorTickValues)
            {
                if (value < axis.ActualMinimum || value > axis.ActualMaximum)
                    continue;

                double transformedValue = axis.Transform(value);

                if (MajorPen != null)
                {
                    if (isHorizontal)
                    {
                        rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, MajorPen);

                    }
                    else
                    {
                        rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, MajorPen);
                    }
                }

                if (isHorizontal)
                {
                    rc.DrawLine(transformedValue, apos + a0, transformedValue, apos + a1, MajorTickPen);

                }
                else
                {
                    rc.DrawLine(apos + a0, transformedValue, apos + a1, transformedValue, MajorTickPen);
                }

                if (value == 0 && axis.PositionAtZeroCrossing)
                    continue;

                var pt = new ScreenPoint();
                var ha = HorizontalTextAlign.Right;
                var va = VerticalTextAlign.Middle;
                switch (axis.Position)
                {
                    case AxisPosition.Left:
                        pt = new ScreenPoint(apos + a1 - TICK_DIST, transformedValue);
                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Right, VerticalTextAlign.Middle, out ha, out va);
                        break;
                    case AxisPosition.Right:
                        pt = new ScreenPoint(apos + a1 + TICK_DIST, transformedValue);
                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Left, VerticalTextAlign.Middle, out ha, out va);
                        break;
                    case AxisPosition.Top:
                        pt = new ScreenPoint(transformedValue, apos + a1 - TICK_DIST);
                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Bottom, out ha, out va);
                        break;
                    case AxisPosition.Bottom:
                        pt = new ScreenPoint(transformedValue, apos + a1 + TICK_DIST);
                        GetRotatedAlignments(axis.Angle, HorizontalTextAlign.Center, VerticalTextAlign.Top, out ha, out va);
                        break;

                }

                string text = axis.FormatValue(value);
                var size = rc.DrawMathText(pt, text, Plot.TextColor,
                             axis.FontFamily, axis.FontSize, axis.FontWeight,
                             axis.Angle, ha, va);

                maxWidth = Math.Max(maxWidth, size.Width);
                maxHeight = Math.Max(maxHeight, size.Height);
            }

            if (axis.PositionAtZeroCrossing)
            {
                double t0 = axis.Transform(0);
                if (isHorizontal)
                {
                    rc.DrawLine(t0, Plot.PlotArea.Top, t0, Plot.PlotArea.Bottom, ZeroPen);

                }
                else
                {
                    rc.DrawLine(Plot.PlotArea.Left, t0, Plot.PlotArea.Right, t0, ZeroPen);
                }
            }

            if (axis.ExtraGridlines != null)
            {
                foreach (double value in axis.ExtraGridlines)
                {
                    if (!IsWithin(value, axis.ActualMinimum, axis.ActualMaximum))
                        continue;

                    double transformedValue = axis.Transform(value);
                    if (isHorizontal)
                    {
                        rc.DrawLine(transformedValue, Plot.PlotArea.Top, transformedValue, Plot.PlotArea.Bottom, ExtraPen);

                    }
                    else
                    {
                        rc.DrawLine(Plot.PlotArea.Left, transformedValue, Plot.PlotArea.Right, transformedValue, ExtraPen);
                    }
                }
            }
            if (isHorizontal)
            {
                rc.DrawLine(Plot.PlotArea.Left, apos, Plot.PlotArea.Right, apos, MajorPen);

            }
            else
            {
                rc.DrawLine(apos, Plot.PlotArea.Top, apos, Plot.PlotArea.Bottom, MajorPen);
            }

            if (!String.IsNullOrWhiteSpace(axis.Title))
            {
                // Axis legend
                double ymid = axis.Transform((axis.ActualMinimum + axis.ActualMaximum) / 2);
                double angle = -90;
                var lpt = new ScreenPoint();

                var halign = HorizontalTextAlign.Center;
                var valign = VerticalTextAlign.Top;

                if (axis.PositionAtZeroCrossing)
                {
                    ymid = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);
                    // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom;
                }

                switch (axis.Position)
                {
                    case AxisPosition.Left:
                        lpt = new ScreenPoint(AXIS_LEGEND_DIST, ymid);
                        break;
                    case AxisPosition.Right:
                        lpt = new ScreenPoint(rc.Width - AXIS_LEGEND_DIST, ymid);
                        valign = VerticalTextAlign.Bottom;
                        break;
                    case AxisPosition.Top:
                        lpt = new ScreenPoint(ymid, AXIS_LEGEND_DIST);
                        halign = HorizontalTextAlign.Center;
                        valign = VerticalTextAlign.Top;
                        angle = 0;
                        break;
                    case AxisPosition.Bottom:
                        lpt = new ScreenPoint(ymid, rc.Height - AXIS_LEGEND_DIST);
                        halign = HorizontalTextAlign.Center;
                        valign = VerticalTextAlign.Bottom;
                        angle = 0;
                        break;
                }

                rc.DrawText(lpt, axis.Title, Plot.TextColor,
                            axis.FontFamily, axis.FontSize, axis.FontWeight,
                            angle, halign, valign);
            }
        }
        public virtual Point InverseTransform(double x, double y, Axis yAxis)
        {
            Debug.Assert(yAxis != null);
            if (IsPolar)
            {
                x -= MidPoint.X;
                y -= MidPoint.Y;
                double th = Math.Atan2(y, x);
                double r = Math.Sqrt(x * x + y * y);
                x = r / Scale + Offset;
                y = yAxis != null ? th / yAxis.Scale + yAxis.Offset : double.NaN;
                return new Point(x, y);
            }

            return new Point(InverseTransformX(x), yAxis.InverseTransformX(y));
        }
        private void RenderVerticalAxis(Axis axis, Axis perpendicularAxis)
        {
            double x = Plot.Bounds.Left;
            switch (axis.Position)
            {
                case AxisPosition.Left:
                    x = Plot.Bounds.Left;
                    break;
                case AxisPosition.Right:
                    x = Plot.Bounds.Right;
                    break;
            }
            if (axis.PositionAtZeroCrossing)
                x = perpendicularAxis.TransformX(0);

            double x0, x1;

            if (axis.ShowMinorTicks)
            {
                GetHorizontalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out x0, out x1);
                foreach (double yValue in minorTickValues)
                {
                    if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum)
                    {
                        continue;
                    }

                    if (majorTickValues.Contains(yValue))
                    {
                        continue;
                    }
                    double y = axis.TransformX(yValue);

                    if (minorPen != null)
                    {
                        RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, minorPen);
                    }

                    RenderLine(x + x0, y, x + x1, y, minorTickPen);
                }
            }

            GetHorizontalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out x0, out x1);
            double maxw = 0;

            bool isleft = axis.Position == AxisPosition.Left;

            foreach (double yValue in majorTickValues)
            {
                if (yValue < axis.ActualMinimum || yValue > axis.ActualMaximum)
                    continue;

                double y = axis.TransformX(yValue);

                if (majorPen != null)
                {
                    RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen);
                }

                RenderLine(x + x0, y, x + x1, y, majorTickPen);

                if (yValue == 0 && axis.PositionAtZeroCrossing)
                    continue;

                var pt = new ScreenPoint(isleft ? x + x1 - TICK_DIST : x + x1 + TICK_DIST, y);
                string text = axis.FormatValue(yValue);
                double w = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;
                rc.DrawText(pt, text, Plot.TextColor,
                            axis.FontFamily, axis.FontSize, axis.FontWeight,
                            axis.Angle,
                            isleft ? HorizontalTextAlign.Right : HorizontalTextAlign.Left, VerticalTextAlign.Middle);
                maxw = Math.Max(maxw, w);
            }

            if (axis.PositionAtZeroCrossing)
            {
                double y = axis.TransformX(0);
                RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, zeroPen);
            }

            if (axis.ExtraGridlines != null)
                foreach (double y in axis.ExtraGridlines)
                {
                    if (!IsWithin(y, axis.ActualMinimum, axis.ActualMaximum))
                        continue;
                    double sy = axis.TransformX(y);
                    RenderLine(Plot.Bounds.Left, sy, Plot.Bounds.Right, sy, extraPen);
                }

            RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen);

            double ymid = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2);

            HorizontalTextAlign halign = HorizontalTextAlign.Center;
            VerticalTextAlign valign = VerticalTextAlign.Top;

            if (axis.PositionAtZeroCrossing)
            {
                ymid = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum);
                // valign = axis.IsReversed ? VerticalTextAlign.Top : VerticalTextAlign.Bottom;
            }

            if (isleft)
            {
                x = AXIS_LEGEND_DIST;
            }
            else
            {
                x = rc.Width - AXIS_LEGEND_DIST;
                valign = VerticalTextAlign.Bottom;
            }

            rc.DrawText(new ScreenPoint(x, ymid), axis.Title, Plot.TextColor,
                        axis.FontFamily, axis.FontSize, axis.FontWeight,
                        -90, halign, valign);
        }
        /// <summary>
        /// Renders the minor items.
        /// </summary>
        /// <param name="axis">
        /// The axis.
        /// </param>
        /// <param name="axisPosition">
        /// The axis position.
        /// </param>
        private void RenderMinorItems(Axis axis, double axisPosition)
        {
            double eps = axis.ActualMinorStep * 1e-3;
            double actualMinimum = axis.ActualMinimum;
            double actualMaximum = axis.ActualMaximum;

            double plotAreaLeft = this.Plot.PlotArea.Left;
            double plotAreaRight = this.Plot.PlotArea.Right;
            double plotAreaTop = this.Plot.PlotArea.Top;
            double plotAreaBottom = this.Plot.PlotArea.Bottom;
            bool isHorizontal = axis.IsHorizontal();

            double a0;
            double a1;
            var minorSegments = new List<ScreenPoint>();
            var minorTickSegments = new List<ScreenPoint>();
            this.GetTickPositions(axis, axis.TickStyle, axis.MinorTickSize, axis.Position, out a0, out a1);

            foreach (double value in this.MinorTickValues)
            {
                if (value < actualMinimum - eps || value > actualMaximum + eps)
                {
                    continue;
                }

                if (this.MajorTickValues.Contains(value))
                {
                    continue;
                }

                if (axis.PositionAtZeroCrossing && Math.Abs(value) < eps)
                {
                    continue;
                }

                double transformedValue = axis.Transform(value);

                if (isHorizontal)
                {
                    SnapTo(plotAreaLeft, ref transformedValue);
                    SnapTo(plotAreaRight, ref transformedValue);
                }
                else
                {
                    SnapTo(plotAreaTop, ref transformedValue);
                    SnapTo(plotAreaBottom, ref transformedValue);
                }

                // Draw the minor grid line
                if (this.MinorPen != null)
                {
                    if (isHorizontal)
                    {
                        minorSegments.Add(new ScreenPoint(transformedValue, plotAreaTop));
                        minorSegments.Add(new ScreenPoint(transformedValue, plotAreaBottom));
                    }
                    else
                    {
                        if (transformedValue < plotAreaTop || transformedValue > plotAreaBottom)
                        {
                        }

                        minorSegments.Add(new ScreenPoint(plotAreaLeft, transformedValue));
                        minorSegments.Add(new ScreenPoint(plotAreaRight, transformedValue));
                    }
                }

                // Draw the minor tick
                if (axis.TickStyle != TickStyle.None)
                {
                    if (isHorizontal)
                    {
                        minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a0));
                        minorTickSegments.Add(new ScreenPoint(transformedValue, axisPosition + a1));
                    }
                    else
                    {
                        minorTickSegments.Add(new ScreenPoint(axisPosition + a0, transformedValue));
                        minorTickSegments.Add(new ScreenPoint(axisPosition + a1, transformedValue));
                    }
                }
            }

            // Draw all the line segments);
            if (this.MinorPen != null)
            {
                this.rc.DrawLineSegments(minorSegments, this.MinorPen);
            }

            if (this.MinorTickPen != null)
            {
                this.rc.DrawLineSegments(minorTickSegments, this.MinorTickPen);
            }
        }
        private void RenderMagnitudeAxis(Axis axis, Axis angleAxis)
        {
            if (axis.RelatedAxis != null)
                angleAxis = axis.RelatedAxis;

            if (axis.ShowMinorTicks)
            {
                //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);

                foreach (double xValue in minorTickValues)
                {
                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
                    {
                        continue;
                    }

                    if (majorTickValues.Contains(xValue))
                    {
                        continue;
                    }

                    var pts = new List<ScreenPoint>();
                    for (double th = angleAxis.ActualMinimum;
                         th <= angleAxis.ActualMaximum;
                         th += angleAxis.MinorStep*0.1)
                    {
                        pts.Add(axis.Transform(xValue, th, angleAxis));
                    }

                    if (minorPen != null)
                    {
                        rc.DrawLine(pts, minorPen.Color, minorPen.Thickness, minorPen.DashArray);
                    }
                    // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
                }
            }

            //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);

            foreach (double xValue in majorTickValues)
            {
                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
                {
                    continue;
                }

                var pts = new List<ScreenPoint>();
                for (double th = angleAxis.ActualMinimum; th <= angleAxis.ActualMaximum; th += angleAxis.MinorStep*0.1)
                {
                    pts.Add(axis.Transform(xValue, th, angleAxis));
                }

                if (majorPen != null)
                {
                    rc.DrawLine(pts, majorPen.Color, majorPen.Thickness, majorPen.DashArray);
                }

                // RenderGridline(x, y + y0, x, y + y1, majorTickPen);

                //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
                //string text = axis.FormatValue(xValue);
                //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;

                //rc.DrawText(pt, text, plot.TextColor,
                //            axis.FontFamily, axis.FontSize, axis.FontWeight,
                //            axis.Angle,
                //            HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);

                //maxh = Math.Max(maxh, h);
            }
        }
 /// <summary>
 /// Check if the data series is using the specified axis.
 /// </summary>
 /// <param name="axis">
 /// An axis which should be checked if used
 /// </param>
 /// <returns>
 /// True if the axis is in use.
 /// </returns>
 protected internal abstract bool IsUsing(Axis axis);
        /// <summary>
        /// Gets the first axes that covers the area of the specified point.
        /// </summary>
        /// <param name="pt">
        /// The point.
        /// </param>
        /// <param name="xaxis">
        /// The xaxis.
        /// </param>
        /// <param name="yaxis">
        /// The yaxis.
        /// </param>
        public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
        {
            xaxis = yaxis = null;

            // Get the axis position of the given point. Using null if the point is inside the plot area.
            AxisPosition? position = null;
            double plotAreaValue = 0;
            if (pt.X < this.PlotArea.Left)
            {
                position = AxisPosition.Left;
                plotAreaValue = this.PlotArea.Left;
            }

            if (pt.X > this.PlotArea.Right)
            {
                position = AxisPosition.Right;
                plotAreaValue = this.PlotArea.Right;
            }

            if (pt.Y < this.PlotArea.Top)
            {
                position = AxisPosition.Top;
                plotAreaValue = this.PlotArea.Top;
            }

            if (pt.Y > this.PlotArea.Bottom)
            {
                position = AxisPosition.Bottom;
                plotAreaValue = this.PlotArea.Bottom;
            }

            foreach (var axis in this.Axes)
            {
                if (axis is ColorAxis)
                {
                    continue;
                }

                if (axis is MagnitudeAxis)
                {
                    xaxis = axis;
                    continue;
                }

                if (axis is AngleAxis)
                {
                    yaxis = axis;
                    continue;
                }

                double x = double.NaN;
                if (axis.IsHorizontal())
                {
                    x = axis.InverseTransform(pt.X);
                }

                if (axis.IsVertical())
                {
                    x = axis.InverseTransform(pt.Y);
                }

                if (x >= axis.ActualMinimum && x <= axis.ActualMaximum)
                {
                    if (position == null)
                    {
                        if (axis.IsHorizontal())
                        {
                            if (xaxis == null)
                            {
                                xaxis = axis;
                            }
                        }
                        else if (axis.IsVertical())
                        {
                            if (yaxis == null)
                            {
                                yaxis = axis;
                            }
                        }
                    }
                    else if (position == axis.Position)
                    {
                        // Choose right tier
                        double positionTierMinShift = axis.PositionTierMinShift;
                        double positionTierMaxShift = axis.PositionTierMaxShift;

                        double posValue = axis.IsHorizontal() ? pt.Y : pt.X;
                        bool isLeftOrTop = position == AxisPosition.Top || position == AxisPosition.Left;
                        if ((posValue >= plotAreaValue + positionTierMinShift
                             && posValue < plotAreaValue + positionTierMaxShift && !isLeftOrTop)
                            ||
                            (posValue <= plotAreaValue - positionTierMinShift
                             && posValue > plotAreaValue - positionTierMaxShift && isLeftOrTop))
                        {
                            if (axis.IsHorizontal())
                            {
                                if (xaxis == null)
                                {
                                    xaxis = axis;
                                }
                            }
                            else if (axis.IsVertical())
                            {
                                if (yaxis == null)
                                {
                                    yaxis = axis;
                                }
                            }
                        }
                    }
                }
            }
        }
        private void RenderAngleAxis(Axis axis, Axis magnitudeAxis)
        {
            if (axis.RelatedAxis != null)
                magnitudeAxis = axis.RelatedAxis;

            if (axis.ShowMinorTicks)
            {
                //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);

                foreach (double xValue in minorTickValues)
                {
                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
                    {
                        continue;
                    }

                    if (majorTickValues.Contains(xValue))
                    {
                        continue;
                    }

                    var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis);

                    if (minorPen != null)
                    {
                        RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, minorPen, false);
                    }
                    // RenderGridline(x, y + y0, x, y + y1, minorTickPen);
                }
            }

            //  GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);

            foreach (double xValue in majorTickValues)
            {
                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
                {
                    continue;
                }

                var pt = magnitudeAxis.Transform(magnitudeAxis.ActualMaximum, xValue, axis);

                if (majorPen != null)
                {
                    RenderLine(axis.MidPoint.x, axis.MidPoint.y, pt.x, pt.y, majorPen, false);
                }
                // RenderGridline(x, y + y0, x, y + y1, majorTickPen);

                //var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
                //string text = axis.FormatValue(xValue);
                //double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;

                //rc.DrawText(pt, text, plot.TextColor,
                //            axis.FontFamily, axis.FontSize, axis.FontWeight,
                //            axis.Angle,
                //            HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);

                //maxh = Math.Max(maxh, h);
            }
        }
 /// <summary>
 /// Transform the specified screen point to data coordinates.
 /// </summary>
 /// <param name="p">The point.</param>
 /// <param name="xaxis">The x axis.</param>
 /// <param name="yaxis">The y axis.</param>
 /// <returns>The data point.</returns>
 public static DataPoint InverseTransform(ScreenPoint p, Axis xaxis, Axis yaxis)
 {
     return xaxis.InverseTransform(p.x, p.y, yaxis);
 }
 private void GetVerticalTickPositions(Axis axis, TickStyle glt, double ticksize,
                                       out double y0, out double y1)
 {
     y0 = 0;
     y1 = 0;
     bool istop = axis.Position == AxisPosition.Top;
     double topsign = istop ? -1 : 1;
     switch (glt)
     {
         case TickStyle.Crossing:
             y0 = -ticksize*topsign;
             y1 = ticksize*topsign;
             break;
         case TickStyle.Inside:
             y0 = -ticksize*topsign;
             break;
         case TickStyle.Outside:
             y1 = ticksize*topsign;
             break;
     }
 }
 /// <summary>
 /// Inverse transform the specified screen point.
 /// </summary>
 /// <param name="x">
 /// The x coordinate.
 /// </param>
 /// <param name="y">
 /// The y coordinate.
 /// </param>
 /// <param name="yaxis">
 /// The y-axis.
 /// </param>
 /// <returns>
 /// The data point.
 /// </returns>
 public virtual DataPoint InverseTransform(double x, double y, Axis yaxis)
 {
     return new DataPoint(this.InverseTransform(x), yaxis != null ? yaxis.InverseTransform(y) : 0);
 }
 private void GetHorizontalTickPositions(Axis axis, TickStyle glt, double ticksize, out double x0,
                                         out double x1)
 {
     x0 = 0;
     x1 = 0;
     bool isLeft = axis.Position == AxisPosition.Left;
     double leftSign = isLeft ? -1 : 1;
     switch (glt)
     {
         case TickStyle.Crossing:
             x0 = -ticksize*leftSign;
             x1 = ticksize*leftSign;
             break;
         case TickStyle.Inside:
             x0 = -ticksize*leftSign;
             break;
         case TickStyle.Outside:
             x1 = ticksize*leftSign;
             break;
     }
 }
 /// <summary>
 /// Check if the data series is using the specified axis.
 /// </summary>
 /// <param name="axis">
 /// An axis which should be checked if used
 /// </param>
 /// <returns>
 /// True if the axis is in use.
 /// </returns>
 protected internal override bool IsUsing(Axis axis)
 {
     return this.XAxis == axis || this.YAxis == axis;
 }
 public void CreatePens(Axis axis)
 {
     minorPen = CreatePen(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle);
     majorPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
     minorTickPen = CreatePen(axis.TicklineColor, axis.MinorGridlineThickness, LineStyle.Solid);
     majorTickPen = CreatePen(axis.TicklineColor, axis.MajorGridlineThickness, LineStyle.Solid);
     zeroPen = CreatePen(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
     extraPen = CreatePen(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle);
 }
 /// <summary>
 /// The create pens.
 /// </summary>
 /// <param name="axis">
 /// The axis.
 /// </param>
 protected void CreatePens(Axis axis)
 {
     this.MinorPen = OxyPen.Create(axis.MinorGridlineColor, axis.MinorGridlineThickness, axis.MinorGridlineStyle);
     this.MajorPen = OxyPen.Create(axis.MajorGridlineColor, axis.MajorGridlineThickness, axis.MajorGridlineStyle);
     this.MinorTickPen = OxyPen.Create(axis.TicklineColor, axis.MinorGridlineThickness);
     this.MajorTickPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness);
     this.ZeroPen = OxyPen.Create(axis.TicklineColor, axis.MajorGridlineThickness);
     this.ExtraPen = OxyPen.Create(axis.ExtraGridlineColor, axis.ExtraGridlineThickness, axis.ExtraGridlineStyle);
     this.AxislinePen = OxyPen.Create(axis.AxislineColor, axis.AxislineThickness, axis.AxislineStyle);
 }
        private void RenderHorizontalAxis(Axis axis, Axis perpendicularAxis)
        {
            double y = Plot.Bounds.Bottom;
            switch (axis.Position)
            {
                case AxisPosition.Top:
                    y = Plot.Bounds.Top;
                    break;
                case AxisPosition.Bottom:
                    y = Plot.Bounds.Bottom;
                    break;
            }
            if (axis.PositionAtZeroCrossing)
            {
                y = perpendicularAxis.TransformX(0);
            }

            double y0, y1;

            if (axis.ShowMinorTicks)
            {
                GetVerticalTickPositions(axis, axis.TickStyle, axis.MinorTickSize, out y0, out y1);

                foreach (double xValue in minorTickValues)
                {
                    if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
                    {
                        continue;
                    }

                    if (majorTickValues.Contains(xValue))
                    {
                        continue;
                    }

                    double x = axis.TransformX(xValue);
                    if (minorPen != null)
                    {
                        RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, minorPen);
                    }
                    RenderLine(x, y + y0, x, y + y1, minorTickPen);
                }
            }

            GetVerticalTickPositions(axis, axis.TickStyle, axis.MajorTickSize, out y0, out y1);

            double maxh = 0;
            bool istop = axis.Position == AxisPosition.Top;
            foreach (double xValue in majorTickValues)
            {
                if (xValue < axis.ActualMinimum || xValue > axis.ActualMaximum)
                {
                    continue;
                }

                double x = axis.TransformX(xValue);

                if (majorPen != null)
                {
                    RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, majorPen);
                }
                RenderLine(x, y + y0, x, y + y1, majorTickPen);

                if (xValue == 0 && axis.PositionAtZeroCrossing)
                    continue;

                var pt = new ScreenPoint(x, istop ? y + y1 - TICK_DIST : y + y1 + TICK_DIST);
                string text = axis.FormatValue(xValue);
                double h = rc.MeasureText(text, axis.FontFamily, axis.FontSize, axis.FontWeight).Height;

                rc.DrawText(pt, text, Plot.TextColor,
                            axis.FontFamily, axis.FontSize, axis.FontWeight,
                            axis.Angle,
                            HorizontalTextAlign.Center, istop ? VerticalTextAlign.Bottom : VerticalTextAlign.Top);

                maxh = Math.Max(maxh, h);
            }

            if (axis.PositionAtZeroCrossing)
            {
                double x = axis.TransformX(0);
                RenderLine(x, Plot.Bounds.Top, x, Plot.Bounds.Bottom, zeroPen);
            }

            if (axis.ExtraGridlines != null)
            {
                foreach (double x in axis.ExtraGridlines)
                {
                    if (!IsWithin(x, axis.ActualMinimum, axis.ActualMaximum))
                        continue;
                    double sx = axis.TransformX(x);
                    RenderLine(sx, Plot.Bounds.Top, sx, Plot.Bounds.Bottom, extraPen);
                }
            }

            // The horizontal axis line
            RenderLine(Plot.Bounds.Left, y, Plot.Bounds.Right, y, majorPen);

            // The horizontal axis legend (centered horizontally)
            double legendX = axis.TransformX((axis.ActualMinimum + axis.ActualMaximum)/2);
            HorizontalTextAlign halign = HorizontalTextAlign.Center;
            VerticalTextAlign valign = VerticalTextAlign.Bottom;

            if (axis.PositionAtZeroCrossing)
            {
                legendX = perpendicularAxis.TransformX(perpendicularAxis.ActualMaximum);
            }

            double legendY = rc.Height - AXIS_LEGEND_DIST;
            if (istop)
            {
                legendY = AXIS_LEGEND_DIST;
                valign = VerticalTextAlign.Top;
            }
            rc.DrawText(new ScreenPoint(legendX, legendY),
                        axis.Title, Plot.TextColor,
                        axis.FontFamily, axis.FontSize, axis.FontWeight, 0, halign, valign);
        }
 /// <summary>
 /// Determines whether the point is valid.
 /// </summary>
 /// <param name="pt">The point.</param>
 /// <param name="xaxis">The x axis.</param>
 /// <param name="yaxis">The y axis.</param>
 /// <returns>
 ///  <c>true</c> if [is valid point] [the specified pt]; otherwise, <c>false</c>.
 /// </returns>
 public virtual bool IsValidItem(HighLowItem pt, Axis xaxis, Axis yaxis)
 {
     return !double.IsNaN(pt.X) && !double.IsInfinity(pt.X) && !double.IsNaN(pt.High)
            && !double.IsInfinity(pt.High) && !double.IsNaN(pt.Low) && !double.IsInfinity(pt.Low);
 }
Beispiel #31
0
        /// <summary>
        /// Gets the first axes that covers the area of the specified point.
        /// </summary>
        /// <param name="pt">
        /// The point.
        /// </param>
        /// <param name="xaxis">
        /// The xaxis.
        /// </param>
        /// <param name="yaxis">
        /// The yaxis.
        /// </param>
        public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
        {
            xaxis = yaxis = null;

            // Get the axis position of the given point. Using null if the point is inside the plot area.
            AxisPosition?position      = null;
            double       plotAreaValue = 0;

            if (pt.X < this.PlotArea.Left)
            {
                position      = AxisPosition.Left;
                plotAreaValue = this.PlotArea.Left;
            }

            if (pt.X > this.PlotArea.Right)
            {
                position      = AxisPosition.Right;
                plotAreaValue = this.PlotArea.Right;
            }

            if (pt.Y < this.PlotArea.Top)
            {
                position      = AxisPosition.Top;
                plotAreaValue = this.PlotArea.Top;
            }

            if (pt.Y > this.PlotArea.Bottom)
            {
                position      = AxisPosition.Bottom;
                plotAreaValue = this.PlotArea.Bottom;
            }

            foreach (var axis in this.Axes)
            {
                if (axis is ColorAxis)
                {
                    continue;
                }

                if (axis is MagnitudeAxis)
                {
                    xaxis = axis;
                    continue;
                }

                if (axis is AngleAxis)
                {
                    yaxis = axis;
                    continue;
                }

                double x = double.NaN;
                if (axis.IsHorizontal())
                {
                    x = axis.InverseTransform(pt.X);
                }

                if (axis.IsVertical())
                {
                    x = axis.InverseTransform(pt.Y);
                }

                if (x >= axis.ActualMinimum && x <= axis.ActualMaximum)
                {
                    if (position == null)
                    {
                        if (axis.IsHorizontal())
                        {
                            if (xaxis == null)
                            {
                                xaxis = axis;
                            }
                        }
                        else if (axis.IsVertical())
                        {
                            if (yaxis == null)
                            {
                                yaxis = axis;
                            }
                        }
                    }
                    else if (position == axis.Position)
                    {
                        // Choose right tier
                        double positionTierMinShift = axis.PositionTierMinShift;
                        double positionTierMaxShift = axis.PositionTierMaxShift;

                        double posValue    = axis.IsHorizontal() ? pt.Y : pt.X;
                        bool   isLeftOrTop = position == AxisPosition.Top || position == AxisPosition.Left;
                        if ((posValue >= plotAreaValue + positionTierMinShift &&
                             posValue < plotAreaValue + positionTierMaxShift && !isLeftOrTop)
                            ||
                            (posValue <= plotAreaValue - positionTierMinShift &&
                             posValue > plotAreaValue - positionTierMaxShift && isLeftOrTop))
                        {
                            if (axis.IsHorizontal())
                            {
                                if (xaxis == null)
                                {
                                    xaxis = axis;
                                }
                            }
                            else if (axis.IsVertical())
                            {
                                if (yaxis == null)
                                {
                                    yaxis = axis;
                                }
                            }
                        }
                    }
                }
            }
        }