当前位置:首页 > 谈天说地 > 正文内容

WPF实现雷达图(仿英雄联盟)的示例代码

34资源网2022年07月29日 10:11227

前言

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

 

由于在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.包哪里来,动动手指就能领)。

看下图所示是好多参与这次活动领取红包的朋友:

支付宝红包

扫描二维码推送至手机访问。

版权声明:本文由34楼发布,如需转载请注明出处。

本文链接:https://www.34l.com/post/19996.html

分享给朋友:

相关文章

28句用哀兵必胜的句子造句大全
28句用哀兵必胜的句子造句大全

28句用哀兵必胜的句子造句大全(1) 哀兵必胜!苏联红军终于赶走法西斯。(2) 所谓哀兵必胜,那也是要建立在哀兵还有一拼的实力上面。(3) 哀兵必胜,侵略者必将遭到可耻的失败。zaojv.com(4) 在古代战争中有许多哀兵必胜的战例。(5...

好想你花开富贵大礼包多少钱一提?1236g优惠价只需要43.90元
好想你花开富贵大礼包多少钱一提?1236g优惠价只需要43.90元

好想你花开富贵大礼包多少钱一提?好想你,花开富贵礼盒1236g零食大礼包,原价58.90元,领取15元的优惠券减掉之后只需要43.90元,这个价格在近30日内属于最低价,喜欢这款商品的朋友不要错过哦。好想你花开富贵礼盒1236g,零食大礼包...

调整心态温暖哲理经典语录,看这些语录能够调整心态
调整心态温暖哲理经典语录,看这些语录能够调整心态

取得成功是他人不成功时仍在坚持不懈。若自身不作出一点外貌,别人想拉你一把都不知道你的手在哪儿。直至你不会再找我聊,直至你找不着我,直至最终,你一直在某一瞬间猛地想起我。但是,那个时候,被你弄丢的我就确实早已没有了,也再不想要你再找回家了。理...

经典语录20句分享:这城市风很大,孤独的人总是晚回家
经典语录20句分享:这城市风很大,孤独的人总是晚回家

1、不怕变成自己厌恶的人,我怕的是,过的还不如他们。2、无论受了多少委屈。我只会把它憋在心里。不是不想说,只是不知道该怎么说,能和谁说。3、思念很长,所以一日如两年,时间很短,所以两年如一日。4、你是不是又在苦心翻找一句话,只为给那个人看。...

B站、爱奇艺:这对难兄难弟

11月17日,哔哩哔哩(下称“B站”)与爱奇艺发布截至2021年9月30日的第三季度财报。B站Q3营收52.066亿元,同比增长61%,净亏损26.863亿元;爱奇艺Q3营收75.891亿元,同比增长6%,净亏损16.984亿元。 两家先...

龚文祥真的破产了吗?
龚文祥真的破产了吗?

图源:摄图网 编者按:本文来自微信公众号十里村(ID:shilipxl),作者:村长住在十里村,创业邦经授权转载 各位村民好,我是村长。 号称团队不超过10个人,一年就能赚五千万的微商教父龚文祥破产了!!! 因此还上了各大平台的热搜榜...