Ejemplo n.º 1
0
        /// <summary>
        /// Finds the nearest point on the specified polyline.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="points">The points.</param>
        /// <returns>The nearest point.</returns>
        public static ScreenPoint FindNearestPointOnPolyline(ScreenPoint point, IList<ScreenPoint> points)
        {
            double minimumDistance = double.MaxValue;
            var nearestPoint = default(ScreenPoint);

            for (int i = 0; i + 1 < points.Count; i++)
            {
                var p1 = points[i];
                var p2 = points[i + 1];
                if (ScreenPoint.IsUndefined(p1) || ScreenPoint.IsUndefined(p2))
                {
                    continue;
                }

                // Find the nearest point on the line segment.
                var nearestPointOnSegment = FindPointOnLine(point, p1, p2);

                if (ScreenPoint.IsUndefined(nearestPointOnSegment))
                {
                    continue;
                }

                double l2 = (point - nearestPointOnSegment).LengthSquared;

                if (l2 < minimumDistance)
                {
                    nearestPoint = nearestPointOnSegment;
                    minimumDistance = l2;
                }
            }

            return nearestPoint;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the polygon outline of the specified rotated and aligned box.
        /// </summary>
        /// <param name="size">The size of the  box.</param>
        /// <param name="origin">The origin of the box.</param>
        /// <param name="angle">The rotation angle of the box.</param>
        /// <param name="horizontalAlignment">The horizontal alignment of the box.</param>
        /// <param name="verticalAlignment">The vertical alignment of the box.</param>
        /// <returns>A sequence of points defining the polygon outline of the box.</returns>
        public static IEnumerable<ScreenPoint> GetPolygon(this OxySize size, ScreenPoint origin, double angle, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment)
        {
            var u = horizontalAlignment == HorizontalAlignment.Left ? 0 : horizontalAlignment == HorizontalAlignment.Center ? 0.5 : 1;
            var v = verticalAlignment == VerticalAlignment.Top ? 0 : verticalAlignment == VerticalAlignment.Middle ? 0.5 : 1;

            var offset = new ScreenVector(u * size.Width, v * size.Height);

            // the corners of the rectangle
            var p0 = new ScreenVector(0, 0) - offset;
            var p1 = new ScreenVector(size.Width, 0) - offset;
            var p2 = new ScreenVector(size.Width, size.Height) - offset;
            var p3 = new ScreenVector(0, size.Height) - offset;

            if (angle != 0)
            {
                var theta = angle * Math.PI / 180.0;
                var costh = Math.Cos(theta);
                var sinth = Math.Sin(theta);
                Func<ScreenVector, ScreenVector> rotate = p => new ScreenVector((costh * p.X) - (sinth * p.Y), (sinth * p.X) + (costh * p.Y));

                p0 = rotate(p0);
                p1 = rotate(p1);
                p2 = rotate(p2);
                p3 = rotate(p3);
            }

            yield return origin + p0;
            yield return origin + p1;
            yield return origin + p2;
            yield return origin + p3;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Tracker is calling to determine the nearest point.
        /// </summary>
        /// <param name="point">The point clicked</param>
        /// <param name="interpolate">A value indicating whether interpolation should be used.</param>
        /// <returns>The return hit result</returns>
        public override TrackerHitResult GetNearestPoint(OxyPlot.ScreenPoint point, bool interpolate)
        {
            TrackerHitResult hitResult = base.GetNearestPoint(point, interpolate);

            if (hitResult != null && OnHoverOverPoint != null)
            {
                HoverPointArgs e = new HoverPointArgs();
                if (Title == null)
                {
                    e.SeriesName = ToolTip;
                }
                else
                {
                    e.SeriesName = Title;
                }

                e.X = hitResult.DataPoint.X;
                e.Y = hitResult.DataPoint.Y;
                OnHoverOverPoint.Invoke(this, e);
                if (e.HoverText != null)
                {
                    hitResult.Series.TrackerFormatString = e.HoverText + "\n{1}: {2}\n{3}: {4}";
                }
            }

            return(hitResult);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Draws or measures text containing sub- and superscript.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="pt">The point.</param>
        /// <param name="text">The text.</param>
        /// <param name="textColor">Color of the text.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="ha">The horizontal alignment.</param>
        /// <param name="va">The vertical alignment.</param>
        /// <param name="maxsize">The maximum size of the text.</param>
        /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param>
        /// <returns>The size of the text.</returns>
        /// <example>Subscript: H_{2}O
        /// Superscript: E=mc^{2}
        /// Both: A^{2}_{i,j}</example>
        public static OxySize DrawMathText(
            this IRenderContext rc,
            ScreenPoint pt,
            string text,
            OxyColor textColor,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double angle,
            HorizontalAlignment ha,
            VerticalAlignment va,
            OxySize? maxsize,
            bool measure)
        {
            if (string.IsNullOrEmpty(text))
            {
                return OxySize.Empty;
            }

            if (text.Contains("^{") || text.Contains("_{"))
            {
                double x = pt.X;
                double y = pt.Y;

                // Measure
                var size = InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, true, angle);

                switch (ha)
                {
                    case HorizontalAlignment.Right:
                        x -= size.Width;
                        break;
                    case HorizontalAlignment.Center:
                        x -= size.Width * 0.5;
                        break;
                }

                switch (va)
                {
                    case VerticalAlignment.Bottom:
                        y -= size.Height;
                        break;
                    case VerticalAlignment.Middle:
                        y -= size.Height * 0.5;
                        break;
                }

                InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, false, angle);
                return measure ? size : OxySize.Empty;
            }

            rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize);
            if (measure)
            {
                return rc.MeasureText(text, fontFamily, fontSize, fontWeight);
            }

            return OxySize.Empty;
        }
