コード例 #1
0
ファイル: HeatMapSeries.cs プロジェクト: ylatuya/oxyplot
        /// <summary>
        /// Renders the series on the specified render context.
        /// </summary>
        /// <param name="rc">
        /// The rendering context.
        /// </param>
        /// <param name="model">
        /// The model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            if (this.Data == null)
            {
                this.image = null;
                return;
            }

            int    m      = this.Data.GetLength(0);
            int    n      = this.Data.GetLength(1);
            double dx     = (this.X1 - this.X0) / m;
            double left   = this.X0 - (dx * 0.5);
            double right  = this.X1 + (dx * 0.5);
            double dy     = (this.Y1 - this.Y0) / n;
            double bottom = this.Y0 - (dy * 0.5);
            double top    = this.Y1 + (dy * 0.5);
            var    s00    = this.Transform(left, bottom);
            var    s11    = this.Transform(right, top);
            var    rect   = OxyRect.Create(s00, s11);

            if (this.image == null || this.Data.GetHashCode() != this.dataHash)
            {
                this.UpdateImage();
                this.dataHash = this.Data.GetHashCode();
            }

            if (this.image != null)
            {
                var clip = this.GetClippingRect();
                rc.DrawClippedImage(clip, this.image, rect.Left, rect.Top, rect.Width, rect.Height, 1, true);
            }
        }
コード例 #2
0
ファイル: EllipseAnnotation.cs プロジェクト: ylatuya/oxyplot
        /// <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);

            this.screenRectangle = OxyRect.Create(this.Transform(this.X - (Width / 2), Y - (Height / 2)), this.Transform(X + (Width / 2), Y + (Height / 2)));

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

            rc.DrawClippedEllipse(clipping, this.screenRectangle, this.Fill, this.Stroke, this.StrokeThickness);

            if (!string.IsNullOrEmpty(this.Text))
            {
                var textPosition = this.screenRectangle.Center;
                rc.DrawClippedText(
                    clipping,
                    textPosition,
                    this.Text,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    this.TextRotation,
                    HorizontalAlignment.Center,
                    VerticalAlignment.Middle);
            }
        }
コード例 #3
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);

            double x0 = double.IsNaN(this.MinimumX) || this.MinimumX.Equals(double.MinValue) ? this.XAxis.ActualMinimum : this.MinimumX;
            double x1 = double.IsNaN(this.MaximumX) || this.MaximumX.Equals(double.MaxValue) ? this.XAxis.ActualMaximum : this.MaximumX;
            double y0 = double.IsNaN(this.MinimumY) || this.MinimumY.Equals(double.MinValue) ? this.YAxis.ActualMinimum : this.MinimumY;
            double y1 = double.IsNaN(this.MaximumY) || this.MaximumY.Equals(double.MaxValue) ? this.YAxis.ActualMaximum : this.MaximumY;

            this.screenRectangle = OxyRect.Create(this.Transform(x0, y0), this.Transform(x1, y1));

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

            rc.DrawClippedRectangle(this.screenRectangle, clipping, this.Fill, null, 0);

            if (!string.IsNullOrEmpty(this.Text))
            {
                var textPosition = this.screenRectangle.Center;
                rc.DrawClippedText(
                    clipping,
                    textPosition,
                    this.Text,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    this.TextRotation,
                    HorizontalTextAlign.Center,
                    VerticalTextAlign.Middle);
            }
        }
