Search code examples
c#silverlightsilverlight-4.0silverlight-toolkitpie-chart

Silverlight Toolkit ; Pie Chart Colors


I have a huge problem that I can't figure out. Let's say that I have five different fruits, and I want each of them to be associated with a certain color. Let's say that I have three "baskets" which contain zero or more of said fruits.

When I Make Pie charts for my three baskets, Each wedge is just some random color that is presumable picked by the control. How would I say, make the blueberries blue, bannanas yellow, etc. in the chart?

I know this is a weird question, but I can't think of a simpler way to describe it.

I don't care if the solution is in XAML or code, just as long as it works.


Solution

  • I have found the solution, after much swearing and investigation. There are a lot of moving parts here, so I am going to keep each as brief as possible while still conveying the main points.

    For starters I have a collection of objects that I am trying to keep track of:

    public class PileOfFruit
    {
      public string Name {get; set; }
      public int Count { get; set; }
    }
    

    In my view model, I have a collection of those objects.

    public class BasketVM
    {
    ...
        private ObservableCollection<PileOfFruit> _FruitBasket = new ObservableCollection<PileOfFruit>();
        public ObservableCollection<PileOfFruit> FruitBasket
        {
          get { return _FruitBasket; }
        }
    ...
    }
    

    In my view I will define the pie chart that will display the quantites of the fruits in the basket. The most important factor here is the template binding to SliceTemplate

    <chartingToolkit:Chart x:Name="ExampleChart">
        <chartingToolkit:PieSeries ItemsSource={Binding FruitBasket
                                   DependentValueBinding="{Binding Count}" 
                                   IndependentValueBinding="{Binding Name}">
            <chartingToolkit:PieSeries.Palette>
                <visualizationToolkit:ResourceDictionaryCollection>
                <ResourceDictionary>
                    <Style x:Key="DataPointStyle" TargetType="Control">
                        <Setter Property="Template" Value="{StaticResource SliceTemplate}"/>
                    </Style>
    

    Now in app.xaml or some other place we can drop in the template for the PieDataSeries object. Pay close attention to the value on Fill It is bound to the independent value which will be something like 'banana' 'grape' or whatever. This in turn is passed off to a value converter.

    <converters:FruitToColorConverter x:Key="FruitToColorConverter"/>
    
    <ControlTemplate x:Key="SliceTemplate" TargetType="chart:PieDataPoint">
      <Path Data="{TemplateBinding Geometry}"
            Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IndependentValue, Converter={StaticResource FruitToColorConverter}}"
            Stroke="{TemplateBinding BorderBrush}">
        ....
    

    The associated data converter is what will finally set the color that we want. So if we do something like this...

    public class FruitToColorConverter : IValueConverter
    {
      private SolidColorBrush Default = new SolidColorBrush(Colors.Black);
    
      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
      {
        if (value == null || (!(value is string))) { return Default; }
    
        switch (value as string)
        {
          case "Apple":
            return new SolidColorBrush(Colors.Red);
          case "BlueBerry":
            return new SolidColorBrush(Colors.Blue);
          default:
            return Default;
            ......
    

    And that is how you get the correct colors each and every time. If I left anything out or should clarify, please let me know so I can make corrections. There are a lot of moving parts here.. =P