/// <summary>
        /// Renders the specified axis.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="pass">The pass.</param>
        public override void Render(Axis axis, int pass)
        {
            base.Render(axis, pass);

            double totalShift = axis.AxisDistance + 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);
                this.RenderAxisTitle(axis, titlePosition);
            }
        }
示例#2
0
 /// <summary>
 /// Gets the maximum scale of the specified axis.
 /// </summary>
 public double AxisMaximum(Models.Graph.Axis.AxisType axisType)
 {
     OxyPlot.Axes.Axis axis = GetAxis(axisType);
     if (axis != null)
     {
         return(axis.ActualMaximum);
     }
     else
     {
         return(double.NaN);
     }
 }
示例#3
0
        /// <summary>
        /// Gets the interval (major step) of the specified axis.
        /// </summary>
        public double AxisMajorStep(Models.Graph.Axis.AxisType axisType)
        {
            OxyPlot.Axes.Axis axis = GetAxis(axisType);

            if (axis != null)
            {
                return(axis.IntervalLength);
            }
            else
            {
                return(double.NaN);
            }
        }
示例#4
0
        /// <summary>
        /// Gets the minimum scale of the specified axis.
        /// </summary>
        public double AxisMinimum(Models.Graph.Axis.AxisType axisType)
        {
            plot1.Refresh();
            OxyPlot.Axes.Axis axis = GetAxis(axisType);

            if (axis != null)
            {
                return(axis.ActualMinimum);
            }
            else
            {
                return(double.NaN);
            }
        }
示例#5
0
        /// <summary>
        /// Gets the minimum scale of the specified axis.
        /// </summary>
        public double AxisMinimum(Models.Graph.Axis.AxisType axisType)
        {
            /// TBI foreach (PlotView p in plots)
            /// TBI    p.Refresh();
            OxyPlot.Axes.Axis axis = GetAxis(axisType);

            if (axis != null)
            {
                return(axis.ActualMinimum);
            }
            else
            {
                return(double.NaN);
            }
        }
示例#6
0
        /// <summary>
        /// Format axis tick labels so that there is a leading zero on the tick
        /// labels when necessary.
        /// </summary>
        /// <param name="axis">The axis to format</param>
        private void FormatAxisTickLabels(OxyPlot.Axes.Axis axis)
        {
            // axis.IntervalLength = 100;

            if (axis is DateTimeAxis)
            {
                DateTimeAxis dateAxis = axis as DateTimeAxis;

                int numDays = (largestDate - smallestDate).Days;
                if (numDays < 100)
                {
                    dateAxis.IntervalType = DateTimeIntervalType.Days;
                }
                else if (numDays <= 366)
                {
                    dateAxis.IntervalType = DateTimeIntervalType.Months;
                    dateAxis.StringFormat = "dd-MMM";
                }
                else if (numDays <= 720)
                {
                    dateAxis.IntervalType = DateTimeIntervalType.Months;
                    dateAxis.StringFormat = "MMM-yyyy";
                }
                else
                {
                    dateAxis.IntervalType = DateTimeIntervalType.Years;
                    dateAxis.StringFormat = "yyyy";
                }
            }

            if (axis is LinearAxis &&
                (axis.ActualStringFormat == null || !axis.ActualStringFormat.Contains("yyyy")))
            {
                // We want the axis labels to always have a leading 0 when displaying decimal places.
                // e.g. we want 0.5 rather than .5

                // Use the current culture to format the string.
                string st = axis.ActualMajorStep.ToString(System.Globalization.CultureInfo.InvariantCulture);

                // count the number of decimal places in the above string.
                int pos = st.IndexOfAny(".,".ToCharArray());
                if (pos != -1)
                {
                    int numDecimalPlaces = st.Length - pos - 1;
                    axis.StringFormat = "F" + numDecimalPlaces.ToString();
                }
            }
        }
示例#7
0
        /// <summary>
        /// Gets the minimum scale of the specified axis.
        /// </summary>
        public double AxisMinimum(Models.Graph.Axis.AxisType axisType)
        {
            foreach (PlotView p in plots)
            {
                p.InvalidatePlot(true);
            }
            OxyPlot.Axes.Axis axis = GetAxis(axisType);

            if (axis != null)
            {
                return(axis.ActualMinimum);
            }
            else
            {
                return(double.NaN);
            }
        }