Ejemplo n.º 5
0
 public TrackerHitResult(Series.Series series, DataPoint dp, ScreenPoint sp, object item = null, double index = -1, string text = null)
 {
     this.DataPoint = dp;
     this.Position = sp;
     this.Item = item;
     this.Index = index;
     this.Series = series;
     this.Text = text;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TrackerHitResult"/> class.
 /// </summary>
 /// <param name="series">The series.</param>
 /// <param name="dp">The data point.</param>
 /// <param name="sp">The screen point.</param>
 /// <param name="item">The item.</param>
 /// <param name="index">The index.</param>
 /// <param name="text">The text.</param>
 public TrackerHitResult(OxyPlot.Series.Series series, IDataPoint dp, ScreenPoint sp, object item = null, double index = -1, string text = null)
 {
     this.DataPoint = dp;
     this.Position = sp;
     this.Item = item;
     this.Index = index;
     this.Series = series;
     this.Text = text;
     var ds = series as DataPointSeries;
     if (ds != null)
     {
         this.XAxis = ds.XAxis;
         this.YAxis = ds.YAxis;
     }
 }
Ejemplo n.º 7
0
        public static PlotModel DrawTextAlignment()
        {
            var model = new PlotModel();
            model.Annotations.Add(new DelegateAnnotation(rc =>
            {
                const double FontSize = 20d;

                for (var ha = HorizontalAlignment.Left; ha <= HorizontalAlignment.Right; ha++)
                {
                    for (var va = VerticalAlignment.Top; va <= VerticalAlignment.Bottom; va++)
                    {
                        var origin = new ScreenPoint((((int)ha + 1) * 200) + 20, (((int)va + 1) * FontSize * 3) + 20);
                        rc.FillCircle(origin, 3, OxyColors.Blue);
                        rc.DrawText(origin, ha + "-" + va, OxyColors.Black, fontSize: FontSize, horizontalAlignment: ha, verticalAlignment: va);
                    }
                }
            }));
            return model;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Renders the series on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        /// <param name="model">The owner plot model.</param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            if (Points.Count == 0)
            {
                return;
            }

            if (Points.Count % 2 != 0)
            {
                throw new InvalidOperationException("The number of points should be even.");
            }

            if (this.XAxis == null || this.YAxis == null)
            {
                throw new InvalidOperationException("Axis has not been defined.");
            }

            var clippingRect = GetClippingRect();

            var screenPoints = Points.Select(this.Transform).ToList();
            var verticalLines = new List<ScreenPoint>();

            for (int i = 0; i < screenPoints.Count; i += 2)
            {
                if (screenPoints[i].DistanceToSquared(screenPoints[i + 1]) < this.StrokeThickness)
                {
                    screenPoints[i] = new ScreenPoint(screenPoints[i].X - (this.StrokeThickness * 0.5), screenPoints[i].Y);
                    screenPoints[i + 1] = new ScreenPoint(screenPoints[i].X + (this.StrokeThickness * 0.5), screenPoints[i].Y);
                }

                if (this.ShowVerticals && i > 0 && Math.Abs(screenPoints[i - 1].X - screenPoints[i].X) < this.Epsilon)
                {
                    verticalLines.Add(screenPoints[i - 1]);
                    verticalLines.Add(screenPoints[i]);
                }
            }

            rc.DrawClippedLineSegments(clippingRect, screenPoints, this.ActualColor, this.StrokeThickness, this.LineStyle.GetDashArray(), this.LineJoin, false);
            rc.DrawClippedLineSegments(clippingRect, verticalLines, this.ActualColor, this.StrokeThickness / 3, LineStyle.Dash.GetDashArray(), this.LineJoin, false);

            rc.DrawMarkers(screenPoints, clippingRect, this.MarkerType, null, this.MarkerSize, this.MarkerFill, this.MarkerStroke, this.MarkerStrokeThickness);
        }
Ejemplo n.º 9
0
        public static PlotModel DrawMathTextAlignment()
        {
            var text = "A_{2}^{3}B";
            var model = new PlotModel();
            model.Annotations.Add(new DelegateAnnotation(rc =>
            {
                const string FontFamily = "Arial";
                const double FontSize = 20d;
                const double FontWeight = FontWeights.Normal;

                for (var ha = HorizontalAlignment.Left; ha <= HorizontalAlignment.Right; ha++)
                {
                    for (var va = VerticalAlignment.Top; va <= VerticalAlignment.Bottom; va++)
                    {
                        var origin = new ScreenPoint((((int)ha + 1) * 200) + 20, (((int)va + 1) * FontSize * 3) + 20);
                        rc.FillCircle(origin, 3, OxyColors.Blue);
                        rc.DrawMathText(origin, text, OxyColors.Black, FontFamily, FontSize, FontWeight, 0, ha, va);
                    }
                }
            }));
            return model;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Finds the point on line.
        /// </summary>
        /// <param name="p">The point.</param>
        /// <param name="p1">The first point on the line.</param>
        /// <param name="p2">The second point on the line.</param>
        /// <returns>The nearest point on the line.</returns>
        /// <remarks>See <a href="http://paulbourke.net/geometry/pointlineplane/">Bourke</a>.</remarks>
        public static ScreenPoint FindPointOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
        {
            double dx = p2.x - p1.x;
            double dy = p2.y - p1.y;
            double u = FindPositionOnLine(p, p1, p2);

            if (double.IsNaN(u))
            {
                u = 0;
            }

            if (u < 0)
            {
                u = 0;
            }

            if (u > 1)
            {
                u = 1;
            }

            return new ScreenPoint(p1.x + (u * dx), p1.y + (u * dy));
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Gets the distance to the specified point.
 /// </summary>
 /// <param name="point">
 /// The point.
 /// </param>
 /// <returns>
 /// The distance.
 /// </returns>
 public double DistanceTo(ScreenPoint point)
 {
     double dx = point.x - this.x;
     double dy = point.y - this.y;
     return Math.Sqrt((dx * dx) + (dy * dy));
 }
        /// <summary>
        /// Gets the point on the series that is nearest the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
        /// <returns>
        /// A TrackerHitResult for the current hit.
        /// </returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            if (interpolate)
            {
                // Cannot interpolate if there is no line
                if (this.ActualColor == null || this.StrokeThickness.IsZero())
                {
                    return null;
                }

                if (!this.CanTrackerInterpolatePoints)
                {
                    return null;
                }
            }

            if (interpolate && this.Smooth && this.SmoothedPoints != null)
            {
                return this.GetNearestInterpolatedPointInternal(this.SmoothedPoints, point);
            }

            return base.GetNearestPoint(point, interpolate);
        }
        /// <summary>
        /// Renders the point labels.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rect.</param>
        protected void RenderPointLabels(IRenderContext rc, OxyRect clippingRect)
        {
            int index = -1;
            foreach (var point in this.Points)
            {
                index++;

                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
                {
                    continue;
                }

                var pt = this.XAxis.Transform(point.X, point.Y, this.YAxis);
                pt.Y -= this.LabelMargin;

                if (!clippingRect.Contains(pt))
                {
                    continue;
                }

                var s = StringHelper.Format(
                    this.ActualCulture, this.LabelFormatString, this.GetItem(index), point.X, point.Y);

#if SUPPORTLABELPLACEMENT
                    switch (this.LabelPlacement)
                    {
                        case LabelPlacement.Inside:
                            pt = new ScreenPoint(rect.Right - this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalTextAlign.Right;
                            break;
                        case LabelPlacement.Middle:
                            pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalTextAlign.Center;
                            break;
                        case LabelPlacement.Base:
                            pt = new ScreenPoint(rect.Left + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalTextAlign.Left;
                            break;
                        default: // Outside
                            pt = new ScreenPoint(rect.Right + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalTextAlign.Left;
                            break;
                    }
#endif

                rc.DrawClippedText(
                    clippingRect,
                    pt,
                    s,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    0,
                    HorizontalTextAlign.Center,
                    VerticalTextAlign.Bottom);
            }
        }
Ejemplo n.º 14
0
 public DataSeries GetSeriesFromPoint(ScreenPoint pt, double limit)
 {
     return Model.GetSeriesFromPoint(pt, limit);
 }
Ejemplo n.º 15
0
        /// <summary>
        ///     Gets the point on the series that is nearest the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="interpolate">
        ///     Interpolate the series if this flag is set to <c>true</c>.
        /// </param>
        /// <returns>A TrackerHitResult for the current hit.</returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            foreach (var v in this.Values)
            {
                if (double.IsNaN(v) || v < this.XAxis.ActualMinimum || v > this.XAxis.ActualMaximum)
                {
                    continue;
                }

                double x = this.XAxis.Transform(v);
                var r = new OxyRect(
                    x - this.symbolSize.Width / 2,
                    this.symbolPosition - this.symbolSize.Height,
                    this.symbolSize.Width,
                    this.symbolSize.Height);
                if (r.Contains(point))
                {
                    var text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, null, this.Title, v);

                    return new TrackerHitResult(
                        this,
                        new DataPoint(v, double.NaN),
                        new ScreenPoint(x, this.symbolPosition - this.symbolSize.Height)) { Text = text };
                }
            }

            return null;
        }
Ejemplo n.º 16
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 x-axis.</param>
        /// <param name="yaxis">The y-axis.</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 IColorAxis)
                {
                    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;
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The p.</param>
        /// <param name="text">The text.</param>
        /// <param name="c">The c.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotate.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">Size of the max.</param>
        public override void DrawText(
            ScreenPoint p,
            string text,
            OxyColor c,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize?maxSize)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            var lines = Regex.Split(text, "\r\n");

            var textSize   = this.MeasureText(text, fontFamily, fontSize, fontWeight);
            var lineHeight = textSize.Height / lines.Length;
            var lineOffset = new ScreenVector(-Math.Sin(rotate / 180.0 * Math.PI) * lineHeight, +Math.Cos(rotate / 180.0 * Math.PI) * lineHeight);

            if (this.UseVerticalTextAlignmentWorkaround)
            {
                // offset the position, and set the valign to neutral value of `Bottom`
                double offsetRatio = valign == VerticalAlignment.Bottom ? (1.0 - lines.Length) : valign == VerticalAlignment.Top ? 1.0 : (1.0 - (lines.Length / 2.0));
                valign = VerticalAlignment.Bottom;

                p += lineOffset * offsetRatio;

                foreach (var line in lines)
                {
                    var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
                    this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);

                    p += lineOffset;
                }
            }
            else
            {
                if (valign == VerticalAlignment.Bottom)
                {
                    for (var i = lines.Length - 1; i >= 0; i--)
                    {
                        var line = lines[i];
                        var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
                        this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);

                        p -= lineOffset;
                    }
                }
                else
                {
                    foreach (var line in lines)
                    {
                        var size = this.MeasureText(line, fontFamily, fontSize, fontWeight);
                        this.w.WriteText(p, line, c, fontFamily, fontSize, fontWeight, rotate, halign, valign);

                        p += lineOffset;
                    }
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Gets the point on the curve that is nearest the specified point.
        /// </summary>
        /// <param name = "point">The point.</param>
        /// <param name = "dpn">The nearest point (data coordinates).</param>
        /// <param name = "spn">The nearest point (screen coordinates).</param>
        /// <returns></returns>
        public override bool GetNearestInterpolatedPoint(ScreenPoint point, out DataPoint dpn, out ScreenPoint spn)
        {
            spn = default(ScreenPoint);
            dpn = default(DataPoint);

            // http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
            double minimumDistance = double.MaxValue;

            for (int i = 0; i + 1 < points.Count; i++)
            {
                var p1  = points[i];
                var p2  = points[i + 1];
                var sp1 = AxisBase.Transform(p1, XAxis, YAxis);
                var sp2 = AxisBase.Transform(p2, XAxis, YAxis);

                double sp21X = sp2.x - sp1.x;
                double sp21Y = sp2.y - sp1.y;
                double u1    = (point.x - sp1.x) * sp21X + (point.y - sp1.y) * sp21Y;
                double u2    = sp21X * sp21X + sp21Y * sp21Y;
                double ds    = sp21X * sp21X + sp21Y * sp21Y;

                if (ds < 4)
                {
                    // if the points are very close, we can get numerical problems, just use the first point...
                    u1 = 0; u2 = 1;
                }

                if (u2 == 0)
                {
                    continue; // P1 && P2 coincident
                }

                double u = u1 / u2;
                if (u < 0 || u > 1)
                {
                    continue; // outside line
                }

                double sx = sp1.x + u * sp21X;
                double sy = sp1.y + u * sp21Y;

                double dx       = point.x - sx;
                double dy       = point.y - sy;
                double distance = dx * dx + dy * dy;

                if (distance < minimumDistance)
                {
                    double px = p1.x + u * (p2.x - p1.x);
                    double py = p1.y + u * (p2.y - p1.y);
                    dpn             = new DataPoint(px, py);
                    spn             = new ScreenPoint(sx, sy);
                    minimumDistance = distance;
                }
            }

            return(minimumDistance < double.MaxValue);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Renders the Series on the specified rendering context.
        /// </summary>
        /// <param name="rc">
        /// The rendering context.
        /// </param>
        /// <param name="model">
        /// The model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            this.ActualMinimumBarRectangles = new List <OxyRect>();
            this.ActualMaximumBarRectangles = new List <OxyRect>();

            if (this.ValidItems.Count == 0)
            {
                return;
            }

            var clippingRect   = this.GetClippingRect();
            var categoryAxis   = this.GetCategoryAxis();
            var actualBarWidth = this.GetActualBarWidth();

            for (var i = 0; i < this.ValidItems.Count; i++)
            {
                var item = this.ValidItems[i];

                var categoryIndex = item.GetCategoryIndex(i);

                var baseValue = double.IsNaN(item.BaseValue) ? this.BaseValue : item.BaseValue;

                var p0 = this.Transform(item.Minimum, categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex]);
                var p1 = this.Transform(
                    item.Maximum, categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex] + actualBarWidth);
                var p2 = this.Transform(baseValue, categoryIndex - 0.5 + categoryAxis.BarOffset[categoryIndex]);
                p2.X = (int)p2.X;

                var minimumRectangle = OxyRect.Create(p0.X, p0.Y, p2.X, p1.Y);
                var maximumRectangle = OxyRect.Create(p2.X, p0.Y, p1.X, p1.Y);

                this.ActualMinimumBarRectangles.Add(minimumRectangle);
                this.ActualMaximumBarRectangles.Add(maximumRectangle);

                rc.DrawClippedRectangleAsPolygon(
                    minimumRectangle,
                    clippingRect,
                    item.MinimumColor ?? this.ActualMinimumFillColor,
                    this.StrokeColor,
                    this.StrokeThickness);
                rc.DrawClippedRectangleAsPolygon(
                    maximumRectangle,
                    clippingRect,
                    item.MaximumColor ?? this.ActualMaximumFillColor,
                    this.StrokeColor,
                    this.StrokeThickness);

                if (this.MinimumLabelFormatString != null)
                {
                    var s = StringHelper.Format(
                        this.ActualCulture,
                        this.MinimumLabelFormatString,
                        this.GetItem(this.ValidItemsIndexInversion[i]),
                        item.Minimum);
                    var pt = new ScreenPoint(
                        minimumRectangle.Left - this.LabelMargin, (minimumRectangle.Top + minimumRectangle.Bottom) / 2);

                    rc.DrawClippedText(
                        clippingRect,
                        pt,
                        s,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        0,
                        HorizontalTextAlign.Right,
                        VerticalTextAlign.Middle);
                }

                if (this.MaximumLabelFormatString != null)
                {
                    var s = StringHelper.Format(
                        this.ActualCulture,
                        this.MaximumLabelFormatString,
                        this.GetItem(this.ValidItemsIndexInversion[i]),
                        item.Maximum);
                    var pt = new ScreenPoint(
                        maximumRectangle.Right + this.LabelMargin, (maximumRectangle.Top + maximumRectangle.Bottom) / 2);

                    rc.DrawClippedText(
                        clippingRect,
                        pt,
                        s,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        0,
                        HorizontalTextAlign.Left,
                        VerticalTextAlign.Middle);
                }
            }
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Fills a circle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="center">The center.</param>
 /// <param name="r">The radius.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="edgeRenderingMode">The edge rendering mode.</param>
 public static void FillCircle(this IRenderContext rc, ScreenPoint center, double r, OxyColor fill, EdgeRenderingMode edgeRenderingMode)
 {
     DrawCircle(rc, center.X, center.Y, r, fill, OxyColors.Undefined, 0d, edgeRenderingMode);
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Adds a marker geometry to the specified collections.
        /// </summary>
        /// <param name="p">The position of the marker.</param>
        /// <param name="type">The marker type.</param>
        /// <param name="outline">The custom outline, if <paramref name="type" /> is <see cref="MarkerType.Custom" />.</param>
        /// <param name="size">The size of the marker.</param>
        /// <param name="ellipses">The output ellipse collection.</param>
        /// <param name="rects">The output rectangle collection.</param>
        /// <param name="polygons">The output polygon collection.</param>
        /// <param name="lines">The output line collection.</param>
        private static void AddMarkerGeometry(
            ScreenPoint p,
            MarkerType type,
            IEnumerable <ScreenPoint> outline,
            double size,
            IList <OxyRect> ellipses,
            IList <OxyRect> rects,
            IList <IList <ScreenPoint> > polygons,
            IList <ScreenPoint> lines)
        {
            if (type == MarkerType.Custom)
            {
                if (outline == null)
                {
                    throw new ArgumentNullException("outline", "The outline should be set when MarkerType is 'Custom'.");
                }

                var poly = outline.Select(o => new ScreenPoint(p.X + (o.x * size), p.Y + (o.y * size))).ToList();
                polygons.Add(poly);
                return;
            }

            switch (type)
            {
            case MarkerType.Circle:
            {
                ellipses.Add(new OxyRect(p.x - size, p.y - size, size * 2, size * 2));
                break;
            }

            case MarkerType.Square:
            {
                rects.Add(new OxyRect(p.x - size, p.y - size, size * 2, size * 2));
                break;
            }

            case MarkerType.Diamond:
            {
                polygons.Add(
                    new[]
                    {
                        new ScreenPoint(p.x, p.y - (M2 * size)), new ScreenPoint(p.x + (M2 * size), p.y),
                        new ScreenPoint(p.x, p.y + (M2 * size)), new ScreenPoint(p.x - (M2 * size), p.y)
                    });
                break;
            }

            case MarkerType.Triangle:
            {
                polygons.Add(
                    new[]
                    {
                        new ScreenPoint(p.x - size, p.y + (M1 * size)),
                        new ScreenPoint(p.x + size, p.y + (M1 * size)), new ScreenPoint(p.x, p.y - (M2 * size))
                    });
                break;
            }

            case MarkerType.Plus:
            case MarkerType.Star:
            {
                lines.Add(new ScreenPoint(p.x - size, p.y));
                lines.Add(new ScreenPoint(p.x + size, p.y));
                lines.Add(new ScreenPoint(p.x, p.y - size));
                lines.Add(new ScreenPoint(p.x, p.y + size));
                break;
            }
            }

            switch (type)
            {
            case MarkerType.Cross:
            case MarkerType.Star:
            {
                lines.Add(new ScreenPoint(p.x - (size * M3), p.y - (size * M3)));
                lines.Add(new ScreenPoint(p.x + (size * M3), p.y + (size * M3)));
                lines.Add(new ScreenPoint(p.x - (size * M3), p.y + (size * M3)));
                lines.Add(new ScreenPoint(p.x + (size * M3), p.y - (size * M3)));
                break;
            }
            }
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Draws a circle at the specified position.
 /// </summary>
 /// <param name="rc">The render context.</param>
 /// <param name="center">The center.</param>
 /// <param name="r">The radius.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The thickness.</param>
 /// <param name="edgeRenderingMode">The edge rendering mode.</param>
 public static void DrawCircle(this IRenderContext rc, ScreenPoint center, double r, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode)
 {
     DrawCircle(rc, center.X, center.Y, r, fill, stroke, thickness, edgeRenderingMode);
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Draws a list of markers.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRectangle">The clipping rectangle.</param>
        /// <param name="markerPoints">The marker points.</param>
        /// <param name="markerType">Type of the marker.</param>
        /// <param name="markerOutline">The marker outline.</param>
        /// <param name="markerSize">Size of the markers.</param>
        /// <param name="markerFill">The marker fill.</param>
        /// <param name="markerStroke">The marker stroke.</param>
        /// <param name="markerStrokeThickness">The marker stroke thickness.</param>
        /// <param name="edgeRenderingMode">The edge rendering mode.</param>
        /// <param name="resolution">The resolution.</param>
        /// <param name="binOffset">The bin Offset.</param>
        public static void DrawMarkers(
            this IRenderContext rc,
            OxyRect clippingRectangle,
            IList <ScreenPoint> markerPoints,
            MarkerType markerType,
            IList <ScreenPoint> markerOutline,
            IList <double> markerSize,
            OxyColor markerFill,
            OxyColor markerStroke,
            double markerStrokeThickness,
            EdgeRenderingMode edgeRenderingMode,
            int resolution        = 0,
            ScreenPoint binOffset = new ScreenPoint())
        {
            if (markerType == MarkerType.None)
            {
                return;
            }

            int n        = markerPoints.Count;
            var ellipses = new List <OxyRect>(n);
            var rects    = new List <OxyRect>(n);
            var polygons = new List <IList <ScreenPoint> >(n);
            var lines    = new List <ScreenPoint>(n);

            var hashset = new Dictionary <uint, bool>();

            int i = 0;

            double minx = clippingRectangle.Left;
            double maxx = clippingRectangle.Right;
            double miny = clippingRectangle.Top;
            double maxy = clippingRectangle.Bottom;

            foreach (var p in markerPoints)
            {
                if (resolution > 1)
                {
                    var  x    = (int)((p.X - binOffset.X) / resolution);
                    var  y    = (int)((p.Y - binOffset.Y) / resolution);
                    uint hash = (uint)(x << 16) + (uint)y;
                    if (hashset.ContainsKey(hash))
                    {
                        i++;
                        continue;
                    }

                    hashset.Add(hash, true);
                }

                bool outside = p.x <minx || p.x> maxx || p.y <miny || p.y> maxy;
                if (!outside)
                {
                    int j = i < markerSize.Count ? i : 0;
                    AddMarkerGeometry(p, markerType, markerOutline, markerSize[j], ellipses, rects, polygons, lines);
                }

                i++;
            }

            if (edgeRenderingMode == EdgeRenderingMode.Automatic)
            {
                edgeRenderingMode = EdgeRenderingMode.PreferGeometricAccuracy;
            }

            if (ellipses.Count > 0)
            {
                rc.DrawEllipses(ellipses, markerFill, markerStroke, markerStrokeThickness, edgeRenderingMode);
            }

            if (rects.Count > 0)
            {
                rc.DrawRectangles(rects, markerFill, markerStroke, markerStrokeThickness, edgeRenderingMode);
            }

            if (polygons.Count > 0)
            {
                rc.DrawPolygons(polygons, markerFill, markerStroke, markerStrokeThickness, edgeRenderingMode);
            }

            if (lines.Count > 0)
            {
                rc.DrawLineSegments(lines, markerStroke, markerStrokeThickness, edgeRenderingMode);
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Draws the text.
        /// </summary>
        /// <param name="p">The position of the text.</param>
        /// <param name="text">The text.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">Size of the font.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="rotate">The rotation angle.</param>
        /// <param name="halign">The horizontal alignment.</param>
        /// <param name="valign">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        public override void DrawText(
            ScreenPoint p,
            string text,
            OxyColor fill,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double rotate,
            HorizontalAlignment halign,
            VerticalAlignment valign,
            OxySize?maxSize)
        {
            this.doc.SaveState();
            this.doc.SetFont(fontFamily, fontSize / 96 * 72, fontWeight > 500);
            this.doc.SetFillColor(fill);

            double width, height;

            this.doc.MeasureText(text, out width, out height);
            if (maxSize != null)
            {
                if (width > maxSize.Value.Width)
                {
                    width = Math.Max(maxSize.Value.Width, 0);
                }

                if (height > maxSize.Value.Height)
                {
                    height = Math.Max(maxSize.Value.Height, 0);
                }
            }

            double dx = 0;

            if (halign == HorizontalAlignment.Center)
            {
                dx = -width / 2;
            }

            if (halign == HorizontalAlignment.Right)
            {
                dx = -width;
            }

            double dy = 0;

            if (valign == VerticalAlignment.Middle)
            {
                dy = -height / 2;
            }

            if (valign == VerticalAlignment.Top)
            {
                dy = -height;
            }

            double y = this.doc.PageHeight - p.Y;

            this.doc.Translate(p.X, y);
            if (Math.Abs(rotate) > 1e-6)
            {
                this.doc.Rotate(-rotate);
            }

            this.doc.Translate(dx, dy);

            // this.doc.DrawRectangle(0, 0, width, height);
            this.doc.SetClippingRectangle(0, 0, width, height);
            this.doc.DrawText(0, 0, text);
            this.doc.RestoreState();
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Draws text.
 /// </summary>
 /// <param name="p">The position.</param>
 /// <param name="text">The text.</param>
 /// <param name="fill">The text color.</param>
 /// <param name="fontFamily">The font family.</param>
 /// <param name="fontSize">Size of the font (in device independent units, 1/96 inch).</param>
 /// <param name="fontWeight">The font weight.</param>
 /// <param name="rotate">The rotation angle.</param>
 /// <param name="halign">The horizontal alignment.</param>
 /// <param name="valign">The vertical alignment.</param>
 /// <param name="maxSize">The maximum size of the text (in device independent units, 1/96 inch).</param>
 public void DrawText(
     ScreenPoint p,
     string text,
     OxyColor fill,
     string fontFamily = null,
     double fontSize = 10,
     double fontWeight = 500,
     double rotate = 0,
     HorizontalAlignment halign = HorizontalAlignment.Left,
     VerticalAlignment valign = VerticalAlignment.Top,
     OxySize? maxSize = null)
 {
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Fines the edge interception.
        /// </summary>
        /// <param name="bounds">The bounds.</param>
        /// <param name="edge">The edge.</param>
        /// <param name="a">The first point.</param>
        /// <param name="b">The second point.</param>
        /// <returns>The interception.</returns>
        private static ScreenPoint LineIntercept(OxyRect bounds, RectangleEdge edge, ScreenPoint a, ScreenPoint b)
        {
            if (a.x.Equals(b.x) && a.y.Equals(b.y))
            {
                return(a);
            }

            switch (edge)
            {
            case RectangleEdge.Bottom:
                if (b.Y.Equals(a.Y))
                {
                    throw new ArgumentException("no intercept found");
                }

                return(new ScreenPoint(a.X + (((b.X - a.X) * (bounds.Bottom - a.Y)) / (b.Y - a.Y)), bounds.Bottom));

            case RectangleEdge.Left:
                if (b.X.Equals(a.X))
                {
                    throw new ArgumentException("no intercept found");
                }

                return(new ScreenPoint(bounds.Left, a.Y + (((b.Y - a.Y) * (bounds.Left - a.X)) / (b.X - a.X))));

            case RectangleEdge.Right:
                if (b.X.Equals(a.X))
                {
                    throw new ArgumentException("no intercept found");
                }

                return(new ScreenPoint(bounds.Right, a.Y + (((b.Y - a.Y) * (bounds.Right - a.X)) / (b.X - a.X))));

            case RectangleEdge.Top:
                if (b.Y.Equals(a.Y))
                {
                    throw new ArgumentException("no intercept found");
                }

                return(new ScreenPoint(a.X + (((b.X - a.X) * (bounds.Top - a.Y)) / (b.Y - a.Y)), bounds.Top));
            }

            throw new ArgumentException("no intercept found");
        }
        /// <summary>
        /// Draws or measures text containing sub- and superscript.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="pt">The point.</param>
        /// <param name="text">The text.</param>
        /// <param name="textColor">Color of the text.</param>
        /// <param name="fontFamily">The font family.</param>
        /// <param name="fontSize">The font size.</param>
        /// <param name="fontWeight">The font weight.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="ha">The horizontal alignment.</param>
        /// <param name="va">The vertical alignment.</param>
        /// <param name="maxSize">The maximum size of the text.</param>
        /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param>
        /// <returns>The size of the text.</returns>
        /// <example>Subscript: H_{2}O
        /// Superscript: E=mc^{2}
        /// Both: A^{2}_{i,j}</example>
        public static OxySize DrawMathText(
            this IRenderContext rc,
            ScreenPoint pt,
            string text,
            OxyColor textColor,
            string fontFamily,
            double fontSize,
            double fontWeight,
            double angle,
            HorizontalAlignment ha,
            VerticalAlignment va,
            OxySize?maxSize,
            bool measure)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(OxySize.Empty);
            }

            if (text.Contains("^{") || text.Contains("_{"))
            {
                var x = pt.X;
                var y = pt.Y;

                // Measure
                var size = InternalDrawMathText(rc, x, y, 0, 0, text, textColor, fontFamily, fontSize, fontWeight, true, angle);

                var dx = 0d;
                var dy = 0d;

                switch (ha)
                {
                case HorizontalAlignment.Right:
                    dx = -size.Width;
                    break;

                case HorizontalAlignment.Center:
                    dx = -size.Width * 0.5;
                    break;
                }

                switch (va)
                {
                case VerticalAlignment.Bottom:
                    dy = -size.Height;
                    break;

                case VerticalAlignment.Middle:
                    dy = -size.Height * 0.5;
                    break;
                }

                InternalDrawMathText(rc, x, y, dx, dy, text, textColor, fontFamily, fontSize, fontWeight, false, angle);
                return(measure ? size : OxySize.Empty);
            }

            rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxSize);
            if (measure)
            {
                return(rc.MeasureText(text, fontFamily, fontSize, fontWeight));
            }

            return(OxySize.Empty);
        }
Ejemplo n.º 28
0
 protected override void OnMouseWheel(MouseEventArgs e)
 {
     base.OnMouseWheel(e);
     bool control = Control.ModifierKeys == Keys.Control;
     bool shift = Control.ModifierKeys == Keys.Shift;
     var p = new ScreenPoint(e.X, e.Y);
     foreach (var a in MouseActions)
         a.OnMouseWheel(p, e.Delta, control, shift);
 }
Ejemplo n.º 29
0
        /// <summary>
        /// Gets the point on the series that is nearest the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
        /// <returns>
        /// A TrackerHitResult for the current hit.
        /// </returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            var dp = this.InverseTransform(point);
            int i = (int)dp.Y;
            int j = (int)dp.X;

            if (i >= 0 && i < this.matrix.GetLength(0) && j >= 0 && j < this.matrix.GetLength(1))
            {
                var value = this.matrix[i, j];
                var text = StringHelper.Format(
                    this.ActualCulture,
                    this.TrackerFormatString,
                    null,
                    this.Title,
                    i, 
                    j, 
                    value);
                return new TrackerHitResult(this, dp, point, null, -1, text);
            }

            return null; 
        }
Ejemplo n.º 30
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 x-axis.</param>
        /// <param name="yaxis">The y-axis.</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.IsAxisVisible)
                {
                    continue;
                }

                if (axis is IColorAxis)
                {
                    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;
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 31
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            Focus();
            Capture = true;

            bool control = Control.ModifierKeys == Keys.Control;
            bool shift = Control.ModifierKeys == Keys.Shift;

            var button = OxyMouseButton.Left;
            if (e.Button == MouseButtons.Middle)
                button = OxyMouseButton.Middle;
            if (e.Button == MouseButtons.Right)
                button = OxyMouseButton.Right;
            if (e.Button == MouseButtons.XButton1)
                button = OxyMouseButton.XButton1;
            if (e.Button == MouseButtons.XButton2)
                button = OxyMouseButton.XButton2;

            var p = new ScreenPoint(e.X, e.Y);
            foreach (var a in MouseActions)
                a.OnMouseDown(p, button, e.Clicks, control, shift);
        }
Ejemplo n.º 32
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OxyRect"/> struct by location and size.
 /// </summary>
 /// <param name="p0">The location.</param>
 /// <param name="size">The size.</param>
 public OxyRect(ScreenPoint p0, OxySize size)
     : this(p0.X, p0.Y, size.Width, size.Height)
 {
 }
Ejemplo n.º 33
0
 public void GetAxesFromPoint(ScreenPoint pt, out AxisBase xaxis, out AxisBase yaxis)
 {
     Model.GetAxesFromPoint(pt, out xaxis, out yaxis);
 }
Ejemplo n.º 34
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OxyRect" /> struct that is exactly large enough to contain the two specified points.
 /// </summary>
 /// <param name="p0">The first point that the new rectangle must contain.</param>
 /// <param name="p1">The second point that the new rectangle must contain.</param>
 public OxyRect(ScreenPoint p0, ScreenPoint p1)
     : this(Math.Min(p0.X, p1.X), Math.Min(p0.Y, p1.Y), Math.Abs(p1.X - p0.X), Math.Abs(p1.Y - p0.Y))
 {
 }
Ejemplo n.º 35
0
        /// <summary>
        /// Renders the annotation on the specified context.
        /// </summary>
        /// <param name="rc">The render context.</param>
        public override void Render(IRenderContext rc)
        {
            base.Render(rc);

            var lon0 = this.XAxis.ActualMinimum;
            var lon1 = this.XAxis.ActualMaximum;
            var lat0 = this.YAxis.ActualMinimum;
            var lat1 = this.YAxis.ActualMaximum;

            // the desired number of tiles horizontally
            double tilesx = this.PlotModel.Width / this.TileSize;

            // calculate the desired zoom level
            var n = tilesx / (((lon1 + 180) / 360) - ((lon0 + 180) / 360));
            var zoom = (int)Math.Round(Math.Log(n) / Math.Log(2));
            if (zoom < this.MinZoomLevel)
            {
                zoom = this.MinZoomLevel;
            }

            if (zoom > this.MaxZoomLevel)
            {
                zoom = this.MaxZoomLevel;
            }

            // find tile coordinates for the corners
            double x0, y0;
            LatLonToTile(lat0, lon0, zoom, out x0, out y0);
            double x1, y1;
            LatLonToTile(lat1, lon1, zoom, out x1, out y1);

            double xmax = Math.Max(x0, x1);
            double xmin = Math.Min(x0, x1);
            double ymax = Math.Max(y0, y1);
            double ymin = Math.Min(y0, y1);

            var clippingRectangle = this.GetClippingRect();

            // Add the tiles
            for (var x = (int)xmin; x < xmax; x++)
            {
                for (var y = (int)ymin; y < ymax; y++)
                {
                    string uri = this.GetTileUri(x, y, zoom);
                    var img = this.GetImage(uri, rc.RendersToScreen);

                    if (img == null)
                    {
                        continue;
                    }

                    // transform from tile coordinates to lat/lon
                    double latitude0, latitude1, longitude0, longitude1;
                    TileToLatLon(x, y, zoom, out latitude0, out longitude0);
                    TileToLatLon(x + 1, y + 1, zoom, out latitude1, out longitude1);

                    // transform from lat/lon to screen coordinates
                    var s00 = this.Transform(longitude0, latitude0);
                    var s11 = this.Transform(longitude1, latitude1);

                    var r = OxyRect.Create(s00.X, s00.Y, s11.X, s11.Y);

                    // draw the image
                    rc.DrawClippedImage(clippingRectangle, img, r.Left, r.Top, r.Width, r.Height, this.Opacity, true);
                }
            }

            // draw the copyright notice
            var p = new ScreenPoint(clippingRectangle.Right - 5, clippingRectangle.Bottom - 5);
            var textSize = rc.MeasureText(this.CopyrightNotice, this.ActualFont, this.ActualFontSize, this.ActualFontWeight);
            rc.DrawRectangle(new OxyRect(p.X - textSize.Width - 2, p.Y - textSize.Height - 2, textSize.Width + 4, textSize.Height + 4), OxyColor.FromAColor(200, OxyColors.White), OxyColors.Undefined);

            rc.DrawText(
                p,
                this.CopyrightNotice,
                OxyColors.Black,
                this.ActualFont,
                this.ActualFontSize,
                this.ActualFontWeight,
                0,
                HorizontalAlignment.Right,
                VerticalAlignment.Bottom);
        }
Ejemplo n.º 36
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OxyRect" /> struct that is exactly large enough to contain the two specified points.
 /// </summary>
 /// <param name="p0">The first point that the new rectangle must contain.</param>
 /// <param name="p1">The second point that the new rectangle must contain.</param>
 public OxyRect(ScreenPoint p0, ScreenPoint p1)
     : this(Math.Min(p0.X, p1.X), Math.Min(p0.Y, p1.Y), Math.Abs(p1.X - p0.X), Math.Abs(p1.Y - p0.Y))
 {
 }
Ejemplo n.º 37
0
        /// <summary>
        /// Gets the point on the series that is nearest the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
        /// <returns>A TrackerHitResult for the current hit.</returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            var points = this.Points;

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

            var spn = default(ScreenPoint);
            var dpn = default(DataPoint);
            double index = -1;

            double minimumDistance = double.MaxValue;

            for (int i = 0; i + 1 < points.Count; i += 2)
            {
                var p1 = points[i];
                var p2 = points[i + 1];
                if (!this.IsValidPoint(p1) || !this.IsValidPoint(p2))
                {
                    continue;
                }

                var sp1 = this.Transform(p1);
                var sp2 = this.Transform(p2);

                // Find the nearest point on the line segment.
                var spl = ScreenPointHelper.FindPointOnLine(point, sp1, sp2);

                if (ScreenPoint.IsUndefined(spl))
                {
                    // P1 && P2 coincident
                    continue;
                }

                double l2 = (point - spl).LengthSquared;

                if (l2 < minimumDistance)
                {
                    double u = (spl - sp1).Length / (sp2 - sp1).Length;
                    dpn = new DataPoint(p1.X + (u * (p2.X - p1.X)), p1.Y + (u * (p2.Y - p1.Y)));
                    spn = spl;
                    minimumDistance = l2;
                    index = i + u;
                }
            }

            if (minimumDistance < double.MaxValue)
            {
                return new TrackerHitResult
                {
                    Series = this,
                    DataPoint = dpn,
                    Position = spn,
                    Item = this.GetItem((int)index),
                    Index = index
                };
            }

            return null;
        }
Ejemplo n.º 38
0
        /// <summary>
        /// Renders the LineSeries on the specified rendering context.
        /// </summary>
        /// <param name="rc">
        /// The rendering context.
        /// </param>
        /// <param name="model">
        /// The owner plot model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            if (this.Points.Count == 0)
            {
                return;
            }

            if (this.XAxis == null || this.YAxis == null)
            {
                Trace("Axis not defined.");
                return;
            }

            double minDistSquared = this.MinimumSegmentLength * this.MinimumSegmentLength;

            var clippingRect = this.GetClippingRect();

            Action <IList <ScreenPoint>, IList <ScreenPoint> > renderPoints = (lpts, mpts) =>
            {
                var lineStyle = this.ActualLineStyle;

                // clip the line segments with the clipping rectangle
                if (this.StrokeThickness > 0 && lineStyle != LineStyle.None)
                {
                    var verticalStrokeThickness = double.IsNaN(this.VerticalStrokeThickness) ? StrokeThickness : VerticalStrokeThickness;
                    if (!verticalStrokeThickness.Equals(this.StrokeThickness) || this.VerticalLineStyle != lineStyle)
                    {
                        var hlpts = new List <ScreenPoint>();
                        var vlpts = new List <ScreenPoint>();
                        for (int i = 0; i + 2 < lpts.Count; i += 2)
                        {
                            hlpts.Add(lpts[i]);
                            hlpts.Add(lpts[i + 1]);
                            vlpts.Add(lpts[i + 1]);
                            vlpts.Add(lpts[i + 2]);
                        }

                        rc.DrawClippedLineSegments(
                            hlpts,
                            clippingRect,
                            this.GetSelectableColor(this.ActualColor),
                            this.StrokeThickness,
                            lineStyle,
                            this.LineJoin,
                            false);
                        rc.DrawClippedLineSegments(
                            vlpts,
                            clippingRect,
                            this.GetSelectableColor(this.ActualColor),
                            verticalStrokeThickness,
                            this.VerticalLineStyle,
                            this.LineJoin,
                            false);
                    }
                    else
                    {
                        rc.DrawClippedLine(
                            lpts,
                            clippingRect,
                            0,
                            this.GetSelectableColor(this.ActualColor),
                            this.StrokeThickness,
                            lineStyle,
                            this.LineJoin,
                            false);
                    }
                }

                if (this.MarkerType != MarkerType.None)
                {
                    rc.DrawMarkers(
                        mpts,
                        clippingRect,
                        this.MarkerType,
                        this.MarkerOutline,
                        new[] { this.MarkerSize },
                        this.MarkerFill,
                        this.MarkerStroke,
                        this.MarkerStrokeThickness);
                }
            };

            // Transform all points to screen coordinates
            // Render the line when invalid points occur
            var    linePoints   = new List <ScreenPoint>();
            var    markerPoints = new List <ScreenPoint>();
            double previousY    = double.NaN;

            foreach (var point in this.Points)
            {
                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
                {
                    renderPoints(linePoints, markerPoints);
                    linePoints.Clear();
                    markerPoints.Clear();
                    previousY = double.NaN;
                    continue;
                }

                ScreenPoint transformedPoint = this.Transform(point);
                if (!double.IsNaN(previousY))
                {
                    // Horizontal line from the previous point to the current x-coordinate
                    linePoints.Add(new ScreenPoint(transformedPoint.X, previousY));
                }

                linePoints.Add(transformedPoint);
                markerPoints.Add(transformedPoint);
                previousY = transformedPoint.Y;
            }

            renderPoints(linePoints, markerPoints);
        }
 /// <summary>
 /// Renders the legend symbol for the line series on the
 /// specified rendering context.
 /// </summary>
 /// <param name="rc">
 /// The rendering context.
 /// </param>
 /// <param name="legendBox">
 /// The bounding rectangle of the legend box.
 /// </param>
 public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 {
     double xmid = (legendBox.Left + legendBox.Right) / 2;
     double ymid = (legendBox.Top + legendBox.Bottom) / 2;
     var pts = new[] { new ScreenPoint(legendBox.Left, ymid), new ScreenPoint(legendBox.Right, ymid) };
     rc.DrawLine(pts, this.GetSelectableColor(this.ActualColor), this.StrokeThickness, LineStyleHelper.GetDashArray(this.ActualLineStyle));
     var midpt = new ScreenPoint(xmid, ymid);
     rc.DrawMarker(
         midpt,
         legendBox,
         this.MarkerType,
         this.MarkerOutline,
         this.MarkerSize,
         this.MarkerFill,
         this.MarkerStroke,
         this.MarkerStrokeThickness);
 }
        /// <summary>
        /// Gets the point on the series that is nearest the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
        /// <returns>
        /// A TrackerHitResult for the current hit.
        /// </returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            if (interpolate)
            {
                return null;
            }

            double minimumDistance = double.MaxValue;
            var result = new TrackerHitResult(this, DataPoint.Undefined, ScreenPoint.Undefined);

            Action<DataPoint, HighLowItem, int> check = (p, item, index) =>
                {
                    var sp = this.Transform(p);
                    double dx = sp.x - point.x;
                    double dy = sp.y - point.y;
                    double d2 = (dx * dx) + (dy * dy);

                    if (d2 < minimumDistance)
                    {
                        result.DataPoint = p;
                        result.Position = sp;
                        result.Item = item;
                        result.Index = index;
                        if (this.TrackerFormatString != null)
                        {
                            result.Text = StringHelper.Format(
                                this.ActualCulture,
                                this.TrackerFormatString,
                                item,
                                this.Title,
                                p.X,
                                item.High,
                                item.Low,
                                item.Open,
                                item.Close);
                        }

                        minimumDistance = d2;
                    }
                };
            int i = 0;
            foreach (var item in this.items)
            {
                check(new DataPoint(item.X, item.High), item, i);
                check(new DataPoint(item.X, item.Low), item, i);
                check(new DataPoint(item.X, item.Open), item, i);
                check(new DataPoint(item.X, item.Close), item, i++);
            }

            if (minimumDistance < double.MaxValue)
            {
                return result;
            }

            return null;
        }
Ejemplo n.º 41
0
 /// <summary>
 /// Determines whether the specified point is undefined.
 /// </summary>
 /// <param name="point">
 /// The point.
 /// </param>
 /// <returns>
 /// <c>true</c> if the specified point is undefined; otherwise, <c>false</c> .
 /// </returns>
 public static bool IsUndefined(ScreenPoint point)
 {
     return double.IsNaN(point.X) && double.IsNaN(point.Y);
 }
Ejemplo n.º 42
0
 /// <summary>
 /// Determines whether the specified point is inside the rectangle.
 /// </summary>
 /// <param name="p">The point.</param>
 /// <returns><c>true</c> if the rectangle contains the specified point; otherwise, <c>false</c>.</returns>
 public bool Contains(ScreenPoint p)
 {
     return(this.Contains(p.x, p.y));
 }
Ejemplo n.º 43
0
 /// <summary>
 /// Gets the squared distance to the specified point.
 /// </summary>
 /// <param name="point">
 /// The point.
 /// </param>
 /// <returns>
 /// The squared distance.
 /// </returns>
 public double DistanceToSquared(ScreenPoint point)
 {
     double dx = point.x - this.x;
     double dy = point.y - this.y;
     return (dx * dx) + (dy * dy);
 }
Ejemplo n.º 44
0
        /// <summary>
        /// Gets a series from the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="limit">The limit.</param>
        /// <returns>The nearest series.</returns>
        public Series.Series GetSeriesFromPoint(ScreenPoint point, double limit = 100)
        {
            double mindist = double.MaxValue;
            Series.Series nearestSeries = null;
            foreach (var series in this.Series.Reverse().Where(s => s.IsVisible))
            {
                var thr = series.GetNearestPoint(point, true) ?? series.GetNearestPoint(point, false);

                if (thr == null)
                {
                    continue;
                }

                // find distance to this point on the screen
                double dist = point.DistanceTo(thr.Position);
                if (dist < mindist)
                {
                    nearestSeries = series;
                    mindist = dist;
                }
            }

            if (mindist < limit)
            {
                return nearestSeries;
            }

            return null;
        }
Ejemplo n.º 45
0
 /// <summary>
 /// Determines whether the specified point is inside the rectangle.
 /// </summary>
 /// <param name="p">The point.</param>
 /// <returns><c>true</c> if the rectangle contains the specified point; otherwise, <c>false</c>.</returns>
 public bool Contains(ScreenPoint p)
 {
     return this.Contains(p.x, p.y);
 }
        /// <summary>
        /// Renders the point labels.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rect.</param>
        protected void RenderPointLabels(IRenderContext rc, OxyRect clippingRect)
        {
            int index = -1;

            foreach (var point in this.Points)
            {
                index++;

                if (!this.IsValidPoint(point, this.XAxis, this.YAxis))
                {
                    continue;
                }

                var pt = this.XAxis.Transform(point.X, point.Y, this.YAxis);
                pt.Y -= this.LabelMargin;

                if (!clippingRect.Contains(pt))
                {
                    continue;
                }

                var s = StringHelper.Format(
                    this.ActualCulture, this.LabelFormatString, this.GetItem(index), point.X, point.Y);

#if SUPPORTLABELPLACEMENT
                switch (this.LabelPlacement)
                {
                case LabelPlacement.Inside:
                    pt = new ScreenPoint(rect.Right - this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                    ha = HorizontalTextAlign.Right;
                    break;

                case LabelPlacement.Middle:
                    pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2);
                    ha = HorizontalTextAlign.Center;
                    break;

                case LabelPlacement.Base:
                    pt = new ScreenPoint(rect.Left + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                    ha = HorizontalTextAlign.Left;
                    break;

                default:         // Outside
                    pt = new ScreenPoint(rect.Right + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                    ha = HorizontalTextAlign.Left;
                    break;
                }
#endif

                rc.DrawClippedText(
                    clippingRect,
                    pt,
                    s,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    0,
                    HorizontalTextAlign.Center,
                    VerticalTextAlign.Bottom);
            }
        }
Ejemplo n.º 47
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OxyRect"/> struct by location and size.
 /// </summary>
 /// <param name="p0">The location.</param>
 /// <param name="size">The size.</param>
 public OxyRect(ScreenPoint p0, OxySize size)
     : this(p0.X, p0.Y, size.Width, size.Height)
 {
 }
Ejemplo n.º 48
0
        /// <summary>
        /// Gets the point on the curve that is nearest the specified point.
        /// </summary>
        /// <param name = "point">The point.</param>
        /// <param name = "dpn">The nearest point (data coordinates).</param>
        /// <param name = "spn">The nearest point (screen coordinates).</param>
        /// <returns></returns>
        protected bool GetNearestInterpolatedPointInternal(
            IList <IDataPoint> points, ScreenPoint point, out DataPoint dpn, out ScreenPoint spn, out int index)
        {
            spn   = default(ScreenPoint);
            dpn   = default(DataPoint);
            index = -1;

            // http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
            double minimumDistance = double.MaxValue;

            for (int i = 0; i + 1 < points.Count; i++)
            {
                IDataPoint  p1  = points[i];
                IDataPoint  p2  = points[i + 1];
                ScreenPoint sp1 = AxisBase.Transform(p1, this.XAxis, this.YAxis);
                ScreenPoint sp2 = AxisBase.Transform(p2, this.XAxis, this.YAxis);

                double sp21X = sp2.x - sp1.x;
                double sp21Y = sp2.y - sp1.y;
                double u1    = (point.x - sp1.x) * sp21X + (point.y - sp1.y) * sp21Y;
                double u2    = sp21X * sp21X + sp21Y * sp21Y;
                double ds    = sp21X * sp21X + sp21Y * sp21Y;

                if (ds < 4)
                {
                    // if the points are very close, we can get numerical problems, just use the first point...
                    u1 = 0;
                    u2 = 1;
                }

                if (u2 < double.Epsilon && u2 > -double.Epsilon)
                {
                    continue; // P1 && P2 coincident
                }

                double u = u1 / u2;
                if (u < 0)
                {
                    u = 0;
                }
                if (u > 1)
                {
                    u = 1;
                }

                double sx = sp1.x + u * sp21X;
                double sy = sp1.y + u * sp21Y;

                double dx       = point.x - sx;
                double dy       = point.y - sy;
                double distance = dx * dx + dy * dy;

                if (distance < minimumDistance)
                {
                    double px = p1.X + u * (p2.X - p1.X);
                    double py = p1.Y + u * (p2.Y - p1.Y);
                    dpn             = new DataPoint(px, py);
                    spn             = new ScreenPoint(sx, sy);
                    minimumDistance = distance;
                    index           = i;
                }
            }

            return(minimumDistance < double.MaxValue);
        }