前言 有小伙伴提出需要实现雷达图 。
【仿英雄联盟 WPF实现雷达图的示例代码】
由于在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 = https://baike.zhangchenghui.com/517288/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实现雷达图(仿英雄联盟)的示例代码的详细内容,更多关于wpf雷达图的资料请关注www.887551.com其它相关文章!
-- 展开阅读全文 --
推荐阅读
- Android简单实现动态权限获取相机权限及存储空间等多权限
- 白羊座男生的分手前兆
- 怎么和巨蟹座女生异地恋
- 和摩羯座男生异地恋怎么维持?
- 和双子座男生异地恋怎么维持?
- 巨蟹座男生的分手前兆
- 射手座男生的分手前兆
- 射手座女生的分手前兆
- baidunetdiskdownload是什么文件夹