public void ClipPolygon()
 {
     var bounds = new OxyRect(0, 0, 1, 1);
     var points = CreatePointList();
     var result = SutherlandHodgmanClipping.ClipPolygon(bounds, points);
     Assert.AreEqual(4, result.Count);
 }
Пример #2
0
        /// <summary>
        /// Renders the polygon annotation.
        /// </summary>
        /// <param name="rc">The render context.</param>
        public override void Render(IRenderContext rc)
        {
            base.Render(rc);

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

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

            rc.DrawClippedEllipse(
                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,
                    this.TextHorizontalAlignment,
                    this.TextVerticalAlignment);
            }
        }
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            this.SetAlias(false);
            var convertedRectangle = rect.Convert();
            if (fill.IsVisible())
            {
                this.SetFill(fill);
                using (var path = new CGPath())
                {
                    path.AddEllipseInRect(convertedRectangle);
                    this.gctx.AddPath(path);
                }

                this.gctx.DrawPath(CGPathDrawingMode.Fill);
            }

            if (stroke.IsVisible() && thickness > 0)
            {
                this.SetStroke(stroke, thickness);

                using (var path = new CGPath())
                {
                    path.AddEllipseInRect(convertedRectangle);
                    this.gctx.AddPath(path);
                }

                this.gctx.DrawPath(CGPathDrawingMode.Stroke);
            }
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CohenSutherlandClipping" /> class.
 /// </summary>
 /// <param name="rect">The clipping rectangle.</param>
 public CohenSutherlandClipping(OxyRect rect)
 {
     this.xmin = rect.Left;
     this.xmax = rect.Right;
     this.ymin = rect.Top;
     this.ymax = rect.Bottom;
 }
 public void SinglePointOutside()
 {
     var points = new[] { new ScreenPoint(0, 0) };
     var clippingRectangle = new OxyRect(0.3, -0.5, 0.5, 1);
     var rc = Substitute.For<IRenderContext>();
     var received = new List<ScreenPoint>();
     rc.DrawClippedLine(clippingRectangle, points, 1, OxyColors.Black, 1, null, LineJoin.Miter, false, null, received.AddRange);
     Assert.AreEqual(0, received.Count);
 }
 public void CrossingLine()
 {
     var points = new[] { new ScreenPoint(0, 0), new ScreenPoint(100, 0) };
     var clippingRectangle = new OxyRect(30, -50, 50, 100);
     var rc = Substitute.For<IRenderContext>();
     var received = new List<ScreenPoint>();
     rc.DrawClippedLine(clippingRectangle, points, 1, OxyColors.Black, 1, null, LineJoin.Miter, false, null, received.AddRange);
     Assert.AreEqual(2, received.Count);
     Assert.AreEqual(new ScreenPoint(30, 0), received[0]);
     Assert.AreEqual(new ScreenPoint(80, 0), received[1]);
 }
Пример #7
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 = new OxyRect(this.Transform(x0, y0), this.Transform(x1, y1));

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

            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);
            }
        }
Пример #8
0
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle defining the ellipse.</param>
        /// <param name="fill">The fill.</param>
        /// <param name="stroke">The stroke.</param>
        /// <param name="thickness">The thickness.</param>
        public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            var el = new Ellipse();
            if (stroke.IsVisible())
            {
                el.Stroke = stroke.ToBrush();
                el.StrokeThickness = thickness;
            }

            if (fill.IsVisible())
            {
                el.Fill = fill.ToBrush();
            }

            el.Width = rect.Width;
            el.Height = rect.Height;
            Canvas.SetLeft(el, rect.Left);
            Canvas.SetTop(el, rect.Top);
            this.Add(el, rect.Left, rect.Top);
        }
 public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1)
 {
     using (var paint = new Paint())
     {
         paint.AntiAlias = true;
         paint.StrokeWidth = (float)thickness;
         if (fill != null)
         {
             paint.SetStyle(Paint.Style.Fill);
             paint.Color = stroke.ToColor();
             canvas.DrawOval(rect.ToRectF(), paint);
         }
         if (stroke != null)
         {
             paint.SetStyle(Paint.Style.Stroke);
             paint.Color = stroke.ToColor();
             canvas.DrawOval(rect.ToRectF(), paint);
         }
     }
 }
Пример #10
0
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            // center of ellipse
            var ex = rect.Left + (rect.Width / 2.0);
            var ey = rect.Top + (rect.Height / 2.0);

            // ellipse dimensions
            var ew = rect.Width;
            var eh = rect.Height;

            if (fill.IsVisible())
            {
                this.g.Save();

                this.g.Translate(ex, ey); // make (ex, ey) == (0, 0)
                this.g.Scale(ew / 2.0, eh / 2.0); // for width: ew / 2.0 == 1.0, eh / 2.0 == 1.0

                this.g.Arc(0.0, 0.0, 1.0, 0.0, 2.0 * Math.PI); // 'circle' centered at (0, 0)
                this.g.ClosePath();
                this.g.SetSourceColor(fill);
                this.g.Fill();
                this.g.Restore();
            }

            if (stroke.IsVisible() && thickness > 0)
            {
                this.g.Save();

                // g.SmoothingMode = SmoothingMode.HighQuality; // TODO
                this.g.Translate(ex, ey); // make (ex, ey) == (0, 0)
                this.g.Scale(ew / 2.0, eh / 2.0); // for width: ew / 2.0 == 1.0

                // for height: eh / 2.0 == 1.0
                this.g.Arc(0.0, 0.0, 1.0, 0.0, 2.0 * Math.PI); // 'circle' centered at (0, 0)
                this.g.SetSourceColor(stroke);
                this.g.LineWidth = thickness * 2.0 / ew;
                this.g.Stroke();
                this.g.Restore();
            }
        }
Пример #11
0
        /// <summary>
        /// Renders a continuous line.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        /// <param name="pointsToRender">The points to render.</param>
        protected virtual void RenderLine(IRenderContext rc, OxyRect clippingRect, IList<ScreenPoint> pointsToRender)
        {
            var dashArray = this.ActualDashArray;

            if (this.outputBuffer == null)
            {
                this.outputBuffer = new List<ScreenPoint>(pointsToRender.Count);
            }

            rc.DrawClippedLine(
                clippingRect,
                pointsToRender,
                this.MinimumSegmentLength * this.MinimumSegmentLength,
                this.GetSelectableColor(this.ActualColor),
                this.StrokeThickness,
                dashArray,
                this.LineJoin,
                false,
                this.outputBuffer);
        }
Пример #12
0
 /// <summary>
 /// Draws a rectangle.
 /// </summary>
 /// <param name="rect">The rectangle.</param>
 /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the rectangle will not be filled.</param>
 /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the rectangle will not be stroked.</param>
 /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param>
 public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1)
 {
 }
Пример #13
0
        /// <summary>
        /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
        /// </summary>
        /// <param name="bounds">The bounds.</param>
        internal override void UpdateTransform(OxyRect bounds)
        {
            double x0 = bounds.Left;
            double x1 = bounds.Right;
            double y0 = bounds.Bottom;
            double y1 = bounds.Top;

            this.ScreenMin = new ScreenPoint(x0, y1);
            this.ScreenMax = new ScreenPoint(x1, y0);

            this.MidPoint = new ScreenPoint((x0 + x1) / 2, (y0 + y1) / 2);

            // this.ActualMinimum = 0;
            double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
            this.SetTransform(0.5 * r / (this.ActualMaximum - this.ActualMinimum), this.ActualMinimum);
        }
Пример #14
0
        /// <summary>
        /// Renders by scaling a fixed image.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="model">The model.</param>
        public void RenderFixed(IRenderContext rc, PlotModel model)
        {
            if (image == null)
            {
                int m = this.Data.GetLength(0);
                int n = this.Data.GetLength(1);

                int width  = this.ImageSize;
                int height = this.ImageSize;
                if (this.pixels == null || this.pixels.GetLength(0) != height || this.pixels.GetLength(1) != width)
                {
                    this.pixels = new OxyColor[width, height];
                }

                var p = this.pixels;
                for (int yi = 0; yi < height; yi++)
                {
                    for (int xi = 0; xi < width; xi++)
                    {
                        double x = (xi - width * 0.5) / (width * 0.5) * this.Magnitude1;
                        double y = -(yi - height * 0.5) / (height * 0.5) * this.Magnitude1;

                        double angle     = Math.Atan2(y, x) / Math.PI * 180;
                        double magnitude = Math.Sqrt(x * x + y * y);

                        if (angle < 0)
                        {
                            angle += 360;
                        }

                        // transform to indices in the Data array
                        var ii = (angle - this.Angle0) / (this.Angle1 - this.Angle0) * m;
                        var jj = (magnitude - this.Magnitude0) / (this.Magnitude1 - this.Magnitude0) * n;
                        if (ii >= 0 && ii < m && jj >= 0 && jj < n)
                        {
                            // get the (interpolated) value
                            var value = this.GetValue(ii, jj);

                            // use the color axis to get the color
                            p[xi, yi] = OxyColor.FromAColor(160, this.ColorAxis.GetColor(value));
                        }
                        else
                        {
                            // outside the range of the Data array
                            p[xi, yi] = OxyColors.Transparent;
                        }
                    }
                }

                // Create the PNG image
                this.image = OxyImage.Create(p, ImageFormat.Png);
            }

            OxyRect dest;

            if (this.PlotModel.PlotType != PlotType.Polar)
            {
                var topleft     = this.Transform(-this.Magnitude1, this.Magnitude1);
                var bottomright = this.Transform(this.Magnitude1, -this.Magnitude1);
                dest = new OxyRect(topleft.X, topleft.Y, bottomright.X - topleft.X, bottomright.Y - topleft.Y);
            }
            else
            {
                var top    = this.Transform(this.Magnitude1, 90);
                var bottom = this.Transform(this.Magnitude1, 270);
                var left   = this.Transform(this.Magnitude1, 180);
                var right  = this.Transform(this.Magnitude1, 0);
                dest = new OxyRect(left.X, top.Y, right.X - left.X, bottom.Y - top.Y);
            }

            // Render the image
            var clip = this.GetClippingRect();

            rc.DrawClippedImage(clip, this.image, dest.Left, dest.Top, dest.Width, dest.Height, 1, false);
        }
