/// <summary>
        /// Gets the coordinates of the (rotated) background rectangle.
        /// </summary>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="size">
        /// The size.
        /// </param>
        /// <param name="padding">
        /// The padding.
        /// </param>
        /// <param name="rotation">
        /// The rotation.
        /// </param>
        /// <param name="horizontalAlignment">
        /// The horizontal alignment.
        /// </param>
        /// <param name="verticalAlignment">
        /// The vertical alignment.
        /// </param>
        /// <returns>
        /// The background rectangle coordinates.
        /// </returns>
        private static IList <ScreenPoint> GetTextBounds(
            ScreenPoint position,
            OxySize size,
            OxyThickness padding,
            double rotation,
            HorizontalTextAlign horizontalAlignment,
            VerticalTextAlign verticalAlignment)
        {
            double left, right, top, bottom;

            switch (horizontalAlignment)
            {
            case HorizontalTextAlign.Center:
                left  = -size.Width * 0.5;
                right = -left;
                break;

            case HorizontalTextAlign.Right:
                left  = -size.Width;
                right = 0;
                break;

            default:
                left  = 0;
                right = size.Width;
                break;
            }

            switch (verticalAlignment)
            {
            case VerticalTextAlign.Middle:
                top    = -size.Height * 0.5;
                bottom = -top;
                break;

            case VerticalTextAlign.Bottom:
                top    = -size.Height;
                bottom = 0;
                break;

            default:
                top    = 0;
                bottom = size.Height;
                break;
            }

            double cost    = Math.Cos(rotation / 180 * Math.PI);
            double sint    = Math.Sin(rotation / 180 * Math.PI);
            var    u       = new ScreenVector(cost, sint);
            var    v       = new ScreenVector(-sint, cost);
            var    polygon = new ScreenPoint[4];

            polygon[0] = position + u * (left - padding.Left) + v * (top - padding.Top);
            polygon[1] = position + u * (right + padding.Right) + v * (top - padding.Top);
            polygon[2] = position + u * (right + padding.Right) + v * (bottom + padding.Bottom);
            polygon[3] = position + u * (left - padding.Left) + v * (bottom + padding.Bottom);
            return(polygon);
        }
        /// <summary>
        /// Adjusts the plot margins.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <returns><c>true</c> if the margins were adjusted.</returns>
        private bool AdjustPlotMargins(IRenderContext rc)
        {
            var visibleAxes = this.Axes.Where(axis => axis.IsAxisVisible).ToList();

            foreach (var axis in visibleAxes)
            {
                axis.Measure(rc);
            }

            var desiredMargin = new OxyThickness();

            void IncludeInMargin(double size, AxisPosition borderPosition)
            {
                desiredMargin = borderPosition switch
                {
                    AxisPosition.Bottom => new OxyThickness(desiredMargin.Left, desiredMargin.Top, desiredMargin.Right, Math.Max(desiredMargin.Bottom, size)),
                    AxisPosition.Left => new OxyThickness(Math.Max(desiredMargin.Left, size), desiredMargin.Top, desiredMargin.Right, desiredMargin.Bottom),
                    AxisPosition.Right => new OxyThickness(desiredMargin.Left, desiredMargin.Top, Math.Max(desiredMargin.Right, size), desiredMargin.Bottom),
                    AxisPosition.Top => new OxyThickness(desiredMargin.Left, Math.Max(desiredMargin.Top, size), desiredMargin.Right, desiredMargin.Bottom),
                    _ => desiredMargin,
                };
            }

            // include the value of the outermost position tier on each side ('normal' axes only)
            for (var position = AxisPosition.Left; position <= AxisPosition.Bottom; position++)
            {
                var axesOfPosition = visibleAxes.Where(a => a.Position == position);
                var requiredSize   = this.AdjustAxesPositions(axesOfPosition);
                IncludeInMargin(requiredSize, position);
            }

            // include the desired margin of all visible axes (including polar axes)
            foreach (var axis in visibleAxes)
            {
                desiredMargin = desiredMargin.Include(axis.DesiredMargin);
            }

            var currentMargin = this.PlotMargins;

            currentMargin = new OxyThickness(
                double.IsNaN(currentMargin.Left) ? desiredMargin.Left : currentMargin.Left,
                double.IsNaN(currentMargin.Top) ? desiredMargin.Top : currentMargin.Top,
                double.IsNaN(currentMargin.Right) ? desiredMargin.Right : currentMargin.Right,
                double.IsNaN(currentMargin.Bottom) ? desiredMargin.Bottom : currentMargin.Bottom);

            if (currentMargin.Equals(this.ActualPlotMargins))
            {
                return(false);
            }

            this.ActualPlotMargins = currentMargin;
            return(true);
        }
        /// <summary>
        /// Draws the rectangle as an aliased polygon.
        /// (makes sure pixel alignment is the same as for lines)
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="rect">
        /// The rectangle.
        /// </param>
        /// <param name="fill">
        /// The fill.
        /// </param>
        /// <param name="stroke">
        /// The stroke.
        /// </param>
        /// <param name="thickness">
        /// The thickness.
        /// </param>
        public static void DrawRectangleAsPolygon(
            this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, OxyThickness thickness)
        {
            if (thickness.Left.Equals(thickness.Right) && thickness.Left.Equals(thickness.Top) &&
                thickness.Left.Equals(thickness.Bottom))
            {
                DrawRectangleAsPolygon(rc, rect, fill, stroke, thickness.Left);
                return;
            }

            var sp0 = new ScreenPoint(rect.Left, rect.Top);
            var sp1 = new ScreenPoint(rect.Right, rect.Top);
            var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
            var sp3 = new ScreenPoint(rect.Left, rect.Bottom);

            rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, null, 0, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp0, sp1 }, null, stroke, thickness.Top, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp1, sp2 }, null, stroke, thickness.Right, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp2, sp3 }, null, stroke, thickness.Bottom, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp3, sp0 }, null, stroke, thickness.Left, null, OxyPenLineJoin.Miter, true);
        }
