Download Sample Projects (28.22 kb)
In my previous post, How to set silverlight column chart style programatically", I discussed one of the customizations of chart styles. In this post I will discuss one more customization of Silverlight charts rendering. This is about customizing display of Tooltip display on charts. If you look at default tool tip display, they are limited to displaying some combination of Independent and Dependent value. In some cases, that information is sufficient. But you may have cases where you want your tool tips to be verbose to convey more information about the data point that was used to render that point or column etc.
First and foremost concept that you will need to understand is how a chart actually gets rendered. Who decided the layout of various components of a chart display. Like any other Silverlight control, its the control template that defines how to chart is going to be rendered. So to customize the dispplay of Silverlight control, you can create a new template or take the default template and make modifications to it to come up with your own display scheme. Now you are asking from where can you get the default template for various chart types. The answer to it is Silverlight Toolkit source code. If you look in Charting/DataPoint folder of Controls.DataVisualization.Toolkit project, you will find template files for all chart types.
Let us get started. For this discussion I picked Column type chart. Here are the steps that I followed to create a new template file for my column charts.
<Style TargetType="charting:ColumnDataPoint" x:Key="ByteBlocksColumns">
Open the XAML file where you have added chart that you want to display. In the sample project, it is in Home.xaml. And then assign DataPointStyle property to point to the static resource that we created from default implementation of ColumnDataPoint. And make sure that you use the key name that you used in the resource file. Following snippet shows how I did it in sample project.
<chartingToolkit:Chart Title="Fruit Supply and Demand"
x:Name="FruitChart"
Width="500"
Height="350">
<chartingToolkit:Chart.Series>
<chartingToolkit:ColumnSeries
DataPointStyle="{StaticResource ByteBlocksColumns}"
Title="Fruit Supply"
IndependentValueBinding="{Binding Name}"
DependentValueBinding="{Binding Supply}"/>
</chartingToolkit:Chart.Series>
</chartingToolkit:Chart>
Now you should be able to compile and run your project. We have not done any customization of tool tip yet. At this point you should be able to run the project with default template.
If you look near bottom of ColumnChartStyle.xaml file, you will find following snippet of code.
<ToolTipService.ToolTip>
<ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
</ToolTipService.ToolTip>
This is default implementation of how and what is displayed in tool tip. So you can see that by default only DependentValue is displayed. So this is the place where you will need to make changes to customize the display of tooltip for chart. If you are only interested in making some minor changes like adding some static text or adding display of dependent value as well, you can make a change as below.
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizonal">
<ContentControl Content="{TemplateBinding FormattedDependentValue}"/>
<TextBlock Text="-" />
<ContentControl Content="{TemplateBinding FormattedIndependentValue}"/>
</StackPanel Orientation="Horizonal">
</ToolTipService.ToolTip>
In the sample project, I have implemented a use case where I want to create tool tip display at run time. What this means is that content of tool tip is being constructed based on some input from the existing data that is bound to that column. So in the template I am going to make some changes as shown below.
<ToolTipService.ToolTip>
<StackPanel Orientation="Horizontal">
<ContentControl Content="{Binding Id, Converter={StaticResource FruitConverter}}"/>
</StackPanel>
</ToolTipService.ToolTip>
In the snippet above you will see use of two things. One is that I am binding the content to the actual data object that was used to render that point. Second is use of converter. I am passing "Id" of the object as parameter to the converter. And in the converter I do some mock query to get more data. Following code shows how I constructed text of tool tip.
public class FruitSupplyToolTipConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return GetToolTip(int.Parse(value.ToString()));
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
object GetToolTip(int id)
{
var supply = MockData.FruitSupply.GetSupply();
var query = from item in supply where item.Id == id select item;
var items = query.ToList();
if (items.Count == 0)
{
return string.Empty;
}
return CreateToolTip(items[0]);
}
object CreateToolTip(FruitSupply supply)
{
var panel = new StackPanel();
panel.Orientation = Orientation.Vertical;
var tipTextBlock = new TextBlock();
tipTextBlock.Inlines.Add(new Run { Text = supply.Name });
tipTextBlock.Inlines.Add(new LineBreak());
tipTextBlock.Inlines.Add(new Run { Text = string.Format("Supply: {0}", supply.Supply)});
tipTextBlock.Inlines.Add(new LineBreak());
panel.Children.Add(tipTextBlock);
var hlink = new HyperlinkButton();
hlink.Content = "For more informattion Goto http://www.ByteBlocks.com";
hlink.NavigateUri = new Uri("http://www.byteblocks.com");
panel.Children.Add(hlink);
return panel;
}
}
You could argue that instead of going to the extent of using converter to build a tool tip text, I could have added another property to data object that contains the text and then bind tool tip to that property. That would have worked perfectly as well. But for demonstrating how you can construct tool tip text based on some other pieces of data or if tool tip content changes rapidly with time as well, then you need to access it at run time.
I hope this should give you good starting point to go nuts on more nifty tool tips.
How to plan CCSP Exam preparation
Develop a MongoDB pipeline to transform data into time buckets
Alert and Confirm pop up using BootBox in AngularJS
AngularJS Grouped Bar Chart and Line Chart using D3
How to lock and unlock account in Asp.Net Identity provider
2024 © Byteblocks, ALL Rights Reserved. Privacy Policy | Terms of Use