コード例 #4
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.ActualBarRectangles = new List <OxyRect>();

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

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

            var actualBarWidth = this.GetActualBarWidth();
            var stackIndex     = categoryAxis.StackIndexMapping[this.StackGroup];

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

                var    categoryIndex = item.GetCategoryIndex(i);
                double categoryValue = categoryAxis.GetCategoryValue(categoryIndex, stackIndex, actualBarWidth);

                var p0 = this.Transform(item.Start, categoryValue);
                var p1 = this.Transform(item.End, categoryValue + actualBarWidth);

                var rectangle = OxyRect.Create(p0.X, p0.Y, p1.X, p1.Y);

                this.ActualBarRectangles.Add(rectangle);

                rc.DrawClippedRectangleAsPolygon(
                    rectangle,
                    clippingRect,
                    this.GetSelectableFillColor(item.Color ?? this.ActualFillColor),
                    this.StrokeColor,
                    this.StrokeThickness);

                if (this.LabelFormatString != null)
                {
                    var s = StringHelper.Format(
                        this.ActualCulture, this.LabelFormatString, this.GetItem(i), item.Start, item.End, item.Title);

                    var pt = new ScreenPoint(
                        (rectangle.Left + rectangle.Right) / 2, (rectangle.Top + rectangle.Bottom) / 2);

                    rc.DrawClippedText(
                        clippingRect,
                        pt,
                        s,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        0,
                        HorizontalAlignment.Center,
                        VerticalAlignment.Middle);
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Renders the rectangle annotation.
        /// </summary>
        /// <param name="rc">The render context.</param>
        public override void Render(IRenderContext rc)
        {
            base.Render(rc);

            double x0 = double.IsNaN(this.MinimumX) || this.MinimumX.Equals(double.MinValue)
                            ? this.ClipByXAxis
                                ? this.XAxis.ActualMinimum
                                : this.XAxis.InverseTransform(this.PlotModel.PlotArea.Left)
                            : this.MinimumX;
            double x1 = double.IsNaN(this.MaximumX) || this.MaximumX.Equals(double.MaxValue)
                            ? this.ClipByXAxis
                                ? this.XAxis.ActualMaximum
                                : this.XAxis.InverseTransform(this.PlotModel.PlotArea.Right)
                            : this.MaximumX;
            double y0 = double.IsNaN(this.MinimumY) || this.MinimumY.Equals(double.MinValue)
                            ? this.ClipByYAxis
                                ? this.YAxis.ActualMinimum
                                : this.YAxis.InverseTransform(this.PlotModel.PlotArea.Bottom)
                            : this.MinimumY;
            double y1 = double.IsNaN(this.MaximumY) || this.MaximumY.Equals(double.MaxValue)
                            ? this.ClipByYAxis
                                ? this.YAxis.ActualMaximum
                                : this.YAxis.InverseTransform(this.PlotModel.PlotArea.Top)
                            : this.MaximumY;

            this.screenRectangle = new OxyRect(this.Transform(x0, y0), this.Transform(x1, y1));

            // clip to the area defined by the axes
            var clippingRectangle = OxyRect.Create(
                this.ClipByXAxis ? this.XAxis.ScreenMin.X : this.PlotModel.PlotArea.Left,
                this.ClipByYAxis ? this.YAxis.ScreenMin.Y : this.PlotModel.PlotArea.Top,
                this.ClipByXAxis ? this.XAxis.ScreenMax.X : this.PlotModel.PlotArea.Right,
                this.ClipByYAxis ? this.YAxis.ScreenMax.Y : this.PlotModel.PlotArea.Bottom);

            rc.DrawClippedRectangle(
                clippingRectangle,
                this.screenRectangle,
                this.GetSelectableFillColor(this.Fill),
                this.GetSelectableColor(this.Stroke),
                this.StrokeThickness);

            if (!string.IsNullOrEmpty(this.Text))
            {
                var textPosition = this.GetActualTextPosition(() => this.screenRectangle.Center);
                rc.DrawClippedText(
                    clippingRectangle,
                    textPosition,
                    this.Text,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    this.TextRotation,
                    HorizontalAlignment.Center,
                    VerticalAlignment.Middle);
            }
        }
コード例 #6
0
        public void Render_MultipleNonEmptyLine_RendersTheLines(LineStyle?style, double[] dashes)
        {
            // Setup
            var random    = new Random(21);
            int lineCount = random.Next(5, 455);
            var series    = new MultipleLineSeries();

            if (style.HasValue)
            {
                series.LineStyle = style.Value;
            }

            series.Dashes = dashes;
            var model = new PlotModel();

            model.Series.Add(series);

            var mocks         = new MockRepository();
            var renderContext = mocks.StrictMock <IRenderContext>();

            renderContext.Stub(rc => rc.SetClip(OxyRect.Create(0, 0, 0, 0))).Return(true);
            renderContext.Stub(rc => rc.ResetClip());
            renderContext.Expect(rc => rc.DrawLine(
                                     Arg <ScreenPoint[]> .Matches(sp => sp.Length == 1),
                                     Arg <OxyColor> .Is.Equal(series.Color),
                                     Arg <double> .Is.Equal(series.StrokeThickness),
                                     Arg <double[]> .Is.Equal(dashes ?? style.Value.GetDashArray()),
                                     Arg <LineJoin> .Is.Anything,
                                     Arg <bool> .Is.Anything)).Repeat.Times(lineCount);

            mocks.ReplayAll();

            for (var i = 0; i < lineCount; i++)
            {
                series.Lines.Add(new[]
                {
                    new DataPoint(random.Next(-50, 50), random.Next(-50, 50))
                });
            }

            ((IPlotModel)model).Update(false);

            // Call
            series.Render(renderContext);

            // Assert
            mocks.VerifyAll();
        }
コード例 #7
0
        public void Render_MultipleNonEmptyArea_RendersTheAreas()
        {
            // Setup
            var random    = new Random(21);
            int areaCount = random.Next(5, 455);
            var series    = new MultipleAreaSeries();
            var model     = new PlotModel();

            model.Series.Add(series);

            var mocks         = new MockRepository();
            var renderContext = mocks.StrictMock <IRenderContext>();

            renderContext.Stub(rc => rc.SetClip(OxyRect.Create(0, 0, 0, 0))).Return(true);
            renderContext.Stub(rc => rc.ResetClip());
            renderContext.Expect(rc => rc.DrawPolygon(
                                     Arg <ScreenPoint[]> .Matches(sp => sp.Length == 1),
                                     Arg <OxyColor> .Is.Equal(series.Fill),
                                     Arg <OxyColor> .Is.Equal(series.Color),
                                     Arg <double> .Is.Equal(series.StrokeThickness),
                                     Arg <double[]> .Is.Anything,
                                     Arg <LineJoin> .Is.Anything,
                                     Arg <bool> .Is.Anything)).Repeat.Times(areaCount);

            mocks.ReplayAll();

            for (var i = 0; i < areaCount; i++)
            {
                series.Areas.Add(new[]
                {
                    new DataPoint(random.Next(-50, 50), random.Next(-50, 50))
                });
            }

            ((IPlotModel)model).Update(false);

            // Call
            series.Render(renderContext);

            // Assert
            mocks.VerifyAll();
        }
コード例 #8
0
        /// <summary>
        /// Renders the annotation on the specified context.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="model">The model.</param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            base.Render(rc, model);

            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 = model.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);
        }