Пример #15
0
        /// <summary>
        /// Renders the series on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        public override void Render(IRenderContext rc)
        {
            var nitems = this.Items.Count;
            var items  = this.Items;

            if (nitems == 0 || this.StrokeThickness <= 0 || this.LineStyle == LineStyle.None)
            {
                return;
            }

            this.VerifyAxes();

            var clippingRect = this.GetClippingRect();
            var dashArray    = this.LineStyle.GetDashArray();

            var dataCandlewidth     = (this.CandleWidth > 0) ? this.CandleWidth : this.minDx * 0.80;
            var halfDataCandlewidth = .5 * dataCandlewidth;

            // colors
            var fillUp   = this.GetSelectableFillColor(this.IncreasingColor);
            var fillDown = this.GetSelectableFillColor(this.DecreasingColor);
            var lineUp   = this.GetSelectableColor(this.IncreasingColor.ChangeIntensity(0.70));
            var lineDown = this.GetSelectableColor(this.DecreasingColor.ChangeIntensity(0.70));

            // determine render range
            var xmin = this.XAxis.ActualMinimum;
            var xmax = this.XAxis.ActualMaximum;

            this.WindowStartIndex = this.UpdateWindowStartIndex(items, item => item.X, xmin, this.WindowStartIndex);

            for (int i = this.WindowStartIndex; i < nitems; i++)
            {
                var bar = items[i];

                // if item beyond visible range, done
                if (bar.X > xmax)
                {
                    return;
                }

                // check to see whether is valid
                if (!this.IsValidItem(bar, this.XAxis, this.YAxis))
                {
                    continue;
                }

                var fillColor = bar.Close > bar.Open ? fillUp : fillDown;
                var lineColor = bar.Close > bar.Open ? lineUp : lineDown;

                var high = this.Transform(bar.X, bar.High);
                var low  = this.Transform(bar.X, bar.Low);
                var max  = this.Transform(bar.X, Math.Max(bar.Open, bar.Close));
                var min  = this.Transform(bar.X, Math.Min(bar.Open, bar.Close));

                if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
                {
                    // Upper extent
                    rc.DrawClippedLine(
                        clippingRect,
                        new[] { high, max },
                        0,
                        lineColor,
                        this.StrokeThickness,
                        this.EdgeRenderingMode,
                        dashArray,
                        this.LineJoin);

                    // Lower extent
                    rc.DrawClippedLine(
                        clippingRect,
                        new[] { min, low },
                        0,
                        lineColor,
                        this.StrokeThickness,
                        this.EdgeRenderingMode,
                        dashArray,
                        this.LineJoin);
                }

                var p1   = this.Transform(bar.X - halfDataCandlewidth, bar.Open);
                var p2   = this.Transform(bar.X + halfDataCandlewidth, bar.Close);
                var rect = new OxyRect(p1, p2);
                rc.DrawClippedRectangle(clippingRect, rect, fillColor, lineColor, this.StrokeThickness, this.EdgeRenderingMode);
            }
        }
Пример #16
0
        /// <summary>
        /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
        /// </summary>
        /// <param name="bounds">The bounds.</param>
        internal override void UpdateTransform(OxyRect bounds)
        {
            var x0 = bounds.Left;
            var x1 = bounds.Right;
            var y0 = bounds.Bottom;
            var y1 = bounds.Top;

            this.ScreenMin = new ScreenPoint(x0, y1);
            this.ScreenMax = new ScreenPoint(x1, y0);

            var newScale = (this.EndAngle - this.StartAngle) / (this.ActualMaximum - this.ActualMinimum);
            var newOffset = this.ActualMinimum - (this.StartAngle / newScale);
            this.SetTransform(newScale, newOffset);
        }
Пример #17
0
 /// <summary>
 /// Converts an <see cref="OxyRect" /> to a <see cref="Rect" />.
 /// </summary>
 /// <param name="r">The rectangle.</param>
 /// <returns>A <see cref="Rect" />.</returns>
 private Rect ToRect(OxyRect r)
 {
     return(new Rect(r.Left, r.Top, r.Width, r.Height));
 }
Пример #18
0
 /// <summary>
 /// Shows the zoom rectangle.
 /// </summary>
 /// <param name="rectangle">The rectangle.</param>
 public void ShowZoomRectangle(OxyRect rectangle)
 {
 }
 /// <summary>
 /// Sets the clip rectangle.
 /// </summary>
 /// <param name="clippingRect">The clipping rectangle.</param>
 /// <returns>True if the clip rectangle was set.</returns>
 public bool SetClip(OxyRect clippingRect)
 {
     this.clip = clippingRect.ToRect(false);
     return(true);
 }
Пример #20
0
 /// <summary>
 /// Draws the rectangle.
 /// </summary>
 /// <param name="rect">The rectangle.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The stroke thickness.</param>
 public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
 {
     this.renderUnits.Add(new RectangleRenderUnit(rect.ToRectangleF(), this.GetBrush(stroke), this.GetBrush(fill), (float)thickness));
 }
Пример #21
0
 /// <summary>
 /// Sets the clipping rectangle.
 /// </summary>
 /// <param name="clippingRect">The clipping rectangle.</param>
 /// <returns>True if the clipping rectangle was set.</returns>
 public bool SetClip(OxyRect clippingRect)
 {
     this.clipRect = clippingRect.ToRectangleF();
     renderUnits.Add(new ClipRectRenderUnit(clipRect));
     return(true);
 }
Пример #22
0
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            var el = rect.ToEllipse();

            this.renderUnits.Add(new EllipseRenderUnit(el, this.GetBrush(stroke), this.GetBrush(fill), (float)thickness));
        }
Пример #23
0
 /// <summary>
 /// Draws an ellipse.
 /// </summary>
 /// <param name="rect">The rectangle.</param>
 /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the ellipse will not be filled.</param>
 /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the ellipse will not be stroked.</param>
 /// <param name="thickness">The thickness (in device independent units, 1/96 inch).</param>
 public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1)
 {
 }
Пример #24
0
 /// <summary>
 /// Sets the clip rectangle.
 /// </summary>
 /// <param name="rect">The clip rectangle.</param>
 /// <returns>
 /// True if the clip rectangle was set.
 /// </returns>
 public bool SetClip(OxyRect rect)
 {
     return(true);
 }
