<
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