コード例 #9
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);

            this.CalculateActualMinimumsMaximums();

            this.screenPoints = this.GetScreenPoints();

            // clip to the area defined by the axes
            var clippingRectangle = OxyRect.Create(
                this.ClipByXAxis ? this.XAxis.ScreenMin.X : this.PlotModel.PlotArea.Left,
                this.ClipByYAxis ? this.YAxis.ScreenMin.Y : this.PlotModel.PlotArea.Top,
                this.ClipByXAxis ? this.XAxis.ScreenMax.X : this.PlotModel.PlotArea.Right,
                this.ClipByYAxis ? this.YAxis.ScreenMax.Y : this.PlotModel.PlotArea.Bottom);

            const double MinimumSegmentLength = 4;

            var clippedPoints = new List <ScreenPoint>();
            var dashArray     = this.LineStyle.GetDashArray();

            if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
            {
                rc.DrawClippedLine(
                    clippingRectangle,
                    this.screenPoints,
                    MinimumSegmentLength * MinimumSegmentLength,
                    this.GetSelectableColor(this.Color),
                    this.StrokeThickness,
                    dashArray,
                    this.LineJoin,
                    this.Aliased,
                    null,
                    clippedPoints.AddRange);
            }

            ScreenPoint position;
            double      angle;
            double      margin = this.TextMargin;

            if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
            {
                margin = 0;
            }
            else
            {
                margin *= this.TextLinePosition < 0.5 ? 1 : -1;
            }

            if (GetPointAtRelativeDistance(clippedPoints, this.TextLinePosition, margin, out position, out angle))
            {
                if (angle < -90)
                {
                    angle += 180;
                }

                if (angle > 90)
                {
                    angle -= 180;
                }

                switch (this.TextOrientation)
                {
                case AnnotationTextOrientation.Horizontal:
                    angle = 0;
                    break;

                case AnnotationTextOrientation.Vertical:
                    angle = -90;
                    break;
                }

                // Apply 'padding' to the position
                var angleInRadians = angle / 180 * Math.PI;
                var f = 1;

                if (this.TextHorizontalAlignment == HorizontalAlignment.Right)
                {
                    f = -1;
                }

                if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
                {
                    f = 0;
                }

                position += new ScreenVector(f * this.TextPadding * Math.Cos(angleInRadians), f * this.TextPadding * Math.Sin(angleInRadians));

                if (!string.IsNullOrEmpty(this.Text))
                {
                    var textPosition = this.GetActualTextPosition(() => position);

                    if (this.TextPosition.IsDefined())
                    {
                        angle = this.TextRotation;
                    }

                    if (this.ClipText)
                    {
                        var cs = new CohenSutherlandClipping(clippingRectangle);
                        if (cs.IsInside(position))
                        {
                            rc.DrawClippedText(
                                clippingRectangle,
                                textPosition,
                                this.Text,
                                this.ActualTextColor,
                                this.ActualFont,
                                this.ActualFontSize,
                                this.ActualFontWeight,
                                angle,
                                this.TextHorizontalAlignment,
                                this.TextVerticalAlignment);
                        }
                    }
                    else
                    {
                        rc.DrawText(
                            textPosition,
                            this.Text,
                            this.ActualTextColor,
                            this.ActualFont,
                            this.ActualFontSize,
                            this.ActualFontWeight,
                            angle,
                            this.TextHorizontalAlignment,
                            this.TextVerticalAlignment);
                    }
                }
            }
        }