Пример #25
0
        /// <summary>
        /// Renders the point labels.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        protected void RenderPointLabels(IRenderContext rc, OxyRect clippingRect)
        {
            int index = -1;
            foreach (var point in this.ActualPoints)
            {
                index++;

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

                var pt = this.Transform(point) + new ScreenVector(0, -this.LabelMargin);

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

                var item = this.GetItem(index);
                var s = StringHelper.Format(this.ActualCulture, this.LabelFormatString, item, 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 = HorizontalAlignment.Right;
                            break;
                        case LabelPlacement.Middle:
                            pt = new ScreenPoint((rect.Left + rect.Right) / 2, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalAlignment.Center;
                            break;
                        case LabelPlacement.Base:
                            pt = new ScreenPoint(rect.Left + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalAlignment.Left;
                            break;
                        default: // Outside
                            pt = new ScreenPoint(rect.Right + this.LabelMargin, (rect.Top + rect.Bottom) / 2);
                            ha = HorizontalAlignment.Left;
                            break;
                    }
            #endif

                rc.DrawClippedText(
                    clippingRect,
                    pt,
                    s,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    0,
                    HorizontalAlignment.Center,
                    VerticalAlignment.Bottom);
            }
        }
Пример #26
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.data == null || this.data.Count == 0)
            {
                return;
            }

            var items  = this.data;
            var nitems = this.data.Count;

            this.VerifyAxes();

            var clippingRect = this.GetClippingRect();

            var datacandlewidth     = (this.BarWidth > 0) ? this.BarWidth : this.minDx * 0.80;
            var halfDataCandleWidth = datacandlewidth * 0.5;

            // colors
            var fillUp   = this.GetSelectableFillColor(this.PositiveColor);
            var fillDown = this.GetSelectableFillColor(this.NegativeColor);

            var barfillUp   = this.PositiveHollow ? OxyColors.Transparent : fillUp;
            var barfillDown = this.NegativeHollow ? OxyColors.Transparent : fillDown;

            var lineUp   = this.GetSelectableColor(this.PositiveColor.ChangeIntensity(this.StrokeIntensity));
            var lineDown = this.GetSelectableColor(this.NegativeColor.ChangeIntensity(this.StrokeIntensity));

            // determine render range
            var xmin = this.XAxis.ActualMinimum;
            var xmax = this.XAxis.ActualMaximum;

            this.winIndex = OhlcvItem.FindIndex(items, xmin, this.winIndex);

            for (int i = this.winIndex; i < nitems; i++)
            {
                var bar = items[i];

                // if item beyond visible range, done
                if (bar.X > xmax)
                {
                    break;
                }

                // check to see whether is valid
                if (!bar.IsValid())
                {
                    continue;
                }

                var p1 = this.Transform(bar.X - halfDataCandleWidth, 0);

                switch (this.VolumeStyle)
                {
                case VolumeStyle.Combined:
                {
                    var p2        = this.Transform(bar.X + halfDataCandleWidth, Math.Abs(bar.BuyVolume - bar.SellVolume));
                    var fillcolor = (bar.BuyVolume > bar.SellVolume) ? barfillUp : barfillDown;
                    var linecolor = (bar.BuyVolume > bar.SellVolume) ? lineUp : lineDown;
                    var rect1     = new OxyRect(p1, p2);
                    rc.DrawClippedRectangle(clippingRect, rect1, fillcolor, linecolor, this.StrokeThickness, this.EdgeRenderingMode);
                }

                break;

                case VolumeStyle.PositiveNegative:
                {
                    var p2Buy  = this.Transform(bar.X + halfDataCandleWidth, bar.BuyVolume);
                    var p2Bell = this.Transform(bar.X + halfDataCandleWidth, -bar.SellVolume);

                    var rectBuy  = new OxyRect(p1, p2Buy);
                    var rectSell = new OxyRect(p1, p2Bell);

                    rc.DrawClippedRectangle(clippingRect, rectBuy, fillUp, lineUp, this.StrokeThickness, this.EdgeRenderingMode);
                    rc.DrawClippedRectangle(clippingRect, rectSell, fillDown, lineDown, this.StrokeThickness, this.EdgeRenderingMode);
                }

                break;

                case VolumeStyle.Stacked:
                {
                    var p2Buy  = this.Transform(bar.X + halfDataCandleWidth, bar.BuyVolume);
                    var p2Sell = this.Transform(bar.X + halfDataCandleWidth, bar.SellVolume);
                    var pBoth  = this.Transform(bar.X - halfDataCandleWidth, bar.BuyVolume + bar.SellVolume);

                    OxyRect rectBuy;
                    OxyRect rectSell;

                    if (bar.BuyVolume > bar.SellVolume)
                    {
                        rectSell = new OxyRect(p1, p2Sell);
                        rectBuy  = new OxyRect(p2Sell, pBoth);
                    }
                    else
                    {
                        rectBuy  = new OxyRect(p1, p2Buy);
                        rectSell = new OxyRect(p2Buy, pBoth);
                    }

                    rc.DrawClippedRectangle(clippingRect, rectBuy, fillUp, lineUp, this.StrokeThickness, this.EdgeRenderingMode);
                    rc.DrawClippedRectangle(clippingRect, rectSell, fillDown, lineDown, this.StrokeThickness, this.EdgeRenderingMode);

                    break;
                }

                case VolumeStyle.None:
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (this.InterceptStrokeThickness > 0 && this.InterceptLineStyle != LineStyle.None)
            {
                // draw volume y=0 line
                var p1    = this.InverseTransform(clippingRect.BottomLeft);
                var p2    = this.InverseTransform(clippingRect.TopRight);
                var lineA = this.Transform(p1.X, 0);
                var lineB = this.Transform(p2.X, 0);

                rc.DrawClippedLine(
                    clippingRect,
                    new[] { lineA, lineB },
                    0,
                    this.InterceptColor,
                    this.InterceptStrokeThickness,
                    this.EdgeRenderingMode,
                    this.InterceptLineStyle.GetDashArray(),
                    LineJoin.Miter);
            }
        }
 /// <summary>
 /// Sets the clip rectangle.
 /// </summary>
 /// <param name="clippingRect">The clipping rectangle.</param>
 /// <returns>True if the clip rectangle was set.</returns>
 public bool SetClip(OxyRect clippingRect)
 {
     this.clip = clippingRect.ToRect(false);
     return true;
 }
Пример #28
0
 /// <summary>
 /// Renders the legend symbol on the specified render context.
 /// </summary>
 /// <param name="rc">The rendering context.</param>
 /// <param name="legendBox">The legend rectangle.</param>
 public abstract void RenderLegend(IRenderContext rc, OxyRect legendBox);
		public override void DrawEllipse (OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
		{
			if (fill != null)
            {
				ToColor(fill).SetFill();
                var path = new CGPath ();
	            path.AddElipseInRect(ToRectangle(rect));

	            gctx.AddPath (path);
	            gctx.DrawPath (CGPathDrawingMode.Fill);
            }

            if (stroke == null || thickness <= 0)
            {
                return;
            }

			SetAttributes (null, stroke, thickness);

			var path2 = new CGPath ();
            path2.AddElipseInRect(ToRectangle(rect));


            gctx.AddPath (path2);
            gctx.DrawPath (CGPathDrawingMode.Stroke);
		}
Пример #30
0
        /// <summary>
        /// Renders the series on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        // ReSharper disable once FunctionComplexityOverflow
        public override void Render(IRenderContext rc)
        {
            if (this.data == null || this.data.Count == 0)
            {
                return;
            }

            var items  = this.data;
            var nitems = this.data.Count;

            this.VerifyAxes();

            var clippingBar = this.GetClippingRect(this.BarAxis);
            var clippingSep = this.GetSeparationClippingRect();
            var clippingVol = this.GetClippingRect(this.VolumeAxis);

            var datacandlewidth = (this.CandleWidth > 0) ? this.CandleWidth : this.minDx * 0.80;
            var candlewidth     =
                this.XAxis.Transform(items[0].X + datacandlewidth) -
                this.XAxis.Transform(items[0].X) - this.StrokeThickness;

            // colors
            var fillUp   = this.GetSelectableFillColor(this.PositiveColor);
            var fillDown = this.GetSelectableFillColor(this.NegativeColor);

            var barfillUp   = this.PositiveHollow ? OxyColors.Transparent : fillUp;
            var barfillDown = this.NegativeHollow ? OxyColors.Transparent : fillDown;

            var lineUp   = this.GetSelectableColor(this.PositiveColor.ChangeIntensity(this.StrokeIntensity));
            var lineDown = this.GetSelectableColor(this.NegativeColor.ChangeIntensity(this.StrokeIntensity));

            // determine render range
            var xmin = this.XAxis.ActualMinimum;
            var xmax = this.XAxis.ActualMaximum;

            this.winIndex = OhlcvItem.FindIndex(items, xmin, this.winIndex);

            for (int i = this.winIndex; i < nitems; i++)
            {
                var bar = items[i];

                // if item beyond visible range, done
                if (bar.X > xmax)
                {
                    break;
                }

                // check to see whether is valid
                if (!bar.IsValid())
                {
                    continue;
                }

                var fillColor = bar.Close > bar.Open ? barfillUp : barfillDown;
                var lineColor = bar.Close > bar.Open ? lineUp : lineDown;

                var high = this.Transform(bar.X, bar.High);
                var low  = this.Transform(bar.X, bar.Low);

                var open  = this.Transform(bar.X, bar.Open);
                var close = this.Transform(bar.X, bar.Close);

                var max = new ScreenPoint(open.X, Math.Max(open.Y, close.Y));
                var min = new ScreenPoint(open.X, Math.Min(open.Y, close.Y));

                // Bar part
                rc.DrawClippedLine(
                    clippingBar,
                    new[] { high, min },
                    0,
                    lineColor,
                    this.StrokeThickness,
                    null,
                    LineJoin.Miter,
                    true);

                // Lower extent
                rc.DrawClippedLine(
                    clippingBar,
                    new[] { max, low },
                    0,
                    lineColor,
                    this.StrokeThickness,
                    null,
                    LineJoin.Miter,
                    true);

                // Body
                var openLeft = open + new ScreenVector(-candlewidth * 0.5, 0);

                if (max.Y - min.Y < 1.0)
                {
                    var leftPoint  = new ScreenPoint(openLeft.X - this.StrokeThickness, min.Y);
                    var rightPoint = new ScreenPoint(openLeft.X + this.StrokeThickness + candlewidth, min.Y);
                    rc.DrawClippedLine(clippingBar, new[] { leftPoint, rightPoint }, leftPoint.DistanceToSquared(rightPoint), lineColor, this.StrokeThickness, null, LineJoin.Miter, true);

                    leftPoint  = new ScreenPoint(openLeft.X - this.StrokeThickness, max.Y);
                    rightPoint = new ScreenPoint(openLeft.X + this.StrokeThickness + candlewidth, max.Y);
                    rc.DrawClippedLine(clippingBar, new[] { leftPoint, rightPoint }, leftPoint.DistanceToSquared(rightPoint), lineColor, this.StrokeThickness, null, LineJoin.Miter, true);
                }
                else
                {
                    var rect = new OxyRect(openLeft.X, min.Y, candlewidth, max.Y - min.Y);
                    rc.DrawClippedRectangleAsPolygon(clippingBar, rect, fillColor, lineColor, this.StrokeThickness);
                }

                // Volume Part
                if (this.VolumeAxis == null || this.VolumeStyle == VolumeStyle.None)
                {
                    continue;
                }

                var iY0 = this.VolumeAxis.Transform(0);
                switch (this.VolumeStyle)
                {
                case VolumeStyle.Combined:
                {
                    var adj       = this.VolumeAxis.Transform(Math.Abs(bar.BuyVolume - bar.SellVolume));
                    var fillcolor = (bar.BuyVolume > bar.SellVolume) ? barfillUp : barfillDown;
                    var linecolor = (bar.BuyVolume > bar.SellVolume) ? lineUp : lineDown;
                    var rect1     = new OxyRect(openLeft.X, adj, candlewidth, Math.Abs(adj - iY0));
                    rc.DrawClippedRectangleAsPolygon(clippingVol, rect1, fillcolor, linecolor, this.StrokeThickness);
                }

                break;

                case VolumeStyle.PositiveNegative:
                {
                    var buyY  = this.VolumeAxis.Transform(bar.BuyVolume);
                    var sellY = this.VolumeAxis.Transform(-bar.SellVolume);
                    var rect1 = new OxyRect(openLeft.X, buyY, candlewidth, Math.Abs(buyY - iY0));
                    rc.DrawClippedRectangleAsPolygon(clippingVol, rect1, fillUp, lineUp, this.StrokeThickness);
                    var rect2 = new OxyRect(openLeft.X, iY0, candlewidth, Math.Abs(sellY - iY0));
                    rc.DrawClippedRectangleAsPolygon(clippingVol, rect2, fillDown, lineDown, this.StrokeThickness);
                }

                break;

                case VolumeStyle.Stacked:
                    if (bar.BuyVolume > bar.SellVolume)
                    {
                        var buyY     = this.VolumeAxis.Transform(bar.BuyVolume);
                        var sellY    = this.VolumeAxis.Transform(bar.SellVolume);
                        var dyoffset = sellY - iY0;
                        var rect2    = new OxyRect(openLeft.X, sellY, candlewidth, Math.Abs(sellY - iY0));
                        rc.DrawClippedRectangleAsPolygon(clippingVol, rect2, fillDown, lineDown, this.StrokeThickness);
                        var rect1 = new OxyRect(openLeft.X, buyY + dyoffset, candlewidth, Math.Abs(buyY - iY0));
                        rc.DrawClippedRectangleAsPolygon(clippingVol, rect1, fillUp, lineUp, this.StrokeThickness);
                    }
                    else
                    {
                        var buyY     = this.VolumeAxis.Transform(bar.BuyVolume);
                        var sellY    = this.VolumeAxis.Transform(bar.SellVolume);
                        var dyoffset = buyY - iY0;
                        var rect1    = new OxyRect(openLeft.X, buyY, candlewidth, Math.Abs(buyY - iY0));
                        rc.DrawClippedRectangleAsPolygon(clippingVol, rect1, fillUp, lineUp, this.StrokeThickness);
                        var rect2 = new OxyRect(openLeft.X, sellY + dyoffset, candlewidth, Math.Abs(sellY - iY0));
                        rc.DrawClippedRectangleAsPolygon(clippingVol, rect2, fillDown, lineDown, this.StrokeThickness);
                    }

                    break;
                }
            }

            if (this.SeparatorStrokeThickness > 0 && this.SeparatorLineStyle != LineStyle.None)
            {
                // draw volume & bar separation line
                if (this.VolumeStyle != VolumeStyle.None)
                {
                    var ysep = (clippingSep.Bottom + clippingSep.Top) / 2.0;
                    rc.DrawClippedLine(
                        clippingSep,
                        new[] { new ScreenPoint(clippingSep.Left, ysep), new ScreenPoint(clippingSep.Right, ysep) },
                        0,
                        this.SeparatorColor,
                        this.SeparatorStrokeThickness,
                        this.SeparatorLineStyle.GetDashArray(),
                        LineJoin.Miter,
                        true);
                }

                // draw volume y=0 line
                if (this.VolumeAxis != null && this.VolumeStyle == VolumeStyle.PositiveNegative)
                {
                    var y0 = this.VolumeAxis.Transform(0);
                    rc.DrawClippedLine(
                        clippingVol,
                        new[] { new ScreenPoint(clippingVol.Left, y0), new ScreenPoint(clippingVol.Right, y0) },
                        0,
                        OxyColors.Goldenrod,
                        this.SeparatorStrokeThickness,
                        this.SeparatorLineStyle.GetDashArray(),
                        LineJoin.Miter,
                        true);
                }
            }
        }
Пример #31
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.Items.Count == 0)
            {
                return;
            }

            this.VerifyAxes();

            var clippingRect   = this.GetClippingRect();
            var dashArray      = this.LineStyle.GetDashArray();
            var actualColor    = this.GetSelectableColor(this.ActualColor);
            var shadowEndColor = this.GetSelectableColor(this.ShadowEndColor);

            foreach (var v in this.Items)
            {
                if (!this.IsValidItem(v, this.XAxis, this.YAxis))
                {
                    continue;
                }

                if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
                {
                    var high = this.Transform(v.X, v.High);
                    var low  = this.Transform(v.X, v.Low);

                    if (double.IsNaN(v.Open) || double.IsNaN(v.Close))
                    {
                        rc.DrawClippedLine(
                            clippingRect,
                            new[] { low, high },
                            0,
                            actualColor,
                            this.StrokeThickness,
                            dashArray,
                            this.LineJoin,
                            false);
                    }
                    else
                    {
                        var open  = this.Transform(v.X, v.Open);
                        var close = this.Transform(v.X, v.Close);
                        var max   = new ScreenPoint(open.X, Math.Max(open.Y, close.Y));
                        var min   = new ScreenPoint(open.X, Math.Min(open.Y, close.Y));

                        // Upper shadow
                        rc.DrawClippedLine(
                            clippingRect,
                            new[] { high, min },
                            0,
                            actualColor,
                            this.StrokeThickness,
                            dashArray,
                            this.LineJoin,
                            true);

                        // Lower shadow
                        rc.DrawClippedLine(
                            clippingRect,
                            new[] { max, low },
                            0,
                            actualColor,
                            this.StrokeThickness,
                            dashArray,
                            this.LineJoin,
                            true);

                        // Shadow ends
                        if (this.ShadowEndColor.IsVisible() && this.ShadowEndLength > 0)
                        {
                            var highLeft  = new ScreenPoint(high.X - (this.CandleWidth * 0.5 * this.ShadowEndLength) - 1, high.Y);
                            var highRight = new ScreenPoint(high.X + (this.CandleWidth * 0.5 * this.ShadowEndLength), high.Y);
                            rc.DrawClippedLine(
                                clippingRect,
                                new[] { highLeft, highRight },
                                0,
                                shadowEndColor,
                                this.StrokeThickness,
                                dashArray,
                                this.LineJoin,
                                true);

                            var lowLeft  = new ScreenPoint(low.X - (this.CandleWidth * 0.5 * this.ShadowEndLength) - 1, low.Y);
                            var lowRight = new ScreenPoint(low.X + (this.CandleWidth * 0.5 * this.ShadowEndLength), low.Y);
                            rc.DrawClippedLine(
                                clippingRect,
                                new[] { lowLeft, lowRight },
                                0,
                                shadowEndColor,
                                this.StrokeThickness,
                                dashArray,
                                this.LineJoin,
                                true);
                        }

                        // Body
                        var openLeft  = open + new ScreenVector(-this.CandleWidth * 0.5, 0);
                        var rect      = new OxyRect(openLeft.X, min.Y, this.CandleWidth, max.Y - min.Y);
                        var fillColor = v.Close > v.Open
                                            ? this.GetSelectableFillColor(this.ActualIncreasingFill)
                                            : this.GetSelectableFillColor(this.DecreasingFill);
                        rc.DrawClippedRectangleAsPolygon(clippingRect, rect, fillColor, actualColor, this.StrokeThickness);
                    }
                }
            }
        }
Пример #32
0
        /// <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 y0 = (legendBox.Top * 0.2) + (legendBox.Bottom * 0.8);
            double y1 = (legendBox.Top * 0.4) + (legendBox.Bottom * 0.6);
            double y2 = (legendBox.Top * 0.8) + (legendBox.Bottom * 0.2);

            var pts0 = new[] { new ScreenPoint(legendBox.Left, y0), new ScreenPoint(legendBox.Right, y0) };
            var pts1 = new[] { new ScreenPoint(legendBox.Right, y2), new ScreenPoint(legendBox.Left, y1) };
            var pts = new List<ScreenPoint>();
            pts.AddRange(pts0);
            pts.AddRange(pts1);
            rc.DrawLine(pts0, this.GetSelectableColor(this.ActualColor), this.StrokeThickness, this.ActualLineStyle.GetDashArray());
            rc.DrawLine(pts1, this.GetSelectableColor(this.ActualColor2), this.StrokeThickness, this.ActualLineStyle.GetDashArray());
            rc.DrawPolygon(pts, this.GetSelectableFillColor(this.ActualFill), OxyColors.Undefined);
        }
