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

Controlling bar segment width in stacked bar RadCartesianChart

5 Answers 419 Views
ChartView
This is a migrated thread and some comments may be shown as answers.
Scott
Top achievements
Rank 1
Scott asked on 03 Mar 2014, 03:28 PM
I have two stacked bar charts displayed side-by-side, as shown in the attached image.  I need for the bar width to be the same between both charts.  The examples I've found show to do this for the entire bar by setting the point template, for example:

<chartView:BarSeries.PointTemplate>                     
    <DataTemplate>                         
       <Rectangle Fill="{Binding myFill} Width="50"/>                     
   </DataTemplate>                 
</chartView:BarSeries.PointTemplate>

This doesn't work for me because the template only gives me access to the entire bar and not each individual segment (each segment of the bar has its own fill color).  How can I achieve my goal?  Can I turn off the auto-sizing of the bars?  Can I somehow access the template for each individual segment of the stacked bar, rather than the template for the entire bar?  Can I set the widths in the DataBindingComplete event of the BarSeries object?

Thanks,
Scott

5 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 05 Mar 2014, 02:44 PM
Hello Scott,

There are a few approaches you can use to achieve your requirement. You can change the size of the bars by setting the GapLength property of the axis. This property controls how much free space should remain from the category slot after the bar is added.

You can also set a PointTemplate for each bar in the BarSeries if you use the BarSeries.PointTemplates collection which contains DataTemplates for all DataPoints. You can see how to use this collection in the BarSeries help article. In addition here is an example:
<telerik:BarSeries.PointTemplates>
    <DataTemplate>
        <Rectangle Fill="Red" Width="50"/>                    
   </DataTemplate>
    <DataTemplate>
        <Rectangle Fill="Green" Width="50"/>
    </DataTemplate>
</telerik:BarSeries.PointTemplates>

Another approach can be to set the DefaultVisualStyle property of the BarSeries. This will set the style for each bar in the series.
<UserControl.Resources>
    <Style x:Key="barStyle" TargetType="Border">
        <Setter Property="MaxWidth" Value="50" />
        <Setter Property="Background" Value="{Binding DataItem.Fill}"/>
    </Style>
</UserControl.Resources>

.........

<telerik:BarSeries CombineMode="Stack"
           ItemsSource="{Binding Items}"   
           
ValueBinding="Value"               
           
CategoryBinding="Category"               
           
DefaultVisualStyle="{StaticResource barStyle}"/>
......

You can see the implementation with the DefaultVisualStyle in the attached project.

Regards,
Martin
Telerik

DevCraft Q1'14 is here! Join the free online conference to see how this release solves your top-5 .NET challenges. Reserve your seat now!

0
linnet
Top achievements
Rank 1
answered on 04 May 2014, 07:32 AM
Hello,
I tried secend approach whitch used DefaultVisualStyle property of the BarSeries to change bar width.
It's worked, but I can't let the bar move to center.

Thank you for the support!
0
Peshito
Telerik team
answered on 05 May 2014, 12:21 PM
Hello linnet,

From the image attached I assume that you are using DateTimeContinuous axis. If this is so, please try using a DateTimeCategorical axis instead and see how it goes. With continuous axis, the data is sorted chronologically and displayed in accordance of the date time factor which combined with stacked bars will result in the scenario you have.

Hope this helps.

Regards,
Peshito
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
linnet
Top achievements
Rank 1
answered on 06 May 2014, 09:59 AM
Hello Peshito,
I'm sorry for did not attached code on reply.
From that image attached, I used Categorical Axis and the value in XAxis may not be "2013, 2014", but "Group A, Group B".
On Attached file(illustration.png) I set the bar size, but I still want move the bar to center where upon the "Group A, Group B".

Here is my code:

ChartView.xaml
<UserControl.DataContext>
    <my:ChartViewModel />
</UserControl.DataContext>
 
<UserControl.Resources>
    <Style x:Key="barStyle" TargetType="Border">
        <Setter Property="MaxWidth" Value="40"></Setter>
        <Setter Property="Background" Value="{Binding DataItem.Fill}"/>
    </Style>
</UserControl.Resources>
 
<telerik:RadCartesianChart x:Name="chart" Grid.Row="0" Grid.Column="0" Height="Auto" Palette="Summer">
    <telerik:RadCartesianChart.HorizontalAxis>
        <telerik:CategoricalAxis></telerik:CategoricalAxis>
    </telerik:RadCartesianChart.HorizontalAxis>
 
    <telerik:RadCartesianChart.VerticalAxis>
        <telerik:LinearAxis x:Name="verticalAxis"  />
    </telerik:RadCartesianChart.VerticalAxis>
 
    <telerik:BarSeries ItemsSource="{Binding Data}"
                             ValueBinding="Value"
                             CategoryBinding="XValue"
                             CombineMode="Stack"
                             ShowLabels="False"
                             FontSize="10" DefaultVisualStyle="{StaticResource barStyle}">
        <telerik:BarSeries.LegendSettings>
            <telerik:SeriesLegendSettings Title="{Binding SeriesTitle1}" />
        </telerik:BarSeries.LegendSettings>
    </telerik:BarSeries>
    <telerik:BarSeries ItemsSource="{Binding Data2}"
                             ValueBinding="Value"
                             CategoryBinding="XValue"
                             CombineMode="Stack"
                             ShowLabels="False"
                             FontSize="10" DefaultVisualStyle="{StaticResource barStyle}">
        <telerik:BarSeries.LegendSettings>
            <telerik:SeriesLegendSettings Title="{Binding SeriesTitle2}" />
        </telerik:BarSeries.LegendSettings>
    </telerik:BarSeries>
