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雷达图的资料请关注萬仟网其它相关文章!
看完文章,还可以扫描下面的二维码下载快手极速版领4元红包
除了扫码领红包之外,大家还可以在快手极速版做签到,看视频,做任务,参与抽奖,邀请好友赚钱)。
邀请两个好友奖最高196元,如下图所示:







