当前位置:网站首页>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...
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);
}
边栏推荐
- Cross modal semantic association alignment retrieval - image text matching
- Tencent game client development interview (unity + cocos) double bombing social recruitment 6 rounds of interviews
- break net
- Codeforces Round #643 (Div. 2)——B. Young Explorers
- Usage of hydraulic rotary joint
- MySQL查询为什么没走索引?这篇文章带你全面解析
- The numerical value of the number of figures thought of by the real-time update of the ranking list
- cv2-drawline
- 快手小程序担保支付php源码封装
- How to make the conductive slip ring signal better
猜你喜欢

ClickHouse原理解析与应用实践》读书笔记(8)

pb9.0 insert ole control 错误的修复工具

The foreach map in JS cannot jump out of the loop problem and whether foreach will modify the original array

分布式定时任务之XXL-JOB

Remote Sensing投稿经验分享

从Starfish OS持续对SFO的通缩消耗,长远看SFO的价值

How to make enterprise recruitment QR code?

C language - modularization -clion (static library, dynamic library) use

第七章 行为级建模

Application of slip ring in direct drive motor rotor
随机推荐
GBASE观察 | 数据泄露频发 信息系统安全应如何守护
Tencent game client development interview (unity + cocos) double bombing social recruitment 6 rounds of interviews
Summary of log feature selection (based on Tianchi competition)
metasploit
Tapdata 的 2.0 版 ,開源的 Live Data Platform 現已發布
Nacos microservice gateway component +swagger2 interface generation
adb工具介绍
MATLAB R2021b 安装libsvm
从Starfish OS持续对SFO的通缩消耗,长远看SFO的价值
神经网络与深度学习-5- 感知机-PyTorch
How to fix the slip ring
Leetcode exercise - Sword finger offer 36 Binary search tree and bidirectional linked list
[error] error loading H5 weight attributeerror: 'STR' object has no attribute 'decode‘
common commands
Capability contribution three solutions of gbase were selected into the "financial information innovation ecological laboratory - financial information innovation solutions (the first batch)"
为什么更新了 DNS 记录不生效?
跨模态语义关联对齐检索-图像文本匹配(Image-Text Matching)
[SolidWorks] modify the drawing format
Qml 字体使用pixelSize来自适应界面
How to make enterprise recruitment QR code?