Пример #33
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.data == null || this.data.Count == 0)
            {
                return;
            }

            var items  = this.data;
            var nitems = this.data.Count;

            this.VerifyAxes();

            var clipping = this.GetClippingRect();

            var datacandlewidth = (this.BarWidth > 0) ? this.BarWidth : this.minDx * 0.80;
            var candlewidth     =
                this.XAxis.Transform(items[0].X + datacandlewidth) -
                this.XAxis.Transform(items[0].X) - this.StrokeThickness;

            // colors
            var fillUp   = this.GetSelectableFillColor(this.PositiveColor);
            var fillDown = this.GetSelectableFillColor(this.NegativeColor);

            var barfillUp   = this.PositiveHollow ? OxyColors.Transparent : fillUp;
            var barfillDown = this.NegativeHollow ? OxyColors.Transparent : fillDown;

            var lineUp   = this.GetSelectableColor(this.PositiveColor.ChangeIntensity(this.StrokeIntensity));
            var lineDown = this.GetSelectableColor(this.NegativeColor.ChangeIntensity(this.StrokeIntensity));

            // determine render range
            var xmin = this.XAxis.ActualMinimum;
            var xmax = this.XAxis.ActualMaximum;

            this.winIndex = OhlcvItem.FindIndex(items, xmin, this.winIndex);

            for (int i = this.winIndex; i < nitems; i++)
            {
                var bar = items[i];

                // if item beyond visible range, done
                if (bar.X > xmax)
                {
                    break;
                }

                // check to see whether is valid
                if (!bar.IsValid())
                {
                    continue;
                }

                var leftX = this.XAxis.Transform(bar.X) - (this.BarWidth / 2.0);
                var y0    = this.YAxis.Transform(0);

                switch (this.VolumeStyle)
                {
                case VolumeStyle.Combined:
                {
                    var adj       = this.YAxis.Transform(Math.Abs(bar.BuyVolume - bar.SellVolume));
                    var fillcolor = (bar.BuyVolume > bar.SellVolume) ? barfillUp : barfillDown;
                    var linecolor = (bar.BuyVolume > bar.SellVolume) ? lineUp : lineDown;
                    var rect1     = new OxyRect(leftX, adj, candlewidth, Math.Abs(adj - y0));
                    rc.DrawClippedRectangleAsPolygon(clipping, rect1, fillcolor, linecolor, this.StrokeThickness);
                }

                break;

                case VolumeStyle.PositiveNegative:
                {
                    var buyY  = this.YAxis.Transform(bar.BuyVolume);
                    var sellY = this.YAxis.Transform(-bar.SellVolume);
                    var rect1 = new OxyRect(leftX, buyY, candlewidth, Math.Abs(buyY - y0));
                    rc.DrawClippedRectangleAsPolygon(clipping, rect1, fillUp, lineUp, this.StrokeThickness);
                    var rect2 = new OxyRect(leftX, y0, candlewidth, Math.Abs(sellY - y0));
                    rc.DrawClippedRectangleAsPolygon(clipping, rect2, fillDown, lineDown, this.StrokeThickness);
                }

                break;

                case VolumeStyle.Stacked:
                    if (bar.BuyVolume > bar.SellVolume)
                    {
                        var buyY     = this.YAxis.Transform(bar.BuyVolume);
                        var sellY    = this.YAxis.Transform(bar.SellVolume);
                        var dyoffset = sellY - y0;
                        var rect2    = new OxyRect(leftX, sellY, candlewidth, Math.Abs(sellY - y0));
                        rc.DrawClippedRectangleAsPolygon(clipping, rect2, fillDown, lineDown, this.StrokeThickness);
                        var rect1 = new OxyRect(leftX, buyY + dyoffset, candlewidth, Math.Abs(buyY - y0));
                        rc.DrawClippedRectangleAsPolygon(clipping, rect1, fillUp, lineUp, this.StrokeThickness);
                    }
                    else
                    {
                        var buyY     = this.YAxis.Transform(bar.BuyVolume);
                        var sellY    = this.YAxis.Transform(bar.SellVolume);
                        var dyoffset = buyY - y0;
                        var rect1    = new OxyRect(leftX, buyY, candlewidth, Math.Abs(buyY - y0));
                        rc.DrawClippedRectangleAsPolygon(clipping, rect1, fillUp, lineUp, this.StrokeThickness);
                        var rect2 = new OxyRect(leftX, sellY + dyoffset, candlewidth, Math.Abs(sellY - y0));
                        rc.DrawClippedRectangleAsPolygon(clipping, rect2, fillDown, lineDown, this.StrokeThickness);
                    }

                    break;
                }
            }

            if (this.InterceptStrokeThickness > 0 && this.InterceptLineStyle != LineStyle.None)
            {
                // draw volume y=0 line
                var intercept = this.YAxis.Transform(0);
                rc.DrawClippedLine(
                    clipping,
                    new[] { new ScreenPoint(clipping.Left, intercept), new ScreenPoint(clipping.Right, intercept) },
                    0,
                    this.InterceptColor,
                    this.InterceptStrokeThickness,
                    this.InterceptLineStyle.GetDashArray(),
                    LineJoin.Miter,
                    true);
            }
        }