示例#8
0
        /// <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 override DataPoint InverseTransform(double x, double y, Axis yaxis)
        {
            var angleAxis = yaxis as AngleAxis;
            if (angleAxis == null)
            {
                throw new InvalidOperationException("Polar angle axis not defined!");
            }

            x -= this.MidPoint.x;
            y -= this.MidPoint.y;
            y *= -1;
            double th = Math.Atan2(y, x);
            double r = Math.Sqrt((x * x) + (y * y));
            x = (r / this.Scale) + this.Offset;
            y = (th / angleAxis.Scale) + angleAxis.Offset;
            return new DataPoint(x, y);
        }
        /// <summary>
        /// Renders the specified axis.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="pass">The pass.</param>
        /// <exception cref="System.NullReferenceException">Angle axis should not be <c>null</c>.</exception>
        public override void Render(Axis axis, int pass)
        {
            base.Render(axis, pass);

            var angleAxis = this.Plot.DefaultAngleAxis;

            if (angleAxis == null)
            {
                throw new NullReferenceException("Angle axis should not be null.");
            }

            angleAxis.UpdateActualMaxMin();

            var majorTicks = MajorTickValues.Where(x => x > axis.ActualMinimum && x <= axis.ActualMaximum).ToArray();

            if (pass == 0 && this.MinorPen != null)
            {
                var minorTicks = MinorTickValues.Where(x => x >= axis.ActualMinimum && x <= axis.ActualMaximum && !majorTicks.Contains(x)).ToArray();

                foreach (var tickValue in minorTicks)
                {
                    this.RenderTick(axis, angleAxis, tickValue, this.MinorPen);
                }
            }

            if (pass == 0 && this.MajorPen != null)
            {
                foreach (var tickValue in majorTicks)
                {
                    this.RenderTick(axis, angleAxis, tickValue, this.MajorPen);
                }
            }

            if (pass == 1)
            {
                foreach (double tickValue in majorTicks)
                {
                    this.RenderTickText(axis, tickValue, angleAxis);
                }
            }
        }
示例#10
0
 /// <summary>
 /// Format the specified axis.
 /// </summary>
 /// <param name="axisType">The axis type to format</param>
 /// <param name="title">The axis title. If null then a default axis title will be shown</param>
 /// <param name="inverted">Invert the axis?</param>
 /// <param name="minimum">Minimum axis scale</param>
 /// <param name="maximum">Maximum axis scale</param>
 /// <param name="interval">Axis scale interval</param>
 public void FormatAxis(
     Models.Graph.Axis.AxisType axisType,
     string title,
     bool inverted,
     double minimum,
     double maximum,
     double interval)
 {
     OxyPlot.Axes.Axis oxyAxis = this.GetAxis(axisType);
     if (oxyAxis != null)
     {
         oxyAxis.Title             = title;
         oxyAxis.MinorTickSize     = 0;
         oxyAxis.AxislineStyle     = LineStyle.Solid;
         oxyAxis.AxisTitleDistance = 10;
         if (inverted)
         {
             oxyAxis.StartPosition = 1;
             oxyAxis.EndPosition   = 0;
         }
         else
         {
             oxyAxis.StartPosition = 0;
             oxyAxis.EndPosition   = 1;
         }
         if (!double.IsNaN(minimum))
         {
             oxyAxis.Minimum = minimum;
         }
         if (!double.IsNaN(maximum))
         {
             oxyAxis.Maximum = maximum;
         }
         if (!double.IsNaN(interval) && interval > 0)
         {
             oxyAxis.MajorStep = interval;
         }
     }
 }
示例#11
0
 /// <summary>
 /// Determines whether the specified 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 the point is valid; otherwise, <c>false</c> .
 /// </returns>
 public virtual bool IsValidPoint(ScatterPoint 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>
        /// 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 HorizontalAlignment halign,
            ref VerticalAlignment 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)
            {
                middle = Lerp(axis.Transform(axis.ActualMaximum), axis.Transform(axis.ActualMinimum), axis.TitlePosition);
            }

            switch (axis.Position)
            {
                case AxisPosition.Left:
                    return new ScreenPoint(titlePosition, middle);
                case AxisPosition.Right:
                    valign = VerticalAlignment.Bottom;
                    return new ScreenPoint(titlePosition, middle);
                case AxisPosition.Top:
                    halign = HorizontalAlignment.Center;
                    valign = VerticalAlignment.Top;
                    angle = 0;
                    return new ScreenPoint(middle, titlePosition);
                case AxisPosition.Bottom:
                    halign = HorizontalAlignment.Center;
                    valign = VerticalAlignment.Bottom;
                    angle = 0;
                    return new ScreenPoint(middle, titlePosition);
                default:
                    throw new ArgumentOutOfRangeException("axis");
            }
        }
