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 } }