Showing and Hiding Series in chart
Lets say we have a chart like this

it kind of looks like too many lines and user doesnt have easy way to see the different trends or easily compare the different measures user wants.
Showing and hiding a particular series will be nice addition to charts to allow the user to pick and choose what to see. we want the user to be able to click the legenditem to toggle the display of the series.


we will start adding a style for the LegendItem, the original style looks like this
<Style TargetType=”charting:LegendItem”>
<Setter Property=”IsTabStop” Value=”False” />
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”charting:LegendItem”>
<StackPanel Orientation=”Horizontal”>
<Rectangle Width=”8″ Height=”8″ Fill=”{Binding Background}”
Stroke=”{Binding BorderBrush}” StrokeThickness=”1″ Margin=”0,0,3,0″ />
<datavis:Title Content=”{TemplateBinding Content}” />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and we specify the style on the LineSeries like this
<charting:LineSeries LegendItemStyle=”{StaticResource LegendItemStyle}” Title=”Total Visits”
IndependentValueBinding=”{Binding OrderDate}”
DependentValueBinding=”{Binding Visits}” />
As we want to provide a way for the user to toggle the visibility of the Series. we will re-style the LegendItem to use a CheckBox for this sample
<Style x:Key=”LegendItemStyle” TargetType=”charting:LegendItem”>
<Setter Property=”IsTabStop” Value=”False” />
<Setter Property=”Template”>
<Setter.Value>
<ControlTemplate TargetType=”charting:LegendItem”>
<CheckBox Click=”CheckBox_Click” Cursor=”Hand” IsChecked=”true”
Content=”{TemplateBinding Content}” Tag=”{TemplateBinding Content}”>
<CheckBox.Template>
<ControlTemplate TargetType=”CheckBox”>
<StackPanel Orientation=”Horizontal”>
<Rectangle Width=”8″ Height=”8″ Fill=”{Binding Background}” Stroke=”{Binding BorderBrush}”
StrokeThickness=”1″ Margin=”0,0,3,0″ />
<datavis:Title Content=”{TemplateBinding Content}” />
</StackPanel>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(After posting I realized that instead of binding again to Tag we could base our condition on the content itself. Too lazy to change the code now)
To start with, we want all the series to be shown so we set the IsChecked property to “true”.
we added a click handler also to checkbox in which we are going to check the IsChecked property and decide if we want the series to be shown or hidden
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox chk = (sender as CheckBox);
LineSeries ls = chart1.Series.Cast
().Where(s => s.Title.ToString() == chk.Tag.ToString()).ElementAtOrDefault(0);
if (chk.IsChecked.Value)
chk.Opacity = ls.Opacity = 1;
else
{
chk.Opacity = 0.5;
ls.Opacity = 0;
}
}
Very Nicely done.
Thank you
Doesn’t seem as if there’s a convenient way to use this for the general case of having multiple charts on the same screen, or at least it’s not obvious how that would be done.
Thanks for the jumpstart, though, it’s much appreciated.
Not sure, I understand what you are trying to do
Well, you have a reference to the chart hard-coded into the checkbox event handler (chart1). Since my page has four charts on it, it would seem that I can’t use the LegendItemStyle as-is on each chart, and I’m too new to Silverlight to know how to accomplish this without literally copying and pasting the style for each chart
you could modify the function for checkbox click like below, so that chart name is not hard coded and will work for multiple charts
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox chk = (sender as CheckBox);
Chart ch = GetParent(chk);
LineSeries ls = ch.Series.Cast().Where(s => s.Title.ToString() == chk.Tag.ToString()).ElementAtOrDefault(0);
if (chk.IsChecked.Value)
chk.Opacity = ls.Opacity = 1;
else
{
chk.Opacity = 0.5;
ls.Opacity = 0;
}
}
//Add this function in your code behind
public T GetParent(DependencyObject obj) where T : DependencyObject
{
DependencyObject parent = VisualTreeHelper.GetParent(obj);
while (parent != null)
{
if (parent.GetType() == typeof(T))
break;
else
parent = GetParent(parent);
}
return parent as T;
}
Excellent. I had tried looking at the .Parent property (which is always null), but had not known about the VisualTreeHelper class. Thanks a bunch!
you are welcome
VERY HELPFUL. I needed to use legend items to remove the series from the chart and this worked BEAUTIFULLY! Thanks so much.
Great post, helped me with a problem with syncing up lineseries colors with an external control. I was able to modify the legend style to meet my needs and merge that with your demo and it’s workign well. Thanks.
Thanks