This is a migrated thread and some comments may be shown as answers.

Styling Series without losing Legend Colors

5 Answers 149 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Fabian Gehri
Top achievements
Rank 1
Fabian Gehri asked on 05 Oct 2011, 08:27 PM
Dear Telerik Team

We are using the RadChart control to display charts whose structure (e.g. the number of series, their color and the number of categories) is only known at runtime. We are using the MVVM pattern and bind to the SeriesMappings and ItemsSource properties of RadChart. The colors for the series are set via the SeriesDefinition.Appearance.Fill property of the SeriesMappings.

So far, this works perfectly fine, but now we want to be able to change the colors of individual items in each series. E.g. having a red and a blue series we want the first item of the red series to be orange instead of red, but again these colors are only known at runtime.

According to this article the SeriesDefinition.Appearance property only allows one color per series. Using the styles property of ChartArea or RadChart or using the Palette Brushes would make all series look the same. So, we came to the conclusion that we need to retemplate the default series style.

We were able to retemplate the style of the Bar item as in this Demo by binding the Fill property to a Brush property of our custom DataItem object.
<Style x:Key="CustomBarStyle" TargetType="telerik:Bar">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="telerik:Bar">
                    <Canvas x:Name="PART_MainContainer">
                        <Rectangle x:Name="PART_DefiningGeometry"
                                   Height="{TemplateBinding ItemActualHeight}"
                                   Width="{TemplateBinding ItemActualWidth}"
                                   Fill="{Binding DataItem.Brush}"
                                   Style="{TemplateBinding ItemStyle}" />
                        <Rectangle Height="{TemplateBinding ItemActualHeight}"
                                   Width="{TemplateBinding ItemActualWidth}"
                                   Fill="{StaticResource BarMaskBrush}" />
                        <Canvas.RenderTransform>
                            <ScaleTransform x:Name="PART_AnimationTransform" ScaleY="0" />
                        </Canvas.RenderTransform>
                    </Canvas>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

This only works when the SeriesDefinition.Appearance.Fill property is not set, otherwise the SeriesDefinition.Appearance.Fill property takes precedence over the custom style. The problem with this is that the legend items then show the default colors (i.e. the colors which the series would have when SeriesDefinition.Appearance.Fill is not set).
To overcome this we tried also to retemplate the style of the ChartLegendItem, but we could not find what we could bind to the Fill property of the ChartLegendItem.

Also using the CreateItemStyleDelegate of the RadChart as in this help topic did not help us further. In the example, only a predefined brush is set to the ChartLegendItems Fill property, but what we need is to set the colors according to our own color definitions (which are only known at runtime). For this we would need a possibility to get the index of the series which the ChartLegendItem corresponds to.

Is there any possibility to achieve what we need?

I guess it is not possible to change something on the precendence of the SeriesDefinition.Appearance over the custom style?

Is there a way to get the series by the ChartLegendItem? (So far, we are using ChartLegendItem.Label to find the series, but this will fail if multiple series have the same LegendLabel.)

Or is there even a completely different approach which allows to set colors to individual items without losing the colors in the legend?

Regards,
Fabian Gehri

PS: We are using the Q3 2010 release, but we also tried the Q2 2011 trial version, which did not make a difference.

5 Answers, 1 is accepted

Sort by
0
Accepted
Sia
Telerik team
answered on 10 Oct 2011, 05:07 PM
Hello Fabian Gehri,

Thank you for the detailed information about your scenario.
Two possible options come to my mind:

  1. To generate your legend items manually. More information about this can be found here.
  2. If you need a legend item per series item and you have set the legend display mode to be data point as shown here,  you can bind the ChartLegendItem's fill to the same Brush property, because its DataContext is the corresponding DataPoint:
