WPF實(shí)現(xiàn)雷達(dá)圖(仿英雄聯(lián)盟)的示例代碼
前言
有小伙伴提出需要實(shí)現(xiàn)雷達(dá)圖。
由于在WPF中沒有現(xiàn)成的雷達(dá)圖控件,所以我們自己實(shí)現(xiàn)一個(gè)。
PS:有更好的方式歡迎推薦。
實(shí)現(xiàn)代碼
一、創(chuàng)建 RadarChart.cs 菜單繼承 Control代碼如下
RadarChart.cs實(shí)現(xiàn)思路如下
1、RadarArray :存放展示集合 。
2、重寫OnRender 。
3、根據(jù)三角函數(shù)和圓的半徑計(jì)算出圓上的N個(gè)點(diǎn)繪制成多邊形GetPolygonPoint()。
4、在繪制多邊形的時(shí)候因?yàn)樾枰鄠€(gè)大小不一的多邊形,則需要多次調(diào)用GetPolygonPoint()方法,最外層繪制150,中間層100,中心點(diǎn)層 50。
5、DrawPoints() 方法增加了一個(gè)bool參數(shù)isDrawText是否繪制Text文本,因?yàn)樽钔鈧?cè)需要繪制文本。
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; } } } ?
二、創(chuàng)建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>
三、創(chuàng)建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; } } } ?
效果預(yù)覽
數(shù)據(jù)來源于英雄聯(lián)盟用戶
數(shù)據(jù)1《屈越》
數(shù)據(jù)2《方拯》
以上就是WPF實(shí)現(xiàn)雷達(dá)圖(仿英雄聯(lián)盟)的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于WPF雷達(dá)圖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#中調(diào)用命令行cmd開啟wifi熱點(diǎn)的實(shí)例代碼
最近想在win7上開啟wifi熱點(diǎn),于是就弄出下面這個(gè)小東西,里面涉及如何在控制臺(tái)上輸入命令,分享一下。首先在VS中創(chuàng)建一個(gè)window窗口,然后創(chuàng)建兩個(gè)四個(gè)button,兩個(gè)輸入框2013-04-04WinForm判斷關(guān)閉事件來源于用戶點(diǎn)擊右上角“關(guān)閉”按鈕的方法
這篇文章主要介紹了WinForm判斷關(guān)閉事件來源于用戶點(diǎn)擊右上角“關(guān)閉”按鈕的方法,涉及C#針對WinForm事件的判定技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09