欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF实现特殊统计图

程序员文章站 2022-06-10 08:56:01
效果图: ActiveFunItem.xaml代码:

效果图:

WPF实现特殊统计图

 

activefunitem.xaml代码:

<usercontrol x:class="suncreate.vipf.client.ui.activefunitem"
             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" 
             mc:ignorable="d" 
             d:designheight="74" d:designwidth="50">
    <grid>
        <grid.rowdefinitions>
            <rowdefinition height="{binding itemwidth}"></rowdefinition>
            <rowdefinition height="24"></rowdefinition>
        </grid.rowdefinitions>
        <border width="{binding itemwidth}" height="{binding itemwidth}" background="{binding fillcolor}" borderbrush="{binding bordercolor}" borderthickness="2" cornerradius="{binding itemwidthhalf}" >
            <border.tooltip>
                <tooltip>
                    <tooltip.template>
                        <controltemplate>
                            <border background="#88333333" cornerradius="4">
                                <textblock margin="5" foreground="#f2f2f2" text="{binding funname}"></textblock>
                            </border>
                        </controltemplate>
                    </tooltip.template>
                </tooltip>
            </border.tooltip>
            <image width="{binding iconwidth}" height="{binding iconwidth}" stretch="fill" source="{binding image}" verticalalignment="center" horizontalalignment="center"></image>
        </border>
        <stackpanel grid.row="1" orientation="horizontal" horizontalalignment="center">
            <textblock text="{binding count}" foreground="#008bf1" fontsize="20" verticalalignment="center"></textblock>
            <textblock text="次" foreground="#008bf1" fontsize="20" verticalalignment="center"></textblock>
        </stackpanel>
    </grid>
</usercontrol>

activefunitem.xaml.cs代码:

using system;
using system.collections.generic;
using system.componentmodel;
using system.linq;
using system.text;
using system.threading.tasks;
using system.windows;
using system.windows.controls;
using system.windows.data;
using system.windows.documents;
using system.windows.input;
using system.windows.media;
using system.windows.media.imaging;
using system.windows.navigation;
using system.windows.shapes;

namespace suncreate.vipf.client.ui
{
    /// <summary>
    /// 图标控件
    /// </summary>
    public partial class activefunitem : usercontrol, inotifypropertychanged
    {
        private thickness _originalmargin;
        /// <summary>
        /// 初始margin
        /// </summary>
        public thickness originalmargin
        {
            get
            {
                return _originalmargin;
            }
            set
            {
                _originalmargin = value;
                onpropertychanged("originalmargin");
            }
        }

        private int _itemwidth = 50;
        /// <summary>
        /// 圆宽度
        /// </summary>
        public int itemwidth
        {
            get
            {
                return _itemwidth;
            }
            set
            {
                _itemwidth = value;
                onpropertychanged("itemwidth");

                itemwidthhalf = itemwidth / 2;
                iconwidth = (int)(itemwidth * 0.65);
            }
        }

        private int _itemwidthhalf = 25;
        /// <summary>
        /// 圆宽度一半
        /// </summary>
        public int itemwidthhalf
        {
            get
            {
                return _itemwidthhalf;
            }
            set
            {
                _itemwidthhalf = value;
                onpropertychanged("itemwidthhalf");
            }
        }

        private int _iconwidth = 30;
        /// <summary>
        /// 图标宽度
        /// </summary>
        public int iconwidth
        {
            get
            {
                return _iconwidth;
            }
            set
            {
                _iconwidth = value;
                onpropertychanged("iconwidth");
            }
        }

        private solidcolorbrush _fillcolor = new solidcolorbrush((color)colorconverter.convertfromstring("#ff9848"));
        /// <summary>
        /// 填充颜色
        /// </summary>
        public solidcolorbrush fillcolor
        {
            get
            {
                return _fillcolor;
            }
            set
            {
                _fillcolor = value;
                onpropertychanged("fillcolor");
            }
        }

        private solidcolorbrush _bordercolor = new solidcolorbrush((color)colorconverter.convertfromstring("#ed6900"));
        /// <summary>
        /// 边框颜色
        /// </summary>
        public solidcolorbrush bordercolor
        {
            get
            {
                return _bordercolor;
            }
            set
            {
                _bordercolor = value;
                onpropertychanged("bordercolor");
            }
        }

        private imagesource _image = new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-人脸分析.png", urikind.relativeorabsolute));
        /// <summary>
        /// 图标的图片
        /// </summary>
        public imagesource image
        {
            get { return _image; }
            set
            {
                _image = value;
                onpropertychanged("image");
            }
        }