示例#4
0
        public LoadTestChart(List<Heartbeat> heartbeats)
        {
            Background = OxyColors.Transparent;
            PlotAreaBorderThickness = new OxyThickness(1, 0, 0, 1);
            Padding = new OxyThickness(15, 30, 30, 20);
            LegendPosition = LegendPosition.LeftTop;
            LegendPlacement = LegendPlacement.Inside;

            Series.Add(new LineSeries
            {
                ItemsSource = heartbeats,
                DataFieldX = "TotalRuntime",
                DataFieldY = "TotalErrors",
                Color = OxyColors.Red,
                Title = "Errors",
                Smooth = false
            });

            Series.Add(new LineSeries
            {
                ItemsSource = heartbeats,
                DataFieldX = "TotalRuntime",
                DataFieldY = "TotalThreads",
                Color = OxyColors.Green,
                Title = "Threads",
                Smooth = false
            });

            Series.Add(new LineSeries
            {
                ItemsSource = heartbeats,
                DataFieldX = "TotalRuntime",
                DataFieldY = "Throughput",
                Color = OxyColors.DodgerBlue,
                Title = "Throughput",
                Smooth = false
            });
        }
示例#5
0
        /// <summary>
        /// Increases margin size if needed, do it on the specified border.
        /// </summary>
        /// <param name="currentMargin">The current margin.</param>
        /// <param name="minBorderSize">Minimum size of the border.</param>
        /// <param name="borderPosition">The border position.</param>
        private static void EnsureMarginIsBigEnough(ref OxyThickness currentMargin, double minBorderSize, AxisPosition borderPosition)
        {
            switch (borderPosition)
            {
            case AxisPosition.Bottom:
                currentMargin = new OxyThickness(currentMargin.Left, currentMargin.Top, currentMargin.Right, Math.Max(currentMargin.Bottom, minBorderSize));
                break;

            case AxisPosition.Left:
                currentMargin = new OxyThickness(Math.Max(currentMargin.Left, minBorderSize), currentMargin.Top, currentMargin.Right, currentMargin.Bottom);
                break;

            case AxisPosition.Right:
                currentMargin = new OxyThickness(currentMargin.Left, currentMargin.Top, Math.Max(currentMargin.Right, minBorderSize), currentMargin.Bottom);
                break;

            case AxisPosition.Top:
                currentMargin = new OxyThickness(currentMargin.Left, Math.Max(currentMargin.Top, minBorderSize), currentMargin.Right, currentMargin.Bottom);
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#6
0
 /// <summary>
 /// Determines whether this instance and another specified <see cref="T:OxyThickness" /> object have the same value.
 /// </summary>
 /// <param name="other">The thickness to compare to this instance.</param>
 /// <returns><c>true</c> if the value of the <paramref name="other" /> parameter is the same as the value of this instance; otherwise, <c>false</c>.</returns>
 public bool Equals(OxyThickness other)
 {
     return(this.Left.Equals(other.Left) && this.Top.Equals(other.Top) && this.Width.Equals(other.Width) && this.Height.Equals(other.Height));
 }
        /// <summary>
        /// Draws the rectangle as an aliased polygon.
        /// (makes sure pixel alignment is the same as for lines)
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="rect">
        /// The rectangle.
        /// </param>
        /// <param name="fill">
        /// The fill.
        /// </param>
        /// <param name="stroke">
        /// The stroke.
        /// </param>
        /// <param name="thickness">
        /// The thickness.
        /// </param>
        public static void DrawRectangleAsPolygon(
            this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, OxyThickness thickness)
        {
            if (thickness.Left == thickness.Right && thickness.Left == thickness.Top
                && thickness.Left == thickness.Bottom)
            {
                DrawRectangleAsPolygon(rc, rect, fill, stroke, thickness.Left);
                return;
            }

            var sp0 = new ScreenPoint(rect.Left, rect.Top);
            var sp1 = new ScreenPoint(rect.Right, rect.Top);
            var sp2 = new ScreenPoint(rect.Right, rect.Bottom);
            var sp3 = new ScreenPoint(rect.Left, rect.Bottom);
            rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, null, 0, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp0, sp1 }, null, stroke, thickness.Top, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp1, sp2 }, null, stroke, thickness.Right, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp2, sp3 }, null, stroke, thickness.Bottom, null, OxyPenLineJoin.Miter, true);
            rc.DrawPolygon(new[] { sp3, sp0 }, null, stroke, thickness.Left, null, OxyPenLineJoin.Miter, true);
        }
