1:XAML
<Style targettype="local:PieChart"> <Setter Property="Foreground" Value="#FF767676" /> <Setter Property="Palette"> <Setter.Value> <local:PaletteCollection> <Style targettype="Path"> <Setter Property="Fill" Value="#FF25a0db" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FF9cd60f" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FFeb7a2a" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FFd4df32" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FFcc0000" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FFE8BC34" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FF00ABA9" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> <Style targettype="Path"> <Setter Property="Fill" Value="#FF339933" /> <Setter Property="stroke" Value="#FFFFFF" /> </Style> </local:PaletteCollection> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate targettype="local:PieChart"> <Grid> <Grid.ColumnDeFinitions> <ColumnDeFinition Width="*" /> <ColumnDeFinition Width="Auto" /> </Grid.ColumnDeFinitions> <Grid x:Name="gChart" Grid.Column="0"> </Grid> <Grid x:Name="gLegend" Grid.Column="1" Width="{TemplateBinding LegendWidth}" > <ScrollViewer Margin="20,0" BorderThickness="0" HorizontalScrollBarVisibility="disabled" VerticalScrollBarVisibility="Auto"> <StackPanel x:Name="spLegend" Orientation="Vertical" /> </ScrollViewer> </Grid> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
2:C#后台
/// <summary> /// 饼状图控件 /// 参数说明: /// Label:类型标签,传值的类型标签,如Dictionary的Key; /// Value:值,如Dictionary的Value; /// ShowLabel:是否显示饼图标签; /// ShowLegend:是否显示图例; /// Palette:饼图的颜色板,可以用PaletteCollection类添加,默认颜色有8种; /// LegendWidth:图例的宽度; /// ItemsSource:饼图的数据源; /// /// author:hzw /// time:2013/08/20 /// </summary> [TemplatePart(Name = "gLegend",Type = typeof(Grid))] [TemplatePart(Name = "gChart",Type = typeof(Grid))] [TemplatePart(Name = "spLegend",Type = typeof(StackPanel))] public class PieChart : Control { /// <summary> /// 类型标签 /// </summary> public string Label { get; set; } /// <summary> /// 值 /// </summary> public string Value { get; set; } FxChart c = new FxChart("",null,""); /// <summary> /// 构造函数 /// </summary> public PieChart() { this.DefaultStyleKey = typeof(PieChart); SizeChanged += new SizeChangedEventHandler(PieChart_SizeChanged); } /// <summary> /// 尺寸变化事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void PieChart_SizeChanged(object sender,SizeChangedEventArgs e) { if (ItemsSource != null) { BindData(); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); if (ItemsSource != null) { BindData(); } } #region 依赖性属性设置 public static readonly DependencyProperty ShowLabelProperty = DependencyProperty.Register("ShowLabel",typeof(bool),typeof(PieChart),new PropertyMetadata(false,new PropertyChangedCallback(OnShowLabelPropertyChanged))); /// <summary> /// 显示标签 /// </summary> /// <param name="d"></param> /// <param name="e"></param> private static void OnShowLabelPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { PieChart obj = (PieChart)d; obj.BindData(); } public bool ShowLabel { get { return (bool)GetValue(ShowLabelProperty); } set { SetValue(ShowLabelProperty,value); this.BindData(); } } public static readonly DependencyProperty ShowLegendProperty = DependencyProperty.Register("ShowLegend",new PropertyChangedCallback(OnShowLegendPropertyChanged))); /// <summary> /// 是否显示图例 /// </summary> /// <param name="d"></param> /// <param name="e"></param> private static void OnShowLegendPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { PieChart obj = (PieChart)d; obj.BindData(); } public bool ShowLegend { get { return (bool)GetValue(ShowLegendProperty); } set { SetValue(ShowLegendProperty,value); this.BindData(); } } public static readonly DependencyProperty PaletteProperty = DependencyProperty.Register("Palette",typeof(PaletteCollection),new PropertyMetadata(new PaletteCollection())); /// <summary> /// 调色板 /// </summary> public PaletteCollection Palette { get { return (PaletteCollection)GetValue(PaletteProperty); } set { SetValue(PaletteProperty,value); } } public static readonly DependencyProperty LegendWidthProperty = DependencyProperty.Register("LegendWidth",typeof(double),new PropertyMetadata((double)80,new PropertyChangedCallback(OnLegendWidthPropertyChanged))); /// <summary> /// 图例宽度 /// </summary> /// <param name="d"></param> /// <param name="e"></param> private static void OnLegendWidthPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { PieChart obj = (PieChart)d; obj.BindData(); } public double LegendWidth { get { return (double)GetValue(LegendWidthProperty); } set { SetValue(LegendWidthProperty,value); } } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource",typeof(IEnumerable),new PropertyMetadata(null,new PropertyChangedCallback(OnItemsSourcePropertyChanged))); /// <summary> /// 数据源 /// </summary> /// <param name="d"></param> /// <param name="e"></param> private static void OnItemsSourcePropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e) { PieChart obj = (PieChart)d; obj.BindData(); } public IEnumerable ItemsSource { get { return (IEnumerable)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty,value); BindData(); } } #endregion const double ChartSpace = 100; const double LabelSpace = 1; List<Path> _List = new List<Path>(); #region 绑定数据源 /// <summary> /// 绑定数据 /// </summary> private void BindData() { string labelPath = this.Label; string valuePath = this.Value; if (this.ActualWidth == double.NaN || this.ActualWidth == 0) return; Grid gLegend = (Grid)this.GetTemplateChild("gLegend"); Grid gChart = (Grid)this.GetTemplateChild("gChart"); StackPanel spLegend = (StackPanel)this.GetTemplateChild("spLegend"); if (gLegend == null || gChart == null || spLegend == null) return; gChart.Children.Clear(); spLegend.Children.Clear(); _List.Clear(); gLegend.Visibility = ShowLegend ? Visibility.Visible : Visibility.Collapsed; double chartSpace = ChartSpace; //饼图位置 double chartWidth = this.ActualWidth - (ShowLegend ? LegendWidth : 0); Point centerPoint = new Point(chartWidth / 2,this.ActualHeight / 2); if (chartWidth > this.ActualHeight) chartWidth = this.ActualHeight; if (ShowLabel && chartWidth > chartSpace) chartWidth = chartWidth - chartSpace; //初始角度 double startAngle = 0; //初始点 Point startPoint = new Point(centerPoint.X,centerPoint.Y - (chartWidth / 2)); if (ItemsSource != null && !string.IsNullOrEmpty(labelPath) && !string.IsNullOrEmpty(valuePath)) { //取总数 double sum = 0; foreach (object obj in ItemsSource) { PropertyInfo piLabel = obj.GetType().GetProperty(labelPath); PropertyInfo piValue = obj.GetType().GetProperty(valuePath); if (piLabel == null) throw new Exception("标签错误!"); if (piValue == null) throw new Exception("值错误!"); object v = piValue.GetValue(obj,null); if (v != null) { sum += double.Parse(v.ToString()); } } int paletteIndex = 0; Brush fill = new SolidColorBrush(Color.FromArgb(0xFF,0xBA,0xBA)); //Brush stroke = new SolidColorBrush(Colors.White); Style style = new Style(); style.Setters.Add(new Setter { Property = Path.FillProperty,Value = new SolidColorBrush(Color.FromArgb(0xFF,0xBA)) }); style.Setters.Add(new Setter { Property = Path.strokeProperty,Value = new SolidColorBrush(Colors.White) }); foreach (object obj in ItemsSource) { //获取调色板 if (Palette != null && Palette.Count > 0) { style = Palette[paletteIndex]; foreach (Setter setter in style.Setters) { if (setter.Property == Path.FillProperty) fill = (Brush)setter.Value; //if (setter.Property == Path.strokeProperty) // stroke = (Brush)setter.Value; } paletteIndex++; if (paletteIndex >= Palette.Count) paletteIndex = 0; } PropertyInfo piLabel = obj.GetType().GetProperty(Label); PropertyInfo piValue = obj.GetType().GetProperty(Value); string label = piLabel.GetValue(obj,null).ToString(); double value = double.Parse(piValue.GetValue(obj,null).ToString()); //插入图例 Grid gridLegendItem = new Grid { Margin = new Thickness(0,2,0) }; gridLegendItem.ColumnDeFinitions.Add(new ColumnDeFinition { Width = new GridLength(20) }); gridLegendItem.ColumnDeFinitions.Add(new ColumnDeFinition()); Rectangle rectLengendItem = new Rectangle { Fill = fill,Width = 12,Height = 12,VerticalAlignment = VerticalAlignment.Top,Margin = new Thickness(0,0) }; TextBlock tbLengendItem = new TextBlock { textwrapping = textwrapping.Wrap }; //设置图例说明 tbLengendItem.Text = label; Grid.SetColumn(tbLengendItem,1); gridLegendItem.Children.Add(rectLengendItem); gridLegendItem.Children.Add(tbLengendItem); spLegend.Children.Add(gridLegendItem); //当前角度 double cAngle = value * 360 / sum + startAngle; Point curPoint = startPoint; //计算坐标 curPoint.X = centerPoint.X + (chartWidth / 2) * Math.Cos((cAngle - 90) * Math.PI / 180); curPoint.Y = centerPoint.Y + (chartWidth / 2) * Math.Sin((cAngle - 90) * Math.PI / 180); //插入块 Path path = new Path(); path.Style = style; //path.Fill = fill; //path.stroke = stroke; path.strokeThickness = 1; Pathfigure pathfigure = new Pathfigure { IsClosed = true }; pathfigure.StartPoint = centerPoint; Linesegment line = new Linesegment(); line.Point = startPoint; pathfigure.Segments.Add(line); //饼图的圆弧 ArcSegment arc = new ArcSegment(); arc.Size = new Size(chartWidth / 2,chartWidth / 2); arc.Point = curPoint; arc.SweepDirection = SweepDirection.Clockwise; pathfigure.Segments.Add(arc); PathGeometry pathGeometry = new PathGeometry(); pathGeometry.figures.Add(pathfigure); path.Data = pathGeometry; gChart.Children.Add(path); _List.Add(path); path.Tag = obj; //饼图标识显示 if (ShowLabel) { //计算中间角度 double mAngle = value * 180 / sum + startAngle; //计算Label坐标 double lX = centerPoint.X + (chartWidth / 2) * Math.Cos((mAngle - 90) * Math.PI / 180); double lY = centerPoint.Y + (chartWidth / 2) * Math.Sin((mAngle - 90) * Math.PI / 180); //饼图注记显示 TextBlock tbLabel = new TextBlock { textwrapping = textwrapping.Wrap,TextAlignment = TextAlignment.Center }; //tbLabel.Text = label + "\r\n" + (string.IsNullOrEmpty(this.ValueFormat) ? value.ToString() : value.ToString(this.ValueFormat)); //设置为只显示值 //tbLabel.Text = value.ToString(); //设置为显示名称和值 tbLabel.Text = label + "\r\n" + string.Format("{0:#%}",value / sum); if (mAngle <= 90) { tbLabel.HorizontalAlignment = HorizontalAlignment.Left; tbLabel.VerticalAlignment = VerticalAlignment.Bottom; tbLabel.Margin = new Thickness(lX + LabelSpace,this.ActualHeight - lY + LabelSpace); } else { if (mAngle <= 180) { tbLabel.HorizontalAlignment = HorizontalAlignment.Left; tbLabel.VerticalAlignment = VerticalAlignment.Top; tbLabel.Margin = new Thickness(lX + LabelSpace,lY + LabelSpace,0); } else { if (mAngle <= 270) { tbLabel.HorizontalAlignment = HorizontalAlignment.Right; tbLabel.VerticalAlignment = VerticalAlignment.Top; tbLabel.Margin = new Thickness(0,this.ActualWidth - (ShowLegend ? LegendWidth : 0) - lX + LabelSpace,0); } else { tbLabel.HorizontalAlignment = HorizontalAlignment.Right; tbLabel.VerticalAlignment = VerticalAlignment.Bottom; tbLabel.Margin = new Thickness(0,this.ActualHeight - lY + LabelSpace); } } } gChart.Children.Add(tbLabel); } startPoint = curPoint; startAngle = cAngle; } } } #endregion }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。