Пример #34
0
        /// <summary>
        /// Renders the legend symbol for the 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 yopen = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.7);
            double yclose = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.3);
            double[] dashArray = this.LineStyle.GetDashArray();
            rc.DrawLine(
                new[] { new ScreenPoint(xmid, legendBox.Top), new ScreenPoint(xmid, legendBox.Bottom) },
                this.GetSelectableColor(this.ActualColor),
                this.StrokeThickness,
                dashArray,
                OxyPenLineJoin.Miter,
                true);

            // Shadow ends
            if (this.ShadowEndColor.IsVisible() && this.ShadowEndLength > 0)
            {
                var highLeft = new ScreenPoint(xmid - (this.CandleWidth * 0.5 * this.ShadowEndLength) - 1, legendBox.Top);
                var highRight = new ScreenPoint(xmid + (this.CandleWidth * 0.5 * this.ShadowEndLength), legendBox.Top);
                rc.DrawLine(
                     new[] { highLeft, highRight },
                     this.GetSelectableColor(this.ShadowEndColor),
                     this.StrokeThickness,
                     dashArray,
                     this.LineJoin,
                     true);

                var lowLeft = new ScreenPoint(xmid - (this.CandleWidth * 0.5 * this.ShadowEndLength) - 1, legendBox.Bottom);
                var lowRight = new ScreenPoint(xmid + (this.CandleWidth * 0.5 * this.ShadowEndLength), legendBox.Bottom);
                rc.DrawLine(
                    new[] { lowLeft, lowRight },
                    this.GetSelectableColor(this.ShadowEndColor),
                    this.StrokeThickness,
                    dashArray,
                    this.LineJoin,
                    true);
            }

            rc.DrawRectangleAsPolygon(
                new OxyRect(xmid - (this.CandleWidth * 0.5), yclose, this.CandleWidth, yopen - yclose),
                this.GetSelectableFillColor(this.ActualIncreasingFill),
                this.GetSelectableColor(this.ActualColor),
                this.StrokeThickness);
        }
Пример #35
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++;
            }
        }
Пример #36
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>();
            this.ActualItems         = new List <RectangleBarItem>();

            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);
                this.ActualItems.Add(item);

                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;
                }
            }
        }
Пример #37
0
        /// <summary>
        /// Draws an ellipse.
        /// </summary>
        /// <param name="rect">The rectangle.</param>
        /// <param name="fill">The fill color.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
        {
            this.paint.Reset();
            {
                if (fill.IsVisible())
                {
                    this.SetFill(fill);
                    this.canvas.DrawOval(this.Convert(rect), this.paint);
                }

                if (stroke.IsVisible())
                {
                    this.SetStroke(stroke, thickness);
                    this.canvas.DrawOval(this.Convert(rect), this.paint);
                }
            }
        }
Пример #38
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);

            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);
            }
        }
Пример #39
0
 public void ShowZoomRectangle(OxyRect rectangle)
 {
     throw new System.NotImplementedException();
 }
Пример #40
0
 /// <summary>
 /// Sets the clipping rectangle.
 /// </summary>
 /// <param name="clippingRect">The clipping rectangle.</param>
 /// <returns><c>true</c> if the clip rectangle was set.</returns>
 public bool SetClip(OxyRect clippingRect)
 {
     this.clip = this.ToRect(clippingRect);
     return(true);
 }
Пример #41
0
 /// <summary>
 /// Shows the zoom rectangle.
 /// </summary>
 /// <param name="r">
 /// The rectangle.
 /// </param>
 public void ShowZoomRectangle(OxyRect r)
 {
     this.zoomControl.Width = r.Width;
     this.zoomControl.Height = r.Height;
     Canvas.SetLeft(this.zoomControl, r.Left);
     Canvas.SetTop(this.zoomControl, r.Top);
     this.zoomControl.Template = this.ZoomRectangleTemplate;
     this.zoomControl.Visibility = Visibility.Visible;
 }
