TL;TR: Skip all the way down and download the complete style without "Show" storyboard for the Silverlight Toolkit March 2009 release.
I am currently looking at a couple of Silverlight features and extensions. And what's about the first thing one wants to see - GRAPHS. Well, that's me at least - maybe my background in Physics does push me in weird ways most of the times sometimes...
What I found was that the performance of the charts is not that great - when going to more than a couple datapoints ... to say like 1000?!
Oh, and of course those datapoints should change all the time, right? Turns out that does kinda have some impact on performance - since every single datapoint has an animation attached to it when it gets shown or hidden.
I am a total noob when it comes to XAML in general and Silverlight in particular - so it was a huge break-through for me to find out that one can change the style of existing controls. Yeah I know. Knocked me out though. So I got the trial of Expressoin Blend 2, did all the steps that were necessary to get to the templates. And found out that now all my datapoints where bright orange. Umm, that's not fun.
So after a bit more of fumbling around I found out that it's all very easy - when one knows how to do it... I know this is one of the "aha, actually he is not that bright" kinda revelation blog posts.
Aaaanyway.
The new template for a datapoint (in this particular case a LineDataPoint for LineSeries) that has no fade in translation looks like this:
XML:<ControlTemplate TargetType='charting:LineDataPoint' x:Key='LineNoTransition'>
<Grid Opacity='1' x:Name='Root'>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name='CommonStates'>
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration='0:0:0.1' />
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name='Normal' />
<vsm:VisualState x:Name='MouseOver'>
<Storyboard>
<ColorAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='MouseOverHighlight' Storyboard.TargetProperty='(Shape.Fill).(SolidColorBrush.Color)'>
<SplineColorKeyFrame KeyTime='00:00:00' Value='#FFFFDF00' />
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='MouseOverHighlight' Storyboard.TargetProperty='(UIElement.Opacity)'>
<SplineDoubleKeyFrame KeyTime='00:00:00' Value='0.24' />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name='SelectionStates'>
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration='0:0:0.1' />
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name='Unselected' />
<vsm:VisualState x:Name='Selected'>
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Duration='00:00:00.0010000' Storyboard.TargetName='SelectionHighlight' Storyboard.TargetProperty='(UIElement.Opacity)'>
<SplineDoubleKeyFrame KeyTime='00:00:00' Value='0.18' />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name='RevealStates'>
<vsm:VisualState x:Name='Shown' />
<vsm:VisualState x:Name='Hidden' />
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<ToolTipService.ToolTip>
<ContentControl Content='{TemplateBinding FormattedDependentValue}' />
</ToolTipService.ToolTip>
<Ellipse Fill='{TemplateBinding Background}' Stroke='{TemplateBinding BorderBrush}' />
<Ellipse RenderTransformOrigin='0.661,0.321'>
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin='0.681,0.308'>
<GradientStop Color='#00FFFFFF' />
<GradientStop Color='#FF3D3A3A' Offset='1' />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Fill='Red' Opacity='0' x:Name='SelectionHighlight' />
<Ellipse Fill='White' Opacity='0' x:Name='MouseOverHighlight' />
</Grid>
</ControlTemplate>
Notice that I set the opacity of the "Root" grid to 1 (it is 0 in the original style) and removed all storyboards from the "Shown" and "Hidden" VisualStates. So now we have a ControlTemplate that shows the datapoint right away (opaycity to 1) and does not need any additional CPU cycles for animations (no storyboards).
In order to be able to attach these animation-less templates to the respective data series we need an additional template:
XML:<Style TargetType='charting:LineDataPoint' x:Key='LineDataPointStyleBlue'>
<Setter Property='Background'>
<Setter.Value>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX='0.5' CenterY='0.5' ScaleX='2.09' ScaleY='1.819' />
<TranslateTransform X='-0.425' Y='-0.486' />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color='#FFB9D6F7' />
<GradientStop Color='#FF284B70' Offset='1' />
</RadialGradientBrush>
</Setter.Value>
</Setter>
<Setter Property='BorderBrush' Value='Gray' />
<Setter Property='BorderThickness' Value='1' />
<Setter Property='IsTabStop' Value='False' />
<Setter Property='Width' Value='8' />
<Setter Property='Height' Value='8' />
<Setter Property='Template' Value='{StaticResource LineNoTransition}' />
</Style>
Notice that I went to the source of the chart library and copied the original style for "Background" getting rid of the hideous "orange". Plus notice the Value for the Template that points to our new animation-less template.
Last but not least attach the new dataline template to the chart:
XML:<charting:Chart x:Name="Performance">
<charting:LineSeries
x:Name="SleepTimez"
ItemsSource="{Binding Path=Performance.SleepTimez}"
Title="T"
DependentValuePath="Count"
IndependentValuePath="Time"
DataPointStyle="{StaticResource LineDataPointStyleBlue}" />
<charting:LineSeries
x:Name="ListSleepTimez"
ItemsSource="{Binding Path=Performance.ListSleepTimez}"
Title="LT"
DependentValuePath="Count"
IndependentValuePath="Time"
DataPointStyle="{StaticResource LineDataPointStyleRed}" />
<charting:LineSeries
x:Name="ChartSleepTimez"
ItemsSource="{Binding Path=Performance.ChartSleepTimez}"
Title="CT"
DependentValuePath="Count"
IndependentValuePath="Time"
DataPointStyle="{StaticResource LineDataPointStyleLightGreen}" />
</charting:Chart>
And that's pretty much it. Unfortunatelly I was not able to make the style palette work again - so right now I have to manually choose and attach colors to the various data series. But that's good enough for me right now.
I have not figured out yet how to remove the "hide" transition. It seems as if the removal of datapoints from a graph still trigger an animation, but I don't know why. Any hints?
Download: Complete LineDataPoint style
Tweet this