コード例 #10
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)
        {
            if (this.Items.Count == 0)
            {
                return;
            }

            var clippingRect = this.GetClippingRect();

            int i = 0;

            this.ActualBarRectangles = new List <OxyRect>();

            foreach (var item in this.Items)
            {
                if (!this.IsValid(item.X0) || !this.IsValid(item.X1) ||
                    !this.IsValid(item.Y0) || !this.IsValid(item.Y1))
                {
                    continue;
                }

                var p0 = this.Transform(item.X0, item.Y0);
                var p1 = this.Transform(item.X1, item.Y1);

                var rectangle = OxyRect.Create(p0.X, p0.Y, p1.X, p1.Y);

                this.ActualBarRectangles.Add(rectangle);

                rc.DrawClippedRectangleAsPolygon(
                    clippingRect,
                    rectangle,
                    this.GetSelectableFillColor(item.Color.GetActualColor(this.ActualFillColor)),
                    this.StrokeColor,
                    this.StrokeThickness);

                if (this.LabelFormatString != null)
                {
                    var s = this.Format(
                        this.LabelFormatString,
                        this.GetItem(i),
                        item.X0,
                        item.X1,
                        item.Y0,
                        item.Y1,
                        item.Title);

                    var pt = new ScreenPoint(
                        (rectangle.Left + rectangle.Right) / 2, (rectangle.Top + rectangle.Bottom) / 2);

                    rc.DrawClippedText(
                        clippingRect,
                        pt,
                        s,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        0,
                        HorizontalAlignment.Center,
                        VerticalAlignment.Middle);
                }

                i++;
            }
        }