Пример #42
0
        /// <summary>
        /// Renders the points as line, broken line and markers.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        /// <param name="points">The points to render.</param>
        protected void RenderPoints(IRenderContext rc, OxyRect clippingRect, IList <DataPoint> points)
        {
            var lastValidPoint         = new ScreenPoint?();
            var areBrokenLinesRendered = this.BrokenLineThickness > 0 && this.BrokenLineStyle != LineStyle.None;
            var dashArray = areBrokenLinesRendered ? this.BrokenLineStyle.GetDashArray() : null;
            var broken    = areBrokenLinesRendered ? new List <ScreenPoint>(2) : null;

            if (this.contiguousScreenPointsBuffer == null)
            {
                this.contiguousScreenPointsBuffer = new List <ScreenPoint>(points.Count);
            }

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

            if (this.IsXMonotonic)
            {
                // determine render range
                var xmin = this.XAxis.ActualMinimum;
                xmax = this.XAxis.ActualMaximum;
                this.WindowStartIndex = this.UpdateWindowStartIndex(points, point => point.X, xmin, this.WindowStartIndex);

                startIdx = this.WindowStartIndex;
            }

            for (int i = startIdx; i < points.Count; i++)
            {
                if (!this.ExtractNextContiguousLineSegment(points, ref i, ref lastValidPoint, xmax, broken, this.contiguousScreenPointsBuffer))
                {
                    break;
                }

                if (areBrokenLinesRendered)
                {
                    if (broken.Count > 0)
                    {
                        var actualBrokenLineColor = this.BrokenLineColor.IsAutomatic()
                                                                                                                ? this.ActualColor
                                                                                                                : this.BrokenLineColor;

                        rc.DrawClippedLineSegments(
                            clippingRect,
                            broken,
                            actualBrokenLineColor,
                            this.BrokenLineThickness,
                            dashArray,
                            this.LineJoin,
                            false);
                        broken.Clear();
                    }
                }
                else
                {
                    lastValidPoint = null;
                }

                if (this.Decimator != null)
                {
                    if (this.decimatorBuffer == null)
                    {
                        this.decimatorBuffer = new List <ScreenPoint>(this.contiguousScreenPointsBuffer.Count);
                    }
                    else
                    {
                        this.decimatorBuffer.Clear();
                    }

                    this.Decimator(this.contiguousScreenPointsBuffer, this.decimatorBuffer);
                    this.RenderLineAndMarkers(rc, clippingRect, this.decimatorBuffer);
                }
                else
                {
                    this.RenderLineAndMarkers(rc, clippingRect, this.contiguousScreenPointsBuffer);
                }

                this.contiguousScreenPointsBuffer.Clear();
            }
        }
Пример #43
0
        /// <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 midpt = new ScreenPoint(xmid, ymid);
            rc.DrawMarker(
                midpt,
                legendBox,
                this.MarkerType,
                this.MarkerOutline,
                this.MarkerSize,
                this.ActualMarkerFillColor,
                this.MarkerStroke,
                this.MarkerStrokeThickness);
        }
Пример #44
0
        /// <summary>
        /// Renders the point labels.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        protected void RenderPointLabels(IRenderContext rc, OxyRect clippingRect)
        {
            int index = -1;

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

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

                var pt = this.Transform(point) + new ScreenVector(0, -this.LabelMargin);

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

                var item = this.GetItem(index);
                var s    = StringHelper.Format(this.ActualCulture, this.LabelFormatString, item, 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 = HorizontalAlignment.Right;
                    break;

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

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

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

                rc.DrawClippedText(
                    clippingRect,
                    pt,
                    s,
                    this.ActualTextColor,
                    this.ActualFont,
                    this.ActualFontSize,
                    this.ActualFontWeight,
                    0,
                    HorizontalAlignment.Center,
                    VerticalAlignment.Bottom);
            }
        }
Пример #45
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.Items.Count == 0)
            {
                return;
            }

            this.VerifyAxes();

            var clippingRect = this.GetClippingRect();
            var dashArray = this.LineStyle.GetDashArray();
            var actualColor = this.GetSelectableColor(this.ActualColor);
            var shadowEndColor = this.GetSelectableColor(this.ShadowEndColor);

            foreach (var v in this.Items)
            {
                if (!this.IsValidItem(v, this.XAxis, this.YAxis))
                {
                    continue;
                }

                if (this.StrokeThickness > 0 && this.LineStyle != LineStyle.None)
                {
                    var high = this.Transform(v.X, v.High);
                    var low = this.Transform(v.X, v.Low);

                    if (double.IsNaN(v.Open) || double.IsNaN(v.Close))
                    {
                        rc.DrawClippedLine(
                            clippingRect,
                            new[] { low, high },
                            0,
                            actualColor,
                            this.StrokeThickness,
                            dashArray,
                            this.LineJoin,
                            false);
                    }
                    else
                    {
                        var open = this.Transform(v.X, v.Open);
                        var close = this.Transform(v.X, v.Close);
                        var max = new ScreenPoint(open.X, Math.Max(open.Y, close.Y));
                        var min = new ScreenPoint(open.X, Math.Min(open.Y, close.Y));

                        // Upper shadow
                        rc.DrawClippedLine(
                            clippingRect,
                            new[] { high, min },
                            0,
                            actualColor,
                            this.StrokeThickness,
                            dashArray,
                            this.LineJoin,
                            true);

                        // Lower shadow
                        rc.DrawClippedLine(
                            clippingRect,
                            new[] { max, low },
                            0,
                            actualColor,
                            this.StrokeThickness,
                            dashArray,
                            this.LineJoin,
                            true);

                        // Shadow ends
                        if (this.ShadowEndColor.IsVisible() && this.ShadowEndLength > 0)
                        {
                            var highLeft = new ScreenPoint(high.X - (this.CandleWidth * 0.5 * this.ShadowEndLength) - 1, high.Y);
                            var highRight = new ScreenPoint(high.X + (this.CandleWidth * 0.5 * this.ShadowEndLength), high.Y);
                            rc.DrawClippedLine(
                                 clippingRect,
                                 new[] { highLeft, highRight },
                                 0,
                                 shadowEndColor,
                                 this.StrokeThickness,
                                 dashArray,
                                 this.LineJoin,
                                 true);

                            var lowLeft = new ScreenPoint(low.X - (this.CandleWidth * 0.5 * this.ShadowEndLength) - 1, low.Y);
                            var lowRight = new ScreenPoint(low.X + (this.CandleWidth * 0.5 * this.ShadowEndLength), low.Y);
                            rc.DrawClippedLine(
                                clippingRect,
                                new[] { lowLeft, lowRight },
                                0,
                                shadowEndColor,
                                this.StrokeThickness,
                                dashArray,
                                this.LineJoin,
                                true);
                        }

                        // Body
                        var openLeft = open + new ScreenVector(-this.CandleWidth * 0.5, 0);
                        var rect = new OxyRect(openLeft.X, min.Y, this.CandleWidth, max.Y - min.Y);
                        var fillColor = v.Close > v.Open
                                            ? this.GetSelectableFillColor(this.ActualIncreasingFill)
                                            : this.GetSelectableFillColor(this.DecreasingFill);
                        rc.DrawClippedRectangleAsPolygon(clippingRect, rect, fillColor, actualColor, this.StrokeThickness);
                    }
                }
            }
        }
Пример #46
0
 /// <summary>
 /// Draws the rectangle.
 /// </summary>
 /// <param name="rect">The rectangle.</param>
 /// <param name="fill">The fill color.</param>
 /// <param name="stroke">The stroke color.</param>
 /// <param name="thickness">The stroke thickness.</param>
 public override void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness)
 {
     this.WriteRectangle(rect.Left, rect.Top, rect.Width, rect.Height, this.CreateStyle(fill, stroke, thickness));
 }
        /// <summary>
        /// Renders the image 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);

            var p = this.GetPoint(this.X, this.Y, rc, model);
            var o = this.GetVector(this.OffsetX, this.OffsetY, rc, model);
            var position = p + o;

            var clippingRect = this.GetClippingRect();

            var imageInfo = rc.GetImageInfo(this.ImageSource);
            if (imageInfo == null)
            {
                return;
            }

            var s = this.GetVector(this.Width, this.Height, rc, model);

            var width = s.X;
            var height = s.Y;

            if (double.IsNaN(width) && double.IsNaN(height))
            {
                width = imageInfo.Width;
                height = imageInfo.Height;
            }

            if (double.IsNaN(width))
            {
                width = height / imageInfo.Height * imageInfo.Width;
            }

            if (double.IsNaN(height))
            {
                height = width / imageInfo.Width * imageInfo.Height;
            }

            double x = position.X;
            double y = position.Y;

            if (this.HorizontalAlignment == HorizontalAlignment.Center)
            {
                x -= width * 0.5;
            }

            if (this.HorizontalAlignment == HorizontalAlignment.Right)
            {
                x -= width;
            }

            if (this.VerticalAlignment == VerticalAlignment.Middle)
            {
                y -= height * 0.5;
            }

            if (this.VerticalAlignment == VerticalAlignment.Bottom)
            {
                y -= height;
            }

            this.actualBounds = new OxyRect(x, y, width, height);

            if (this.X.Unit == PlotLengthUnit.Data || this.Y.Unit == PlotLengthUnit.Data)
            {
                rc.DrawClippedImage(clippingRect, this.ImageSource, x, y, width, height, this.Opacity, this.Interpolate);
            }
            else
            {
                rc.DrawImage(this.ImageSource, x, y, width, height, this.Opacity, this.Interpolate);
            }
        }