        private int _count = 3600;
        /// <summary>
        /// 活跃次数
        /// </summary>
        public int count
        {
            get
            {
                return _count;
            }
            set
            {
                _count = value;
                onpropertychanged("count");
            }
        }

        private string _funname;
        /// <summary>
        /// 功能名称
        /// </summary>
        public string funname
        {
            get
            {
                return _funname;
            }
            set
            {
                _funname = value;
                onpropertychanged("funname");
            }
        }

        public activefunitem()
        {
            initializecomponent();
            this.datacontext = this;
        }

        #region inotifypropertychanged接口
        public event propertychangedeventhandler propertychanged;

        protected void onpropertychanged(string name)
        {
            if (propertychanged != null)
            {
                propertychanged(this, new propertychangedeventargs(name));
            }
        }
        #endregion

    }
}

activefunction.xaml代码:

<usercontrol x:class="suncreate.vipf.client.ui.activefunction"
             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:suncreate.vipf.client.ui"
             mc:ignorable="d" 
             d:designheight="300" d:designwidth="300" loaded="usercontrol_loaded">
    <grid>
        <grid.rowdefinitions>
            <rowdefinition height="30"></rowdefinition>
            <rowdefinition height="1*"></rowdefinition>
        </grid.rowdefinitions>
        <border cornerradius="5 5 0 0" background="#368bf0">
            <stackpanel orientation="horizontal" margin="10 0 0 0">
                <image width="14" source="/suncreate.vipf.client.resources;component/image/_zz/managermainpage/面板-活跃功能.png"></image>
                <textblock margin="10 0 0 0" text="活跃功能" fontsize="14" foreground="#fff" verticalalignment="center"></textblock>
            </stackpanel>
        </border>
        <border grid.row="1" cornerradius="0 0 5 5" background="#ffffff" borderthickness="1 0 1 1" borderbrush="#dddddd" snapstodevicepixels="true">
            <grid>
                <viewbox x:name="viewbox" stretch="fill" height="260" width="260">
                    <canvas width="320" height="320">
                        <grid>
                            <grid width="300" height="300">
                                <grid.background>
                                    <imagebrush stretch="fill" imagesource="/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃总量.png"/>
                                </grid.background>
                            </grid>
                            <grid x:name="container" width="320" height="320">
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="76,20,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="173,20,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="240,79,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="241,182,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="171,247,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="75,247,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="11,178,0,0"></local:activefunitem>
                                <local:activefunitem verticalalignment="top" horizontalalignment="left" margin="12,82,0,0"></local:activefunitem>
                            </grid>
                            <textblock text="{binding count}" fontsize="30" fontweight="bold" foreground="#ff2121" verticalalignment="center" horizontalalignment="center"></textblock>
                        </grid>
                    </canvas>
                </viewbox>
            </grid>
        </border>
    </grid>
</usercontrol>

activefunction.xaml.cs代码:

using system;
using system.collections.generic;
using system.componentmodel;
using system.linq;
using system.text;
using system.threading.tasks;
using system.windows;
using system.windows.controls;
using system.windows.data;
using system.windows.documents;
using system.windows.input;
using system.windows.media;
using system.windows.media.imaging;
using system.windows.navigation;
using system.windows.shapes;

namespace suncreate.vipf.client.ui
{
    /// <summary>
    /// 活跃功能
    /// </summary>
    public partial class activefunction : usercontrol, inotifypropertychanged
    {
        #region 字段属性
        /// <summary>
        /// 图标控件集合
        /// </summary>
        private list<activefunitem> _list = new list<activefunitem>();

