1

I would like to display the dependent value on the pie chart itself(not in the Legend area). I'm using Silverlight 4 + Silverlight 4 Toolkit (April 2010).

This should be fairy common request, but I haven't managed to find a solution. How should I do this?

  <toolkit:Chart Name="samplePieChart" Title="Sample" Width="600">
                    <toolkit:Chart.Series>
                        <toolkit:PieSeries Name="samplePieSeries" 
                                           ItemsSource="{Binding Questions}" 
                                           IndependentValueBinding="{Binding Name}" 
                                           DependentValueBinding="{Binding Count}"
                                           IsSelectionEnabled="True"
                                           />
                    </toolkit:Chart.Series>
                </toolkit:Chart>
mrBob
  • 385
  • 6
  • 22
  • It isn't as easy as you could think. You should redefine the PieDataPoint style, but after that everything will be one-colour. To return to the multi-colour chart, you should redefine the Palette property which has 16 styles inside. If you are fine with much code I can post how to do this. – vortexwolf Apr 23 '11 at 15:43
  • @vorrtex Could you please post the PieDataPoint style needed for this to run. I'm confortable with using style code, and I am interested in how this could be done as I'm getting more into Silverlight. Many thanks! – mrBob Apr 25 '11 at 05:56
  • Ok, I will try to apply my existing code to the pie chart tomorrow. – vortexwolf Apr 25 '11 at 21:36
  • I have edited my answer and added the code of the necessary style. – vortexwolf Apr 26 '11 at 22:21

1 Answers1

9

I have recalled that I have a link with the collection of resources related with charts.

And on that page you can find the link which can help you to add labels to the pie chart: LabeledPieChart

This solution use the derived class from the toolkit Chart class. And although I said that it is possible to create a similar behavior without creating new classes, I don't think that it is easier than using the existing control.

Anyway I can post the custom style of the pie series which displays the dependent value. All that you need is some kind of converter which converts the path geometry of the slice to the Left or the Top property of the Canvas, and the custom style of the data point.

Converter:

public class GeometryToNumberConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var g = value as Geometry;
        var type = parameter as string;
        if (type == "Left")
            return (g.Bounds.Left + g.Bounds.Right) / 2.0;
        else if (type == "Top")
            return (g.Bounds.Top + g.Bounds.Bottom) / 2.0;
        else return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And a few lines of xaml inside the template of the PieDataPoint class:

<Canvas Background="Transparent">
     <TextBlock Text="{TemplateBinding FormattedDependentValue}" 
         Canvas.Left="{Binding Geometry, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource GeometryToNumberConverter}, ConverterParameter=Left}"
         Canvas.Top="{Binding Geometry, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource GeometryToNumberConverter}, ConverterParameter=Top}"/>
</Canvas>

Here is the full code of the PieDataPoint style:

<UserControl.Resources>
    <local:GeometryToNumberConverter x:Name="GeometryToNumberConverter" />

    <Style x:Key="LabelDataPointStyle" TargetType="chart:PieDataPoint">
        <Setter Property="Background" Value="Orange"/>
        <Setter Property="BorderBrush" Value="White"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="RatioStringFormat" Value="{}{0:p2}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="chart:PieDataPoint">
                    <Grid
                    x:Name="Root"
                    Opacity="0">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="0:0:0.1"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <DoubleAnimation
                                        Storyboard.TargetName="MouseOverHighlight"
                                        Storyboard.TargetProperty="Opacity"
                                        To="0.6"
                                        Duration="0"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="SelectionStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="0:0:0.1"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Unselected"/>
                                <VisualState x:Name="Selected">
                                    <Storyboard>
                                        <DoubleAnimation
                                        Storyboard.TargetName="SelectionHighlight"
                                        Storyboard.TargetProperty="Opacity"
                                        To="0.6"
                                        Duration="0"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="RevealStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="0:0:0.5"/>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Shown">
                                    <Storyboard>
                                        <DoubleAnimation
                                        Storyboard.TargetName="Root"
                                        Storyboard.TargetProperty="Opacity"
                                        To="1"
                                        Duration="0"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Hidden">
                                    <Storyboard>
                                        <DoubleAnimation
                                        Storyboard.TargetName="Root"
                                        Storyboard.TargetProperty="Opacity"
                                        To="0"
                                        Duration="0"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Path
                        x:Name="Slice"
                        Data="{TemplateBinding Geometry}"
                        Fill="{TemplateBinding Background}"
                        Stroke="{TemplateBinding BorderBrush}"
                        StrokeMiterLimit="1">
                            <ToolTipService.ToolTip>
                                <StackPanel>
                                    <ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
                                    <ContentControl Content="{TemplateBinding FormattedRatio}"/>
                                </StackPanel>
                            </ToolTipService.ToolTip>
                        </Path>
                        <Path
                        x:Name="SelectionHighlight"
                        Data="{TemplateBinding GeometrySelection}"
                        Fill="Red"
                        StrokeMiterLimit="1"
                        IsHitTestVisible="False"
                        Opacity="0"/>
                        <Path
                        x:Name="MouseOverHighlight"
                        Data="{TemplateBinding GeometryHighlight}"
                        Fill="White"
                        StrokeMiterLimit="1"
                        IsHitTestVisible="False"
                        Opacity="0"/>
                        <Canvas IsHitTestVisible="False">
                            <TextBlock Text="{TemplateBinding FormattedDependentValue}" IsHitTestVisible="False"
                                       Canvas.Left="{Binding Geometry, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource GeometryToNumberConverter}, ConverterParameter=Left}"
                                       Canvas.Top="{Binding Geometry, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource GeometryToNumberConverter}, ConverterParameter=Top}"/>
                        </Canvas>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

