2017-12-27 561 views

回答

0

将百分比添加到System.Windows.Controls.DataVisualization.Charting PieChart不是那么直接,因为没有用于管理标签的属性。

无论如何有一些方法可以达到目标。我写了一个article on my blog来描述我使用的那个。

的第一步是创建一个自定义PieDataPoint类:

public class PieDataPoint : System.Windows.Controls.DataVisualization.Charting.PieDataPoint 
{ 
    public static readonly DependencyProperty TextedGeometryProperty = 
     DependencyProperty.Register("TextedGeometry", typeof(Geometry), typeof(PieDataPoint)); 

    public Geometry TextedGeometry 
    { 
     get { return (Geometry)GetValue(TextedGeometryProperty); } 
     set { SetValue(TextedGeometryProperty, value); } 
    } 

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

    public PieDataPoint() 
    { 
     DependencyPropertyDescriptor dependencyPropertyDescriptor 
      = DependencyPropertyDescriptor.FromProperty(GeometryProperty, GetType()); 

     dependencyPropertyDescriptor.AddValueChanged(this, OnGeometryValueChanged); 
    } 

    private double LabelFontSize 
    { 
     get 
     { 
      FrameworkElement parentFrameworkElement = Parent as FrameworkElement; 
      return Math.Max(8, Math.Min(parentFrameworkElement.ActualWidth, 
       parentFrameworkElement.ActualHeight)/30); 
     } 
    } 

    private void OnGeometryValueChanged(object sender, EventArgs arg) 
    { 
     Point point; 
     FormattedText formattedText; 

     CombinedGeometry combinedGeometry = new CombinedGeometry(); 
     combinedGeometry.GeometryCombineMode = GeometryCombineMode.Exclude; 

     formattedText = new FormattedText(FormattedRatio, 
      CultureInfo.CurrentCulture, 
      FlowDirection.LeftToRight, 
      new Typeface("Arial"), 
      LabelFontSize, 
      Brushes.White); 

     if (ActualRatio == 1) 
     { 
      EllipseGeometry ellipseGeometry = Geometry as EllipseGeometry; 

      point = new Point(ellipseGeometry.Center.X - formattedText.Width/2, 
       ellipseGeometry.Center.Y - formattedText.Height/2); 
     } 
     else if (ActualRatio == 0) 
     { 
      TextedGeometry = null; 
      return; 
     } 
     else 
     { 
      Point tangent; 
      Point half; 
      Point origin; 

      PathGeometry pathGeometry = Geometry as PathGeometry; 
      pathGeometry.GetPointAtFractionLength(.5, out half, out tangent); 
      pathGeometry.GetPointAtFractionLength(0, out origin, out tangent); 

      point = new Point(origin.X + ((half.X - origin.X)/2) - formattedText.Width/2, 
       origin.Y + ((half.Y - origin.Y)/2) - formattedText.Height/2); 

     } 

     combinedGeometry.Geometry1 = Geometry; 
     combinedGeometry.Geometry2 = formattedText.BuildGeometry(point); 

     TextedGeometry = combinedGeometry; 
    } 
} 

正如你可以看到它增加了一个FormattedText几何(用百分比)为原始Geometry。然后,您需要为使用新几何属性(名为TextedGeometry)创建默认样式(在generic.xaml字典中)。

样式必须包含 - 至少 - 这样的事情:

<Path Name="Slice" Data="{TemplateBinding local:PieDataPoint.TextedGeometry}" 
      Fill="{TemplateBinding Control.Background}" 
      Stroke="{TemplateBinding Control.BorderBrush}" 
      StrokeMiterLimit="1"> 
    <ToolTipService.ToolTip> 
     <StackPanel> 
      <ContentControl Content="{TemplateBinding chartingToolkit:DataPoint.FormattedDependentValue}" /> 
      <ContentControl Content="{TemplateBinding chartingToolkit:PieDataPoint.FormattedRatio}" /> 
     </StackPanel> 
    </ToolTipService.ToolTip> 
</Path> 

正如你所看到的“切片”路径都有其Data属性绑定到TextedGeometry

现在有了自定义PieSeries我们可以强制Chart控制使用我们PieDataPoint

public class PieSeries : System.Windows.Controls.DataVisualization.Charting.PieSeries 
{ 
    protected override DataPoint CreateDataPoint() 
    { 
     return new PieDataPoint(); 
    } 
} 

所以在你的XAML可以使用:

<chartingToolkit:Chart Name="pieChart" Title="Pie Series Demo"> 
    <local:PieSeries DependentValuePath="Value" IndependentValuePath="Key" 
         ItemsSource="{Binding}" IsSelectionEnabled="True" /> 

</chartingToolkit:Chart> 

local指的是你的自定义命名空间。我希望它能帮助你。

+0

感谢您的非常详细的答案,先生。 –

+0

@NguyenMinhDat欢迎您,但如果您认为我的回答适合您的问题,请将其标记为正确答案 –