I’m not sure why I concentrate on Pie Charts. Maybe circles are just more attractive to me than bars or points :)
For the January 2009 Expression Newsletter (which will be out in a week or two), I put together a rather deep article on styling pie charts in the Silverlight Toolkit. At the end, I mentioned to check here for info on overlays.
One effect you can achieve with an overlay, is a glassy effect:
Now, overlays aren’t something built into the control, you have to do a little playing around with them to achieve this.
First, you’ll need to modify the control template. Basically you want to end up with a sandwich with the SeriesContainer in between the shadow and the glossy elements, all inside the PlotAreaContainer.
Here’s what it looks like (the specular is shown with the pie as a background because you wouldn’t be able to see it otherwise)
If you want your chart to be pretty color agnostic, or to support having multiple colors for the slices, you will want to change your soft glow to various opacities of white. However, you get a warmer glow if you use a color that is related to the base color of your chart. For example, here’s the same chart, but with a white glow:
As you can see, it really lacks that healthy glow :) That said, a template using only white for the highlights is far more flexible in terms of allowing you to color the various slices. Here’s the same white highlighting with some different slice colors:
The final appearance, while lacking a little life, definitely makes for a more usable pie chart. Due to the straight lines between the slices, it reminds me of one of those half-round glass paperweights that have a picture on the bottom.
Here’s what the style looks like (if anything is cut off to the right, just download the attached project, linked at the end of this post)
<Style x:Key="GlassPieChartPlotAreaStyle"
TargetType="Grid">
<Setter Property="Background"
Value="Transparent" />
</Style>
<ControlTemplate x:Key="GlassPieChartTemplate"
TargetType="charting:Chart">
<Border Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Title -->
<datavis:Title Style="{TemplateBinding TitleStyle}"
Content="{TemplateBinding Title}"
Grid.Row="0"/>
<Grid Margin="0,15,0,15"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Legend -->
<datavis:Legend x:Name="Legend"
Style="{TemplateBinding LegendStyle}"
Grid.Column="1"
Title="{TemplateBinding LegendTitle}"
BorderBrush="{x:Null}"
Background="{x:Null}" />
<!-- Chart Area -->
<Grid x:Name="ChartArea"
Grid.Column="0"
Style="{TemplateBinding ChartAreaStyle}">
<!-- Plot Area -->
<Grid x:Name="PlotArea"
Style="{TemplateBinding PlotAreaStyle}"
>
<!-- Underlay Area, for shadows etc -->
<local:SquareContainer VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="10 14 10 2"
IsHitTestVisible="False"
Visibility="Visible">
<Ellipse Stretch="Uniform"
Margin="0">
<Ellipse.Fill>
<RadialGradientBrush Center=".5,.5"
GradientOrigin=".5,.5">
<GradientStop Offset="0"
Color="#CC000000" />
<GradientStop Offset=".8"
Color="#CC000000" />
<GradientStop Offset="1"
Color="#00000000" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</local:SquareContainer>
<!-- Required containers -->
<Grid x:Name="GridLinesContainer" />
<Grid x:Name="SeriesContainer" Visibility="Visible" />
<Border BorderBrush="{x:Null}"
BorderThickness="1" />
<!-- Overlays for highlights and similar go after this line -->
<!-- Primary Soft Glow -->
<local:SquareContainer VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="14"
IsHitTestVisible="False"
Visibility="Visible">
<Ellipse Stretch="Uniform" Margin="5">
<Ellipse.Fill>
<RadialGradientBrush Center=".5,.4"
GradientOrigin=".3,.3">
<!-- White Highlight -->
<GradientStop Offset="0"
Color="#99ffffff" />
<GradientStop Offset=".5"
Color="#66ffffff" />
<GradientStop Offset="1"
Color="#00ffffff" />
<!-- Ruby Colored Highlight -->
<!--<GradientStop Offset="0"
Color="#CCf5398e" />
<GradientStop Offset=".5"
Color="#99f5398e" />
<GradientStop Offset="1"
Color="#00f5398e" />-->
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</local:SquareContainer>
<!-- Glass Specular Highlight -->
<local:SquareContainer VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="14"
IsHitTestVisible="False"
Visibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.06*" />
<RowDefinition Height="0.8*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.25*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0.25*" />
</Grid.ColumnDefinitions>
<Ellipse Stretch="Fill"
Grid.Row="1"
Grid.Column="1"
Opacity=".75"
>
<Ellipse.Fill>
<RadialGradientBrush Center=".45,0"
GradientOrigin=".45,0"
RadiusX="2"
RadiusY="1">
<GradientStop Offset="0.0"
Color="#EEFFFFFF" />
<GradientStop Offset="1"
Color="#11FFFFFF" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</local:SquareContainer>
</Grid>
</Grid>
</Grid>
</Grid>
</Border>
</ControlTemplate>
Here’s a set of four charts. The default chart appearance is on the upper left. The remaining three all use the same template, but different StylePalettes.
Here’s the xaml for the four charts (without the control template)
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<charting:Chart x:Name="DefaultPieChart"
Grid.Row="0"
Grid.Column="0"
>
<charting:Chart.Series>
<charting:PieSeries IndependentValueBinding="{Binding Label}"
DependentValueBinding="{Binding Value}">
</charting:PieSeries>
</charting:Chart.Series>
</charting:Chart>
<charting:Chart x:Name="MulticolorGlassPieChart"
Grid.Row="0"
Grid.Column="1"
Template="{StaticResource GlassPieChartTemplate}"
PlotAreaStyle="{StaticResource GlassPieChartPlotAreaStyle}">
<charting:Chart.Series>
<charting:PieSeries IndependentValueBinding="{Binding Label}"
DependentValueBinding="{Binding Value}">
<charting:PieSeries.StylePalette>
<datavis:StylePalette>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="#FF57007f" />
<Setter Property="BorderBrush"
Value="#FF2e0007" />
</Style>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="#FF00757f" />
<Setter Property="BorderBrush"
Value="#FF2e0007" />
</Style>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="#FF007f0f" />
<Setter Property="BorderBrush"
Value="#FF2e0007" />
</Style>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="#FF7f2100" />
<Setter Property="BorderBrush"
Value="#FF2e0007" />
</Style>
</datavis:StylePalette>
</charting:PieSeries.StylePalette>
</charting:PieSeries>
</charting:Chart.Series>
</charting:Chart>
<charting:Chart x:Name="RubyGlassPieChart"
Grid.Row="1"
Grid.Column="1"
Template="{StaticResource GlassPieChartTemplate}"
PlotAreaStyle="{StaticResource GlassPieChartPlotAreaStyle}">
<charting:Chart.Series>
<charting:PieSeries IndependentValueBinding="{Binding Label}"
DependentValueBinding="{Binding Value}">
<charting:PieSeries.StylePalette>
<datavis:StylePalette>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="#FF7f0013" />
<Setter Property="BorderBrush"
Value="#FF2e0007" />
</Style>
</datavis:StylePalette>
</charting:PieSeries.StylePalette>
</charting:PieSeries>
</charting:Chart.Series>
</charting:Chart>
<charting:Chart x:Name="BrightMulticolorGlassPieChart"
Grid.Row="1"
Grid.Column="0"
Template="{StaticResource GlassPieChartTemplate}"
PlotAreaStyle="{StaticResource GlassPieChartPlotAreaStyle}">
<charting:Chart.Series>
<charting:PieSeries IndependentValueBinding="{Binding Label}"
DependentValueBinding="{Binding Value}">
<charting:PieSeries.StylePalette>
<datavis:StylePalette>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="Orange" />
<Setter Property="BorderBrush"
Value="White" />
</Style>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="Red" />
<Setter Property="BorderBrush"
Value="White" />
</Style>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="Blue" />
<Setter Property="BorderBrush"
Value="White" />
</Style>
<Style TargetType="charting:PieDataPoint">
<Setter Property="Background"
Value="Green" />
<Setter Property="BorderBrush"
Value="White" />
</Style>
</datavis:StylePalette>
</charting:PieSeries.StylePalette>
</charting:PieSeries>
</charting:Chart.Series>
</charting:Chart>
</Grid>
While I did these examples 100% in xaml in Visual Studio, using the techniques presented here and in previous posts, a talented designer with Blend will be able to create all sorts of interesting designs for the charts.
I hope that gives you some idea of what you can do with a control template, and specifically with something like the Pie Charts from the Silverlight Toolkit.
You can download the full project here.