示例#13
0
        /// <summary>
        /// Convert the given apsim axis to an oxyplot <see cref="Axis"/>.
        /// </summary>
        /// <param name="graph">The graph to be converted.</param>
        public static Axis ToOxyPlotAxis(this APSIM.Shared.Graphing.Axis axis, AxisRequirements requirements, IEnumerable <string> labels)
        {
            if (requirements.AxisKind == null)
            {
                throw new InvalidOperationException("Unable to create series - axis requirements unknown, possibly because no series have any data");
            }
            Axis result = CreateAxis((AxisType)requirements.AxisKind);

            result.Position = axis.Position.ToOxyAxisPosition();
            result.Title    = axis.Title;
            result.PositionAtZeroCrossing = axis.CrossesAtZero;

            if (axis.Minimum is double min)
            {
                if (double.IsNaN(min))
                {
                    Debug.WriteLine("Axis minimum is NaN");
                }
                else
                {
                    result.Minimum = min;
                }
            }
            if (axis.Maximum is double max)
            {
                if (double.IsNaN(max))
                {
                    Debug.WriteLine("Axis maximum is NaN");
                }
                else
                {
                    result.Maximum = max;
                }
            }
            if (axis.Interval is double interval)
            {
                if (double.IsNaN(interval))
                {
                    Debug.WriteLine("Axis interval is NaN");
                }
                else
                {
                    if (requirements.AxisKind == AxisType.DateTime)
                    {
                        Debug.WriteLine("WARNING: Axis interval is set manually on a date axis - need to double check the implementation.");
                    }
                    result.MajorStep = interval;
                }
            }

            if (axis.Inverted)
            {
                result.StartPosition = 1;
                result.EndPosition   = 0;
            }

            // There are many other options which could be exposed to the user.
            result.MinorTickSize     = 0;
            result.AxisTitleDistance = 10;
            result.AxislineStyle     = OxyPlot.LineStyle.Solid;

            if (requirements.AxisKind == AxisType.Category && result is CategoryAxis categoryAxis)
            {
                categoryAxis.LabelField = "Label";
                categoryAxis.Labels.AddRange(labels);
            }

            return(result);
        }
示例#14
0
 /// <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);
 }
示例#15
0
        /// <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 override ScreenPoint Transform(double x, double y, Axis yaxis)
        {
            var angleAxis = yaxis as AngleAxis;
            if (angleAxis == null)
            {
                throw new InvalidOperationException("Polar angle axis not defined!");
            }

            var r = (x - this.Offset) * this.Scale;
            var theta = (y - angleAxis.Offset) * angleAxis.Scale;

            return new ScreenPoint(this.MidPoint.x + (r * Math.Cos(theta / 180 * Math.PI)), this.MidPoint.y - (r * Math.Sin(theta / 180 * Math.PI)));
        }
        /// <summary>
        /// Renders a tick by drawing an lot of segments
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="angleAxis">The angle axis.</param>
        /// <param name="x">The x-value.</param>
        /// <param name="pen">The pen.</param>
        private void RenderTickArc(Axis axis, AngleAxis angleAxis, double x, OxyPen pen)
        {
            // caution: make sure angleAxis.UpdateActualMaxMin(); has been called
            var minAngle = angleAxis.ActualMinimum;
            var maxAngle = angleAxis.ActualMaximum;

            // number of segment to draw a full circle
            // - decrease if you want get more speed
            // - increase if you want more detail
            // (making a public property of it would be a great idea)
            const double MaxSegments = 90.0;

            // compute the actual number of segments
            var segmentCount = (int)(MaxSegments * Math.Abs(angleAxis.EndAngle - angleAxis.StartAngle) / 360.0);

            var angleStep = (maxAngle - minAngle) / (segmentCount - 1);

            var points = new List<ScreenPoint>();

            for (var i = 0; i < segmentCount; i++)
            {
                var angle = minAngle + (i * angleStep);
                points.Add(axis.Transform(x, angle, angleAxis));
            }

            this.RenderContext.DrawLine(points, pen.Color, pen.Thickness, pen.ActualDashArray);
        }
