WPF实现特殊统计图
程序员文章站
2022-06-10 08:56:01
效果图: ActiveFunItem.xaml代码:
效果图:
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 } }