コード例 #1
0
        /// <summary>
        /// Renders the transformed points.
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="clippingRect">
        /// The clipping rect.
        /// </param>
        /// <param name="pointsToRender">
        /// The points to render.
        /// </param>
        protected void RenderPoints(IRenderContext rc, OxyRect clippingRect, IList <ScreenPoint> pointsToRender)
        {
            var screenPoints = pointsToRender;

            if (this.Smooth)
            {
                // spline smoothing (should only be used on small datasets)
                var resampledPoints = ScreenPointHelper.ResamplePoints(pointsToRender, this.MinimumSegmentLength);
                screenPoints = CanonicalSplineHelper.CreateSpline(resampledPoints, 0.5, null, false, 0.25);
            }

            // clip the line segments with the clipping rectangle
            if (this.StrokeThickness > 0 && this.ActualLineStyle != LineStyle.None)
            {
                this.RenderSmoothedLine(rc, clippingRect, screenPoints);
            }

            if (this.MarkerType != MarkerType.None)
            {
                rc.DrawMarkers(
                    pointsToRender,
                    clippingRect,
                    this.MarkerType,
                    this.MarkerOutline,
                    new[] { this.MarkerSize },
                    this.MarkerFill,
                    this.MarkerStroke,
                    this.MarkerStrokeThickness);
            }
        }
コード例 #2
0
        /// <summary>
        /// Tests if the plot element is hit by the specified point.
        /// </summary>
        /// <param name="point">
        /// The point.
        /// </param>
        /// <param name="tolerance">
        /// The tolerance.
        /// </param>
        /// <returns>
        /// A hit test result.
        /// </returns>
        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
        {
            if (ScreenPointHelper.IsPointInPolygon(point, this.screenPoints))
            {
                return(new HitTestResult(point));
            }

            return(null);
        }
コード例 #3
0
        /// <summary>
        /// Gets the point on the curve that is nearest the specified point.
        /// </summary>
        /// <param name="points">
        /// The point list.
        /// </param>
        /// <param name="point">
        /// The point.
        /// </param>
        /// <returns>
        /// A tracker hit result if a point was found.
        /// </returns>
        protected TrackerHitResult GetNearestInterpolatedPointInternal(IList <IDataPoint> points, ScreenPoint point)
        {
            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++)
            {
                var p1 = points[i];
                var p2 = points[i + 1];
                if (!this.IsValidPoint(p1, this.XAxis, this.YAxis) || !this.IsValidPoint(p2, this.XAxis, this.YAxis))
                {
                    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)
            {
                object item = this.GetItem((int)index);
                return(new TrackerHitResult(this, dpn, spn, item)
                {
                    Index = index
                });
            }

            return(null);
        }
コード例 #4
0
        /// <summary>
        /// Tests if the plot element is hit by the specified point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <param name="tolerance">The tolerance.</param>
        /// <returns>
        /// A hit test result.
        /// </returns>
        protected internal override HitTestResult HitTest(ScreenPoint point, double tolerance)
        {
            var    nearestPoint = ScreenPointHelper.FindNearestPointOnPolyline(point, this.screenPoints);
            double dist         = (point - nearestPoint).Length;

            if (dist < tolerance)
            {
                return(new HitTestResult(nearestPoint));
            }

            return(null);
        }
コード例 #5
0
        /// <summary>
        /// Renders the polygon annotation.
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="model">
        /// The plot model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            base.Render(rc, model);
            if (this.Points == null)
            {
                return;
            }

            // transform to screen coordinates
            this.screenPoints = this.Points.Select(p => this.Transform(p)).ToList();
            if (this.screenPoints.Count == 0)
            {
                return;
            }

            // clip to the area defined by the axes
            var clipping = this.GetClippingRect();

            const double MinimumSegmentLength = 4;

            rc.DrawClippedPolygon(
                this.screenPoints,
                clipping,
                MinimumSegmentLength * MinimumSegmentLength,
                this.GetSelectableFillColor(this.Fill),
                this.GetSelectableColor(this.Color),
                this.StrokeThickness,
                this.LineStyle,
                this.LineJoin);

            if (!string.IsNullOrEmpty(this.Text))
            {
                var textPosition = ScreenPointHelper.GetCentroid(this.screenPoints);

                rc.DrawClippedText(
                    clipping,
                    textPosition,
                    this.Text,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    0,
                    HorizontalTextAlign.Center,
                    VerticalTextAlign.Middle);
            }
        }
コード例 #6
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)
        {
            if (interpolate)
            {
                return(null);
            }

            TrackerHitResult result = null;

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

            for (int i = 0; i < points.Count; i++)
            {
                var p1        = points[i];
                var basePoint = new DataPoint(p1.X, this.Base);
                var sp1       = this.Transform(p1);
                var sp2       = this.Transform(basePoint);
                var u         = ScreenPointHelper.FindPositionOnLine(point, sp1, sp2);

                if (double.IsNaN(u))
                {
                    continue;
                }

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

                var    sp       = sp1 + ((sp2 - sp1) * u);
                double distance = (point - sp).LengthSquared;

                if (distance < minimumDistance)
                {
                    result = new TrackerHitResult(
                        this,
                        new DataPoint(p1.X, p1.Y),
                        new ScreenPoint(sp1.x, sp1.y),
                        this.GetItem(i));
                    minimumDistance = distance;
                }
            }

            return(result);
        }
