Click here to Skip to main content
Click here to Skip to main content

Styling a Silverlight Chart

By , 27 Jan 2009
 

GoogleAnalyticsGraph

Introduction

I love Google Analytics! I use it to monitor every site I own… Google’s chart looks very slick! Here is a walkthrough on how to style your Silverlight chart to look like the Google Analytics chart!

Before we start

We need some data. I created very basic TrafficInfo and TrafficInfoCollection objects with some dummy data that I can bind to.

public class TrafficInfo
{
    public DateTime Date { get; set; }
    public int Visits { get; set; }
}

We also need the Silverlight Toolkit (I used the port to WPF created by Jaime Rodriquez).

Let's start with the basics

Add the following two namespaces:

xmlns:charting="clr-namespace:Microsoft.Windows.Controls.DataVisualization.
                Charting;assembly=Microsoft.Windows.Controls.DataVisualization"
xmlns:datavis="clr-namespace:Microsoft.Windows.Controls.DataVisualization;
               assembly=Microsoft.Windows.Controls.DataVisualization"

Now, let's create a simple line chart:

<charting:Chart Width="800" Height="175">
    <charting:Chart.Series>
        <charting:LineSeries IsSelectionEnabled="True"
                    Title="Visits"
                    ItemsSource="{StaticResource TrafficInfo}"
                    IndependentValueBinding="{Binding Date}"
                    DependentValueBinding="{Binding Visits}" />
    </charting:Chart.Series>
</charting:Chart>

And here is our master piece:

SilverlightChartTry1.jpg

Not bad, but…

Style, style, style

Let's start styling our chart… I will split the styling into two parts; the first part will be specific to line charts, and the second part might be relevant to other types of charts too…

Styling the LineSeries

Each LineSeries has a PolylineStyle property. The PolylineStyle controls how the line looks. Here is our GooglePolylineStyle:

<Style x:Key="GooglePolylineStyle" TargetType="Polyline">
    <Setter Property="StrokeThickness" Value="5"/>
</Style>

And, here is the style for the LineDataPoint:

<Style x:Key="GoogleLineDataPointStyle" TargetType="charting:LineDataPoint">
    <Setter Property="Background" Value="#0077CC" />
    <Setter Property="BorderBrush" Value="White"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="IsTabStop" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="charting:LineDataPoint">
                <Grid x:Name="Root" Opacity="1">
                    <ToolTipService.ToolTip>
                        <StackPanel Margin="2,2,2,2">
                            <ContentControl Content="{TemplateBinding IndependentValue}" 
                                            ContentStringFormat="{}{0:MMMM d, yyyy}"/>
                            <ContentControl Content="{TemplateBinding DependentValue}" 
                                            ContentStringFormat="Visits {0:###,###,###}"/>
                        </StackPanel>
                    </ToolTipService.ToolTip>
                    <Ellipse StrokeThickness="{TemplateBinding BorderThickness}" 
                     Stroke="{TemplateBinding BorderBrush}" 
                     Fill="{TemplateBinding Background}"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Also update the chart’s LineSeries to use our newly created styles:

<charting:LineSeries IsSelectionEnabled="True"
            PolylineStyle="{StaticResource GooglePolylineStyle}" 
            DataPointStyle="{StaticResource GoogleLineDataPointStyle}"
            MarkerHeight="10" MarkerWidth="10"
            Title="Visits"
            ItemsSource="{StaticResource TrafficInfo}"                                    
            IndependentValueBinding="{Binding Date}"
            DependentValueBinding="{Binding Visits}" />

And, here is the result:

GoogleLineDataPoint.jpg

There are a few things to notice here. Each DataPoint has the following properties you can use and display in your tooltip:

  • DependentValue
  • FormattedDependentValue
  • IndependentValue
  • FormattedIndependentValue

Each LineSeries can specify the DataPoint marker size using MarkerWidth and MarkerHeight.

Styling the chart

I want to remove the title and the ledger of the chart. There are two options to removing these items! You can create new styles for the title and the ledger that sets its visibility to Collapsed. (This trick also works if you don’t want DataPoint markers.)

<Style x:Key="GoogleNoTitle" TargetType="datavis:Title">
    <Setter Property="Visibility" Value="Collapsed"/>
</Style>

Then, just set the TitleStyle and LedgerStyle properties on the chart:

TitleStyle="{StaticResource GoogleNoTitle}"

The seconds method of removing these is to rather create a new ControlTemplate for the chart and remove them permanently!