コード例 #11
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 barOffset = categoryAxis.GetCurrentBarOffset(categoryIndex);
                var p0        = this.Transform(item.Minimum, categoryIndex - 0.5 + barOffset);
                var p1        = this.Transform(item.Maximum, categoryIndex - 0.5 + barOffset + actualBarWidth);
                var p2        = this.Transform(baseValue, categoryIndex - 0.5 + barOffset);
                p2 = new ScreenPoint((int)p2.X, p2.Y);

                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(
                    clippingRect,
                    minimumRectangle,
                    item.MinimumColor.GetActualColor(this.ActualMinimumFillColor),
                    this.StrokeColor,
                    this.StrokeThickness);
                rc.DrawClippedRectangleAsPolygon(
                    clippingRect,
                    maximumRectangle,
                    item.MaximumColor.GetActualColor(this.ActualMaximumFillColor),
                    this.StrokeColor,
                    this.StrokeThickness);

                if (this.MinimumLabelFormatString != null)
                {
                    var s = this.Format(
                        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,
                        HorizontalAlignment.Right,
                        VerticalAlignment.Middle);
                }

                if (this.MaximumLabelFormatString != null)
                {
                    var s = this.Format(
                        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,
                        HorizontalAlignment.Left,
                        VerticalAlignment.Middle);
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Renders the series on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        public override void Render(IRenderContext rc)
        {
            if (this.Items.Count == 0)
            {
                return;
            }

            var clippingRect = this.GetClippingRect();

            int    startIdx = 0;
            double xmax     = double.MaxValue;

            this.ActualBarRectangles = new List <OxyRect>();

            if (this.IsXMonotonic)
            {
                var xmin = this.XAxis.ActualMinimum;
                xmax = this.XAxis.ActualMaximum;
                this.WindowStartIndex = this.UpdateWindowStartIndex(this.Items, rect => rect.X0, xmin, this.WindowStartIndex);

                startIdx = this.WindowStartIndex;
            }

            int clipCount = 0;

            for (int i = startIdx; i < this.Items.Count; i++)
            {
                var item = this.Items[i];
                if (!this.IsValid(item.X0) || !this.IsValid(item.X1) ||
                    !this.IsValid(item.Y0) || !this.IsValid(item.Y1))
                {
                    continue;
                }

                var p0 = this.Transform(item.X0, item.Y0);
                var p1 = this.Transform(item.X1, item.Y1);

                var rectangle = OxyRect.Create(p0.X, p0.Y, p1.X, p1.Y);

                this.ActualBarRectangles.Add(rectangle);

                rc.DrawClippedRectangleAsPolygon(
                    clippingRect,
                    rectangle,
                    this.GetSelectableFillColor(item.Color.GetActualColor(this.ActualFillColor)),
                    this.StrokeColor,
                    this.StrokeThickness);

                if (this.LabelFormatString != null)
                {
                    var s = StringHelper.Format(
                        this.ActualCulture,
                        this.LabelFormatString,
                        this.GetItem(i),
                        item.X0,
                        item.X1,
                        item.Y0,
                        item.Y1,
                        item.Title);

                    var pt = new ScreenPoint(
                        (rectangle.Left + rectangle.Right) / 2, (rectangle.Top + rectangle.Bottom) / 2);

                    rc.DrawClippedText(
                        clippingRect,
                        pt,
                        s,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        0,
                        HorizontalAlignment.Center,
                        VerticalAlignment.Middle);
                }

                clipCount += item.X0 > xmax ? 1 : 0;
                if (clipCount > 1)
                {
                    break;
                }
            }
        }
コード例 #13
0
 /// <summary>
 /// Gets the rectangle for the specified values.
 /// </summary>
 /// <param name="baseValue">
 /// The base value of the bar
 /// </param>
 /// <param name="topValue">
 /// The top value of the bar
 /// </param>
 /// <param name="beginValue">
 /// The begin value of the bar
 /// </param>
 /// <param name="endValue">
 /// The end value of the bar
 /// </param>
 /// <returns>
 /// The rectangle.
 /// </returns>
 protected override OxyRect GetRectangle(double baseValue, double topValue, double beginValue, double endValue)
 {
     return(OxyRect.Create(this.Transform(baseValue, beginValue), this.Transform(topValue, endValue)));
 }
コード例 #14
0
ファイル: LineAnnotation.cs プロジェクト: ylatuya/oxyplot
        /// <summary>
        /// Renders the line 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);

            bool aliased = false;

            double actualMinimumX = Math.Max(this.MinimumX, this.XAxis.ActualMinimum);
            double actualMaximumX = Math.Min(this.MaximumX, this.XAxis.ActualMaximum);
            double actualMinimumY = Math.Max(this.MinimumY, this.YAxis.ActualMinimum);
            double actualMaximumY = Math.Min(this.MaximumY, this.YAxis.ActualMaximum);

            if (!this.ClipByXAxis)
            {
                double right = XAxis.InverseTransform(PlotModel.PlotArea.Right);
                double left  = XAxis.InverseTransform(PlotModel.PlotArea.Left);
                actualMaximumX = Math.Max(left, right);
                actualMinimumX = Math.Min(left, right);
            }

            if (!this.ClipByYAxis)
            {
                double bottom = YAxis.InverseTransform(PlotModel.PlotArea.Bottom);
                double top    = YAxis.InverseTransform(PlotModel.PlotArea.Top);
                actualMaximumY = Math.Max(top, bottom);
                actualMinimumY = Math.Min(top, bottom);
            }

            // y=f(x)
            Func <double, double> fx = null;

            // x=f(y)
            Func <double, double> fy = null;

            switch (this.Type)
            {
            case LineAnnotationType.Horizontal:
                fx = x => this.Y;
                break;

            case LineAnnotationType.Vertical:
                fy = y => this.X;
                break;

            case LineAnnotationType.EquationY:
                fx = this.Equation;
                break;

            case LineAnnotationType.EquationX:
                fy = this.Equation;
                break;

            default:
                fx = x => (this.Slope * x) + this.Intercept;
                break;
            }

            var points = new List <DataPoint>();

            bool isCurvedLine = !(this.XAxis is LinearAxis) || !(this.YAxis is LinearAxis) || this.Type == LineAnnotationType.EquationY;

            if (!isCurvedLine)
            {
                // we only need to calculate two points if it is a straight line
                if (fx != null)
                {
                    points.Add(new DataPoint(actualMinimumX, fx(actualMinimumX)));
                    points.Add(new DataPoint(actualMaximumX, fx(actualMaximumX)));
                }
                else if (fy != null)
                {
                    points.Add(new DataPoint(fy(actualMinimumY), actualMinimumY));
                    points.Add(new DataPoint(fy(actualMaximumY), actualMaximumY));
                }

                if (this.Type == LineAnnotationType.Horizontal || this.Type == LineAnnotationType.Vertical)
                {
                    // use aliased line drawing for horizontal and vertical lines
                    aliased = true;
                }
            }
            else
            {
                if (fx != null)
                {
                    double x = actualMinimumX;

                    // todo: the step size should be adaptive
                    double dx = (actualMaximumX - actualMinimumX) / 100;
                    while (true)
                    {
                        points.Add(new DataPoint(x, fx(x)));
                        if (x > actualMaximumX)
                        {
                            break;
                        }

                        x += dx;
                    }
                }
                else if (fy != null)
                {
                    double y = actualMinimumY;

                    // todo: the step size should be adaptive
                    double dy = (actualMaximumY - actualMinimumY) / 100;
                    while (true)
                    {
                        points.Add(new DataPoint(fy(y), y));
                        if (y > actualMaximumY)
                        {
                            break;
                        }

                        y += dy;
                    }
                }
            }

            // transform to screen coordinates
            this.screenPoints = points.Select(p => this.Transform(p)).ToList();

            // clip to the area defined by the axes
            var clippingRectangle = OxyRect.Create(
                this.ClipByXAxis ? this.XAxis.ScreenMin.X : PlotModel.PlotArea.Left,
                this.ClipByYAxis ? this.YAxis.ScreenMin.Y : PlotModel.PlotArea.Top,
                this.ClipByXAxis ? this.XAxis.ScreenMax.X : PlotModel.PlotArea.Right,
                this.ClipByYAxis ? this.YAxis.ScreenMax.Y : PlotModel.PlotArea.Bottom);

            const double MinimumSegmentLength = 4;

            IList <ScreenPoint> clippedPoints = null;

            rc.DrawClippedLine(
                this.screenPoints,
                clippingRectangle,
                MinimumSegmentLength * MinimumSegmentLength,
                this.GetSelectableColor(this.Color),
                this.StrokeThickness,
                this.LineStyle,
                this.LineJoin,
                aliased,
                pts => clippedPoints = pts);

            ScreenPoint position;
            double      angle;
            double      margin = this.TextMargin;

            if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
            {
                margin = 0;
            }
            else
            {
                margin *= this.TextPosition < 0.5 ? 1 : -1;
            }

            if (clippedPoints != null && GetPointAtRelativeDistance(clippedPoints, this.TextPosition, margin, out position, out angle))
            {
                if (angle < -90)
                {
                    angle += 180;
                }

                if (angle > 90)
                {
                    angle -= 180;
                }

                switch (this.TextOrientation)
                {
                case AnnotationTextOrientation.Horizontal:
                    angle = 0;
                    break;

                case AnnotationTextOrientation.Vertical:
                    angle = -90;
                    break;
                }

                // Apply 'padding' to the position
                var angleInRadians = angle / 180 * Math.PI;
                var f = 1;

                if (this.TextHorizontalAlignment == HorizontalAlignment.Right)
                {
                    f = -1;
                }

                if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
                {
                    f = 0;
                }

                position.X += f * this.TextPadding * Math.Cos(angleInRadians);
                position.Y += f * this.TextPadding * Math.Sin(angleInRadians);

                var cs = new CohenSutherlandClipping(clippingRectangle);
                if (!string.IsNullOrEmpty(this.Text) && cs.IsInside(position))
                {
                    rc.DrawClippedText(
                        clippingRectangle,
                        position,
                        this.Text,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        angle,
                        this.TextHorizontalAlignment,
                        this.TextVerticalAlignment);
                }
            }
        }