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

Ordering Data Series -- best approach?

3 Answers 52 Views
Chart
This is a migrated thread and some comments may be shown as answers.
William Cook
Top achievements
Rank 1
William Cook asked on 21 Apr 2011, 08:11 PM
What is the best approach to ordering the data series in a chart (bar chart specifically)?

Here's a simplified version of the problem:
Chart has two data series, 'REVENUE' and 'EXPENSE'. Raw data simplies down to:
TYPE (string), AMOUNT (dollars), PROGRAM (string)
'EXPENSE', 100, 'ABC'
'EXPENSE', 50, 'XYZ'
'REVENUE', 500, 'XYZ'

X-Axis is each Program, and needs to remain sorted by Program. However, in the chart area, the bar for the REVENUE series must be displayed *before* the bar for the EXPENSE. So, above 'ABC', there would be a blank and then the 100 bar for EXPENSE, and above 'XYZ' there would be a the 500 bar for REVENUE and then the 50 bar for EXPENSE.

I attempted a few approaches, with only partial luck.
First attempt - Reverse():
if (this.FundsRadChart.DefaultView.ChartArea.DataSeries[0].LegendLabel.Equals("Expense", StringComparison.CurrentCultureIgnoreCase))
{
    this.FundsRadChart.DefaultView.ChartArea.DataSeries.Reverse();
}
This did not impact the order at all...when the order was incorrect, Reverse() was called but the order did not change.

Second attempt - RemoveAt() and Add():
if (this.FundsRadChart.DefaultView.ChartArea.DataSeries[0].LegendLabel.Equals("Expense", StringComparison.CurrentCultureIgnoreCase))
{
    DataSeries actualsData = this.FundsRadChart.DefaultView.ChartArea.DataSeries[0];
    this.FundsRadChart.DefaultView.ChartArea.DataSeries.RemoveAt(0);
    this.FundsRadChart.DefaultView.ChartArea.DataSeries.Add(actualsData);
}
This actually worked, and gave me the correct ordering. However, the data series that was removed / re-added is no longer click-able (an exception is thrown), although the data series that was not removed / re-added is still clickable.

FWIW, I cannot simply ensure the data that the Chart is being bound to always puts the REVENUE first, since some Programs (as in the example data above) will not have values for 'REVENUE'.

What is the recommended approach I should be looking at?

Thanks,

William Cook

 

3 Answers, 1 is accepted

Sort by
0
Evgenia
Telerik team
answered on 27 Apr 2011, 08:38 AM
Hi William,

As I was able to understand from your post, you have a StackedBar Series Type and since some of the Series Items don't have Values they should not be shown in the Stack. Well, removing and adding DataSeries isn't the best approach as you doesn't know whether the item that should be removed is always first (at the bottom of the stack).
What I'm suggesting is that you set 0 as YValue for those Bars that should not appear in the Stacks and turn off their Labels Visibility. The attached sample project demonstrates this. The Chart is bound using using Manual Series Mappings. On the picture attached you may see the result.

Greetings,
Evgenia
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
William Cook
Top achievements
Rank 1
answered on 25 May 2011, 11:19 PM
Hi Evgenia,

Apologies...I should have included screenshots to better explain what I am aiming for.

My particular RadChart is controlled by a pair of radio buttons, which determine whether to group the results by 'Program' or 'MeasureType'. When they are grouped by Program, the Programs should be in alphabetical order across the X-Axis. This works correctly. However, when they are grouped by MeasureType, the X-Axis ordering should be Results, the Outputs, then Demands, then Efficiencies.

I currently achieve the correct ordering when grouping by Program by ordering the data before setting ItemsSource; however, this approach does not seem to work for type. I've simplified the relevant code here:
if (this.GroupByType == "Program")
{
    queryMeasures = from t in this.IndicatorsQueryable orderby t.ProgramName select t;
}
else // this.GroupByType == "Type"
{
    queryMeasures = (from t in this.IndicatorsQueryable select t).OrderBy(t => t.Type, new CompareTypes());
}
this.RadChart.SeriesMappings[0].GroupingSettings.GroupDescriptors.Clear();
this.RadChart.SeriesMappings[0].GroupingSettings.GroupDescriptors.Add(new ChartGroupDescriptor("Color"));
this.RadChart.SeriesMappings[0].GroupingSettings.GroupDescriptors.Add(new ChartGroupDescriptor(this.GroupByType));
ItemMapping yMapping = new ItemMapping("Color", DataPointMember.YValue, ChartAggregateFunction.Count);
ItemMapping catMapping = new ItemMapping(this.GroupByType, DataPointMember.XCategory);
this.RadChart.SeriesMappings[0].ItemMappings.Clear();
this.RadChart.SeriesMappings[0].ItemMappings.Add(yMapping);
this.RadChart.SeriesMappings[0].ItemMappings.Add(catMapping);
this.RadChart.ItemsSource = queryMeasures;

My custom sorter is:
    /// <summary>
    /// Implementation of IComparer to sort Activity Measures in R-O-D-E order.
    /// </summary>
    private class CompareMeasureTypes : IComparer<string>
    {
        /// <summary>
        /// Compares the specified strings.
        /// </summary>
        /// <param name="s1">The first string to compare.</param>
        /// <param name="s2">The second string to compare.</param>
        /// <returns></returns>
        public int Compare(string s1, string s2)
        {
            if (s1.Equals(s2))
            {
                return 0;
            }
            int comparisonResult = 1;
            switch (s1)
            {
                case "Result":
                {
                    comparisonResult = -1;
                    break;
                }
                case "Output":
                {
                    if (!s2.Equals("Result", StringComparison.CurrentCultureIgnoreCase))
                    {
                        comparisonResult = -1;
                    }
                    break;
                }
                case "Demand":
                {
                    if (!s2.Equals("Result", StringComparison.CurrentCultureIgnoreCase) && !s2.Equals("Output", StringComparison.CurrentCultureIgnoreCase))
                    {
                        comparisonResult = -1;
                    }
                    break;
                }
            }
            return comparisonResult;
        }
    }
}
In looking at the data in queryMeasures, it does appear that my custom sorter is correct, in that the data is always in Results, Outputs, Demands, Efficiencies ordering.

What am I missing to get the X-Axis ordering correct?

Thanks!

William
0
Evgenia
Telerik team
answered on 31 May 2011, 08:47 AM
Hi William,

Thanks for the detailed explanation and the images. However it is hard for me to determine the cause of the issue from the information provided. Could you open a new formal thread (Support thread) and send us a sample runnable project (where this issue occurs) so that we will be able to investigate it and help you?

Kind regards,
Evgenia
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
Chart
Asked by
William Cook
Top achievements
Rank 1
Answers by
Evgenia
Telerik team
William Cook
Top achievements
Rank 1
Share this question
or