当前位置:网站首页>WPF custom realistic wind radar chart control

WPF custom realistic wind radar chart control

2022-07-08 01:53:00 Unknown gentleman

WPF Customize Realism Radar chart control

Control mainly uses Transform Realize the rotation drawing of the control
Let's take a picture first Look Look...
 Insert picture description here
XAMl:

  <UserControl.Resources>
        <Style TargetType="Line">
            <Setter Property="Stroke" Value="#AB72D458"/>
            <Setter Property="X1" Value="0"/>
            <Setter Property="Y1" Value="0"/>
            <Setter Property="X2" Value="1"/>
            <Setter Property="Y1" Value="0"/>
            <Setter Property="Stretch" Value="Fill"/>
            <Setter Property="StrokeThickness" Value="1"/>
            <Setter Property="RenderTransformOrigin" Value="0.5,0.05"/>
        </Style>
    </UserControl.Resources>

    <Grid Margin="8" x:Name="RadarGrid" Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}">
        <Ellipse Margin="-8" StrokeThickness="8">
            <Ellipse.Stroke>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#777777"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </Ellipse.Stroke>
            <Ellipse.Effect>
                <DropShadowEffect ShadowDepth="4" BlurRadius="20" Direction="-90" Color="#B6B4B4"/>
            </Ellipse.Effect>
        </Ellipse>

        <!--#region  Base map  -->
        <Ellipse>
            <Ellipse.Fill>
                <RadialGradientBrush>
                    <GradientStop Color="#FF02AE03"/>
                    <GradientStop Color="#FF034300" Offset="0.904"/>
                </RadialGradientBrush>
            </Ellipse.Fill>
        </Ellipse>
        <!--#endregion-->

        <!--#region  Scan line  -->

        <!--<Grid RenderTransformOrigin="0.5,0.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.Triggers>
                <EventTrigger RoutedEvent="Loaded">
                    <BeginStoryboard>
                        <Storyboard RepeatBehavior="Forever">
                            <DoubleAnimation Storyboard.TargetName="ScanEllipse" Duration="0:0:2"
                                             Storyboard.TargetProperty="Angle" From="0" To="360"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Grid.Triggers>
            <Grid.RenderTransform>
                <RotateTransform x:Name="ScanEllipse"/>
            </Grid.RenderTransform>
            <Line X1="0" Y1="0" X2="1" Y2="0" StrokeThickness="4" StrokeDashCap="Round" StrokeDashArray="{x:Null}" Stretch="Fill">
                <Line.Stroke>
                    <LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
                        <GradientStop Color="#FFC5FFB6" Offset="0.008"/>
                        <GradientStop Color="Transparent" Offset="1"/>
                    </LinearGradientBrush>
                </Line.Stroke>
                <Line.Effect>
                    <BlurEffect/>
                </Line.Effect>
            </Line>
        </Grid>-->

        <!--#endregion-->

        <Line/>
        <Line>
            <Line.RenderTransform>
                <RotateTransform Angle="30"/>
            </Line.RenderTransform>
        </Line>

        <Line>
            <Line.RenderTransform>
                <RotateTransform Angle="60"/>
            </Line.RenderTransform>
        </Line>
        <Line>
            <Line.RenderTransform>
                <RotateTransform Angle="90"/>
            </Line.RenderTransform>
        </Line>
        <Line>
            <Line.RenderTransform>
                <RotateTransform Angle="120"/>
            </Line.RenderTransform>
        </Line>
        <Line>
            <Line.RenderTransform>
                <RotateTransform Angle="150"/>
            </Line.RenderTransform>
        </Line>

        <Ellipse Stroke="#FF0C6703" StrokeThickness="2"/>
        <Ellipse Stroke="#E4A0F424" Margin="50"/>
        <Ellipse Stroke="#C3A0F424" Margin="100"/>
        <Ellipse Stroke="#9EA0F424" Margin="150"/>
        <Ellipse Stroke="#AEA0F424" Margin="200"/>
        <Ellipse Fill="#AEA0F424" Width="10" Height="10"/>

        <Grid x:Name="dataGrid"/>
        <!--<TextBlock Text="10" VerticalAlignment="Center" Foreground="{StaticResource MahApps.Brushes.ThemeBackground}" Margin="0" />
        <TextBlock Text="8" VerticalAlignment="Center" Foreground="{StaticResource MahApps.Brushes.ThemeBackground}" Margin="48" />
        <TextBlock Text="6" VerticalAlignment="Center" Foreground="{StaticResource MahApps.Brushes.ThemeBackground}" Margin="98" />
        <TextBlock Text="4" VerticalAlignment="Center" Foreground="{StaticResource MahApps.Brushes.ThemeBackground}" Margin="148"/>
        <TextBlock Text="2" VerticalAlignment="Center" Foreground="{StaticResource MahApps.Brushes.ThemeBackground}" Margin="198"/>-->
    </Grid>