示例#17
0
文件: Axis.cs 项目: gutyoh/oxyplot
        /// <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>
        /// Renders the specified axis.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="pass">The pass.</param>
        public override void Render(Axis axis, int pass)
        {
            base.Render(axis, pass);

            bool drawAxisLine = true;
            double totalShift = axis.AxisDistance + 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;
                    break;
                case AxisPosition.Right:
                    axisPosition = plotAreaRight + totalShift;
                    break;
                case AxisPosition.Top:
                    axisPosition = plotAreaTop - totalShift;
                    break;
                case AxisPosition.Bottom:
                    axisPosition = plotAreaBottom + totalShift;
                    break;
            }

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

                // the axis should be positioned at the origin of the perpendicular axis
                axisPosition = perpendicularAxis.Transform(0);

                var p0 = perpendicularAxis.Transform(perpendicularAxis.ActualMinimum);
                var p1 = perpendicularAxis.Transform(perpendicularAxis.ActualMaximum);

                // find the min/max positions
                var min = Math.Min(p0, p1);
                var max = Math.Max(p0, p1);

                // also consider the plot area
                var areaMin = axis.IsHorizontal() ? plotAreaTop : plotAreaLeft;
                var areaMax = axis.IsHorizontal() ? plotAreaBottom : plotAreaRight;
                min = Math.Max(min, areaMin);
                max = Math.Min(max, areaMax);

                if (axisPosition < min)
                {
                    axisPosition = min;

                    var borderThickness = axis.IsHorizontal()
                        ? this.Plot.PlotAreaBorderThickness.Top
                        : this.Plot.PlotAreaBorderThickness.Left;
                    if (borderThickness > 0 && this.Plot.PlotAreaBorderColor.IsVisible())
                    {
                        // there is already a line here...
                        drawAxisLine = false;
                    }
                }

                if (axisPosition > max)
                {
                    axisPosition = max;

                    var borderThickness = axis.IsHorizontal()
                        ? this.Plot.PlotAreaBorderThickness.Bottom
                        : this.Plot.PlotAreaBorderThickness.Right;
                    if (borderThickness > 0 && this.Plot.PlotAreaBorderColor.IsVisible())
                    {
                        // there is already a line here...
                        drawAxisLine = false;
                    }
                }
            }

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

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

            if (pass == 1)
            {
                this.RenderMajorItems(axis, axisPosition, titlePosition, drawAxisLine);
                this.RenderAxisTitle(axis, titlePosition);
            }
        }
示例#19
0
文件: Axis.cs 项目: gutyoh/oxyplot
 /// <summary>
 /// Transforms the specified point from screen space to data space.
 /// </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);
 }