示例#8
0
 /// <summary>
 /// Creates a new <see cref="OxyThickness"/> with the maximum dimensions of this instance and the specified other instance.
 /// </summary>
 /// <param name="other">The other instance.</param>
 /// <returns>A new <see cref="OxyThickness"/>.</returns>
 public OxyThickness Include(OxyThickness other)
 {
     return(new OxyThickness(Math.Max(other.Left, this.Left), Math.Max(other.Top, this.Top), Math.Max(other.Right, this.Right), Math.Max(other.Bottom, this.Bottom)));
 }
示例#9
0
 /// <summary>
 /// Determines whether this instance and another specified <see cref="T:OxyThickness" /> object have the same value.
 /// </summary>
 /// <param name="other">The thickness to compare to this instance.</param>
 /// <returns><c>true</c> if the value of the <paramref name="other" /> parameter is the same as the value of this instance; otherwise, <c>false</c>.</returns>
 public bool Equals(OxyThickness other)
 {
     return(this.Left.Equals(other.Left) && this.Top.Equals(other.Top) && this.Right.Equals(other.Right) && this.Bottom.Equals(other.Bottom));
 }
        /// <summary>
        /// Gets the coordinates of the (rotated) background rectangle.
        /// </summary>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="size">
        /// The size.
        /// </param>
        /// <param name="padding">
        /// The padding.
        /// </param>
        /// <param name="rotation">
        /// The rotation.
        /// </param>
        /// <param name="horizontalAlignment">
        /// The horizontal alignment.
        /// </param>
        /// <param name="verticalAlignment">
        /// The vertical alignment.
        /// </param>
        /// <returns>
        /// The background rectangle coordinates.
        /// </returns>
        private static IList<ScreenPoint> GetTextBounds(
            ScreenPoint position,
            OxySize size,
            OxyThickness padding,
            double rotation,
            HorizontalTextAlign horizontalAlignment,
            VerticalTextAlign verticalAlignment)
        {
            double left, right, top, bottom;
            switch (horizontalAlignment)
            {
                case HorizontalTextAlign.Center:
                    left = -size.Width * 0.5;
                    right = -left;
                    break;
                case HorizontalTextAlign.Right:
                    left = -size.Width;
                    right = 0;
                    break;
                default:
                    left = 0;
                    right = size.Width;
                    break;
            }

            switch (verticalAlignment)
            {
                case VerticalTextAlign.Middle:
                    top = -size.Height * 0.5;
                    bottom = -top;
                    break;
                case VerticalTextAlign.Bottom:
                    top = -size.Height;
                    bottom = 0;
                    break;
                default:
                    top = 0;
                    bottom = size.Height;
                    break;
            }

            double cost = Math.Cos(rotation / 180 * Math.PI);
            double sint = Math.Sin(rotation / 180 * Math.PI);
            var u = new ScreenVector(cost, sint);
            var v = new ScreenVector(-sint, cost);
            var polygon = new ScreenPoint[4];
            polygon[0] = position + u * (left - padding.Left) + v * (top - padding.Top);
            polygon[1] = position + u * (right + padding.Right) + v * (top - padding.Top);
            polygon[2] = position + u * (right + padding.Right) + v * (bottom + padding.Bottom);
            polygon[3] = position + u * (left - padding.Left) + v * (bottom + padding.Bottom);
            return polygon;
        }