C#:

  /// <summary>
    /// RadarChart.xaml  Interaction logic of 
    /// </summary>
    public partial class RadarChart : UserControl
    {
    
        public RadarChart()
        {
    
            InitializeComponent();
        }
        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
    
            base.OnRenderSizeChanged(sizeInfo);
            Refresh();
        }

        public ObservableCollection<RadarData> RadarDatas
        {
    
            get {
     return (ObservableCollection<RadarData>)GetValue(RadarDatasProperty); }
            set {
     SetValue(RadarDatasProperty, value); }
        }
        public static readonly DependencyProperty RadarDatasProperty =
            DependencyProperty.Register("RadarDatas", typeof(ObservableCollection<RadarData>), typeof(RadarChart), new PropertyMetadata(null, OnDataChanged));

        private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
    
            var sen = (d as RadarChart);
            if (sen.RadarDatas != null)
            {
    
                sen.RadarDatas.CollectionChanged += (s, er) => sen.Refresh();
            }
        }

        private const double maxDistance = 10;
        private void Refresh()
        {
    
            dataGrid.Children.Clear();
            if (RadarDatas == null)
            {
    
                return;
            }
            Point center = new Point(RadarGrid.ActualHeight / 2, RadarGrid.ActualWidth / 2);
            foreach (var item in RadarDatas)
            {
    
                if (item.Distance > maxDistance)
                {
    
                    continue;
                }

                ContentControl contentControl = new ContentControl() {
     Width = 30, Height = 30 };
                double locat = 0;
                if (item.Distance != 0)
                {
    
                    locat = item.Distance / maxDistance * (RadarGrid.ActualHeight + contentControl.Width) / 2 - (contentControl.Width / 2);
                }

                //  Graphical display content 
                item.Content.HorizontalAlignment = HorizontalAlignment.Center;
                item.Content.VerticalAlignment = VerticalAlignment.Center;
                contentControl.Content = item.Content;
                TranslateTransform translate = new TranslateTransform() {
     Y = -locat };
                contentControl.RenderTransform = translate;
                contentControl.Foreground = Brushes.White;

                //  Display the text of the current distance 
                TextBlock textBlock = new TextBlock() {
     Text = item.Distance.ToString("f1")};
                textBlock.VerticalAlignment = VerticalAlignment.Bottom;
                textBlock.FontSize = 14d;
                textBlock.HorizontalAlignment = HorizontalAlignment.Center;
                TranslateTransform translateText = new TranslateTransform() {
     Y = -locat / 2 };
                RotateTransform rotateText = new RotateTransform(-item.Angle);
                TransformGroup group = new TransformGroup();
                group.Children.Add(rotateText);
                group.Children.Add(translateText);
                textBlock.RenderTransform = group;
                textBlock.Foreground = Brushes.White;

                //  Underline 
                Line line = new Line() {
     X1 = 0, Y1 = 0, X2 = 0, Y2 = 1, Width = 0d,Height=0d};
                var lineHeight = item.Distance / maxDistance * (RadarGrid.ActualHeight + contentControl.Width) / 2 - (contentControl.Width / 2);
                if (lineHeight > contentControl.Width)
                {
    
                    line.Height = item.Distance / maxDistance * (RadarGrid.ActualHeight + contentControl.Width) / 2 - (contentControl.Width / 2);
                    line.Width = item.Distance / maxDistance * (RadarGrid.ActualHeight + contentControl.Width) / 2;
                }

                line.Stroke = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#9EBE0E19"));
                line.StrokeThickness = 3;
                line.VerticalAlignment = VerticalAlignment.Bottom;
                line.HorizontalAlignment = HorizontalAlignment.Center;
                Grid lineGrid = new Grid();
                lineGrid.RowDefinitions.Add(new RowDefinition());
                lineGrid.RowDefinitions.Add(new RowDefinition());

                lineGrid.Children.Add(line);
                lineGrid.Children.Add(textBlock);


                Grid grid = new Grid();
                RotateTransform rotate = new RotateTransform() {
     Angle = item.Angle };
                grid.RenderTransformOrigin = new Point(0.5, 0.5);
                grid.RenderTransform = rotate;

                grid.Children.Add(contentControl);
                grid.Children.Add(lineGrid);

                dataGrid.Children.Add(grid);
            }
        }
    }

    public class RadarData
    {
    
        public double Angle {
     get; set; }

        public double Distance {
     get; set; }

        public FrameworkElement Content {
     get; set; }
    }

Test usage data :

  double testdis = 10;
        double testdis1 = 0;
        double testdis2 = 5;
        /// <summary>
        ///  Test radar chart 
        /// </summary>
        void TestRadar()
        {
    
            testdis = testdis <= 1 ? 10 : testdis;
            testdis1 = testdis1 >= 9 ? 0 : testdis1;
            testdis2 = testdis2 >= 9 ? 0 : testdis2;
            RadarTestData.Clear();
            testdis -= 0.02;

            RadarData data = new RadarData()
            {
    
                Angle = -30,
                Distance = testdis,
                Content = new PackIconMaterial() {
     Width = 30, Foreground = Brushes.Red, Height = 30, Kind = PackIconMaterialKind.Run },
            };
            RadarTestData.Add(data);


            testdis1 += 0.02;
            RadarData data1 = new RadarData()
            {
    
                Angle = 120,
                Distance = testdis1,
                Content = new PackIconMaterial() {
     Width = 20, Foreground = Brushes.Red, Height = 20, Kind = PackIconMaterialKind.Archive },
            };
            RadarTestData.Add(data1);

            testdis2 += 0.02;
            RadarData data2 = new RadarData()
            {
    
                Angle = 45,
                Distance = testdis2,
                Content = new PackIconMaterial() {
     Width = 20, Foreground = Brushes.Red, Height = 20, Kind = PackIconMaterialKind.AlarmLight },
            };
            RadarTestData.Add(data2);
        }
原网站

版权声明
本文为[Unknown gentleman]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/189/202207080016155624.html