示例#20
0
文件: Axis.cs 项目: gutyoh/oxyplot
 /// <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);
 }
 /// <summary>
 /// Returns the angle (in radian) of the axis line in screen coordinate
 /// </summary>
 /// <param name="axis">The axis.</param>
 /// <param name="angleAxis">The angle axis.</param>
 /// <returns>The angle (in radians).</returns>
 private static double GetActualAngle(Axis axis, Axis angleAxis)
 {
     var a = axis.Transform(0, angleAxis.Angle, angleAxis);
     var b = axis.Transform(1, angleAxis.Angle, angleAxis);
     return Math.Atan2(b.y - a.y, b.x - a.x);
 }
        /// <summary>
        /// Renders a tick, chooses the best implementation
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="angleAxis">The angle axis.</param>
        /// <param name="x">The x-value.</param>
        /// <param name="pen">The pen.</param>
        private void RenderTick(Axis axis, AngleAxis angleAxis, double x, OxyPen pen)
        {
            var isFullCircle = Math.Abs(Math.Abs(angleAxis.EndAngle - angleAxis.StartAngle) - 360) < 1e-6;

            if (isFullCircle && pen.ActualDashArray == null)
            {
                this.RenderTickCircle(axis, angleAxis, x, pen);
            }
            else
            {
                this.RenderTickArc(axis, angleAxis, x, pen);
            }
        }
        /// <summary>
        /// Renders major tick text
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="x">The x-value.</param>
        /// <param name="angleAxis">The angle axis.</param>
        private void RenderTickText(Axis axis, double x, Axis angleAxis)
        {
            var actualAngle = GetActualAngle(axis, angleAxis);
            var dx = axis.AxisTickToLabelDistance * Math.Sin(actualAngle);
            var dy = -axis.AxisTickToLabelDistance * Math.Cos(actualAngle);

            HorizontalAlignment ha;
            VerticalAlignment va;
            GetTickTextAligment(actualAngle, out ha, out va);

            var pt = axis.Transform(x, angleAxis.Angle, angleAxis);
            pt = new ScreenPoint(pt.X + dx, pt.Y + dy);

            string text = axis.FormatValue(x);
            this.RenderContext.DrawMathText(
                pt,
                text,
                axis.ActualTextColor,
                axis.ActualFont,
                axis.ActualFontSize,
                axis.ActualFontWeight,
                axis.Angle,
                ha,
                va);
        }
        /// <summary>
        /// Renders the axis title.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="titlePosition">The title position.</param>
        protected virtual void RenderAxisTitle(Axis axis, double titlePosition)
        {
            if (string.IsNullOrEmpty(axis.ActualTitle))
            {
                return;
            }

            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 = HorizontalAlignment.Center;
            var valign = VerticalAlignment.Top;

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

            this.RenderContext.DrawMathText(
                lpt,
                axis.ActualTitle,
                axis.ActualTitleColor,
                axis.ActualTitleFont,
                axis.ActualTitleFontSize,
                axis.ActualTitleFontWeight,
                angle,
                halign,
                valign,
                maxSize);
        }
示例#25
0
 /// <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>
        /// 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>
        /// <param name="drawAxisLine">Draw the axis line if set to <c>true</c>.</param>
        protected virtual void RenderMajorItems(Axis axis, double axisPosition, double titlePosition, bool drawAxisLine)
        {
            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 && axis.MajorTickSize > 0)
                {
                    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 = HorizontalAlignment.Right;
                var va = VerticalAlignment.Middle;
                switch (axis.Position)
                {
                    case AxisPosition.Left:
                        pt = new ScreenPoint(axisPosition + a1 - axis.AxisTickToLabelDistance, transformedValue);
                        this.GetRotatedAlignments(
                            axis.Angle,
                            HorizontalAlignment.Right,
                            VerticalAlignment.Middle,
                            out ha,
                            out va);
                        break;
                    case AxisPosition.Right:
                        pt = new ScreenPoint(axisPosition + a1 + axis.AxisTickToLabelDistance, transformedValue);
                        this.GetRotatedAlignments(
                            axis.Angle,
                            HorizontalAlignment.Left,
                            VerticalAlignment.Middle,
                            out ha,
                            out va);
                        break;
                    case AxisPosition.Top:
                        pt = new ScreenPoint(transformedValue, axisPosition + a1 - axis.AxisTickToLabelDistance);
                        this.GetRotatedAlignments(
                            axis.Angle,
                            HorizontalAlignment.Center,
                            VerticalAlignment.Bottom,
                            out ha,
                            out va);
                        break;
                    case AxisPosition.Bottom:
                        pt = new ScreenPoint(transformedValue, axisPosition + a1 + axis.AxisTickToLabelDistance);
                        this.GetRotatedAlignments(
                            axis.Angle,
                            HorizontalAlignment.Center,
                            VerticalAlignment.Top,
                            out ha,
                            out va);
                        break;
                }

                string text = axis.FormatValue(value);
                this.RenderContext.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 && this.IsWithin(0, actualMinimum, actualMaximum))
            {
                double t0 = axis.Transform(0);
                if (isHorizontal)
                {
                    this.RenderContext.DrawLine(t0, plotAreaTop, t0, plotAreaBottom, this.ZeroPen);
                }
                else
                {
                    this.RenderContext.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.RenderContext.DrawLine(
                            transformedValue,
                            plotAreaTop,
                            transformedValue,
                            plotAreaBottom,
                            this.ExtraPen);
                    }
                    else
                    {
                        this.RenderContext.DrawLine(
                            plotAreaLeft,
                            transformedValue,
                            plotAreaRight,
                            transformedValue,
                            this.ExtraPen);
                    }
                }
            }

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

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

            if (this.MajorTickPen != null)
            {
                this.RenderContext.DrawLineSegments(majorTickSegments, this.MajorTickPen);
            }
        }
