WPF仿LiveCharts实现饼图的绘制

作者:驚鏵 时间:2022-02-08 02:17:05 

每日一笑

下班和实习生一起回家,公交站等车,一乞丐把碗推向实习生乞讨。这时,实习生不慌不忙的说了句:“我不要你的钱,你这钱来的也不容易。” 

前言 

有小伙伴需要统计图。

效果预览(更多效果请下载源码体验)

WPF仿LiveCharts实现饼图的绘制

一、PieControl.cs

using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WpfPieControl.Models;

namespace WpfPieControl
{
   public class PieControl: Control
   {
       public ObservableCollection<PieSegmentModel> PieSegmentModels
       {
           get { return (ObservableCollection<PieSegmentModel>)GetValue(PieSegmentModelsProperty); }
           set { SetValue(PieSegmentModelsProperty, value); }
       }

public static readonly DependencyProperty PieSegmentModelsProperty =
           DependencyProperty.Register("PieSegmentModels", typeof(ObservableCollection<PieSegmentModel>), typeof(PieControl), new UIPropertyMetadata(OnPieSegmentModelChanged));

private static void OnPieSegmentModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
       {
           PieControl pieControl = d as PieControl;
           if (e.NewValue != null)
           {
               var array = e.NewValue as ObservableCollection<PieSegmentModel>;
               double angleNum = 0;
               foreach (var item in array)
               {
                   var color = new SolidColorBrush((Color)ColorConverter.ConvertFromString(pieControl.ColorArray[array.IndexOf(item)]));
                   item.Color = color;
                   item.StartAngle = angleNum;
                   item.EndAngle = angleNum + item.Value / 100 * 360;
                   angleNum = item.EndAngle;
               }
           }
       }
       /// <summary>
       /// colors
       /// </summary>
       private string[] ColorArray = new string[] { "#FDC006", "#607E89", "#2095F2", "#F34336" };

/// <summary>
       /// 0~1
       /// </summary>
       public double ArcThickness
       {
           get { return (double)GetValue(ArcThicknessProperty); }
           set { SetValue(ArcThicknessProperty, value); }
       }

public static readonly DependencyProperty ArcThicknessProperty =
           DependencyProperty.Register("ArcThickness", typeof(double), typeof(PieControl), new PropertyMetadata(1.0));

static PieControl()
       {
           DefaultStyleKeyProperty.OverrideMetadata(typeof(PieControl), new FrameworkPropertyMetadata(typeof(PieControl)));
       }
   }
}

二、App.xaml

<Style TargetType="{x:Type local:PieControl}">
           <Setter Property="UseLayoutRounding" Value="True" />
           <!--<Setter Property="Background" Value="#252525"/>-->
           <Setter Property="Foreground" Value="White"/>
           <Setter Property="Width" Value="250"/>
           <Setter Property="Height" Value="250"/>
           <Setter Property="Template">
               <Setter.Value>
                   <ControlTemplate TargetType="{x:Type local:PieControl}">
                       <ItemsControl Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
                                     ItemsSource="{TemplateBinding PieSegmentModels}"
                                     Background="{TemplateBinding Background}">
                           <ItemsControl.ItemsPanel>
                               <ItemsPanelTemplate>
                                   <Grid IsItemsHost="True"/>
                               </ItemsPanelTemplate>
                           </ItemsControl.ItemsPanel>
                           <ItemsControl.ItemTemplate>
                               <DataTemplate>
                                   <ed:Arc Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
                                               ArcThickness="{Binding ArcThickness,RelativeSource={RelativeSource FindAncestor,AncestorType=local:PieControl}}" ArcThicknessUnit="Percent"
                                               EndAngle="{Binding EndAngle}"
                                               StartAngle="{Binding StartAngle}"
                                               Stretch="None"
                                               ToolTip="{Binding Name}"
                                               Stroke="{Binding ColorStroke}"
                                               StrokeThickness="2"
                                               Fill="{Binding Color}">
                                   </ed:Arc>
                               </DataTemplate>
                           </ItemsControl.ItemTemplate>
                       </ItemsControl>
                   </ControlTemplate>
               </Setter.Value>
           </Setter>
</Style>

三、MainWindow.xaml

