2017-12-27 562 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歡迎您,但如果您認爲我的回答適合您的問題,請將其標記爲正確答案 –