</telerik:RadCartesianChart>

ChartViewModel.cs
public class ChartViewModel : INotifyPropertyChanged
{
    private string _title = string.Empty;
    private string _seriesTitle1 = string.Empty;
    private string _seriesTitle2 = string.Empty;
 
    public IEnumerable<ChartData> Data
    {
        get;
        set;
    }
 
    public IEnumerable<ChartData> Data2
    {
        get;
        set;
    }
 
    public string Title
    {
        get
        {
            return this._title;
        }
        set
        {
            if (this._title != value)
            {
                this._title = value;
                this.OnPropertyChanged("Title");
            }
        }
    }
 
    public string SeriesTitle1
    {
        get
        {
            return this._seriesTitle1;
        }
        set
        {
            if (this._seriesTitle1 != value)
            {
                this._seriesTitle1 = value;
                this.OnPropertyChanged("SeriesTitle1");
            }
        }
    }
 
    public string SeriesTitle2
    {
        get
        {
            return this._seriesTitle2;
        }
        set
        {
            if (this._seriesTitle2 != value)
            {
                this._seriesTitle2 = value;
                this.OnPropertyChanged("SeriesTitle2");
            }
        }
    }
 
    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
 
    protected void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion
}
 
public class ChartData
{
    public string XValue
    {
        get;
        set;
    }
 
    public string YValue
    {
        get;
        set;
    }
 
    public string ZValue
    {
        get;
        set;
    }
 
    public decimal? Value
    {
        get;
        set;
    }
}

MainPage.xaml
<my:ChartView x:Name="chart"></my:ChartView>

MainPage.xaml.cs
public partial class MainPage : UserControl
{
    private int? seed = null;
 
    public MainPage()
    {
        InitializeComponent();
 
        var vm4 = new ChartViewModel()
        {
            Title = "Analysis",
            SeriesTitle1 = "S1",
            SeriesTitle2 = "S2",
            Data = GetChart4Data(11000, 12000),
            Data2 = GetChart4Data(1300, 1800)
        };
        chart.DataContext = vm4;
    }
 
 
    public IEnumerable<ChartData> GetChart4Data(int min, int max)
    {
        if (seed == null)
        {
            seed = DateTime.Now.Millisecond;
        }
        else
        {
            seed += 1;
        }
        //var xvalue = new List<string>() { "2013", "2014" };
        var xvalue = new List<string>() { "Group A", "Group B" };
        var result = new List<ChartData>();
        var rand = new Random(seed.Value);
        foreach (var item in xvalue)
        {
            result.Add(new ChartData()
            {
                XValue = item,
                Value = rand.Next(min, max)
            });
        }
        return result;
    }
}

Thank you for the support.





0
Peshito
Telerik team
answered on 07 May 2014, 11:44 AM
Hi linnet,

Thank you for the provided sample code. This helped me in locating where the issue is.

Using DefaultVisualStyle for your BarSeries will not fully work in your scenario because the chart specifies the size of the bars first which has higher priority over setting them with a style. However using PointTemplate as I see you did at first place, should work for you.

Below is modified version of your code:
ChartView.xaml
<UserControl.Resources>
    <DataTemplate x:Key="pointTemplate">
        <Rectangle Fill="{Binding ElementName=chart, Path=Palette.GlobalEntries[0].Fill}" Width="40"/>
    </DataTemplate>
    <DataTemplate x:Key="pointTemplate2">
        <Rectangle Fill="{Binding ElementName=chart, Path=Palette.GlobalEntries[1].Fill}" Width="40"/>
    </DataTemplate>
</UserControl.Resources>
This will set the width of your bars to be 40 pixels and the color of each bar series will be consistent with the color from the global chart's palette.

<telerik:BarSeries ItemsSource="{Binding Data}"
                            ValueBinding="Value"
                            CategoryBinding="XValue"
                            CombineMode="Stack"
                            ShowLabels="False"
                            FontSize="10" PointTemplate="{StaticResource pointTemplate}" >
               <telerik:BarSeries.LegendSettings>
                   <telerik:SeriesLegendSettings Title="{Binding SeriesTitle1}" />
               </telerik:BarSeries.LegendSettings>
           </telerik:BarSeries>
           <telerik:BarSeries ItemsSource="{Binding Data2}"
                            ValueBinding="Value"
                            CategoryBinding="XValue"
                            CombineMode="Stack"
                            ShowLabels="False"
                            FontSize="10" PointTemplate="{StaticResource pointTemplate2}" >
Please give this approach a try and let me know if further questions arise.

Regards,
Peshito
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
Tags
ChartView
Asked by
Scott
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
linnet
Top achievements
Rank 1
Peshito
Telerik team
Share this question
or