<telerik:RadCartesianChart.SeriesProvider> <telerik:ChartSeriesProvider Source="{Binding Data}"> <telerik:ChartSeriesProvider.SeriesDescriptors> <telerik:CategoricalSeriesDescriptor ItemsSourcePath="Data" ValuePath="Sales" CategoryPath="Article"> <telerik:CategoricalSeriesDescriptor.Style> <Style TargetType="telerik:BarSeries"> <Setter Property="CombineMode" Value="Stack" /> <Setter Property="local:ChartUtilities.SeriesStackGroupKey" Value="{Binding StackGroup}" /> <Setter Property="LegendSettings"> <Setter.Value> <telerik:SeriesLegendSettings Title="{Binding NameInLegend}"/> </Setter.Value> </Setter> </Style> </telerik:CategoricalSeriesDescriptor.Style> </telerik:CategoricalSeriesDescriptor> </telerik:ChartSeriesProvider.SeriesDescriptors> </telerik:ChartSeriesProvider>Thanks!
10 Answers, 1 is accepted
The BarSeries have a DefaultVisualStyle property which expects a Style targeting a Border. In this style you can set the fill, the border brush and the border thickness as per requirements.
Regards,
Petar Marchev
Telerik
How do you apply that style to the dynamic bar charts produced using a ChartSeriesProvider? See my sample code above.
Thanks!
<telerik:ChartSeriesProvider.SeriesDescriptors> <telerik:CategoricalSeriesDescriptor ItemsSourcePath="SubcategoryData" ValuePath="Value" CategoryPath="Category"> <telerik:CategoricalSeriesDescriptor.Style> <Style TargetType="telerik:BarSeries"> <Setter Property="DefaultVisualStyle"> <Setter.Value> <Style TargetType="Border"> <Setter Property="BorderBrush" Value="Black"/> <Setter Property="BorderThickness" Value="1"/> </Style> </Setter.Value> </Setter>...Hi,
I am trying to set the background color of a bar series generated from a ChartSeriesProvider. When explicitly setting the color as follows:
<telerik:CategoricalSeriesDescriptor ItemsSourcePath="SeriesData" ValuePath="Value" CategoryPath="Label"> <telerik:CategoricalSeriesDescriptor.Style> <Style TargetType="telerik:BarSeries" BasedOn="{StaticResource BarSeriesStyle}"> <Setter Property="CombineMode" Value="Stack" /> <Setter Property="DisplayName" Value="{Binding SeriesLabel}" /> <Setter Property="LegendSettings"> <Setter.Value> <telerik:SeriesLegendSettings Title="{Binding SeriesLabel}" /> </Setter.Value> </Setter> <Setter Property="DefaultVisualStyle"> <Setter.Value> <Style TargetType="Border"> <Setter Property="Background" Value="Red"/> <!--<Setter Property="Background" Value="{Binding SeriesBrush}"/>--> </Style> </Setter.Value> </Setter> </Style> </telerik:CategoricalSeriesDescriptor.Style></telerik:CategoricalSeriesDescriptor>It works as expected with all series generated in red. However, when I try to dynamically bind it to a Brush property of the ViewModel, no background is set. See attached screenshots.
FYI here is my ViewModel object
public class ChartSeriesProviderSource : BindableBase{ public AddRangeObservableCollection<CategoryDataPoint> SeriesData { get; private set; } public ChartSeriesProviderSource() { SeriesData = new AddRangeObservableCollection<CategoryDataPoint>(); HasData = false; } private string _seriesLabel; public string SeriesLabel { get { return _seriesLabel; } set { if (value != _seriesLabel) { _seriesLabel = value; OnPropertyChanged(() => SeriesLabel); } } } private string _seriesColorString; public string SeriesColorString { get { return _seriesColorString; } set { if (value != _seriesColorString) { _seriesColorString = value; OnPropertyChanged(() => SeriesColorString); } } } private Brush _seriesBrush; public Brush SeriesBrush { get { return _seriesBrush; } set { if (value != _seriesBrush) { _seriesBrush = value; OnPropertyChanged(() => SeriesBrush); } } } private int _seriesOrder; public int SeriesOrder { get { return _seriesOrder; } set { if (value != _seriesOrder) { _seriesOrder = value; OnPropertyChanged(() => SeriesOrder); } } } private bool _hasData; public bool HasData { get { return _hasData; } set { if (value != _hasData) { _hasData = value; OnPropertyChanged(() => HasData); } } }}The number of series can vary greatly base on data filters applied so I do not want to get into manipulating the palette which I explicitly set to null
<telerik:RadCartesianChart x:Name="chartAtoB" Palette="{x:Null}" Margin="3">
You can use a debugger converter, in the binding that does not work as you expect it to, in order to see what is the actual incoming value. It should be the DataPoint of the bar, not the main view model or the series view model. You should be able to use an ElementName or RelativeSource binding in order to get the data context you are looking for. Let us know how it goes.
Regards,
Petar Marchev
Telerik
Hi Petar,
At first I tried to provide a SeriesBrush property on the CategoryDataPoint but this did not yield anything different. Then I created a DebugConverter
public class DebugConverter : IValueConverter{ public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { Debugger.Break(); return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { Debugger.Break(); return value; }}
<Setter Property="DefaultVisualStyle"> <Setter.Value> <Style TargetType="Border"> <!--<Setter Property="Background" Value="Red"/>--> <Setter Property="Background" Value="{Binding SeriesBrush, Converter={StaticResource debugConverter}}"/> </Style> </Setter.Value></Setter>I am no coding guru so rely heavily on our friend Google. Not sure what I am missing.
I think that if you remove the " SeriesBrush, " part from the expression and place a break point in the Convert method, you should be able to debug it. The reason that this code does not work is that the SeriesBrush property search fails, because the data context of the expression is the DataPoint and not your actual business item. You can access the data item via the DataItem property of the data point. So if you were to change the binding a little it should work:
<Setter Property="Background" Value="{Binding DataItem.SeriesBrush, Converter={StaticResource debugConverter}}"/>An alternative to declaring a SeriesBrush property in the business item is to use a ElementName binding or a RelativeSourceBinding, also you can use a chart palette. I hope this information helps.
Regards,
Petar Marchev
Telerik
Hi Petar,
That did the trick thanks. I did previously try the "DataItem.SeriesBrush" bit, but at that point did not have the Brush property on the DataPoint object. When I added the Brush to the DataPoint following your previous feedback, I did not add it again.
Thanks for the assistance.
Regards
Renier
Hi Petar,
Maybe not directly related to the original question, but in my case it is related due to being on the same UserControl. I have two graphs showing related information, some of the series are common to both and some not - purely data driven. Currently I have separate legends for each graph, but due to limited screen real estate I would like to use a single legend which combine the legend items from both and only show the unique items. Is this possible with some sort of converter or other means?
There is no out-of-the-box feature that will allow you to do this automatically. However, you should be able to concat the two legend items collections on your own and remove the repeated legend items in the new collection. The chart has a LegendItems property that holds its legend items. You can attach a CollectionChanged handler for the two charts' collections, create a new collection, and feed this new collection to the RadLegend.
Regards,
Petar Marchev
Telerik