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); 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雷达图的资料请关注萬仟网其它相关文章!
看完文章,还可以用支付宝扫描下面的二维码领取一个支付宝红包,目前可领1-88元不等
除了扫码可以领取之外,大家还可以(复制 720087999 打开✔支付宝✔去搜索, h`o`n.g.包哪里来,动动手指就能领)。
看下图所示是好多参与这次活动领取红包的朋友: