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

[Solved] ItemWidthPercent issue

6 Answers 242 Views
Chart
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jan
Top achievements
Rank 1
Jan asked on 27 Jun 2011, 01:33 PM
Hello,

i am experimenting a little bit with the ItemWidthPercent property of the ChartArea. I would like to define a histogram chart where all bars are next to each other. The labels should be between each bar and not under them. So i setup the following things to generate a simple histogram:
this.chartControl.DefaultView.ChartLegend.Visibility = Visibility.Collapsed;
 
ChartArea chartArea = this.chartControl.DefaultView.ChartArea;
chartArea.ItemWidthPercent = 100;
chartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.ScrollAndZoom;
chartArea.ZoomScrollSettingsY.ScrollMode = ScrollMode.ScrollAndZoom;
chartArea.AxisX.LabelRotationAngle = -45;
chartArea.AxisX.MinorTickPointMultiplier = 1;
chartArea.AxisX.LayoutMode = AxisLayoutMode.Normal;
chartArea.AxisX.AutoRange = false;
chartArea.AxisX.Step = 1;
chartArea.AxisX.MinValue = 1;
chartArea.AxisX.MaxValue = 6;
 
DataSeries lineSeries = new DataSeries();
lineSeries.Definition = new BarSeriesDefinition();
 
lineSeries.Add(new DataPoint() { XValue = 1.5, YValue = 1 });
lineSeries.Add(new DataPoint() { XValue = 2.5, YValue = 2 });
lineSeries.Add(new DataPoint() { XValue = 3.5, YValue = 3 });
lineSeries.Add(new DataPoint() { XValue = 4.5, YValue = 4 });
lineSeries.Add(new DataPoint() { XValue = 5.5, YValue = 3 });
 
chartControl.DefaultView.ChartArea.DataSeries.Add(lineSeries);

Result picture: screen1.png

You can see, the bar width is not 100 percent. If i change the LayoutMode of the AxisX from Normal to Between, the correct result (corresponding to the bar width) is shown in screen2.png

But also with this setting i can get an incorrect result if i use a different Step value of the AxisX. Normally this is 1, but in my case i must set this depending on my data. So it could be anything greater than 0. Changing the step value to 1.5 (this is the class width of a histogram) and use histogram data for classes which have a width of 1.5 results in the following changed code:
chartArea.AxisX.LayoutMode = AxisLayoutMode.Beetween;
chartArea.AxisX.Step = 1.5;
chartArea.AxisX.MinValue = 0;
chartArea.AxisX.MaxValue = 7.5;
 
lineSeries.Add(new DataPoint() { XValue = 0.75, YValue = 1 });
lineSeries.Add(new DataPoint() { XValue = 2.25, YValue = 2 });
lineSeries.Add(new DataPoint() { XValue = 3.75, YValue = 3 });
lineSeries.Add(new DataPoint() { XValue = 5.25, YValue = 4 });
lineSeries.Add(new DataPoint() { XValue = 6.75, YValue = 3 });
and chart visualization: screen3.png

I think there is an issue with the internal calculation of the bar with (this also includes wrong width if user zooms into the chart). But maybe you have any workaround or solution for me :)

Currently i use the RadChart from the Silverlight 2011 Q1 release with the version 2011.1.315.1040.

Thanks for your help!

6 Answers, 1 is accepted

Sort by
0
Ves
Telerik team
answered on 30 Jun 2011, 12:00 PM
Hello Jan,

Given the description of the desired scenario, it seems your initial setup should cover it. The problem with the gaps is actually caused by a bug in the control. It seems the bar width is not calculated correctly in this case. While our developers check this, you can use this workaround -- set the ItemWidthPercent property like this:
100 +  (1 / number_of_items * 100)

In this specific case the result would be 120.

Alternatively, you can set the AxisX.LayoutMode to AxisLayoutMode.Inside. This works like AxisLayoutMode.Normal with the only difference of half a step padding added in the beginning and in the end of the axis.

I have logged the issue in our Public  Issue Tracking System -- you can find it here. Your Telerik points have been updated.

Best regards,
Ves
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
Jan
Top achievements
Rank 1
answered on 04 Jul 2011, 07:48 AM
Hello Ves,

apologies my late reply, now i have checked your suggestion and it did only work in special cases if AxisX.Step is equal to 1. If i use for example a class widh of 2 with the following code
chartArea.AxisX.AutoRange = false;
chartArea.AxisX.Step = 2;
chartArea.AxisX.MinValue = 0;
chartArea.AxisX.MaxValue = 6;
chartArea.ItemWidthPercent = 100 + (Int32)(1 / 3.0 * 100); // workaround
 
DataSeries lineSeries = new DataSeries();
lineSeries.Definition = new BarSeriesDefinition();
 
lineSeries.Add(new DataPoint() { XValue = 1, YValue = 1 });
lineSeries.Add(new DataPoint() { XValue = 3, YValue = 0 });
lineSeries.Add(new DataPoint() { XValue = 5, YValue = 2 });
I geht the result shown in screen4 - workaround.png.
0
Ves
Telerik team
answered on 06 Jul 2011, 12:17 PM
Hi Jan,

In this case you will need to multiply the ItemWidthPercent by the step value:

chartArea.ItemWidthPercent = (100 + (Int32)(1 / 3.0 * 100)) * chartArea.AxisX.Step;

Regards,
Ves
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Jan
Top achievements
Rank 1
answered on 06 Jul 2011, 02:05 PM
Hi Ves,

