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.