Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public partial class RoundGauge : UserControl
- {
- private double angle;
- private double minValue;
- private double maxValue;
- public RoundGauge()
- {
- InitializeComponent();
- angle = 0;
- DisplayedValue.Text = Value.ToString();
- CalculateAngle();
- UpdateVisibleArc();
- }
- public static readonly DependencyProperty ValueProperty =
- DependencyProperty.Register("Value", typeof(double), typeof(RoundGauge), new PropertyMetadata(0.0, OnValueChanged));
- public double Value
- {
- get { return (double)GetValue(ValueProperty); }
- set { SetValue(ValueProperty, value); }
- }
- private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- RoundGauge roundGauge = (RoundGauge)d;
- double newValue = (double)e.NewValue;
- if (newValue < roundGauge.MinValue) roundGauge.MinValue = roundGauge.Value;
- if (newValue > roundGauge.MaxValue) roundGauge.MaxValue = roundGauge.Value;
- roundGauge.DisplayedValue.Text = newValue.ToString();
- roundGauge.CalculateAngle();
- roundGauge.UpdateVisibleArc();
- }
- public double MinValue { get => minValue; set => minValue = value; }
- public double MaxValue { get => maxValue; set => maxValue = value; }
- private void CalculateAngle()
- {
- double valueRange = maxValue - minValue;
- double normalizedValue = (Value - minValue) / valueRange;
- angle = normalizedValue * 360;
- }
- private void UpdateVisibleArc()
- {
- GaugeCanvas.Children.Clear();
- var clipGeometry = CreateClipGeometry();
- var gradientStops = CreateGradientStops();
- var startPoint = CalculateStartPoint();
- var endPoint = CalculateEndPoint();
- var gradEndPoint = CalculateGradEndPoint();
- var donutRing = CreateDonutRing(clipGeometry, gradientStops, startPoint, gradEndPoint);
- var circlesPoint = CalculateCirclesPoint(endPoint);
- var circle1 = CreateCircle(circlesPoint, 7, new SolidColorBrush(Color.FromRgb(217, 217, 217)));
- var circle2 = CreateCircle(circlesPoint, 10, new SolidColorBrush(Color.FromRgb(187, 112, 0)));
- var circle3 = CreateCircle(circlesPoint, 12, new SolidColorBrush(Color.FromArgb(51, 187, 112, 0)));
- var circle4 = CreateCircleWithBlur(circlesPoint, 14, new SolidColorBrush(Color.FromArgb(51, 187, 112, 0)));
- if (angle == 360)
- {
- GaugeCanvas.Children.Add(donutRing);
- GaugeCanvas.Children.Add(circle4);
- GaugeCanvas.Children.Add(circle3);
- GaugeCanvas.Children.Add(circle2);
- GaugeCanvas.Children.Add(circle1);
- return;
- }
- var visibleArc = CreateVisibleArc(startPoint, endPoint);
- donutRing.Clip = visibleArc.Data;
- GaugeCanvas.Children.Add(donutRing);
- GaugeCanvas.Children.Add(circle4);
- GaugeCanvas.Children.Add(circle3);
- GaugeCanvas.Children.Add(circle2);
- GaugeCanvas.Children.Add(circle1);
- }
- private PathGeometry CreateClipGeometry()
- {
- var clipGeometry = new PathGeometry();
- var outerCircleGeometry = new EllipseGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
- var innerCircleGeometry = new EllipseGeometry(new Rect(ActualWidth * 0.05, ActualHeight * 0.05, ActualWidth * 0.9, ActualHeight * 0.9));
- clipGeometry.AddGeometry(outerCircleGeometry);
- clipGeometry.AddGeometry(innerCircleGeometry);
- return clipGeometry;
- }
- private GradientStopCollection CreateGradientStops()
- {
- var gradientStops = new GradientStopCollection
- {
- new GradientStop(Color.FromRgb(187, 112, 0), 0),
- new GradientStop(Color.FromRgb(43, 41, 48), 0.6)
- };
- return gradientStops;
- }
- private Point CalculateStartPoint()
- {
- var startAngle = (0 - 210) * Math.PI / 180;
- var startPoint = new Point(ActualWidth / 2 + Math.Cos(startAngle) * ActualWidth / 2, ActualHeight / 2 + Math.Sin(startAngle) * ActualHeight / 2);
- return startPoint;
- }
- private Point CalculateEndPoint()
- {
- var endAngle = (angle + 150) * Math.PI / 180;
- var endPoint = new Point(ActualWidth / 2 + Math.Cos(endAngle) * ActualWidth / 2, ActualHeight / 2 + Math.Sin(endAngle) * ActualHeight / 2);
- return endPoint;
- }
- private Point CalculateGradEndPoint()
- {
- var gradAngle = (angle - 210) * Math.PI / 180;
- var value1 = Math.Sin(gradAngle);
- var value2 = Math.Cos(gradAngle);
- var normalizedCos = (value2 + 1) * 0.5;
- var normalizedSin = (value1 + 1) * 0.5;
- var endGradAngle = Math.Atan2(normalizedSin - 0.5, normalizedCos - 0.5) + Math.PI;
- var x2 = 0.5 + 0.5 * Math.Cos(endGradAngle);
- var y2 = 0.5 + 0.5 * Math.Sin(endGradAngle);
- var gradEndPoint = new Point(x2, y2);
- return gradEndPoint;
- }
- private Path CreateDonutRing(PathGeometry clipGeometry, GradientStopCollection gradientStops, Point startPoint, Point gradEndPoint)
- {
- var gradAngle = (angle - 210) * Math.PI / 180;
- var value1 = Math.Sin(gradAngle);
- var value2 = Math.Cos(gradAngle);
- var normalizedCos = (value2 + 1) * 0.5;
- var normalizedSin = (value1 + 1) * 0.5;
- var donutRing = new Path
- {
- Fill = new LinearGradientBrush(gradientStops)
- {
- StartPoint = new Point(normalizedCos, normalizedSin),
- EndPoint = gradEndPoint,
- },
- Data = clipGeometry
- };
- return donutRing;
- }
- private Point CalculateCirclesPoint(Point endPoint)
- {
- var offset = 8;
- var circlesPoint = new Point();
- if (angle <= 30 || angle >= 300)
- {
- double t = Math.Min(Math.Max((angle - 30) / (360 - 30), 0), 1);
- circlesPoint.X = endPoint.X + offset * (1 - t);
- circlesPoint.Y = endPoint.Y - offset * t;
- }
- else if (angle > 30 && angle <= 120)
- {
- double t = Math.Min(Math.Max((angle - 30) / (120 - 30), 0), 1);
- circlesPoint.X = endPoint.X + offset * (1 - t);
- circlesPoint.Y = endPoint.Y + offset * t;
- }
- else if (angle > 120 - offset && angle <= 210)
- {
- double t = Math.Min(Math.Max((angle - (120 - offset)) / (210 - (120 - offset)), 0), 1);
- circlesPoint.X = endPoint.X - offset * t;
- circlesPoint.Y = endPoint.Y + offset * (1 - t);
- }
- else if (angle > 210 - offset && angle < 300)
- {
- double t = Math.Min(Math.Max((angle - (210 - offset)) / (300 - (210 - offset)), 0), 1);
- circlesPoint.X = endPoint.X - offset * (1 - t);
- circlesPoint.Y = endPoint.Y - offset * t;
- }
- return circlesPoint;
- }
- private Path CreateCircle(Point center, double radius, SolidColorBrush fill)
- {
- var circle = new Path
- {
- Data = new EllipseGeometry(new Rect(new Point(center.X - radius, center.Y - radius), new Size(radius * 2, radius * 2))),
- Fill = fill,
- };
- return circle;
- }
- private Path CreateCircleWithBlur(Point center, double radius, SolidColorBrush fill)
- {
- var circle = new Path
- {
- Data = new EllipseGeometry(new Rect(new Point(center.X - radius, center.Y - radius), new Size(radius * 2, radius * 2))),
- Fill = fill,
- Effect = new BlurEffect
- {
- Radius = 10,
- KernelType = KernelType.Gaussian
- }
- };
- return circle;
- }
- private Path CreateVisibleArc(Point startPoint, Point endPoint)
- {
- var visibleArc = new Path
- {
- Fill = Brushes.Red,
- Data = new PathGeometry
- {
- Figures = new PathFigureCollection
- {
- new PathFigure(new Point(ActualWidth / 2, ActualHeight / 2),
- new List<PathSegment>
- {
- new LineSegment(endPoint, true),
- new ArcSegment(startPoint, new Size(ActualWidth / 2, ActualHeight / 2), 0, angle>=180, SweepDirection.Counterclockwise, true),
- new LineSegment(new Point(ActualWidth / 2, ActualHeight / 2), true)
- },
- true)
- }
- }
- };
- return visibleArc;
- }
- }
- }
Advertisement
Comments
-
- https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/bjkLciTA76c
- https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/2cZdsdJfeQ8
- https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/pyJv-0tIdfw
- https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/BuWe3HAMBgE
- https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/Ez1kvz6Py3c
- https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/FJQPLswJeyk
-
- https://feedback.azure.com/d365community/idea/990cd265-c7b6-ee11-92bc-000d3a033659
Add Comment
Please, Sign In to add comment
Advertisement