<Style x:Key="GoogleChart" TargetType="charting:Chart">
    <Setter Property="PlotAreaStyle">
        <Setter.Value>
            <Style TargetType="Grid">
                <Setter Property="Background" Value="White" />
            </Style>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="charting:Chart">
                <Border
                Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}"
                Padding="10">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Grid Grid.Row="1" Margin="0,15,0,15">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Grid x:Name="ChartArea" 
                                 Style="{TemplateBinding ChartAreaStyle}">
                                <Grid x:Name="PlotArea" 
                                      Style="{TemplateBinding PlotAreaStyle}" 
                                      Margin="0,0,0,0" >
                                    <Grid x:Name="GridLinesContainer" />
                                    <Grid x:Name="SeriesContainer" />
                                    <Border Margin="0,0,0,0" 
                                      BorderBrush="#FF919191" 
                                      BorderThickness="0,1,0,1"/>
                                </Grid>
                            </Grid>
                        </Grid>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The new ControlTemplate merely removes the title and ledger! The last part of the chart we need to style are the axes. If you look at the Google chart, you will notice that the vertical grid lines indicate where a week starts; how difficult would this be?

Each chart has an Axes property, which can contain multiple axis! Here are some of the axis properties I used:

LabelStringFormat MMMM d, yyyy Changes the format of the labels
ShowGridLines True Shows the grid lines
ShowTickMarks True Shows the grid line markers
ShouldIncludeZero True Scales from 0
IntervalType Days Indicates what each unit on the axis is
Interval 7 Interval between points on the axis
IntervalOffset 1 Offset used in creating the axis
IntervalOffsetType Days Offset type

Here is the markup:

<charting:Chart.Axes>
    <charting:Axis Orientation="Horizontal" 
                   AxisType="DateTime" ShowGridLines="True" 
                   ShowTickMarks="True" LabelStringFormat="MMMM d, yyyy" 
                   IntervalType="Days" Interval="7" 
                   IntervalOffset="1" IntervalOffsetType="Days" 
                   Style="{StaticResource GoogleAxisStyle}" />
    <charting:Axis Orientation="Vertical" AxisType="Linear" ShowTickMarks="False" 
                   Interval="4000" IntervalType="Number" 
                   ShowGridLines="True" ShouldIncludeZero="True" 
                   Style="{StaticResource GoogleAxisStyle}"/>
</charting:Chart.Axes>

And that is it.

SilverlightChartDone.jpg

The Silverlight Toolkit Chart control is very flexible and powerful! Try it out, and you will be surprised at the endless ways you can style it!

If you found this article useful or interesting, please vote for it!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

rudigrobler
South Africa South Africa
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberFabián García28 Nov '12 - 8:08 
Thanks a lot Smile | :)
General2010 Charting changedmembertomerhs9 Oct '10 - 21:54 
Hey Guys - 2010 Assembly was updated by Microsoft and this project does not compile at all.
Anyone has update to this one to make life a bit easier?...
 
T.
GeneralDLL doesnot exist!!membersouidi abderrahmen30 Aug '10 - 23:01 
Hi,
 
I downloaded your source but i tried to run, i get error that some dll not exist!!Microsoft.windows.Controls.dataVisualisation!
GeneralRe: DLL doesnot exist!!subeditorIndivara4 Feb '11 - 14:10 
http://forums.silverlight.net/forums/t/83746.aspx[^]
GeneralMy vote of 5memberHariom Dubey7 Jul '10 - 19:23 
i like the way to format tooltip style,plz post some more articles on datapoint customization and tooltip as well.
GeneralMy vote of 1memberOBRon16 Dec '09 - 8:51 
Doesn't compile
GeneralMore ToolTip PropertiesmemberMember 7107482 Oct '09 - 17:05 
Hi,
I bind to a collection of Business Objects and I wanted to show properties of the bound item in the tooltip.   I finally worked out you can access all the properties of the bound item, not just the properties you mentioned. For example: say I was binding to a list of OrderItems, I can use this to get show the Client of the Order
 
<ContentControl DataContext="{TemplateBinding DataContext}" Content="{Binding Order.Client}"
   ContentStringFormat="Client: {0}"/>
 
Hope it's useful Smile | :)
GeneralAxis.IntervalType property does not existmemberTakuan.Daikon24 Aug '09 - 18:12 
I guess the article title is misleading, since it is not in fact even a Silverlight project (uses WPF port?), so some of the code listed in the article does not work. One specific case is that the out-of-the-box Silverlight Toolkit axis class does not expose an IntervalType property. It should, though. The omission amazes me, and is preventing me from using a Date for the axis and specifying a value other than 1 for the Interval.
GeneralRe: Axis.IntervalType property does not existmemberTakuan.Daikon24 Aug '09 - 18:18 
Okay, well, I was partially wrong. You can't use the Axis class, and have to use a descendant class, but when creating fully dynamic charts you may not have all the axes defined in markup. Here's one way to set the IntervalType on a Date axis from code :
 
			
chart.LayoutUpdated += delegate( object sender, EventArgs e )
{
	foreach (Axis loop in chart.ActualAxes)
	{
		if (loop is DateTimeAxis)
		{
			((DateTimeAxis)loop).IntervalType = DateTimeIntervalType.Days;
		}
	}
};
 
