前言

有小伙伴提出需要实现雷达图。

由于在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);elsepoints = 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));elsedrawingContext.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];elseRadarModels = collectionList[0];isRefresh = !isRefresh;}}
}
​

效果预览

数据来源于英雄联盟用户

数据1《屈越》

数据2《方拯》

WPF实现雷达图(仿英雄联盟)相关推荐

  1. 逼真版仿英雄联盟纯html+css+jqueryLOL网页版

    前言: 为了提高自己的编码兴趣,最近使用html,css,JQuery做了一个仿版的<英雄联盟>,虽然自己主修的是后端,但是技多压身.纯属也是自己的一个兴趣.上一节简单的介绍了仿版的< ...

  2. 仿英雄联盟比赛直播网页模板

    介绍: 高仿英雄联盟2017全球决赛官方比赛直播模板,带直播视频.排行榜.赛程列表等等功能. 网盘下载地址: http://kekewl.net/NbiX1vJoyjU0 图片:

  3. DIV布局——仿英雄联盟LOL首页(11页) 大学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载

    HTML5期末大作业:仿英雄联盟网站设计--仿英雄联盟LOL首页(11页) 大学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 文章目录 HTML5期末大作业:仿英雄联盟网站设计- ...

  4. web网页设计期末课程大作业~超高仿英雄联盟LOL游戏官网设计与实现(HTML+CSS+JavaScript)...

    仿英雄联盟LOL游戏官网设计与实现(HTML+CSS+JavaScript) 关于HTML期末网页制作,大作业A+水平 ~游戏网页作业HTML+CSS+JavaScript实现,共有游戏首页 等页面! ...

  5. Android仿英雄联盟/斗鱼波形加载动画

    先上效果图: 实现原理: 通过自定义一个布局,继承自LinearLayout,然后在这个布局当中添加5条竖线,也即是5个矩形View:通过对这5个View分别加入属性动画,即可实现.动画是一个组合动画 ...

  6. HTML5期末大作业:仿英雄联盟网站设计——仿英雄联盟LOL首页(11页) 大学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载

    HTML5期末大作业:仿英雄联盟网站设计--仿英雄联盟LOL首页(11页) 大学生简单个人静态HTML网页设计作品 DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载 常见网页设计作业题材有 ...

  7. 源码分享,仿英雄联盟对战游戏!

    源码介绍 这是一款类似英雄联盟的 5V5 实时对战游戏,同时支持 Linux 和  Windows 系统部署. 我们先来看下这个游戏的内容吧,这是在我机器上编译后运行的效果图: 登录界面 进入后台配置 ...

  8. 一套仿英雄联盟大型多人联机实时对战游戏源码(包含完整服务器和客户端源码)...

    源码介绍 这是一款类似英雄联盟的 5V5 实时对战游戏,同时支持 Linux 和  Windows 系统部署. 我们先来看下这个游戏的内容吧,这是在我机器上编译后运行的效果图: 登录界面 进入后台配置 ...

  9. Discuz大气仿英雄联盟游戏风格论坛模板源码

    正文: Discuz大气游戏风格模板,lol英雄联盟游戏模板,DZ游戏娱乐模板GBK,模板名称:lol英雄联盟游戏(m0398_lol). 程序: wwmes.lanzouq.com/iEMST09y ...

最新文章

  1. 6月第1周回顾:华为再现猝死 中国成全球最大宽带市场
  2. Android 通过http协议数据交互
  3. undb php,显示html过滤报错,我不知道如何修改了。
  4. Eigen: C++开源矩阵计算工具——Eigen的简单用法
  5. 右键文件夹电脑卡死?
  6. linux 打zip gz tar,linux把文件压缩成.tar.gz的命令 | PT Ubuntu Blog
  7. Ajax→异步的JavaScript和XML、HTTP请求响应、Ajax简介同步异步、XMLHttpRequest类的方法及属性、原生Ajax、Koa实现Ajax、接口文档、浏览器同源策略、反向代理
  8. python 读取sheet_python实现读取excel文件中所有sheet操作示例
  9. 《金融时报》和麦肯锡:本年度最佳书单
  10. Apache Echarts实现矢量地图
  11. BUUCTF [GXYCTF2019]Ping Ping Ping 1
  12. 创业时代的七堂必修课
  13. CCS 使用报错合集 -mcu:cc26xx
  14. 数据库综合案例(商店买商品)
  15. 文思海辉智翼云与ZStack IaaS软件完成产品兼容互认证
  16. MySQL连接报ERROR 2003(HY000) Can‘t connect to MySQL server on ‘xxxIP‘(113)
  17. 设置harbor开机自启动
  18. python内置属性与内置方法
  19. 美国“鼠女”放生数千老鼠 旧金山成鼠城
  20. 最新H5定制版早起打卡支付已接带完整搭建教程

热门文章

  1. 数学之路(2)-数据分析-R基础(3)
  2. c语言一串大写字母转小写,C语言的基础函数大小写转换
  3. php mysql迭代器_php 迭代器
  4. 聊一聊转行推荐的问题
  5. 【学术相关】如何避免博士延期毕业?
  6. 【GNN】啥是GNN?GNN咋学?GNN何用?
  7. 探秘AI开发「神器」ModelArts,解读IoT 智能设备,华为云教你玩转 AI开发!
  8. 关于SVM,面试官们都怎么问
  9. 搜索推荐炼丹笔记:酒店搜索位置偏差的边际重要性
  10. 十几万人同时在线的直播间聊天,如何设计服务端架构?