/// <summary>
        /// Renders the Series on the specified rendering context.
        /// </summary>
        /// <param name="rc">
        /// The rendering context.
        /// </param>
        /// <param name="model">
        /// The model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            this.ActualBarRectangles = new List <OxyRect>();

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

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

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

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

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

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

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

                this.ActualBarRectangles.Add(rectangle);

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

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

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

                    rc.DrawClippedText(
                        clippingRect,
                        pt,
                        s,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        0,
                        HorizontalTextAlign.Center,
                        VerticalTextAlign.Middle);
                }
            }
        }
Example #2
0
 /// <summary>
 /// Gets the rectangle for the specified values.
 /// </summary>
 /// <param name="baseValue">
 /// The base value of the bar
 /// </param>
 /// <param name="topValue">
 /// The top value of the bar
 /// </param>
 /// <param name="beginValue">
 /// The begin value of the bar
 /// </param>
 /// <param name="endValue">
 /// The end value of the bar
 /// </param>
 /// <returns>
 /// The rectangle.
 /// </returns>
 protected override OxyRect GetRectangle(double baseValue, double topValue, double beginValue, double endValue)
 {
     return(OxyRect.Create(this.Transform(baseValue, beginValue), this.Transform(topValue, endValue)));
 }
Example #3
0
        /// <summary>
        /// Renders the line annotation.
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="model">
        /// The plot model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            base.Render(rc, model);

            bool aliased = false;

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

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

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

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

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

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

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

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

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

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

            var points = new List <DataPoint>();

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

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

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

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

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

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

                        y += dy;
                    }
                }
            }

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

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

            const double MinimumSegmentLength = 4;

            IList <ScreenPoint> clippedPoints = null;

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

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

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

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

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

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

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

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

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

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

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

                var cs = new CohenSutherlandClipping(clippingRectangle);
                if (!string.IsNullOrEmpty(this.Text) && cs.IsInside(position))
                {
                    rc.DrawClippedText(
                        clippingRectangle,
                        position,
                        this.Text,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        angle,
                        this.TextHorizontalAlignment,
                        this.TextVerticalAlignment);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Renders the Series on the specified rendering context.
        /// </summary>
        /// <param name="rc">
        /// The rendering context.
        /// </param>
        /// <param name="model">
        /// The model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            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(
                    rectangle,
                    clippingRect,
                    this.GetSelectableFillColor(item.Color ?? this.ActualFillColor),
                    this.StrokeColor,
                    this.StrokeThickness);

                if (this.LabelFormatString != null)
                {
                    var s = StringHelper.Format(
                        this.ActualCulture,
                        this.LabelFormatString,
                        this.GetItem(i),
                        item.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,
                        HorizontalTextAlign.Center,
                        VerticalTextAlign.Middle);
                }

                i++;
            }
        }
Example #5
0
        /// <summary>
        /// Renders the Series on the specified rendering context.
        /// </summary>
        /// <param name="rc">
        /// The rendering context.
        /// </param>
        /// <param name="model">
        /// The model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            this.ActualMinimumBarRectangles = new List <OxyRect>();
            this.ActualMaximumBarRectangles = new List <OxyRect>();

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

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

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

                var categoryIndex = item.GetCategoryIndex(i);

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

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

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

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

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

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

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

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

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