示例#27
0
 /// <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);
 }
        /// <summary>
        /// Renders the minor items.
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="axisPosition">The axis position.</param>
        protected virtual 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 && axis.MinorTickSize > 0)
                {
                    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.RenderContext.DrawLineSegments(minorSegments, this.MinorPen);
            }

            if (this.MinorTickPen != null)
            {
                this.RenderContext.DrawLineSegments(minorTickSegments, this.MinorTickPen);
            }
        }
示例#29
0
 /// <summary>
 /// Inverse transforms 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>
 /// <exception cref="System.InvalidOperationException">Angle axis should always be the y-axis.</exception>
 public override DataPoint InverseTransform(double x, double y, Axis yaxis)
 {
     throw new InvalidOperationException("Angle axis should always be the y-axis.");
 }
示例#30
0
 /// <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;
 }
        /// <summary>
        /// Renders a tick by drawing an ellipse
        /// </summary>
        /// <param name="axis">The axis.</param>
        /// <param name="angleAxis">The angle axis.</param>
        /// <param name="x">The x-value.</param>
        /// <param name="pen">The pen.</param>
        private void RenderTickCircle(Axis axis, Axis angleAxis, double x, OxyPen pen)
        {
            var zero = angleAxis.Offset;
            var center = axis.Transform(axis.ActualMinimum, zero, angleAxis);
            var right = axis.Transform(x, zero, angleAxis).X;
            var radius = right - center.X;
            var width = radius * 2;
            var left = right - width;
            var top = center.Y - radius;
            var height = width;

            this.RenderContext.DrawEllipse(new OxyRect(left, top, width, height), OxyColors.Undefined, pen.Color, pen.Thickness);
        }
        private Axis ConvertAxis(ChartAxisViewModel axis)
        {
            Axis newAxis = null;

            switch (axis.AxisType)
            {
            case (ChartAxisType.CategoryX):
            {
                newAxis = new CategoryAxis
                {
                    LabelField  = axis.ValueMemberPath,
                    ItemsSource = axis.DataSource.Data
                };
                break;
            }

            case (ChartAxisType.NumericX):
            case (ChartAxisType.NumericY):
            {
                newAxis = new LinearAxis
                {
                };
                break;
            }

            case (ChartAxisType.CategoryDateTimeX):
            {
                var dtaxis = new DateTimeAxis
                {
                    IntervalType = DateTimeIntervalType.Auto,
                };

                var scale = axis.GetScaleForProperty(axis.ValueMemberPath);
                if (null != scale)
                {
                    scale.PropertyChanged += (s, a) =>
                    {
                        if (a.PropertyName != "Minimum" && a.PropertyName != "Maximum")
                        {
                            return;
                        }

                        var min = new DateTime((long)scale.Minimum);
                        var max = new DateTime((long)scale.Maximum);

                        var laxis = _plotModel.Axes.FirstOrDefault(x => x.Title == scale.Name) as DateTimeAxis;
                        if (null == laxis)
                        {
                            return;
                        }

                        var delta = max - min;

                        var lmax = 0.0d;
                        var lmin = 0.0d;

                        if (TimeSpan.FromSeconds(1) > delta)
                        {
                            laxis.IntervalType = DateTimeIntervalType.Seconds;
                        }
                        else if (TimeSpan.FromMinutes(1) > delta)
                        {
                            laxis.IntervalType = DateTimeIntervalType.Minutes;
                        }
                        else if (TimeSpan.FromHours(1) > delta)
                        {
                            laxis.IntervalType = DateTimeIntervalType.Hours;
                        }
                        else if (TimeSpan.FromDays(1) > delta)
                        {
                            laxis.IntervalType = DateTimeIntervalType.Days;
                        }
                        else if (TimeSpan.FromDays(30) > delta)
                        {
                            laxis.IntervalType = DateTimeIntervalType.Months;
                        }
                        else
                        {
                            laxis.IntervalType = DateTimeIntervalType.Auto;
                        }

                        //TODO: remove
                        laxis.IntervalType = DateTimeIntervalType.Seconds;

                        //laxis.Minimum = scale.Minimum;
                        //laxis.Maximum = scale.Maximum;

                        OnPlotModelChanged();
                    };
                }
                newAxis = dtaxis;
                break;
            }
            }

            if (null == newAxis)
            {
                return(null);
            }

            switch (axis.AxisLocation)
            {
            case (AxisLocation.InsideBottom):
            case (AxisLocation.OutsideBottom):
            {
                newAxis.Position = AxisPosition.Bottom;
                break;
            }

            case (AxisLocation.InsideTop):
            case (AxisLocation.OutsideTop):
            {
                newAxis.Position = AxisPosition.Top;
                break;
            }

            case (AxisLocation.InsideLeft):
            case (AxisLocation.OutsideLeft):
            {
                newAxis.Position = AxisPosition.Left;
                break;
            }

            case (AxisLocation.InsideRight):
            case (AxisLocation.OutsideRight):
            {
                newAxis.Position = AxisPosition.Right;
                break;
            }

            default:
            {
                newAxis.Position = AxisPosition.None;
                break;
            }
            }

            newAxis.Title = axis.Name;

            var series = axis.AxisScaleDescriptors.FirstOrDefault();

            if (null != series)
            {
                newAxis.Title = series.Scale.Name;
            }

            newAxis.Key = newAxis.Title;

            return(newAxis);
        }