<Style x:Key="CustomLegendItem" TargetType="telerik:ChartLegendItem">
    <Setter Property="Padding" Value="5,0,5,0" />
    <Setter Property="Margin" Value="0,3,0,2" />
    <Setter Property="Template" >
        <Setter.Value>
            <ControlTemplate TargetType="telerik:ChartLegendItem">
                <Grid x:Name="PART_MainContainer" Background="{TemplateBinding Background}"
                    HorizontalAlignment="Stretch" VerticalAlignment="Top">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Path x:Name="PART_LegendItemMarker"
                        Width="16"
                        Height="16"
                        Margin="{TemplateBinding Margin}"
                        StrokeThickness="{TemplateBinding MarkerStrokeThickness}"
                        Style="{TemplateBinding ItemStyle}"
                        Fill="{Binding DataItem.Brush}"
                        Stretch="Fill">
                        <Path.Data>
                            <PathGeometry x:Name="PART_ItemMarkerGeometry" />
                        </Path.Data>
                    </Path>
 
                    <TextBlock x:Name="PART_TextBlock"
                            Grid.Column="1"
                            Padding="{TemplateBinding Padding}"
                            Margin="{TemplateBinding Margin}"
                            Foreground="{TemplateBinding Foreground}"
                            Text="{TemplateBinding Label}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Please let me know if this helps.
Kind regards,
Sia
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Fabian Gehri
Top achievements
Rank 1
answered on 12 Oct 2011, 11:20 AM
Hi Sia,

thank you very much for your suggestions.

Legend items per data point is not what we want as there would be too many in most cases. However, generating the legend items manually solved our issue.

Thanks again,
Fabian
0
Bhakti
Top achievements
Rank 1
answered on 03 Feb 2012, 05:02 PM
Hello I have a similar code
 <Style x:Key="CustomLegendItemStyle" TargetType="telerik:ChartLegendItem">
            <Setter Property="Template" >
                <Setter.Value>
                    <ControlTemplate TargetType="telerik:ChartLegendItem" >
                        <Grid x:Name="PART_MainContainer" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0,0,5,0" >
                            <Path x:Name="PART_LegendItemMarker"                                 
                                  Height="20"
                                  Width="80"
                                  Style="{TemplateBinding ItemStyle}"
                                  Stretch="Fill"
                                  >
                                <Path.Data>
                                    <PathGeometry x:Name="PART_ItemMarkerGeometry" />
                                </Path.Data>
                            </Path>
                            <CheckBox IsChecked="True"
                                      VerticalAlignment="Center"
                                      Margin="2,0"
                                      Content="{TemplateBinding Label}"
                                      Foreground="{TemplateBinding Foreground}"                                      
                                      BorderThickness="0"
                                      Checked="CheckBox_Checked" Unchecked="CheckBox_Checked"   />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>


I want to remove the border of the legend items. I have a grid with checkbox and data in each legend item.
0
Sia
Telerik team
answered on 08 Feb 2012, 10:53 AM
Hello Bhakti,

In the original ChartLegendItem template there is a template binding to the exposed MarkerStrokeThickness property, which you need to set as follows:
<Style x:Key="CustomLegendItemStyle" TargetType="telerik:ChartLegendItem">
    <Setter Property="MarkerStrokeThickness" Value="0" />
    <Setter Property="Template" >
        <Setter.Value>
            <ControlTemplate TargetType="telerik:ChartLegendItem" >
                <Grid x:Name="PART_MainContainer" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="0,0,5,0" >
                    <Path x:Name="PART_LegendItemMarker"                                
                            Height="20"
                            Width="80"
                            StrokeThickness="{TemplateBinding MarkerStrokeThickness}"
                            Style="{TemplateBinding ItemStyle}"
                            Stretch="Fill">
                        <Path.Data>
                            <PathGeometry x:Name="PART_ItemMarkerGeometry" />
                        </Path.Data>
                    </Path>
                    <CheckBox IsChecked="True"
                                VerticalAlignment="Center"
                                Margin="2,0"
                                Content="{TemplateBinding Label}"
                                Foreground="{TemplateBinding Foreground}"                                     
                                BorderThickness="0" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

If you need to change the marker shape, please set the following style to the ChartLegend:
<Style x:Key="CustomLegend" TargetType="telerik:ChartLegend">
    <Setter Property="LegendItemMarkerShape" Value="Square" />
</Style>


All the best,
Sia
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Bhakti
Top achievements
Rank 1
answered on 08 Feb 2012, 04:29 PM
Thank You Sia. It worked!
Tags
Chart
Asked by
Fabian Gehri
Top achievements
Rank 1
Answers by
Sia
Telerik team
Fabian Gehri
Top achievements
Rank 1
Bhakti
Top achievements
Rank 1
Share this question
or