示例#11
0
        /// <summary>
        /// Increases margin size if needed, do it on the specified border.
        /// </summary>
        /// <param name="currentMargin">The current margin.</param>
        /// <param name="minBorderSize">Minimum size of the border.</param>
        /// <param name="borderPosition">The border position.</param>
        private static void EnsureMarginIsBigEnough(ref OxyThickness currentMargin, double minBorderSize, AxisPosition borderPosition)
        {
            switch (borderPosition)
            {
                case AxisPosition.Bottom:
                    currentMargin.Bottom = Math.Max(currentMargin.Bottom, minBorderSize);
                    break;

                case AxisPosition.Left:
                    currentMargin.Left = Math.Max(currentMargin.Left, minBorderSize);
                    break;

                case AxisPosition.Right:
                    currentMargin.Right = Math.Max(currentMargin.Right, minBorderSize);
                    break;

                case AxisPosition.Top:
                    currentMargin.Top = Math.Max(currentMargin.Top, minBorderSize);
                    break;

                default:
                    throw new NotImplementedException();
            }
        }
示例#12
0
 /// <summary>
 /// Returns a rectangle that is shrunk by the specified thickness, in all directions.
 /// </summary>
 /// <param name="t">The thickness to apply to the rectangle.</param>
 /// <returns>The deflated <see cref="OxyRect" />.</returns>
 public OxyRect Deflate(OxyThickness t)
 {
     return(new OxyRect(this.left + t.Left, this.top + t.Top, Math.Max(0, this.width - t.Left - t.Right), Math.Max(0, this.height - t.Top - t.Bottom)));
 }
示例#13
0
 /// <summary>
 /// Returns a rectangle that is expanded by the specified thickness, in all directions.
 /// </summary>
 /// <param name="t">The thickness to apply to the rectangle.</param>
 /// <returns>The inflated <see cref="OxyRect" />.</returns>
 public OxyRect Inflate(OxyThickness t)
 {
     return(new OxyRect(this.left - t.Left, this.top - t.Top, this.width + t.Left + t.Right, this.height + t.Top + t.Bottom));
 }
示例#14
0
 /// <summary>
 /// Determines whether this instance and another specified <see cref="T:OxyThickness" /> object have the same value.
 /// </summary>
 /// <param name="other">The thickness to compare to this instance.</param>
 /// <returns><c>true</c> if the value of the <paramref name="other" /> parameter is the same as the value of this instance; otherwise, <c>false</c>.</returns>
 public bool Equals(OxyThickness other)
 {
     return this.Left.Equals(other.Left) && this.Top.Equals(other.Top) && this.Width.Equals(other.Width) && this.Height.Equals(other.Height);
 }
示例#15
0
        /// <summary>
        /// Draws the outline of a rectangle with individual stroke thickness for each side.
        /// </summary>
        /// <param name="rc">The render context.</param>
        /// <param name="rect">The rectangle.</param>
        /// <param name="stroke">The stroke color.</param>
        /// <param name="thickness">The thickness.</param>
        /// <param name="edgeRenderingMode">The edge rendering mode.</param>
        public static void DrawRectangle(this IRenderContext rc, OxyRect rect, OxyColor stroke, OxyThickness thickness, EdgeRenderingMode edgeRenderingMode)
        {
            if (thickness.Left.Equals(thickness.Right) && thickness.Left.Equals(thickness.Top) && thickness.Left.Equals(thickness.Bottom))
            {
                rc.DrawRectangle(rect, OxyColors.Undefined, stroke, thickness.Left, edgeRenderingMode);
                return;
            }

            var adjustedLeft   = rect.Left - thickness.Left / 2 + 0.5;
            var adjustedRight  = rect.Right + thickness.Right / 2 - 0.5;
            var adjustedTop    = rect.Top - thickness.Top / 2 + 0.5;
            var adjustedBottom = rect.Bottom + thickness.Bottom / 2 - 0.5;

            var pointsTop    = new[] { new ScreenPoint(adjustedLeft, rect.Top), new ScreenPoint(adjustedRight, rect.Top) };
            var pointsRight  = new[] { new ScreenPoint(rect.Right, adjustedTop), new ScreenPoint(rect.Right, adjustedBottom) };
            var pointsBottom = new[] { new ScreenPoint(adjustedLeft, rect.Bottom), new ScreenPoint(adjustedRight, rect.Bottom) };
            var pointsLeft   = new[] { new ScreenPoint(rect.Left, adjustedTop), new ScreenPoint(rect.Left, adjustedBottom) };

            rc.DrawLine(pointsTop, stroke, thickness.Top, edgeRenderingMode, null, LineJoin.Miter);
            rc.DrawLine(pointsRight, stroke, thickness.Right, edgeRenderingMode, null, LineJoin.Miter);
            rc.DrawLine(pointsBottom, stroke, thickness.Bottom, edgeRenderingMode, null, LineJoin.Miter);
            rc.DrawLine(pointsLeft, stroke, thickness.Left, edgeRenderingMode, null, LineJoin.Miter);
        }