        /// <summary>
        /// 图标背景颜色
        /// </summary>
        private solidcolorbrush[] _fillcolorarr = new solidcolorbrush[8] {
            new solidcolorbrush((color)colorconverter.convertfromstring("#ff9848")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#009df0")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#009df0")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#ff211b")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#009df0")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#009df0")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#00d235")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#009df0"))
        };

        /// <summary>
        /// 图标背景边框颜色
        /// </summary>
        private solidcolorbrush[] _bordercolorarr = new solidcolorbrush[8] {
            new solidcolorbrush((color)colorconverter.convertfromstring("#ed6900")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#0065d1")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#0065d1")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#b40000")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#0065d1")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#0065d1")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#00912b")),
            new solidcolorbrush((color)colorconverter.convertfromstring("#0065d1"))
        };

        /// <summary>
        /// 图标大小
        /// </summary>
        private int[] _widtharr = new int[8] {
            90,
            80,
            70,
            60,
            55,
            50,
            45,
            40
        };

        /// <summary>
        /// 位置数组
        /// </summary>
        private int[] _posarr = new int[8] {
            3,
            0,
            6,
            2,
            7,
            4,
            1,
            5
        };

        /// <summary>
        /// 功能名称图标集合
        /// </summary>
        private dictionary<string, imagesource> _dictnameicon = new dictionary<string, imagesource>();

        private int _count;
        /// <summary>
        /// 活跃总量
        /// </summary>
        public int count
        {
            get
            {
                return _count;
            }
            set
            {
                _count = value;
                onpropertychanged("count");
            }
        }
        #endregion

        public activefunction()
        {
            initializecomponent();
            this.datacontext = this;

            this.count = 21834; //活跃总量

            #region 功能名称图标集合(后期补充更多功能名称图标)
            _dictnameicon.add("车辆分析", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-车辆分析.png", urikind.relativeorabsolute)));
            _dictnameicon.add("行为分析", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-行为分析.png", urikind.relativeorabsolute)));
            _dictnameicon.add("结构化分析", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-结构化分析.png", urikind.relativeorabsolute)));
            _dictnameicon.add("历史视频", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-历史视频.png", urikind.relativeorabsolute)));
            _dictnameicon.add("人脸分析", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-人脸分析.png", urikind.relativeorabsolute)));
            _dictnameicon.add("实时视频", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-实时视频.png", urikind.relativeorabsolute)));
            _dictnameicon.add("视频巡查", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-视频巡查.png", urikind.relativeorabsolute)));
            _dictnameicon.add("资源申请", new bitmapimage(new uri("/suncreate.vipf.client.resources;component/image/_zz/managermainpage/活跃功能-资源申请.png", urikind.relativeorabsolute)));
            #endregion

            #region 初始化控件
            int i = 0;
            foreach (activefunitem item in container.children)
            {
                item.originalmargin = new thickness(item.margin.left + 25, item.margin.top + 25, 0, 0);
                item.fillcolor = _fillcolorarr[i];
                item.bordercolor = _bordercolorarr[i];
                _list.add(item);
                i++;
            }
            #endregion

            statistic();

        }

        #region 统计
        /// <summary>
        /// 统计
        /// </summary>
        public void statistic()
        {
            #region 活跃功能活跃次数测试数据
            dictionary<string, int> dict = new dictionary<string, int>();
            dict.add("人脸分析", 1223);
            dict.add("行为分析", 239);
            dict.add("结构化分析", 621);
            dict.add("历史视频", 1520);
            dict.add("实时视频", 523);
            dict.add("车辆分析", 805);
            dict.add("视频巡查", 89);
            dict.add("资源申请", 363);
            #endregion

            #region 重新计算activefunitem属性
            list<keyvaluepair<string, int>> _sortedlist = dict.tolist();
            _sortedlist.sort((a, b) => b.value - a.value); //对统计数据排序

            for (int k = 0; k < _sortedlist.count; k++)
            {
                keyvaluepair<string, int> keyvaluepair = _sortedlist[k];
                int index = _posarr[k];

                activefunitem funitem = _list[index];
                funitem.itemwidth = _widtharr[k];
                funitem.margin = new thickness(funitem.originalmargin.left - funitem.itemwidthhalf, funitem.originalmargin.top - funitem.itemwidthhalf, 0, 0);
                funitem.count = keyvaluepair.value;
                funitem.funname = keyvaluepair.key;
                if (_dictnameicon.keys.contains(keyvaluepair.key))
                {
                    funitem.image = _dictnameicon[keyvaluepair.key];
                }
                else
                {
                    funitem.image = null;
                }
            }
            #endregion

        }
        #endregion

        #region inotifypropertychanged接口
        public event propertychangedeventhandler propertychanged;

        protected void onpropertychanged(string name)
        {
            if (propertychanged != null)
            {
                propertychanged(this, new propertychangedeventargs(name));
            }
        }
        #endregion

        #region usercontrol_loaded
        private void usercontrol_loaded(object sender, routedeventargs e)
        {
            double h = this.actualheight - 32;
            double w = this.actualheight - 2;
            if (h < w)
            {
                viewbox.height = h;
                viewbox.width = h;
            }
            else
            {
                viewbox.height = w;
                viewbox.width = w;
            }
        }
        #endregion

    }
}