PieChart.xaml.cs 6.91 KB
using Microsoft.Expression.Shapes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Security.Policy;
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 FLY.ControlLibrary
{
    /// <summary>
    /// PieChart.xaml 的交互逻辑
    /// </summary>
    public partial class PieChart : UserControl
    {
        static SolidColorBrush[] defaultColor;
        static int defaultcolor_idx = 0;
        static PieChart()
        {
            defaultColor = new SolidColorBrush[] {
            new SolidColorBrush(System.Windows.Media.Colors.Red),
            new SolidColorBrush(System.Windows.Media.Colors.Green),
            new SolidColorBrush(System.Windows.Media.Colors.Blue),
            new SolidColorBrush(System.Windows.Media.Colors.LightPink),
            new SolidColorBrush(System.Windows.Media.Colors.LightGreen),
            new SolidColorBrush(System.Windows.Media.Colors.LightBlue) };
        }
        public static Brush GetColor()
        {
            Brush b = defaultColor[defaultcolor_idx];
            defaultcolor_idx++;
            if (defaultcolor_idx >= defaultColor.Count())
                defaultcolor_idx = 0;
            return b;
        }

        List<PicChartItem> items = new List<PicChartItem>();

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(PieChart),
                new PropertyMetadata((d, e) => {
                    PieChart pc = d as PieChart;
                    pc.ItemsBinding();
                }));

        public IEnumerable ItemsSource
        {
            get
            {
                return (IEnumerable)GetValue(ItemsSourceProperty);
            }
            set
            {
                SetValue(ItemsSourceProperty, value);
                ItemsBinding();
            }
        }

        public static readonly DependencyProperty ItemValueBindingProperty =
            DependencyProperty.Register("ItemValueBinding", typeof(string), typeof(PieChart));
        /// <summary>
        /// 值
        /// </summary>
        public string ItemValueBinding
        {
            get
            {
                return (string)GetValue(ItemValueBindingProperty);
            }
            set
            {
                SetValue(ItemValueBindingProperty, value);
            }
        }

        public static readonly DependencyProperty ItemColorBindingProperty =
            DependencyProperty.Register("ItemColorBinding", typeof(string), typeof(PieChart));
        /// <summary>
        /// 值
        /// </summary>
        public string ItemColorBinding
        {
            get
            {
                return (string)GetValue(ItemColorBindingProperty);
            }
            set
            {
                SetValue(ItemColorBindingProperty, value);
            }
        }

        private void ItemsBinding()
        {
            if (ItemsSource == null)
                return;
            IEnumerator iterator = ItemsSource.GetEnumerator();
            while (iterator.MoveNext())
            {
                object obj = iterator.Current;
                if (obj is INotifyPropertyChanged)
                {
                    ((INotifyPropertyChanged)obj).PropertyChanged += PieChart_PropertyChanged;
                }
            }

            Draw();
        }

        private void PieChart_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if ((e.PropertyName == ItemValueBinding) || (e.PropertyName == ItemColorBinding))
            {
                Draw();
            }
        }
        public PieChart()
        {
            InitializeComponent();
        }

        void Draw()
        {

            if (ItemsSource == null)
                return;
            int idx = 0;
            IEnumerator iterator = ItemsSource.GetEnumerator();
            while (iterator.MoveNext())
            {
                object obj = iterator.Current;
                Type t = obj.GetType();
                System.Reflection.PropertyInfo pi_value = t.GetProperty(ItemValueBinding);
                System.Reflection.PropertyInfo pi_color = t.GetProperty(ItemColorBinding);
                if (pi_value == null)
                    return;
                //if (!(pi_value.PropertyType is System.IConvertible))
                //    return;

                double v = Convert.ToDouble(pi_value.GetValue(obj, null));
                Brush c = null;

                if (pi_color != null)
                    c = (Brush)pi_color.GetValue(obj, null);

                PicChartItem item;
                if (idx < items.Count)
                {
                    item = items[idx];
                }
                else
                {
                    item = new PicChartItem();
                    items.Add(item);
                }

                item.Value = v;
                if (c != null)
                    item.Color = c;
                else
                    item.Color = GetColor();

                idx++;
            }
            //把多余的删除
            if(items.Count != idx)
                items.RemoveRange(idx, items.Count - idx);

            if (items.Count() == 0)
                return;

            RootGrid.Children.Clear();

            double total = items.Sum((item) => { return item.Value; });
           
            double startangle = 0;
            foreach (PicChartItem item in items)
            {

                double angle;
                if (total > 0)
                    angle = item.Value / total * 360;
                else
                    angle = 360 / items.Count;

                Arc a = new Arc()
                {
                    ArcThickness = 200,
                    Stretch = Stretch.None,
                    StartAngle = startangle,
                    EndAngle = startangle + angle,
                    Fill = item.Color
                };
                startangle += angle;
                RootGrid.Children.Add(a);
            }
            
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            Draw();
        }

        class PicChartItem : INotifyPropertyChanged
        {

            /// <summary>
            /// 值
            /// </summary>
            public double Value { get; set; }

 
            /// <summary>
            /// 颜色
            /// </summary>
            public Brush Color { get; set; }


            #region INotifyPropertyChanged 成员
            public event PropertyChangedEventHandler PropertyChanged;
            #endregion
        }
    }

}