Advertisement
TimmyChannel

Round Gauge

Jan 19th, 2024
782
0
Never
2
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.52 KB | None | 0 0
  1. public partial class RoundGauge : UserControl
  2.     {
  3.         private double angle;
  4.         private double minValue;
  5.         private double maxValue;
  6.  
  7.         public RoundGauge()
  8.         {
  9.             InitializeComponent();
  10.             angle = 0;
  11.             DisplayedValue.Text = Value.ToString();
  12.             CalculateAngle();
  13.             UpdateVisibleArc();
  14.         }
  15.  
  16.         public static readonly DependencyProperty ValueProperty =
  17.         DependencyProperty.Register("Value", typeof(double), typeof(RoundGauge), new PropertyMetadata(0.0, OnValueChanged));
  18.  
  19.         public double Value
  20.         {
  21.             get { return (double)GetValue(ValueProperty); }
  22.             set { SetValue(ValueProperty, value); }
  23.         }
  24.  
  25.         private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  26.         {
  27.             RoundGauge roundGauge = (RoundGauge)d;
  28.             double newValue = (double)e.NewValue;
  29.             if (newValue < roundGauge.MinValue) roundGauge.MinValue = roundGauge.Value;
  30.             if (newValue > roundGauge.MaxValue) roundGauge.MaxValue = roundGauge.Value;
  31.             roundGauge.DisplayedValue.Text = newValue.ToString();
  32.             roundGauge.CalculateAngle();
  33.             roundGauge.UpdateVisibleArc();
  34.         }
  35.         public double MinValue { get => minValue; set => minValue = value; }
  36.         public double MaxValue { get => maxValue; set => maxValue = value; }
  37.         private void CalculateAngle()
  38.         {
  39.             double valueRange = maxValue - minValue;
  40.             double normalizedValue = (Value - minValue) / valueRange;
  41.  
  42.             angle = normalizedValue * 360;
  43.         }
  44.         private void UpdateVisibleArc()
  45.         {
  46.             GaugeCanvas.Children.Clear();
  47.  
  48.             var clipGeometry = CreateClipGeometry();
  49.             var gradientStops = CreateGradientStops();
  50.             var startPoint = CalculateStartPoint();
  51.             var endPoint = CalculateEndPoint();
  52.             var gradEndPoint = CalculateGradEndPoint();
  53.             var donutRing = CreateDonutRing(clipGeometry, gradientStops, startPoint, gradEndPoint);
  54.             var circlesPoint = CalculateCirclesPoint(endPoint);
  55.             var circle1 = CreateCircle(circlesPoint, 7, new SolidColorBrush(Color.FromRgb(217, 217, 217)));
  56.             var circle2 = CreateCircle(circlesPoint, 10, new SolidColorBrush(Color.FromRgb(187, 112, 0)));
  57.             var circle3 = CreateCircle(circlesPoint, 12, new SolidColorBrush(Color.FromArgb(51, 187, 112, 0)));
  58.             var circle4 = CreateCircleWithBlur(circlesPoint, 14, new SolidColorBrush(Color.FromArgb(51, 187, 112, 0)));
  59.  
  60.             if (angle == 360)
  61.             {
  62.                 GaugeCanvas.Children.Add(donutRing);
  63.                 GaugeCanvas.Children.Add(circle4);
  64.                 GaugeCanvas.Children.Add(circle3);
  65.                 GaugeCanvas.Children.Add(circle2);
  66.                 GaugeCanvas.Children.Add(circle1);
  67.                 return;
  68.             }
  69.  
  70.             var visibleArc = CreateVisibleArc(startPoint, endPoint);
  71.             donutRing.Clip = visibleArc.Data;
  72.  
  73.             GaugeCanvas.Children.Add(donutRing);
  74.             GaugeCanvas.Children.Add(circle4);
  75.             GaugeCanvas.Children.Add(circle3);
  76.             GaugeCanvas.Children.Add(circle2);
  77.             GaugeCanvas.Children.Add(circle1);
  78.         }
  79.  
  80.         private PathGeometry CreateClipGeometry()
  81.         {
  82.             var clipGeometry = new PathGeometry();
  83.             var outerCircleGeometry = new EllipseGeometry(new Rect(0, 0, ActualWidth, ActualHeight));
  84.             var innerCircleGeometry = new EllipseGeometry(new Rect(ActualWidth * 0.05, ActualHeight * 0.05, ActualWidth * 0.9, ActualHeight * 0.9));
  85.             clipGeometry.AddGeometry(outerCircleGeometry);
  86.             clipGeometry.AddGeometry(innerCircleGeometry);
  87.             return clipGeometry;
  88.         }
  89.  
  90.         private GradientStopCollection CreateGradientStops()
  91.         {
  92.             var gradientStops = new GradientStopCollection
  93.             {
  94.                 new GradientStop(Color.FromRgb(187, 112, 0), 0),
  95.                 new GradientStop(Color.FromRgb(43, 41, 48), 0.6)
  96.             };
  97.             return gradientStops;
  98.         }
  99.  
  100.         private Point CalculateStartPoint()
  101.         {
  102.             var startAngle = (0 - 210) * Math.PI / 180;
  103.             var startPoint = new Point(ActualWidth / 2 + Math.Cos(startAngle) * ActualWidth / 2, ActualHeight / 2 + Math.Sin(startAngle) * ActualHeight / 2);
  104.             return startPoint;
  105.         }
  106.  
  107.         private Point CalculateEndPoint()
  108.         {
  109.             var endAngle = (angle + 150) * Math.PI / 180;
  110.             var endPoint = new Point(ActualWidth / 2 + Math.Cos(endAngle) * ActualWidth / 2, ActualHeight / 2 + Math.Sin(endAngle) * ActualHeight / 2);
  111.             return endPoint;
  112.         }
  113.  
  114.         private Point CalculateGradEndPoint()
  115.         {
  116.             var gradAngle = (angle - 210) * Math.PI / 180;
  117.             var value1 = Math.Sin(gradAngle);
  118.             var value2 = Math.Cos(gradAngle);
  119.             var normalizedCos = (value2 + 1) * 0.5;
  120.             var normalizedSin = (value1 + 1) * 0.5;
  121.             var endGradAngle = Math.Atan2(normalizedSin - 0.5, normalizedCos - 0.5) + Math.PI;
  122.             var x2 = 0.5 + 0.5 * Math.Cos(endGradAngle);
  123.             var y2 = 0.5 + 0.5 * Math.Sin(endGradAngle);
  124.             var gradEndPoint = new Point(x2, y2);
  125.             return gradEndPoint;
  126.         }
  127.  
  128.         private Path CreateDonutRing(PathGeometry clipGeometry, GradientStopCollection gradientStops, Point startPoint, Point gradEndPoint)
  129.         {
  130.             var gradAngle = (angle - 210) * Math.PI / 180;
  131.             var value1 = Math.Sin(gradAngle);
  132.             var value2 = Math.Cos(gradAngle);
  133.             var normalizedCos = (value2 + 1) * 0.5;
  134.             var normalizedSin = (value1 + 1) * 0.5;
  135.             var donutRing = new Path
  136.             {
  137.                 Fill = new LinearGradientBrush(gradientStops)
  138.                 {
  139.                     StartPoint = new Point(normalizedCos, normalizedSin),
  140.                     EndPoint = gradEndPoint,
  141.                 },
  142.                 Data = clipGeometry
  143.             };
  144.             return donutRing;
  145.         }
  146.  
  147.         private Point CalculateCirclesPoint(Point endPoint)
  148.         {
  149.             var offset = 8;
  150.             var circlesPoint = new Point();
  151.  
  152.             if (angle <= 30 || angle >= 300)
  153.             {
  154.                 double t = Math.Min(Math.Max((angle - 30) / (360 - 30), 0), 1);
  155.                 circlesPoint.X = endPoint.X + offset * (1 - t);
  156.                 circlesPoint.Y = endPoint.Y - offset * t;
  157.             }
  158.             else if (angle > 30 && angle <= 120)
  159.             {
  160.                 double t = Math.Min(Math.Max((angle - 30) / (120 - 30), 0), 1);
  161.                 circlesPoint.X = endPoint.X + offset * (1 - t);
  162.                 circlesPoint.Y = endPoint.Y + offset * t;
  163.             }
  164.             else if (angle > 120 - offset && angle <= 210)
  165.             {
  166.                 double t = Math.Min(Math.Max((angle - (120 - offset)) / (210 - (120 - offset)), 0), 1);
  167.                 circlesPoint.X = endPoint.X - offset * t;
  168.                 circlesPoint.Y = endPoint.Y + offset * (1 - t);
  169.             }
  170.             else if (angle > 210 - offset && angle < 300)
  171.             {
  172.                 double t = Math.Min(Math.Max((angle - (210 - offset)) / (300 - (210 - offset)), 0), 1);
  173.                 circlesPoint.X = endPoint.X - offset * (1 - t);
  174.                 circlesPoint.Y = endPoint.Y - offset * t;
  175.             }
  176.             return circlesPoint;
  177.         }
  178.  
  179.         private Path CreateCircle(Point center, double radius, SolidColorBrush fill)
  180.         {
  181.             var circle = new Path
  182.             {
  183.                 Data = new EllipseGeometry(new Rect(new Point(center.X - radius, center.Y - radius), new Size(radius * 2, radius * 2))),
  184.                 Fill = fill,
  185.             };
  186.             return circle;
  187.         }
  188.  
  189.         private Path CreateCircleWithBlur(Point center, double radius, SolidColorBrush fill)
  190.         {
  191.             var circle = new Path
  192.             {
  193.                 Data = new EllipseGeometry(new Rect(new Point(center.X - radius, center.Y - radius), new Size(radius * 2, radius * 2))),
  194.                 Fill = fill,
  195.                 Effect = new BlurEffect
  196.                 {
  197.                     Radius = 10,
  198.                     KernelType = KernelType.Gaussian
  199.                 }
  200.             };
  201.             return circle;
  202.         }
  203.  
  204.         private Path CreateVisibleArc(Point startPoint, Point endPoint)
  205.         {
  206.             var visibleArc = new Path
  207.             {
  208.                 Fill = Brushes.Red,
  209.                 Data = new PathGeometry
  210.                 {
  211.                     Figures = new PathFigureCollection
  212.                     {
  213.                         new PathFigure(new Point(ActualWidth / 2, ActualHeight / 2),
  214.                             new List<PathSegment>
  215.                             {
  216.                                 new LineSegment(endPoint, true),
  217.                                 new ArcSegment(startPoint, new Size(ActualWidth / 2, ActualHeight / 2), 0, angle>=180, SweepDirection.Counterclockwise, true),
  218.                                 new LineSegment(new Point(ActualWidth / 2, ActualHeight / 2), true)
  219.                             },
  220.                         true)
  221.                     }
  222.                 }
  223.             };
  224.             return visibleArc;
  225.         }
  226.  
  227.     }
  228. }
Advertisement
Comments
  • lotofares087776
    133 days
    # text 0.53 KB | 0 0
    1. https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/bjkLciTA76c
    2. https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/2cZdsdJfeQ8
    3. https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/pyJv-0tIdfw
    4. https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/BuWe3HAMBgE
    5. https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/Ez1kvz6Py3c
    6. https://groups.google.com/g/microsoft.public.sharepoint.windowsservices/c/FJQPLswJeyk
  • lotofares087776
    133 days
    # text 0.08 KB | 0 0
    1. https://feedback.azure.com/d365community/idea/990cd265-c7b6-ee11-92bc-000d3a033659
Add Comment
Please, Sign In to add comment
Advertisement