You can apply this style so:

<chart:PieSeries DataPointStyle="{StaticResource LabelDataPointStyle}" ...

And the chart will be displayed as one-color orange chart.

If you don't like it, here is the link where I have shown how to change the Palette property of the chart.

This is the example of the Palette with 3 colors, other colors you can add by analogy:

<datavis:ResourceDictionaryCollection x:Key="DefaultPalette">
        <!-- Blue -->
        <ResourceDictionary>
            <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                <GradientStop Color="#FFB9D6F7" />
                <GradientStop Color="#FF284B70" Offset="1" />
            </RadialGradientBrush>
            <Style x:Key="DataPointStyle" TargetType="chart:PieDataPoint" BasedOn="{StaticResource LabelDataPointStyle}">
                <Setter Property="Background" Value="{StaticResource Background}" />
            </Style>
        </ResourceDictionary>
        <!-- Red -->
        <ResourceDictionary>
            <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                <GradientStop Color="#FFFBB7B5" />
                <GradientStop Color="#FF702828" Offset="1" />
            </RadialGradientBrush>
            <Style x:Key="DataPointStyle" TargetType="chart:PieDataPoint" BasedOn="{StaticResource LabelDataPointStyle}">
                <Setter Property="Background" Value="{StaticResource Background}" />
            </Style>
        </ResourceDictionary>
        <!-- Light Green -->
        <ResourceDictionary>
            <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                <GradientStop Color="#FFB8C0AC" />
                <GradientStop Color="#FF5F7143" Offset="1" />
            </RadialGradientBrush>
            <Style x:Key="DataPointStyle" TargetType="chart:PieDataPoint" BasedOn="{StaticResource LabelDataPointStyle}">
                <Setter Property="Background" Value="{StaticResource Background}" />
            </Style>
        </ResourceDictionary>
    </datavis:ResourceDictionaryCollection>

And don't forget to remove the DataPointStyle property from the series definition: <chart:PieSeries DataPointStyle="{StaticResource LabelDataPointStyle}" ... => <chart:PieSeries ...

Community
  • 1
  • 1
vortexwolf
  • 13,967
  • 2
  • 54
  • 72
  • Thansk so much for this. However, I still haven't managed to apply my palette to the labeled pie chart. It seems that it's a known issue [link](http://forums.silverlight.net/forums/p/164956/373196.aspx) – mrBob May 02 '11 at 03:33
  • I've tried a couple of ways to make it work, but without any success. ` – mrBob May 02 '11 at 03:43
  • @MrBob I have accidently set the Background property to the Canvas, my fault. Copy the `LabelDataPointStyle` style once again, now it is correct. Also remove the explicit `DataPointStyle` property from your PieSeries, because these styles will be applied implicitly. – vortexwolf May 02 '11 at 11:33
  • That's it! Vorrtext, you rock! Thanks – mrBob May 02 '11 at 16:47