<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
有小夥伴提出需要實現雷達圖。
由於在WPF中沒有現成的雷達圖控制元件,所以我們自己實現一個。
PS:有更好的方式歡迎推薦。
一、建立 RadarChart.cs 選單繼承 Control程式碼如下
RadarChart.cs實現思路如下
1、RadarArray :存放展示集合 。
2、重寫OnRender 。
3、根據三角函數和圓的半徑計算出圓上的N個點繪製成多邊形GetPolygonPoint()。
4、在繪製多邊形的時候因為需要多個大小不一的多邊形,則需要多次呼叫GetPolygonPoint()方法,最外層繪製150,中間層100,中心點層 50。
5、DrawPoints() 方法增加了一個bool引數isDrawText是否繪製Text文字,因為最外側需要繪製文字。
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; namespace WPFDevelopers.Controls { public class RadarChart:Control { public ObservableCollection<RadarModel> RadarArray { get { return (ObservableCollection<RadarModel>)GetValue(RadarArrayProperty); } set { SetValue(RadarArrayProperty, value); } } public static readonly DependencyProperty RadarArrayProperty = DependencyProperty.Register("RadarArray", typeof(ObservableCollection<RadarModel>), typeof(RadarChart), new PropertyMetadata(null)); static RadarChart() { DefaultStyleKeyProperty.OverrideMetadata(typeof(RadarChart), new FrameworkPropertyMetadata(typeof(RadarChart))); } protected override void OnRender(DrawingContext drawingContext) { DrawPoints(150, drawingContext,true); DrawPoints(100, drawingContext); DrawPoints(50, drawingContext); var myPen = new Pen { Thickness = 4, Brush = Brushes.DodgerBlue }; myPen.Freeze(); StreamGeometry streamGeometry = new StreamGeometry(); using (StreamGeometryContext geometryContext = streamGeometry.Open()) { var h = this.ActualHeight / 2; var w = this.ActualWidth / 2; PointCollection points = new PointCollection(); foreach (var item in RadarArray) { var ss = new Point((item.PointValue.X - w) / 100 * item.ValueMax + w,(item.PointValue.Y - h) / 100 * item.ValueMax + h); points.Add(ss); } geometryContext.BeginFigure(points[points.Count - 1], true, true); geometryContext.PolyLineTo(points, true, true); } streamGeometry.Freeze(); SolidColorBrush rectBrush = new SolidColorBrush(Colors.LightSkyBlue); rectBrush.Opacity = 0.5; drawingContext.DrawGeometry(rectBrush, myPen, streamGeometry); } void DrawPoints(int circleRadius, DrawingContext drawingContext,bool isDrawText = false) { var myPen = new Pen { Thickness = 2, Brush = Brushes.Gainsboro }; myPen.Freeze(); StreamGeometry streamGeometry = new StreamGeometry(); using (StreamGeometryContext geometryContext = streamGeometry.Open()) { var h = this.ActualHeight / 2; var w = this.ActualWidth / 2; PointCollection points = null; if (isDrawText) points = GetPolygonPoint(new Point(w, h), circleRadius, RadarArray.Count, drawingContext); else points = GetPolygonPoint(new Point(w, h), circleRadius, RadarArray.Count); geometryContext.BeginFigure(points[points.Count - 1], true, true); geometryContext.PolyLineTo(points, true, true); } streamGeometry.Freeze(); drawingContext.DrawGeometry(null, myPen, streamGeometry); } private PointCollection GetPolygonPoint(Point center, double r, int polygonBound, DrawingContext drawingContext = null) { double g = 18; double perangle = 360 / polygonBound; double pi = Math.PI; List<Point> values = new List<Point>(); for (int i = 0; i < polygonBound; i++) { Point p2 = new Point(r * Math.Cos(g * pi / 180) + center.X, r * Math.Sin(g * pi / 180) + center.Y); if(drawingContext != null) { FormattedText formattedText = new FormattedText( RadarArray[i].Text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Thin, FontStretches.Normal), 20.001D, Brushes.Black) { MaxLineCount = 1, TextAlignment = TextAlignment.Justify, Trimming = TextTrimming.CharacterEllipsis }; RadarArray[i].PointValue = p2; if (p2.Y > center.Y && p2.X < center.X) drawingContext.DrawText(formattedText, new Point(p2.X - formattedText.Width - 5, p2.Y - formattedText.Height / 2)); else if (p2.Y < center.Y && p2.X > center.X) drawingContext.DrawText(formattedText, new Point(p2.X, p2.Y - formattedText.Height)); else if (p2.Y < center.Y && p2.X < center.X) drawingContext.DrawText(formattedText, new Point(p2.X - formattedText.Width - 5, p2.Y - formattedText.Height)); else if (p2.Y < center.Y && p2.X == center.X) drawingContext.DrawText(formattedText, new Point(p2.X - formattedText.Width, p2.Y - formattedText.Height)); else drawingContext.DrawText(formattedText, new Point(p2.X, p2.Y)); } values.Add(p2); g += perangle; } PointCollection pcollect = new PointCollection(values); return pcollect; } } }
二、建立RadarChartExample.xaml程式碼如下
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.RadarChartExample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" xmlns:wpfdev="https://github.com/yanjinhuagood/WPFDevelopers" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid Background="Gainsboro" > <Border Background="White" Width="500" Height="500"> <Grid Margin="20,10"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="40"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition/> </Grid.RowDefinitions> <WrapPanel> <Rectangle Width="6" Height="26" Fill="Black"/> <TextBlock Text="能力圖" FontWeight="Black" FontSize="24" Padding="10,0"/> </WrapPanel> <wpfdev:RadarChart Grid.Column="0" Grid.Row="1" RadarArray="{Binding RadarModels,RelativeSource={RelativeSource AncestorType=local:RadarChartExample}}"/> </Grid> </Border> </Grid> </UserControl>
三、建立RadarChartExample.xaml.cs程式碼如下
ReadrChartExample.cs 思路如下
1、ValueMax 需要注意最小值0,最大值100。
using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Controls; using WPFDevelopers.Controls; namespace WPFDevelopers.Samples.ExampleViews { /// <summary> /// RadarChartExample.xaml 的互動邏輯 /// </summary> public partial class RadarChartExample : UserControl { public ObservableCollection<RadarModel> RadarModels { get { return (ObservableCollection<RadarModel>)GetValue(RadarModelsProperty); } set { SetValue(RadarModelsProperty, value); } } public static readonly DependencyProperty RadarModelsProperty = DependencyProperty.Register("RadarModels", typeof(ObservableCollection<RadarModel>), typeof(RadarChartExample), new PropertyMetadata(null)); List<ObservableCollection<RadarModel>> collectionList = new List<ObservableCollection<RadarModel>>(); public RadarChartExample() { InitializeComponent(); RadarModels = new ObservableCollection<RadarModel>(); var collection1 = new ObservableCollection<RadarModel>(); collection1.Add(new RadarModel { Text = "擊殺", ValueMax = 95}); collection1.Add(new RadarModel { Text = "生存", ValueMax = 80 }); collection1.Add(new RadarModel { Text = "助攻", ValueMax = 70 }); collection1.Add(new RadarModel { Text = "物理", ValueMax = 80 }); collection1.Add(new RadarModel { Text = "魔法", ValueMax = 90 }); collection1.Add(new RadarModel { Text = "防禦", ValueMax = 87 }); collection1.Add(new RadarModel { Text = "金錢", ValueMax = 59 }); var collection2 = new ObservableCollection<RadarModel>(); collection2.Add(new RadarModel { Text = "擊殺", ValueMax = 59 }); collection2.Add(new RadarModel { Text = "生存", ValueMax = 80 }); collection2.Add(new RadarModel { Text = "助攻", ValueMax = 90 }); collection2.Add(new RadarModel { Text = "物理", ValueMax = 70 }); collection2.Add(new RadarModel { Text = "魔法", ValueMax = 80 }); collection2.Add(new RadarModel { Text = "防禦", ValueMax = 90 }); collection2.Add(new RadarModel { Text = "金錢", ValueMax = 66 }); collectionList.AddRange(new[] { collection1, collection2 }); RadarModels = collectionList[0]; } bool isRefresh = false; private void Button_Click(object sender, RoutedEventArgs e) { if (!isRefresh) RadarModels = collectionList[1]; else RadarModels = collectionList[0]; isRefresh = !isRefresh; } } }
資料來源於英雄聯盟使用者
資料1《屈越》
資料2《方拯》
以上就是WPF實現雷達圖(仿英雄聯盟)的範例程式碼的詳細內容,更多關於WPF雷達圖的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45