<Window x:Class="WpfPieControl.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       xmlns:local="clr-namespace:WpfPieControl"
       mc:Ignorable="d"
       Title="微信公众号:WPF开发者" Height="450" Width="800">
   <StackPanel>
       <WrapPanel Margin="10">
           <local:PieControl PieSegmentModels="{Binding PieSegmentModels,RelativeSource={RelativeSource AncestorType=local:MainWindow}}" ArcThickness="1"/>
           <local:PieControl PieSegmentModels="{Binding PieSegmentModels,RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
                                 Margin="4,0"
                                 ArcThickness="{Binding ElementName=PRAT_Slider,Path=Value}"/>
           <local:PieControl PieSegmentModels="{Binding PieSegmentModels,RelativeSource={RelativeSource AncestorType=local:MainWindow}}" ArcThickness="0.65"/>
       </WrapPanel>
       <Slider Maximum="0.9" Minimum="0.1" x:Name="PRAT_Slider" Margin="10" Width="200"/>
       <Button Content="更新" Click="Button_Click" VerticalAlignment="Bottom" Width="200"/>
   </StackPanel>
</Window>

四、MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
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;
using WpfPieControl.Models;

namespace WpfPieControl
{
   /// <summary>
   /// MainWindow.xaml 的交互逻辑
   /// </summary>
   public partial class MainWindow : Window
   {
       public ObservableCollection<PieSegmentModel> PieSegmentModels
       {
           get { return (ObservableCollection<PieSegmentModel>)GetValue(PieSegmentModelsProperty); }
           set { SetValue(PieSegmentModelsProperty, value); }
       }

public static readonly DependencyProperty PieSegmentModelsProperty =
           DependencyProperty.Register("PieSegmentModels", typeof(ObservableCollection<PieSegmentModel>), typeof(MainWindow), new PropertyMetadata(null));

List<ObservableCollection<PieSegmentModel>> collectionList = new List<ObservableCollection<PieSegmentModel>>();
       public MainWindow()
       {
           InitializeComponent();

PieSegmentModels = new ObservableCollection<PieSegmentModel>();
           var collection1 = new ObservableCollection<PieSegmentModel>();
           collection1.Add(new PieSegmentModel { Name = "一", Value = 10 });
           collection1.Add(new PieSegmentModel { Name = "二", Value = 20 });
           collection1.Add(new PieSegmentModel { Name = "三", Value = 25 });
           collection1.Add(new PieSegmentModel { Name = "四", Value = 45 });
           var collection2 = new ObservableCollection<PieSegmentModel>();
           collection2.Add(new PieSegmentModel { Name = "一", Value = 30 });
           collection2.Add(new PieSegmentModel { Name = "二", Value = 15 });
           collection2.Add(new PieSegmentModel { Name = "三", Value = 10 });
           collection2.Add(new PieSegmentModel { Name = "四", Value = 55 });
           collectionList.AddRange(new[] { collection1, collection2 });

PieSegmentModels = collectionList[0];
       }
       bool isRefresh = false;
       private void Button_Click(object sender, RoutedEventArgs e)
       {
           if (!isRefresh)
               PieSegmentModels = collectionList[1];
           else
               PieSegmentModels = collectionList[0];
           isRefresh = !isRefresh;

}
   }
}

来源:https://www.cnblogs.com/yanjinhua/p/15353711.html

标签:WPF,饼图
0
投稿

猜你喜欢

  • 解析c#在未出现异常情况下查看当前调用堆栈的解决方法

    2023-05-18 02:54:04
  • unity实现贴图矩阵运算(旋转平移缩放)

    2022-07-27 13:53:41
  • Java协议字节操作工具类详情

    2023-11-02 06:25:02
  • C++ opencv实现在图片上画一条线示例代码

    2021-12-15 12:34:27
  • 详细了解JAVA NIO之Buffer(缓冲区)

    2022-08-18 00:59:28
  • Java使用entrySet方法获取Map集合中的元素

    2022-08-06 17:41:05
  • Android自定义按周签到打卡功能实例代码

    2023-08-06 18:45:49
  • Java利用endorsed如何覆盖jdk提供的类详解

    2021-05-30 08:26:33
  • 关于C#委托三种调用的分享使用

    2022-10-29 03:24:35
  • C# 无边框窗体之窗体移动实现代码

    2021-07-22 04:36:48
  • Android音视频开发之MediaExtactor使用教程

    2023-03-20 19:25:11
  • Android一行代码实现圆形头像

    2022-02-23 02:00:25
  • 关于工厂方法模式的Java实现

    2021-12-20 18:06:13
  • 聊聊Spring Cloud Gateway过滤器精确控制异常返回问题

    2022-06-23 01:04:14
  • Android12 蓝牙适配的实现步骤

    2021-08-25 08:36:34
  • Java @GlobalLock注解详细分析讲解

    2023-06-03 03:55:53
  • C# 使用HttpClient模拟请求的案例

    2023-10-16 18:20:14
  • Java 数组元素倒序的三种方式(小结)

    2022-04-01 22:59:19
  • C#中LINQ多条件JOIN时为什么可以使用匿名类

    2023-01-24 15:38:21
  • java中String.intern()方法功能介绍

    2023-11-25 23:49:21
  • asp之家 软件编程 m.aspxhome.com