Пример #48
0
 /// <summary>
 /// Renders the item label.
 /// </summary>
 /// <param name="rc">The render context</param>
 /// <param name="clippingRect">The clipping rectangle</param>
 /// <param name="rect">The rectangle of the item.</param>
 /// <param name="value">The value of the label.</param>
 /// <param name="index">The index of the bar item.</param>
 protected abstract void RenderLabel(
     IRenderContext rc, OxyRect clippingRect, OxyRect rect, double value, int index);
Пример #49
0
 /// <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,
         this.ActualDashArray);
     var midpt = new ScreenPoint(xmid, ymid);
     rc.DrawMarker(
         legendBox,
         midpt,
         this.MarkerType,
         this.MarkerOutline,
         this.MarkerSize,
         this.ActualMarkerFill,
         this.MarkerStroke,
         this.MarkerStrokeThickness);
 }
        /// <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);

            this.CalculateActualMinimumsMaximums();

            this.screenPoints = this.GetScreenPoints();

            // 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;

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

            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);
                    }
                }
            }
        }
Пример #51
0
        /// <summary>
        /// Renders the transformed points as a line (smoothed if <see cref="LineSeries.Smooth"/> is <c>true</c>) and markers (if <see cref="MarkerType"/> is not <c>None</c>).
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        /// <param name="pointsToRender">The points to render.</param>
        protected virtual void RenderLineAndMarkers(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.RenderLine(rc, clippingRect, screenPoints);
            }

            if (this.MarkerType != MarkerType.None)
            {
                var markerBinOffset = this.MarkerResolution > 0 ? this.Transform(this.MinX, this.MinY) : default(ScreenPoint);

                rc.DrawMarkers(
                    clippingRect,
                    pointsToRender,
                    this.MarkerType,
                    this.MarkerOutline,
                    new[] { this.MarkerSize },
                    this.ActualMarkerFill,
                    this.MarkerStroke,
                    this.MarkerStrokeThickness,
                    this.MarkerResolution,
                    markerBinOffset);
            }
        }
Пример #52
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);
        }
Пример #53
0
        /// <summary>
        /// Renders the points as line, broken line and markers.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        /// <param name="points">The points to render.</param>
        protected void RenderPoints(IRenderContext rc, OxyRect clippingRect, ICollection<DataPoint> points)
        {
            var pointEnumerator = points.GetEnumerator();
            var lastValidPoint = new ScreenPoint?();
            var areBrokenLinesRendered = this.BrokenLineThickness > 0 && this.BrokenLineStyle != LineStyle.None;
            var dashArray = areBrokenLinesRendered ? this.BrokenLineStyle.GetDashArray() : null;
            var broken = areBrokenLinesRendered ? new List<ScreenPoint>(2) : null;

            if (this.contiguousScreenPointsBuffer == null)
            {
                this.contiguousScreenPointsBuffer = new List<ScreenPoint>(points.Count);
            }

            while (pointEnumerator.MoveNext() && this.ExtractNextContiguousLineSegment(pointEnumerator, ref lastValidPoint, broken, this.contiguousScreenPointsBuffer))
            {
                if (areBrokenLinesRendered)
                {
                    if (broken.Count > 0)
                    {
                        var actualBrokenLineColor = this.BrokenLineColor.IsAutomatic()
                                                        ? this.ActualColor
                                                        : this.BrokenLineColor;

                        rc.DrawClippedLineSegments(
                            clippingRect,
                            broken,
                            actualBrokenLineColor,
                            this.BrokenLineThickness,
                            dashArray,
                            this.LineJoin,
                            false);
                        broken.Clear();
                    }
                }
                else
                {
                    lastValidPoint = null;
                }

                if (this.Decimator != null)
                {
                    if (this.decimatorBuffer == null)
                    {
                        this.decimatorBuffer = new List<ScreenPoint>(this.contiguousScreenPointsBuffer.Count);
                    }
                    else
                    {
                        this.decimatorBuffer.Clear();
                    }

                    this.Decimator(this.contiguousScreenPointsBuffer, this.decimatorBuffer);
                    this.RenderLineAndMarkers(rc, clippingRect, this.decimatorBuffer);
                }
                else
                {
                    this.RenderLineAndMarkers(rc, clippingRect, this.contiguousScreenPointsBuffer);
                }

                this.contiguousScreenPointsBuffer.Clear();
            }
        }
Пример #54
0
        /// <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.Items.Count == 0)
            {
                return;
            }

            var clippingRect = this.GetClippingRect();

            var outlierScreenPoints = new List <ScreenPoint>();
            var halfBoxWidth        = this.BoxWidth * 0.5;
            var halfWhiskerWidth    = halfBoxWidth * this.WhiskerWidth;
            var strokeColor         = this.GetSelectableColor(this.Stroke);
            var fillColor           = this.GetSelectableFillColor(this.Fill);

            var dashArray = this.LineStyle.GetDashArray();

            foreach (var item in this.Items)
            {
                // Add the outlier points
                outlierScreenPoints.AddRange(item.Outliers.Select(outlier => this.Transform(item.X, outlier)));

                var topWhiskerTop       = this.Transform(item.X, item.UpperWhisker);
                var topWhiskerBottom    = this.Transform(item.X, item.BoxTop);
                var bottomWhiskerTop    = this.Transform(item.X, item.BoxBottom);
                var bottomWhiskerBottom = this.Transform(item.X, item.LowerWhisker);
                rc.DrawClippedLine(
                    clippingRect,
                    new[] { topWhiskerTop, topWhiskerBottom },
                    0,
                    strokeColor,
                    this.StrokeThickness,
                    dashArray,
                    OxyPenLineJoin.Miter,
                    true);
                rc.DrawClippedLine(
                    clippingRect,
                    new[] { bottomWhiskerTop, bottomWhiskerBottom },
                    0,
                    strokeColor,
                    this.StrokeThickness,
                    dashArray,
                    OxyPenLineJoin.Miter,
                    true);

                // Draw the whiskers
                if (this.WhiskerWidth > 0)
                {
                    var topWhiskerLine1    = this.Transform(item.X - halfWhiskerWidth, item.UpperWhisker);
                    var topWhiskerLine2    = this.Transform(item.X + halfWhiskerWidth, item.UpperWhisker);
                    var bottomWhiskerLine1 = this.Transform(item.X - halfWhiskerWidth, item.LowerWhisker);
                    var bottomWhiskerLine2 = this.Transform(item.X + halfWhiskerWidth, item.LowerWhisker);

                    rc.DrawClippedLine(
                        clippingRect,
                        new[] { topWhiskerLine1, topWhiskerLine2 },
                        0,
                        strokeColor,
                        this.StrokeThickness,
                        null,
                        OxyPenLineJoin.Miter,
                        true);
                    rc.DrawClippedLine(
                        clippingRect,
                        new[] { bottomWhiskerLine1, bottomWhiskerLine2 },
                        0,
                        strokeColor,
                        this.StrokeThickness,
                        null,
                        OxyPenLineJoin.Miter,
                        true);
                }

                if (this.ShowBox)
                {
                    // Draw the box
                    var rect = this.GetBoxRect(item);
                    rc.DrawClippedRectangleAsPolygon(clippingRect, rect, fillColor, strokeColor, this.StrokeThickness);
                }

                if (!this.ShowMedianAsDot)
                {
                    // Draw the median line
                    var medianLeft  = this.Transform(item.X - halfBoxWidth, item.Median);
                    var medianRight = this.Transform(item.X + halfBoxWidth, item.Median);
                    rc.DrawClippedLine(
                        clippingRect,
                        new[] { medianLeft, medianRight },
                        0,
                        strokeColor,
                        this.StrokeThickness * this.MedianThickness,
                        null,
                        OxyPenLineJoin.Miter,
                        true);
                }
                else
                {
                    var mc = this.Transform(item.X, item.Median);
                    if (clippingRect.Contains(mc))
                    {
                        var ellipseRect = new OxyRect(
                            mc.X - this.MedianPointSize,
                            mc.Y - this.MedianPointSize,
                            this.MedianPointSize * 2,
                            this.MedianPointSize * 2);
                        rc.DrawEllipse(ellipseRect, fillColor, OxyColors.Undefined, 0);
                    }
                }
            }

            // Draw the outlier(s)
            var markerSizes = outlierScreenPoints.Select(o => this.OutlierSize).ToList();

            rc.DrawMarkers(
                clippingRect,
                outlierScreenPoints,
                this.OutlierType,
                null,
                markerSizes,
                fillColor,
                strokeColor,
                this.StrokeThickness);
        }
