WPF仿LiveCharts实现饼图的绘制

2022-11-13 13:11:59 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;

        }
    }
}

到此这篇关于WPF仿LiveCharts实现饼图的绘制的文章就介绍到这了,更多相关WPF饼图内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章