Obviously, if you are doing this from markup instead of code, just defining the correct type of Axis will work.
GeneralLine colors dynamicallymemberzappingz28 Feb '09 - 1:54 
Neat, short and readable. Killer post i should say. Is it possible to change the line color dynamically like show 4 lines. 2 red lines showing min and max values. 1 green line showing target and a blue line showing current value.
GeneralRe: Line colors dynamicallymemberrudigrobler1 Mar '09 - 19:03 
Thank you zappingz,
 
Yes it's possible! I'll try and create a sample!
GeneralRe: Line colors dynamicallymemberRamsdal4223 Sep '10 - 2:47 
Hey nice post, have you been able to add dynamic colors - im having some problems with that Smile | :)
GeneralRe: Line colors dynamically [modified]membermaxuepeng21 Dec '10 - 15:08 
Hello,I can't dynamically change the color on the right of LineSeries area when I have many lines,the show is that all the lines are the same color,that isn't what I want.
Is there any methords?
Waiting for you reply.
thank you !
modified on Tuesday, December 21, 2010 9:22 PM

GeneralRe: Line colors dynamicallymemberMember 404292826 Apr '11 - 8:44 
You have to use a custom chart style. The Chart has a Palette property of type Collection, containing 15 different color sets by default.
If you "create", well, strip a Chart style off the Chart control (f.e. using Blend), you'll see the Palette property
being set with a resourcedictionary collection, adding fifteen times a new radialgradientbrush and a DataPointStyle.
So, assume you created your custom DataPointStyle called "MyStyle", you modify all the
 
<Style x:Key="DataPointStyle" TargetType="Control"
 
lines to
 
<Style x:Key="DataPointStyle" TargetType="chartingToolkit:LineDataPoint" BasedOn="{StaticResource MyStyle}">
 
in the Chart style, where chartingToolkit is
 
xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
 
Regards
GeneralMy vote of 2memberRichard Deeming10 Feb '09 - 8:07 
The code fails to compile:
MC1000: Unknown build error, 'The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)'
GeneralRe: My vote of 2memberrudigrobler10 Feb '09 - 22:34 
Hi Richard,
 
First off, tnx for atleast letting me know why you have downvoted the article! I will update the project and send it to CP... If you want to fix this issue now, try the following:
 
1. Open the project in VS
2. Remove Microsoft.Windows.Controls.DataVisualization & Microsoft.Windows.Controls.Samples.Common refrences
3. Download SL Toolkit (The WPF port by Jaime) - http://blogs.msdn.com/jaimer/archive/2008/11/16/microsoft-client-continuum-in-action-the-silverlight-toolkit-charts-running-in-wpf.aspx[^]
4. Re-add Microsoft.Windows.Controls.DataVisualization & Microsoft.Windows.Controls.Samples.Common from Jaime's port
 
This should fix the issue, please let me know if it works?
GeneralRe: My vote of 2memberHüseyin Tüfekçilerli17 Feb '09 - 1:55 
I got the same error. The problem is that I had installed the latest WPFToolkit recently and Jaime's port references the previous version. To solve the issue:
 
1- Compile Jaime's Controls.DataVisualization (referencing the latest WPFToolkit) and Controls.Samples.Common projects.
2- Copy Microsoft.Windows.Controls.DataVisualization.dll, Microsoft.Windows.Controls.Samples.Common.dll and WPFToolkit.dll to a folder (called "Lib" for example).
3- Update GoogleAnalyticsGraph references with Microsoft.Windows.Controls.DataVisualization.dll and Microsoft.Windows.Controls.Samples.Common.dll files.
 
It would be better though if Visual Studio doesn't give such a cryptic message Smile | :)
 
HTH,
Hüseyin.
GeneralRe: My vote of 2memberDZaK831 Mar '09 - 12:19 
Hi
I can't compile also Jaime's port. I stopped after 40 minutes with the same errors in VS so what can I say more.. this source code is useless. :/
 
Bests,
Jacek
 
Work smart not hard

GeneralRe: My vote of 2memberrudigrobler1 Mar '09 - 19:04 
I managed to update jaimes code by just removing the olf reference to wpftoolkit and then readding the jan version and compiling it... will post 2 more source editions (wpf old, wpf new and silverlight)
GeneralI can't compile thememberbinarycheese10 Feb '09 - 4:34 
I get this error when I try to compile the project:
 
Error 1 Unknown build error, 'Cannot resolve dependency to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.' GoogleAnalyticsGraph
 