示例#33
0
 /// <summary>
 /// Resets the specified axis.
 /// </summary>
 /// <param name="axis">
 /// The axis.
 /// </param>
 public void Reset(Axis axis)
 {
     axis.Reset();
 }
示例#34
0
 /// <summary>
 /// Zooms the specified axis to the specified values.
 /// </summary>
 /// <param name="axis">
 /// The axis.
 /// </param>
 /// <param name="p1">
 /// The new minimum value.
 /// </param>
 /// <param name="p2">
 /// The new maximum value.
 /// </param>
 public void Zoom(Axis axis, double p1, double p2)
 {
     axis.Zoom(p1, p2);
     this.RefreshPlot(false);
 }
示例#35
0
        /// <summary>
        /// Zooms at the specified position.
        /// </summary>
        /// <param name="axis">
        /// The axis.
        /// </param>
        /// <param name="factor">
        /// The zoom factor.
        /// </param>
        /// <param name="x">
        /// The position to zoom at.
        /// </param>
        public void ZoomAt(Axis axis, double factor, double x = double.NaN)
        {
            if (double.IsNaN(x))
            {
                double sx = (axis.Transform(axis.ActualMaximum) + axis.Transform(axis.ActualMinimum)) * 0.5;
                x = axis.InverseTransform(sx);
            }

            axis.ZoomAt(factor, x);
        }
示例#36
0
 /// <summary>
 /// Gets the axes from a point.
 /// </summary>
 /// <param name="pt">
 /// The point.
 /// </param>
 /// <param name="xaxis">
 /// The x-axis.
 /// </param>
 /// <param name="yaxis">
 /// The y-axis.
 /// </param>
 public void GetAxesFromPoint(ScreenPoint pt, out Axis xaxis, out Axis yaxis)
 {
     if (this.ActualModel != null)
     {
         this.ActualModel.GetAxesFromPoint(pt, out xaxis, out yaxis);
     }
     else
     {
         xaxis = null;
         yaxis = null;
     }
 }
示例#37
0
 /// <summary>
 /// Determines whether the specified item contains a valid point.
 /// </summary>
 /// <param name="item">The item.</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>
 public virtual bool IsValidPoint(BoxPlotItem item, Axis xaxis, Axis yaxis)
 {
     return !double.IsNaN(item.X) && !double.IsInfinity(item.X) && !item.Values.Any(double.IsNaN)
            && !item.Values.Any(double.IsInfinity) && (xaxis != null && xaxis.IsValidValue(item.X))
            && (yaxis != null && item.Values.All(yaxis.IsValidValue));
 }
示例#38
0
 /// <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;
 }
示例#39
0
 /// <summary>
 /// Pans the specified axis.
 /// </summary>
 /// <param name="axis">
 /// The axis.
 /// </param>
 /// <param name="ppt">
 /// The previous point (screen coordinates).
 /// </param>
 /// <param name="cpt">
 /// The current point (screen coordinates).
 /// </param>
 public void Pan(Axis axis, ScreenPoint ppt, ScreenPoint cpt)
 {
     axis.Pan(ppt, cpt);
     this.InvalidatePlot(false);
 }