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

[Solved] Display total number on top of each stacked bar?

1 Answer 502 Views
Chart for XAML
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Kevin
Top achievements
Rank 1
Kevin asked on 21 Nov 2012, 01:38 AM
Is it possible to display the total number for each stacked bar on top of it? I need to implement it in xaml level.

I found a similar question in Silverlight forum, but I'm not sure how to mimic that in Metro version.
http://www.telerik.com/community/forums/silverlight/chart/stacking-bar-chart-and-total-on-top-of-bar.aspx

Also, how can I display the value for each bar chart section, inside the bar possibly?

Thanks.

1 Answer, 1 is accepted

Sort by
0
Giuseppe
Telerik team
answered on 23 Nov 2012, 10:03 AM
Hello Kevin,

Generally the desired functionality is not available out-of-the box but you can achieve it with some custom coding.

First you need to add a calculated property to your business object that will return the stacked sum (you will later bind to it to visualize the stacked sum outside the bars):
public class ChartData
{
    public string Category
    {
        get;
        set;
    }
 
    public double Value
    {
        get;
        set;
    }
 
    public double Value2
    {
        get;
        set;
    }
 
    public double CalculatedStackedSum
    {
        get
        {
            // you will use this property to visualize the stacked sum outside the bars
            return this.Value + this.Value2;
        }
    }
}

Then you need to plug into the series item label positioning mechanism in order to instruct the individual value labels to position center & inside the bars and the stacked sums -- center & outside the bars. The mechanism that enables you to achieve both is the same -- you need to define the respective ChartSeriesLabelDefinitions for each bar series and you need to specify the desired custom strategy for label arrangement via ChartSeriesLabelDefinition.Strategy property (we have defined two separate strategies CenterInsideLabelStrategy and CenterOutsideLabelStrategy respectively).
Note that BarSeries.LabelDefinitions is a collection i.e. you can associate multiple labels with the same series and we will use that feature for the "last" stacked series to visualize the individual item label (center&inside) and the stacked sum label (center&outside, bound to the calculated property from the business object):
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <local:CenterInsideLabelStrategy x:Key="centerInsideStrategy" />
        <local:CenterOutsideLabelStrategy x:Key="centerOutsideStrategy" />
    </Grid.Resources>
 
    <telerik:RadCartesianChart PaletteName="DefaultDark">
        <telerik:RadCartesianChart.HorizontalAxis>
            <telerik:CategoricalAxis />
        </telerik:RadCartesianChart.HorizontalAxis>
        <telerik:RadCartesianChart.VerticalAxis>
            <telerik:LinearAxis />
        </telerik:RadCartesianChart.VerticalAxis>
 
        <telerik:BarSeries CombineMode="Stack" ItemsSource="{Binding Data}" ShowLabels="True">
            <telerik:BarSeries.CategoryBinding>
                <telerik:PropertyNameDataPointBinding PropertyName="Category" />
            </telerik:BarSeries.CategoryBinding>
            <telerik:BarSeries.ValueBinding>
                <telerik:PropertyNameDataPointBinding PropertyName="Value" />
            </telerik:BarSeries.ValueBinding>
            <telerik:BarSeries.LabelDefinitions>
                <!-- use custom label strategy to position the labels center&inside the bars -->
                <telerik:ChartSeriesLabelDefinition Strategy="{StaticResource centerInsideStrategy}" />
            </telerik:BarSeries.LabelDefinitions>
        </telerik:BarSeries>
        <telerik:BarSeries CombineMode="Stack" ItemsSource="{Binding Data}" ShowLabels="True">
            <telerik:BarSeries.CategoryBinding>
                <telerik:PropertyNameDataPointBinding PropertyName="Category" />
            </telerik:BarSeries.CategoryBinding>
            <telerik:BarSeries.ValueBinding>
                <telerik:PropertyNameDataPointBinding PropertyName="Value2" />
            </telerik:BarSeries.ValueBinding>
            <telerik:BarSeries.LabelDefinitions>
                <!-- use custom label strategy to position the labels center&inside the bars -->
                <telerik:ChartSeriesLabelDefinition Strategy="{StaticResource centerInsideStrategy}" />
 
                <!-- Add second label definition to the last stacked series ONLY - it will handle the stacked sums display center&outside the stacks  -->
                <telerik:ChartSeriesLabelDefinition Strategy="{StaticResource centerOutsideStrategy}">
                    <telerik:ChartSeriesLabelDefinition.Binding>
                        <telerik:PropertyNameDataPointBinding PropertyName="CalculatedStackedSum" />
                    </telerik:ChartSeriesLabelDefinition.Binding>
                </telerik:ChartSeriesLabelDefinition>
            </telerik:BarSeries.LabelDefinitions>
        </telerik:BarSeries>
 
    </telerik:RadCartesianChart>
 
</Grid>

public class CenterInsideLabelStrategy : ChartSeriesLabelStrategy
{
    public override LabelStrategyOptions Options
    {
        get
        {
            return LabelStrategyOptions.Arrange;
        }
    }
 
    public override RadRect GetLabelLayoutSlot(DataPoint point, FrameworkElement visual, int labelIndex)
    {
        visual.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
 
        double x = point.LayoutSlot.X + ((point.LayoutSlot.Width - visual.ActualWidth) / 2);
        double y = point.LayoutSlot.Y + ((point.LayoutSlot.Height - visual.ActualHeight) / 2);
 
        return new RadRect(x, y, visual.ActualWidth, visual.ActualHeight);
    }
}

public class CenterOutsideLabelStrategy : ChartSeriesLabelStrategy
{
    public override LabelStrategyOptions Options
    {
        get
        {
            return LabelStrategyOptions.Arrange;
        }
    }
 
    public override RadRect GetLabelLayoutSlot(DataPoint point, FrameworkElement visual, int labelIndex)
    {
        visual.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
 
        double x = point.LayoutSlot.X + ((point.LayoutSlot.Width - visual.ActualWidth) / 2);
        double y = point.LayoutSlot.Y - 20;
 
        return new RadRect(x, y, visual.ActualWidth, visual.ActualHeight);
    }
}


We have attached the sample application for your reference as well.

Hope this helps.


Greetings,
Giuseppe
the Telerik team
Have a suggestion or face a problem - you can use the Ideas & Feedback portal to submit ideas, feedback and vote for them.
Tags
Chart for XAML
Asked by
Kevin
Top achievements
Rank 1
Answers by
Giuseppe
Telerik team
Share this question
or