Jaa


Columns of a different color [Customizing the appearance of Silverlight charts with re-templating and MVVM]

**

This blog has moved to a new location and comments have been disabled.

All old posts, new posts, and comments can be found on The blog of dlaa.me.

See you there!

Comments

  • Anonymous
    February 03, 2009
    PingBack from http://www.clickandsolve.com/?p=3556

  • Anonymous
    February 04, 2009
    In this issue: Corey Schuman, Alex Golesh, Jordan Knight, Jesse Liberty, and David Anson. From SilverlightCream

  • Anonymous
    February 05, 2009
    It's been a couple of months since I shared my semi-comprehensive page of Charting resources on the web

  • Anonymous
    July 02, 2009
    If I use the following code in your Border, I should see the column being split in two: red and yellow. But that doesn't happen. Why? <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" > <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Border Background="Red" /> <Border Grid.Row="1" Background="Yellow" /> </Grid> </Border>

  • Anonymous
    July 03, 2009
    ovidiutudorache, I'm not sure what the problem you're seeing is - when I try the same thing you're doing, it works fine for me. Maybe you could compare what you've got with the working example below to see what might be different enough to be causing a problem? Hope this helps! <charting:Chart>    <charting:Chart.Series>        <charting:ColumnSeries            DependentValuePath="Y">            <charting:ColumnSeries.ItemsSource>                <PointCollection>                    <Point Y="0"/>                    <Point Y="1"/>                    <Point Y="2"/>                </PointCollection>            </charting:ColumnSeries.ItemsSource>            <charting:ColumnSeries.DataPointStyle>                <Style TargetType="charting:ColumnDataPoint">                    <Setter Property="Template">                        <Setter.Value>                            <ControlTemplate TargetType="charting:ColumnDataPoint">                                <Grid>                                    <Grid.RowDefinitions>                                        <RowDefinition/>                                        <RowDefinition/>                                    </Grid.RowDefinitions>                                    <Border Grid.Row="0" Background="Red"/>                                    <Border Grid.Row="1" Background="Yellow"/>                                </Grid>                            </ControlTemplate>                        </Setter.Value>                    </Setter>                </Style>            </charting:ColumnSeries.DataPointStyle>        </charting:ColumnSeries>    </charting:Chart.Series> </charting:Chart>

  • Anonymous
    July 20, 2009
    Your more recent post on SetterValueBindingHelper did an awesome job of making what you're doing in this post much easier. Awesome work!

  • Anonymous
    March 28, 2010

  1. The ControlTemplate already change to <Grid Background= "{Binding brush4VolumDataPointsColor}" > and <Rectangle> <Rectangle.Fill> <LinearGradientBrush> <GradientStop Color="#ff80ffff" Offset="0"/> <GradientStop Color="#ff0000ff" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> are work well. and The test statement oStockDataPoint.dVolum = oStockDataPoint.dVolum * -1; are work well! but brush4VolumDataPointsColor = new SolidColorBrush { Color = Colors.Red }; no effect! color value are zero (perhaps) (no color). why? Thank you very much! /////////////////////////////////////////// using System.ComponentModel; using System.Windows.Media; namespace INotifyPropertyChanged1 { public class StockDataPointViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public cStockDataPoint oStockDataPoint{ get; private set; } public Brush brush4VolumDataPointsColor{ get; private set; } public StockDataPointViewModel(cStockDataPoint StockDataPoint) { oStockDataPoint = StockDataPoint; oStockDataPoint.PropertyChanged += new PropertyChangedEventHandler(HandleStockDataPointPropertyChanged); } void HandleStockDataPointPropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == "dVolum") { if(oStockDataPoint.dVolum < 0) { brush4VolumDataPointsColor = new SolidColorBrush { Color = Colors.Red }; oStockDataPoint.dVolum = oStockDataPoint.dVolum * -1; } else { brush4VolumDataPointsColor = new SolidColorBrush { Color = Colors.Green }; } Helpers.InvokePropertyChanged(PropertyChanged, this, "brush4VolumDataPointsColor"); } } } } ///////////////////////////////////////// <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"> <Style x:Key="StockColumnDataPoint" TargetType="chartingToolkit:ColumnDataPoint"> <Setter Property="Background" Value="Blue"/> <Setter Property="BorderBrush" Value="Black"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="IsTabStop" Value="False"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="chartingToolkit:ColumnDataPoint"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Opacity="0" x:Name="Root"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="0:0:0.1"/> </VisualStateGroup.Transitions> <VisualState x:Name="Normal"/> <VisualState x:Name="MouseOver"> <Storyboard> <DoubleAnimation Storyboard.TargetName="MouseOverHighlight" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0"/> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="SelectionStates"> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="0:0:0.1"/> </VisualStateGroup.Transitions> <VisualState x:Name="Unselected"/> <VisualState x:Name="Selected"> <Storyboard> <DoubleAnimation Storyboard.TargetName="SelectionHighlight" Storyboard.TargetProperty="Opacity" To="0.6" Duration="0"/> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="RevealStates"> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="0:0:0.5"/> </VisualStateGroup.Transitions> <VisualState x:Name="Shown"> <Storyboard> <DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/> </Storyboard> </VisualState> <VisualState x:Name="Hidden"> <Storyboard> <DoubleAnimation Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" To="0" Duration="0"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <!--<Grid Background="{TemplateBinding background}">--> <Grid Background="{Binding brush4VolumDataPointsColor}"> <Rectangle> <Rectangle.Fill> <LinearGradientBrush> <GradientStop Color="#ff80ffff" Offset="0"/> <GradientStop Color="#ff0000ff" Offset="1"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Border BorderBrush="#ff00ffff" BorderThickness="1"> <Border BorderBrush="#ff0000a0" BorderThickness="1"/> </Border> <Rectangle x:Name="SelectionHighlight" Fill="Red" Opacity="0"/> <Rectangle x:Name="MouseOverHighlight" Fill="White" Opacity="0"/> </Grid> <ToolTipService.ToolTip> <ContentControl Content="{TemplateBinding FormattedDependentValue}"/> </ToolTipService.ToolTip> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> ////////////////////////////////////// <UserControl x:Class="INotifyPropertyChanged1.MainPage"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:visualizationToolkit="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit" xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" xmlns:chartingPrimitivesToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives;assembly=System.Windows.Controls.DataVisualization.Toolkit" mc:Ignorable="d" > <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="StockDataResourcesDictionary.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <chartingToolkit:Chart x:Name="tstStockColumnDataPoint" HorizontalAlignment="Left" Width="1280" Height="640" Title="Chart Title" VerticalAlignment="Top" > <chartingToolkit:ColumnSeries DataPointStyle="{StaticResource StockColumnDataPoint}" IndependentValueBinding="{Binding datetime4StockDataGrabbed}" DependentValueBinding="{Binding dVolum}" IsSelectionEnabled="True" /> <chartingToolkit:Chart.Axes> <chartingToolkit:LinearAxis Orientation="Y" MaxWidth="64" FontSize="8" ShowGridLines="True"> </chartingToolkit:LinearAxis> <chartingToolkit:DateTimeAxis Orientation="X" Interval="15" IntervalType="Minutes" > </chartingToolkit:DateTimeAxis> </chartingToolkit:Chart.Axes> </chartingToolkit:Chart> <Button            Content="Randomize Grades"            Click="RandomizeGradesClick"            Grid.Row="1"/> </Grid> </UserControl>
  • Anonymous
    March 28, 2010
    Crystal.ice, As I mentioned to you in email, this sample is part of my DataVisualizationDemos project and is kept up to date there with support for Silverlight 3, Silverlight 4, WPF 3.5, and WPF 4. If you could please have a look there, I think you'll find a sample that runs on the latest bits that you can play around with. http://blogs.msdn.com/delay/archive/2009/11/30/two-birds-squared-silverlight-wpf-data-visualization-development-release-3-and-a-datavisualizationdemos-update.aspx If you're still having trouble after that, let's please continue this discussion in email because it'll probably be a lot easier that way. :) Thanks!

  • Anonymous
    March 29, 2010
    Can anyone provide details on a similar process that would allow you to customize the color of a LineDataPoint by binding the style to a template property? e.g., something like this: <Style TargetType="charting:LineDataPoint" x:Name="ldp1">            <Setter Property="Background" Value="{TemplateBinding LineColor}" /> WPF allows you to do this, but I don't think that Silverlight does.

  • Anonymous
    March 29, 2010
    integragreg, I'm not sure I understand what you're trying to do. The syntax you show will work in both Silverlight and WPF today if you add a Brush-typed LineColor property to the LineDataPoint class where TemplateBinding will look for it. But the *DataPoint classes aren't really exposed to the user, so you'd probably want to control this with a property on the LineSeries class instead - in which case you'd probably want to use a normal Binding and the FindAncestor mode of RelativeSource. THAT will be WPF-only because FindAncestor isn't supported in Silverlight. But it ought to work. :) Hope this helps!

  • Anonymous
    June 14, 2010
    I'm having trouble binding the Fill color for the Legend item.  Using SL4 with the April 2010 Toolkit.  I've tried several variations of Binding with no luck, using a named color works but obviously that's not useful.

  • Anonymous
    June 15, 2010
    After further testing it seems the Pie chart legend works without an issue but the Multichart legend does not.  I'm guessing there is something different about the Multichart's legend and the way it is bound.

  • Anonymous
    June 15, 2010
    Brian, The LegendItems of a PieSeries are each directly associated with the corresponding PieDataPoint - which is why they "just work". That's not possible with the other series where a single LegendItem represents [0..N] FooDataPoints. If you want to customize the background of a ColumnSeries's LegendItem, you should be able to do so either by setting a Style as ColumnSeries.DataPointStyle that includes a Setter for Background=Purple OR by setting a Style as ColumnSeries.LegendItemStyle that includes a custom Template (which can do whatever you want). It sounds like you may have tried that and gotten it to work successfully, but are having trouble changing from Purple to some Binding to a color defined by your model object? In that case, things are probably a little trickier because of the need to get the right source for the Binding passed into it. If you're setting this up in code, that shouldn't be too difficult - just set Binding.Source when you create the Binding. If you're doing it in XAML, you'll probably need to start with my SetterValueBindingHelper and then apply some cleverness. :) blogs.msdn.com/.../one-more-platform-difference-more-or-less-tamed-settervaluebindinghelper-makes-silverlight-setters-better.aspx I haven't tried this myself, but it seems like it should be possible. If you have trouble, let me know and I can add this scenario to my TODO list for blogging. Hope this helps!

  • Anonymous
    June 18, 2010
    I actually went about it in a different method, less effort involved.  :) Since I had multiple charts on the page with a common legend I simply turned off the individual charts legends and made a common legend out of a listbox control.

  • Anonymous
    June 18, 2010
    Brian, Super - that's exactly one of the scenarios we tried to enable. :) Glad to hear it's working out for you!

  • Anonymous
    September 13, 2010
    The comment has been removed

  • Anonymous
    September 13, 2010
    Helen, It's a neat idea, but something like that isn't natively supported by the current implementation. :( What's more, I'm not sure I know of a great way to do this in general. However, if your scenario is a little flexible and not too wild, what you might be able to do (quite easily, in fact!) is use a Brush with a horizontal linear gradient for the Fill of the Area shape. That'd let you create something like a red->blue fade across the length of the area chart - though it wouldn't specifically let you tie the color chages to exact points on the axis. Hope this helps!

  • Anonymous
    January 15, 2012
    how can i change the width of a column and animate it to an increasing column

  • Anonymous
    January 16, 2012
    Narender Rautela, Column width is automatic (though you could change the code if you wanted. Animating data changes is automatic (for data objects implementing INotifyPropertyChanged) as I discuss here: blogs.msdn.com/.../announcing-a-free-open-source-charting-solution-for-silverlight-silverlight-toolkit-released-today-at-pdc.aspx Hope this helps!