Пример #55
0
        /// <summary>
        /// Renders the bar/column item.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="clippingRect">The clipping rectangle.</param>
        /// <param name="topValue">The end value of the bar.</param>
        /// <param name="categoryValue">The category value.</param>
        /// <param name="actualBarWidth">The actual width of the bar.</param>
        /// <param name="item">The item.</param>
        /// <param name="rect">The rectangle of the bar.</param>
        protected override void RenderItem(
            IRenderContext rc,
            OxyRect clippingRect,
            double topValue,
            double categoryValue,
            double actualBarWidth,
            BarItemBase item,
            OxyRect rect)
        {
            base.RenderItem(rc, clippingRect, topValue, categoryValue, actualBarWidth, item, rect);

            var errorItem = item as ErrorColumnItem;
            if (errorItem == null)
            {
                return;
            }

            // Render the error
            var lowerValue = topValue - errorItem.Error;
            var upperValue = topValue + errorItem.Error;
            var left = 0.5 - (this.ErrorWidth / 2);
            var right = 0.5 + (this.ErrorWidth / 2);
            var leftValue = categoryValue + (left * actualBarWidth);
            var middleValue = categoryValue + (0.5 * actualBarWidth);
            var rightValue = categoryValue + (right * actualBarWidth);

            var lowerErrorPoint = this.Transform(middleValue, lowerValue);
            var upperErrorPoint = this.Transform(middleValue, upperValue);

            rc.DrawClippedLine(
                clippingRect,
                new List<ScreenPoint> { lowerErrorPoint, upperErrorPoint },
                0,
                this.StrokeColor,
                this.ErrorStrokeThickness,
                null,
                OxyPenLineJoin.Miter,
                true);

            if (this.ErrorWidth > 0)
            {
                var lowerLeftErrorPoint = this.Transform(leftValue, lowerValue);
                var lowerRightErrorPoint = this.Transform(rightValue, lowerValue);
                rc.DrawClippedLine(
                    clippingRect,
                    new List<ScreenPoint> { lowerLeftErrorPoint, lowerRightErrorPoint },
                    0,
                    this.StrokeColor,
                    this.ErrorStrokeThickness,
                    null,
                    OxyPenLineJoin.Miter,
                    true);

                var upperLeftErrorPoint = this.Transform(leftValue, upperValue);
                var upperRightErrorPoint = this.Transform(rightValue, upperValue);
                rc.DrawClippedLine(
                    clippingRect,
                    new List<ScreenPoint> { upperLeftErrorPoint, upperRightErrorPoint },
                    0,
                    this.StrokeColor,
                    this.ErrorStrokeThickness,
                    null,
                    OxyPenLineJoin.Miter,
                    true);
            }
        }
Пример #56
0
        /// <summary>
        /// Renders the legend symbol on the specified rendering context.
        /// </summary>
        /// <param name="rc">The rendering context.</param>
        /// <param name="legendBox">The legend rectangle.</param>
        public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
        {
            double xmid    = (legendBox.Left + legendBox.Right) / 2;
            double ybottom = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.7);
            double ytop    = legendBox.Top + ((legendBox.Bottom - legendBox.Top) * 0.3);
            double ymid    = (ybottom + ytop) * 0.5;

            var          halfBoxWidth          = legendBox.Width * 0.24;
            var          halfWhiskerWidth      = halfBoxWidth * this.WhiskerWidth;
            const double LegendStrokeThickness = 1;
            var          strokeColor           = this.GetSelectableColor(this.Stroke);
            var          fillColor             = this.GetSelectableFillColor(this.Fill);

            rc.DrawLine(
                new[] { new ScreenPoint(xmid, legendBox.Top), new ScreenPoint(xmid, ytop) },
                strokeColor,
                LegendStrokeThickness,
                LineStyle.Solid.GetDashArray(),
                OxyPenLineJoin.Miter,
                true);

            rc.DrawLine(
                new[] { new ScreenPoint(xmid, ybottom), new ScreenPoint(xmid, legendBox.Bottom) },
                strokeColor,
                LegendStrokeThickness,
                LineStyle.Solid.GetDashArray(),
                OxyPenLineJoin.Miter,
                true);

            if (this.WhiskerWidth > 0)
            {
                // top whisker
                rc.DrawLine(
                    new[]
                {
                    new ScreenPoint(xmid - halfWhiskerWidth - 1, legendBox.Bottom),
                    new ScreenPoint(xmid + halfWhiskerWidth, legendBox.Bottom)
                },
                    strokeColor,
                    LegendStrokeThickness,
                    LineStyle.Solid.GetDashArray(),
                    OxyPenLineJoin.Miter,
                    true);

                // bottom whisker
                rc.DrawLine(
                    new[]
                {
                    new ScreenPoint(xmid - halfWhiskerWidth - 1, legendBox.Top),
                    new ScreenPoint(xmid + halfWhiskerWidth, legendBox.Top)
                },
                    strokeColor,
                    LegendStrokeThickness,
                    LineStyle.Solid.GetDashArray(),
                    OxyPenLineJoin.Miter,
                    true);
            }

            if (this.ShowBox)
            {
                // box
                rc.DrawRectangleAsPolygon(
                    new OxyRect(xmid - halfBoxWidth, ytop, 2 * halfBoxWidth, ybottom - ytop),
                    fillColor,
                    strokeColor,
                    LegendStrokeThickness);
            }

            // median
            if (!this.ShowMedianAsDot)
            {
                rc.DrawLine(
                    new[] { new ScreenPoint(xmid - halfBoxWidth, ymid), new ScreenPoint(xmid + halfBoxWidth, ymid) },
                    strokeColor,
                    LegendStrokeThickness * this.MedianThickness,
                    LineStyle.Solid.GetDashArray(),
                    OxyPenLineJoin.Miter,
                    true);
            }
            else
            {
                var ellipseRect = new OxyRect(
                    xmid - this.MedianPointSize,
                    ymid - this.MedianPointSize,
                    this.MedianPointSize * 2,
                    this.MedianPointSize * 2);
                rc.DrawEllipse(ellipseRect, fillColor, OxyColors.Undefined);
            }
        }
		private RectangleF ToRectangle(OxyRect rect)
        {
            return new RectangleF((int)rect.Left, (int)rect.Top, (int)rect.Width, (int)rect.Height);
        }
Пример #58
0
        /// <summary>
        /// Updates the intervals.
        /// </summary>
        /// <param name="plotArea">
        /// The plot area.
        /// </param>
        internal override void UpdateIntervals(OxyRect plotArea)
        {
            base.UpdateIntervals(plotArea);
            switch (this.actualIntervalType)
            {
            case DateTimeIntervalType.Years:
                this.ActualMinorStep         = 31;
                this.actualMinorIntervalType = DateTimeIntervalType.Years;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "yyyy";
                }

                break;

            case DateTimeIntervalType.Months:
                this.actualMinorIntervalType = DateTimeIntervalType.Months;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "yyyy-MM-dd";
                }

                break;

            case DateTimeIntervalType.Weeks:
                this.actualMinorIntervalType = DateTimeIntervalType.Days;
                this.ActualMajorStep         = 7;
                this.ActualMinorStep         = 1;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "yyyy/ww";
                }

                break;

            case DateTimeIntervalType.Days:
                this.ActualMinorStep = this.ActualMajorStep;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "yyyy-MM-dd";
                }

                break;

            case DateTimeIntervalType.Hours:
                this.ActualMinorStep = this.ActualMajorStep;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "HH:mm";
                }

                break;

            case DateTimeIntervalType.Minutes:
                this.ActualMinorStep = this.ActualMajorStep;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "HH:mm";
                }

                break;

            case DateTimeIntervalType.Seconds:
                this.ActualMinorStep = this.ActualMajorStep;
                if (this.ActualStringFormat == null)
                {
                    this.ActualStringFormat = "HH:mm:ss";
                }

                break;

            case DateTimeIntervalType.Manual:
                break;

            case DateTimeIntervalType.Auto:
                break;
            }
        }
Пример #59
0
 /// <summary>
 /// Renders the legend symbol on the specified rendering context.
 /// </summary>
 /// <param name="rc">The rendering context.</param>
 /// <param name="legendBox">The legend rectangle.</param>
 public override void RenderLegend(IRenderContext rc, OxyRect legendBox)
 {
     double xmid = (legendBox.Left + legendBox.Right) / 2;
     double ymid = (legendBox.Top + legendBox.Bottom) / 2;
     double height = (legendBox.Bottom - legendBox.Top) * 0.8;
     double width = height;
     rc.DrawRectangleAsPolygon(
         new OxyRect(xmid - (0.5 * width), ymid - (0.5 * height), width, height),
         this.GetSelectableFillColor(this.ActualFillColor),
         this.StrokeColor,
         this.StrokeThickness);
 }
Пример #60
0
 /// <summary>
 /// Converts a <see cref="OxyRect" /> to a <see cref="RectangleF" />.
 /// </summary>
 /// <param name="rect">The rectangle to convert.</param>
 /// <returns>The converted rectangle.</returns>
 public static RectangleF Convert(this OxyRect rect)
 {
     return(new RectangleF((float)rect.Left, (float)rect.Top, (float)(rect.Right - rect.Left), (float)(rect.Bottom - rect.Top)));
 }