Ejemplo n.º 1
0
        private void ArrangeRadially(double angle, Point center, double radius)
        {
            Point location = RadialGaugePanel.CreateRotatedPoint(angle, radius, center, RadRadialGauge.GetIndicatorRadiusScale(this));

            Canvas.SetLeft(this.visualElement, location.X);
            Canvas.SetTop(this.visualElement, location.Y);
        }
Ejemplo n.º 2
0
        private void ArrangeLabel(ContentPresenter label, Size finalSize, double currentTickAngle, double radiusScale)
        {
            Size   desiredSize = label.DesiredSize;
            double radius      = Math.Min(finalSize.Width, finalSize.Height) / 2;
            Point  center      = GetIndicatorOffset(desiredSize, finalSize);

            var gauge = this.OwnerGauge as RadRadialGauge;

            double angle = 0;

            if (this.sweepDir == SweepDirection.Clockwise)
            {
                angle = RadialGaugePanel.ConvertDegreesToRadians(gauge.MinAngle) + RadialGaugePanel.ConvertDegreesToRadians(currentTickAngle);
            }
            else
            {
                angle = RadialGaugePanel.ConvertDegreesToRadians(gauge.MaxAngle) - RadialGaugePanel.ConvertDegreesToRadians(currentTickAngle);
            }

            Point labelPosition = CreateRotatedPoint(angle, radius, center, radiusScale);

            if ((TickType)label.GetValue(RadGauge.TickTypeProperty) == TickType.Label)
            {
                labelPosition.X -= desiredSize.Width * Math.Cos(angle) / 3;
            }

            label.Arrange(new Rect(labelPosition, desiredSize));
        }