コード例 #7
0
        /// <summary>
        /// Gets the nearest point.
        /// </summary>
        /// <param name="point">
        /// The point.
        /// </param>
        /// <param name="interpolate">
        /// interpolate if set to <c>true</c> .
        /// </param>
        /// <returns>
        /// A TrackerHitResult for the current hit.
        /// </returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            double minimumDistance = double.MaxValue;
            var    result          = new TrackerHitResult(this, DataPoint.Undefined, ScreenPoint.Undefined);

            foreach (var item in this.Items)
            {
                foreach (var outlier in item.Outliers)
                {
                    var    sp = this.Transform(item.X, outlier);
                    double d  = (sp - point).LengthSquared;
                    if (d < minimumDistance)
                    {
                        result.DataPoint = new DataPoint(item.X, outlier);
                        result.Position  = sp;
                        result.Item      = item;
                        result.Text      = StringHelper.Format(
                            this.ActualCulture,
                            this.OutlierTrackerFormatString,
                            item,
                            this.Title,
                            result.DataPoint.X,
                            outlier);
                        minimumDistance = d;
                    }
                }

                // check if we are inside the box rectangle
                var rect = this.GetBoxRect(item);
                if (rect.Contains(point))
                {
                    result.DataPoint = new DataPoint(item.X, this.YAxis.InverseTransform(point.Y));
                    result.Position  = this.Transform(result.DataPoint);
                    result.Item      = item;

                    result.Text = StringHelper.Format(
                        this.ActualCulture,
                        this.TrackerFormatString,
                        item,
                        this.Title,
                        result.DataPoint.X,
                        item.UpperWhisker,
                        item.BoxTop,
                        item.Median,
                        item.BoxBottom,
                        item.LowerWhisker);

                    minimumDistance = 0;
                }

                var topWhisker    = this.Transform(item.X, item.UpperWhisker);
                var bottomWhisker = this.Transform(item.X, item.LowerWhisker);

                // check if we are near the line
                var    p  = ScreenPointHelper.FindPointOnLine(point, topWhisker, bottomWhisker);
                double d2 = (p - point).LengthSquared;
                if (d2 < minimumDistance)
                {
                    result.DataPoint = this.InverseTransform(p);
                    result.Position  = this.Transform(result.DataPoint);
                    result.Item      = item;
                    result.Text      = StringHelper.Format(
                        this.ActualCulture,
                        this.TrackerFormatString,
                        item,
                        this.Title,
                        result.DataPoint.X,
                        item.UpperWhisker,
                        item.BoxTop,
                        item.Median,
                        item.BoxBottom,
                        item.LowerWhisker);
                    minimumDistance = d2;
                }
            }

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

            return(null);
        }
コード例 #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 (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();

            // Transform all points to screen coordinates
            var points = this.Points;
            int n0     = points.Count;
            IList <ScreenPoint> pts0 = new ScreenPoint[n0];

            for (int i = 0; i < n0; i++)
            {
                pts0[i] = this.XAxis.Transform(points[i].X, points[i].Y, this.YAxis);
            }

            int n1 = this.points2.Count;
            IList <ScreenPoint> pts1 = new ScreenPoint[n1];

            for (int i = 0; i < n1; i++)
            {
                int j = this.Reverse2 ? n1 - 1 - i : i;
                pts1[j] = this.XAxis.Transform(this.points2[i].X, this.points2[i].Y, this.YAxis);
            }

            if (this.Smooth)
            {
                var rpts0 = ScreenPointHelper.ResamplePoints(pts0, this.MinimumSegmentLength);
                var rpts1 = ScreenPointHelper.ResamplePoints(pts1, this.MinimumSegmentLength);

                pts0 = CanonicalSplineHelper.CreateSpline(rpts0, 0.5, null, false, 0.25);
                pts1 = CanonicalSplineHelper.CreateSpline(rpts1, 0.5, null, false, 0.25);
            }

            // draw the clipped lines
            rc.DrawClippedLine(
                pts0,
                clippingRect,
                minDistSquared,
                this.GetSelectableColor(this.ActualColor),
                this.StrokeThickness,
                this.ActualLineStyle,
                this.LineJoin,
                false);
            rc.DrawClippedLine(
                pts1,
                clippingRect,
                minDistSquared,
                this.GetSelectableColor(this.ActualColor),
                this.StrokeThickness,
                this.ActualLineStyle,
                this.LineJoin,
                false);

            // combine the two lines and draw the clipped area
            var pts = new List <ScreenPoint>();

            pts.AddRange(pts1);
            pts.AddRange(pts0);

            // pts = SutherlandHodgmanClipping.ClipPolygon(clippingRect, pts);
            rc.DrawClippedPolygon(pts, clippingRect, minDistSquared, this.GetSelectableFillColor(this.Fill), null);

            // draw the markers on top
            rc.DrawMarkers(
                pts0,
                clippingRect,
                this.MarkerType,
                null,
                new[] { this.MarkerSize },
                this.MarkerFill,
                this.MarkerStroke,
                this.MarkerStrokeThickness,
                1);
            rc.DrawMarkers(
                pts1,
                clippingRect,
                this.MarkerType,
                null,
                new[] { this.MarkerSize },
                this.MarkerFill,
                this.MarkerStroke,
                this.MarkerStrokeThickness,
                1);
        }