yes, you are right, this works in that case but not for all cases. Thats frustrating... :(
I have now created a sample project where i initilize some charts with different settings for the start value, the step value and the item number. You can see in the attached screen, that not all charts are valid for my histogram requirements. Maybe you have an idea how i can solve this. Or maybe it is solved within the next release of the telerik controls and i could use it :)

Here is the code
public MainPage()
{
    InitializeComponent();
    CreateChartCollection();
}
 
private void CreateChartCollection()
{
    ScrollViewer frame = new ScrollViewer();
    frame.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
    frame.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
    WrapPanel panel = new WrapPanel();
    frame.Content = panel;
    this.Content = frame;
 
    panel.Children.Add(CreateChart(1, 10, 2));
    panel.Children.Add(CreateChart(2, 10, 2));
    panel.Children.Add(CreateChart(25, 10, 2));
 
    panel.Children.Add(CreateChart(1, 15, 3.2));
    panel.Children.Add(CreateChart(2, 15, 3.2));
    panel.Children.Add(CreateChart(25, 15, 3.2));
 
    panel.Children.Add(CreateChart(0.3, 10, 2));
    panel.Children.Add(CreateChart(0.6, 10, 2));
    panel.Children.Add(CreateChart(0.86, 10, 2));
 
    panel.Children.Add(CreateChart(0.3, 15, -3));
    panel.Children.Add(CreateChart(0.6, 15, -3));
    panel.Children.Add(CreateChart(0.86, 15, -3));
}
 
private static UIElement CreateChart(double step, int itemCount, double startValue)
{
    RadChart chart = new RadChart();
 
    chart.Height = 300;
    chart.Width = 600;
 
    chart.DefaultView.ChartLegend.Visibility = Visibility.Collapsed;
 
    ChartArea chartArea = chart.DefaultView.ChartArea;
    chartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.ScrollAndZoom;
    chartArea.ZoomScrollSettingsY.ScrollMode = ScrollMode.ScrollAndZoom;
    chartArea.AxisX.LabelRotationAngle = -45;
    chartArea.AxisX.LayoutMode = AxisLayoutMode.Normal;
    chartArea.AxisX.AutoRange = false;
    chartArea.AxisX.Step = step;
    chartArea.AxisX.MinValue = startValue;
    chartArea.AxisX.MaxValue = startValue + (itemCount * step);
    //chartArea.ItemWidthPercent = 100 + (Int32)(1.0 / itemCount * 100);
    chartArea.ItemWidthPercent = (Int32)((100 + (1.0 / itemCount * 100)) * step);
 
    SeriesMapping seriesMapping = new SeriesMapping();
    BarSeriesDefinition barSeries = new BarSeriesDefinition();
 
    seriesMapping.SeriesDefinition = barSeries;
    chart.SeriesMappings.Add(seriesMapping);
    seriesMapping.ItemMappings.Add(new ItemMapping("Key", DataPointMember.XValue));
    seriesMapping.ItemMappings.Add(new ItemMapping("Value", DataPointMember.YValue));
 
    Random ran = new Random();
    Dictionary<Double, Int32> data = new Dictionary<Double, Int32>();
    for (Int32 i = 0; i < itemCount; i++)
    {
        data.Add(startValue + (i * step) + (step * 0.5), ran.Next(10));
    }
 
    seriesMapping.ItemsSource = data;
 
    Grid grid = new Grid();
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
 
    StackPanel panel = new StackPanel();
    TextBlock labelMinValue = new TextBlock { Text = "Start value: " + startValue, Margin = new Thickness(5) };
    TextBlock labelStepValue = new TextBlock { Text = "Step value: " + step, Margin = new Thickness(5) };
    TextBlock labelItemNumberValue = new TextBlock { Text = "Item number: " + itemCount, Margin = new Thickness(5) };
    TextBlock labelItemWidthPercentValue = new TextBlock { Text = "ItemWidthPercent: " + chartArea.ItemWidthPercent, Margin = new Thickness(5) };
 
    panel.Children.Add(labelMinValue);
    panel.Children.Add(labelStepValue);
    panel.Children.Add(labelItemNumberValue);
    panel.Children.Add(labelItemWidthPercentValue);
 
    grid.Children.Add(chart);
    grid.Children.Add(panel);
 
    Grid.SetColumn(chart, 0);
    Grid.SetColumn(panel, 1);
 
    return grid;
}
0
Accepted
Ves
Telerik team
answered on 08 Jul 2011, 04:32 PM
Hi Jan,

This is caused by a conflict with a feature in RadChart, namely adaptive bar width, depending on the order of magnitude of the step. Let's consider the third chart in your example. With this axis range (250) a bar with a width of 1 X axis unit would be as thin as 1/250 of the chart width -- that's too small value, probably a pixel or two. It goes in the opposite direction for the 7-th chart -- the bar would take one third of the chart. This is why RadChart takes the order of magnitude of the axis step into account when calculating the bar width. Here is how to update your code in order to solve this conflict:

chartArea.ItemWidthPercent = (Int32)((100 + (1.0 / itemCount * 100)) * step /  Math.Pow(10, CalculateOrderOfMagnitude(step)));

where the CalculateOrderOfMagnitude method is defined like this:

private static double CalculateOrderOfMagnitude(double step)
        {
            double log10 = Math.Log10(step);
            return  Math.Floor(log10);
        }


Best regards,
Ves
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Jan
Top achievements
Rank 1
answered on 12 Jul 2011, 07:19 AM
Hi Ves,

thank you for the code. It works! Wondeful :)

Thanks and kind regards, Jan
Tags
Chart
Asked by
Jan
Top achievements
Rank 1
Answers by
Ves
Telerik team
Jan
Top achievements
Rank 1
Share this question
or