Ejemplo n.º 3
0
        private void ArrangeMarker(Size desiredSize, double newValue)
        {
            if (this.Owner == null)
            {
                return;
            }

            double radius = Math.Min(desiredSize.Width, desiredSize.Height) / 2;

            switch (this.Owner.OwnerGauge.GaugeType)
            {
            case GaugeType.Linear:
                double distance = RadGauge.MapLogicalToPhysicalValue(newValue - this.minValue, this.isHorizontal ? desiredSize.Width : desiredSize.Height, this.MinMaxValueDifference);
                this.ArrangeLinearly(distance, this.CreateStartPoint(desiredSize), this.CreateDirection());
                break;

            case GaugeType.Radial:
                double angleInDegrees = RadGauge.MapLogicalToPhysicalValue(newValue - this.Owner.OwnerGauge.MinValue, this.maxAngle - this.minAngle, this.MinMaxValueDifference);
                double currentAngle   = this.minAngle + angleInDegrees;

                if (this.IsRotated)
                {
                    this.visualElementRotation.Angle = this.initialRotationAngle + currentAngle;
                }
                else
                {
                    this.visualElementRotation.Angle = this.initialRotationAngle;
                }

                double angleInRadians = RadialGaugePanel.ConvertDegreesToRadians(currentAngle);
                Point  center         = new Point((desiredSize.Width / 2) - (this.visualElement.DesiredSize.Width / 2), (desiredSize.Height / 2) - (this.visualElement.DesiredSize.Height / 2));
                this.ArrangeRadially(angleInRadians, center, radius);
                break;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Calculates and angle in degrees based on a value, a value range, an angle range and a sweep direction.
        /// </summary>
        /// <param name="context">A context that contains the value to be converted to an angle.</param>
        /// <returns>Returns an angle in radians that corresponds to the provided value in the context.</returns>
        internal static double CalculateAngle(CalculateAngleContext context)
        {
            double angleDeg = RadGauge.MapLogicalToPhysicalValue(context.value - context.startValue, context.gaugePhysicalLength, context.gaugeLogicalLength);

            var angle = RadialGaugePanel.ConvertDegreesToRadians(angleDeg);

            return(RadialGaugePanel.ConvertDegreesToRadians(context.minAngle) + angle);
        }
Ejemplo n.º 5
0
        private void UpdateCore()
        {
            var    startAngle = RadialGaugePanel.ConvertDegreesToRadians(this.MinAngle);
            double angle      = RadialGaugePanel.CalculateAngle(this.CreateCalculateAngleContext(this.ActualValue));

            if (startAngle > angle)
            {
                var tmp = startAngle;
                startAngle = angle;
                angle      = tmp;
            }

            this.figure.StartPoint = RadialGaugePanel.CreateRotatedPoint(startAngle, this.Radius, this.Center, this.RadiusScale);
            RadialBarGaugeIndicator.UpdateArc(this.CreateUpdateArcContext(angle, startAngle / Math.PI * 180));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Updates an arc segment with the provided data.
        /// </summary>
        /// <param name="context">A context for the arc to be updated. the arc to update is a part of the context.</param>
        internal static void UpdateArc(UpdateArcContext context)
        {
            context.angle = context.arc.SweepDirection == SweepDirection.Clockwise ? context.angle : -context.angle;

            var arcWidth = Math.Abs(context.angle - RadialGaugePanel.ConvertDegreesToRadians(context.minAngle));

            // Ensure that start and endpoint will not match, so that arc is displayed.
            if (arcWidth >= 2 * Math.PI)
            {
                context.angle -= Math.Sign(context.angle - context.minAngle) * 0.01;
            }

            Point arcEndPoint = RadialGaugePanel.CreateRotatedPoint(context.angle, context.radius, context.center, 1);

            context.arc.IsLargeArc = arcWidth > Math.PI;
            context.arc.Size       = new Size(context.radius, context.radius);
            context.arc.Point      = arcEndPoint;
        }
        /// <summary>
        /// This method is called whenever the segments
        /// need to recreate their visual representation.
        /// </summary>
        /// <param name="availableSize">The available size which the visual parts can occupy.</param>
        internal override void ResetSegments(Size availableSize)
        {
            this.PrepareReset(availableSize);
            this.SegmentInfos.Clear();

            var currentstartAngle = this.minAngle;
            var angleSpan         = this.maxAngle - this.minAngle;

            foreach (BarIndicatorSegment segment in this.Segments)
            {
                if (segment.Path == null)
                {
                    Debug.Assert(false, "Missing segment path.");
                    continue;
                }

                double lengthRatio = segment.Length / this.TotalSegmentLength;
                double angle       = currentstartAngle + (angleSpan * lengthRatio);

                PathFigure figure = new PathFigure();
                double     startAngleInRadians = RadialGaugePanel.ConvertDegreesToRadians(currentstartAngle);
                figure.StartPoint = RadialGaugePanel.CreateRotatedPoint(startAngleInRadians, this.radius, this.center, this.radiusScale);

                ArcSegment newArc = new ArcSegment();
                newArc.Point          = figure.StartPoint;
                newArc.SweepDirection = SweepDirection.Clockwise;
                this.SegmentInfos.Add(new SegmentInfo()
                {
                    PathSegment = newArc, Start = startAngleInRadians, End = RadialGaugePanel.ConvertDegreesToRadians(angle)
                });

                figure.Segments.Add(newArc);

                PathGeometry pathGeom = new PathGeometry();
                pathGeom.Figures.Add(figure);

                Path path = segment.Path;
                path.Stroke          = segment.Stroke;
                path.StrokeThickness = segment.Thickness;
                path.Data            = pathGeom;

                currentstartAngle = angle;
            }
        }
        /// <summary>
        /// This method is called so that a segmented indicator can synchronize
        /// its visual state with its current value.
        /// </summary>
        /// <param name="value">The value to synchronize with.</param>
        internal override void SyncWithValue(double value)
        {
            double currentAngle = RadialGaugePanel.CalculateAngle(this.CreateCalculateAngleContext(value));

            foreach (SegmentInfo info in this.SegmentInfos)
            {
                ArcSegment arc = (ArcSegment)info.PathSegment;
                if (currentAngle >= info.Start && currentAngle <= info.End)
                {
                    RadialBarGaugeIndicator.UpdateArc(this.CreateUpdateArcContext(currentAngle, arc));
                    arc.IsLargeArc = Math.Abs(currentAngle - info.Start) > Math.PI;
                }
                else if (currentAngle > info.End)
                {
                    RadialBarGaugeIndicator.UpdateArc(this.CreateUpdateArcContext(info.End, arc));
                    arc.IsLargeArc = Math.Abs(info.End - info.Start) > Math.PI;
                }
                else if (currentAngle <= info.Start)
                {
                    RadialBarGaugeIndicator.UpdateArc(this.CreateUpdateArcContext(info.Start, arc));
                    arc.IsLargeArc = false;
                }
            }
        }