I have referenced the Microsoft.Windows.Controls.DataVisualization.dll file. Am I missing something?
GeneralRe: I can't compile thememberrudigrobler10 Feb '09 - 22:37 
Hi,
 
Please check out the following suggestion: http://www.codeproject.com/script/Forums/View.aspx?fid=1534217&msg=2919801[^]
GeneralRe: I can't compile thememberbinarycheese17 Feb '09 - 11:00 
Why can't you just include the dependency files in the solution like everybody else?
I still can't compile
GeneralRe: I can't compile thememberssawchenko7 Dec '09 - 7:17 
I also couldn't get this to compile. I started trying to remap references, but ended up giving up.
GeneralRe: I can't compile thememberpcummings30 Jul '10 - 2:12 
Doesn't compile in 2010
GeneralSilverlight implementationmembergizi4 Feb '09 - 0:54 
Thanks for the code and the clear explanation.
While using your code in Silverlight toolkit chart, you must replace this XAML code: (I guess OK for WPF)
 

 
With this code:

(Assuming you format your data points)
 
The ContentStringFormat is not valid in Silverlight
 
Gizi

GeneralRe: Silverlight implementationmembergizi4 Feb '09 - 0:58 
Sorry, my XAML was not visible:
Your Code:<ContentControl Content="{TemplateBinding IndependentValue}" ContentStringFormat="{}{0:MMMM d, yyyy}"/>
 
My Code:
<ContentControl Content="{TemplateBinding FormattedIndependentValue}" />
GeneralRe: Silverlight implementationmemberarikooe6 Feb '09 - 9:25 
Hi,
First i wanna join the others saying this is a great tool.
The problem is i only got to see the attached screenshots - it won't work for silverlight even after this line change.
Is there an easy conversion for this proj' into silverlight?
 
forgive me 4 my ignorance Smile | :) ...
thanx!!
GeneralRe: Silverlight implementationmembergizi6 Feb '09 - 11:12 
The sample was a Silverlight project. It worked for me OK as it is.
Somehow when I used these ideas in another vb.net project, I got this small problem. What was the problem you had?
GeneralRe: Silverlight implementationmemberarikooe7 Feb '09 - 1:17 
The error i get is:
"Unknown build error, 'Cannot resolve dependency to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event."
GeneralRe: Silverlight implementationmembergizi8 Feb '09 - 20:04 
Did you download the free Silverlight Toolkit?
This adds 4 dll's Microsoft.Windows.Controls.dll and another 3 that you must reference for this project.
Check if they are missing, this may cause the problem you have
GeneralRe: Silverlight implementationmemberrudigrobler8 Feb '09 - 21:42 
Thank you for pointing this out... will try in silverlight as soon as I have a opportunity!
 
Will post the results!
GeneralRe: Silverlight implementationmemberarikooe10 Feb '09 - 20:19 
sorry, even after adding these 4 DLL's - it won't work.
GeneralRe: Silverlight implementationmembergizi11 Feb '09 - 7:02 
Can you display the errors you get?
Are all your references OK?
GeneralExcellent SamplemvpPete O'Hanlon28 Jan '09 - 0:51 
I like this one a lot Rudi. Great job and a +5.
 
"WPF has many lovers. It's a veritable porn star!" - Josh Smith
 

My blog | My articles | MoXAML PowerToys



GeneralRe: Excellent Samplememberrudigrobler28 Jan '09 - 1:00 
Thank you Pete!!!
GeneralWow 5/5memberprasad0227 Jan '09 - 18:50 
Wow 5/5 good work...
 
Thanks and Regards,
prasad

GeneralRe: Wow 5/5memberrudigrobler27 Jan '09 - 19:06 
Thank you prasad02,
 
I appreciate the 5/5!
GeneralAnother good article RudimemberColinM12327 Jan '09 - 12:14 
And nice timing as I want to look at charting in the next week or two Smile | :)
Might not be obvious to everybody that Axes is the plural of Axis.
 

GeneralRe: Another good article Rudimemberrudigrobler27 Jan '09 - 19:05 
Thank you Colin
 
I have to admit that I also did not know that Axes is the plural of Axis but that is the naming thy used inside the control!
GeneralGood workmvpMika Wendelius27 Jan '09 - 10:38 
Easy to read and explains styling well. Good work.
 
The need to optimize rises from a bad design.My articles[^]

GeneralRe: Good workmemberrudigrobler27 Jan '09 - 19:04 
Thank you Mika
GeneralIts nice RudimvpSacha Barber27 Jan '09 - 6:26 
Nice one son.
 
Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralRe: Its nice Rudimemberrudigrobler27 Jan '09 - 19:03 
Thank you Sacha

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 27 Jan 2009
Article Copyright 2009 by rudigrobler
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid