Profile Picture

More space for small percentages

Posted By Mike M 11 Years Ago
Author
Message
Mike M
Posted 11 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 5, Visits: 1
Hi,

I've been tasked to fix an issue in someone else's code, so I'm not particularly familiar with the Nevron Chart API.

The attached image shows off the issue that needs to be resolved. The code is constructing several of what I believe are stacked horizontal bar charts. One of these "rows" is shown in the image.

The problem is when the percentages get very small, the color associated with the percentage label isn't wide enough to fit the number. Another problem with this is that numbers begin clumping up on the right side of the chart as the percentages get smaller.

What recommendations do you have to create a little more space on the right side of the chart when the percentages get too small to fit them?

Thanks!!

Attachments
chart_text_cutoff.PNG (136 views, 3.00 KB)
Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,054, Visits: 4,009
This clipping of the labels doesn't happen with the default settings, so it must be something in the configuration. Can you please provide us with the code that configures the chart?

Attached is an image generated from our Winforms examples application (the Stack Bar Chart example, slightly modified) - the bar labels are not clipped.

Best Regards,
Nevron Support Team



Attachments
HorizontalStack.png (107 views, 9.00 KB)
Mike M
Posted 11 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 5, Visits: 1
Thanks for the response. It should be noted that these charts are being generated in a Web Forms application.

Here's the configuration:

protected NChartControl _nChartCtrl;
protected NChart _nChart;

public MyStackedBarChart(int width, int height, int exportWidth, int exportHeight, int exportResolution)
{
_exportWidth = exportWidth;
_exportHeight = exportHeight;
_exportResolution = exportResolution;

_nChart = _nChartCtrl.Charts[0];

_nChart.PaintCallback = new ShrmStackedBarChartPaintCallback();

if ( width > 0 && height > 0 )
{
_nChart.Width = width;
_nChart.Height = height;
}

_nChart.BackgroundFillStyle = new NColorFillStyle(Color.Transparent);
_nChart.Axis(StandardAxis.Depth).Visible = false;
_nChart.PredefinedChartStyle = PredefinedChartStyle.HorizontalLeft;
_nChart.Dock = System.Windows.Forms.DockStyle.Fill;

_nChart.Padding = new NMarginsL(
new NLength(0, NRelativeUnit.ParentPercentage),
new NLength(2, NRelativeUnit.ParentPercentage),
new NLength(2, NRelativeUnit.ParentPercentage),
new NLength(2, NRelativeUnit.ParentPercentage)
);

_nChart.Wall(ChartWallType.Back).Visible = false;

NAxis xAxis = _nChart.Axis(StandardAxis.PrimaryX);
NOrdinalScaleConfigurator xScaleConfig = (NOrdinalScaleConfigurator)xAxis.ScaleConfigurator;

xScaleConfig.AutoLabels = false;
xScaleConfig.LabelStyle.ContentAlignment = ContentAlignment.MiddleRight;
xScaleConfig.LabelStyle.TextStyle.FillStyle = new NColorFillStyle(Color.FromArgb(25, 25, 25));
xScaleConfig.RulerStyle.BorderStyle = new NStrokeStyle(Color.FromArgb(25, 25, 25));
xScaleConfig.OuterMajorTickStyle.LineStyle = new NStrokeStyle(Color.FromArgb(25, 25, 25));

xScaleConfig.MajorTickMode = MajorTickMode.CustomStep;
xScaleConfig.CustomStep = 1;
xScaleConfig.InnerMajorTickStyle.Visible = false;
xScaleConfig.DisplayDataPointsBetweenTicks = false;

NAxis yAxis = _nChart.Axis(StandardAxis.PrimaryY);

// we need this for a little bit of space between the bars and the x-axis
yAxis.View = new NRangeAxisView(new NRange1DD(-0.02, 1));

NLinearScaleConfigurator yScaleConfig = (NLinearScaleConfigurator)yAxis.ScaleConfigurator;
yScaleConfig.RulerStyle.BorderStyle = new NStrokeStyle(Color.FromArgb(25, 25, 25));
yScaleConfig.LabelStyle.TextStyle.FillStyle = new NColorFillStyle(Color.FromArgb(25, 25, 25));
yScaleConfig.OuterMajorTickStyle.Visible = false;
yScaleConfig.InnerMajorTickStyle.Visible = false;
yScaleConfig.MajorGridStyle.LineStyle.Color = Color.Transparent;

// small offset from x-axis
yScaleConfig.MajorTickMode = MajorTickMode.CustomTicks;
yScaleConfig.CustomMajorTicks.Add(0);
yScaleConfig.CustomMajorTicks.Add(.2);
yScaleConfig.CustomMajorTicks.Add(.4);
yScaleConfig.CustomMajorTicks.Add(.6);
yScaleConfig.CustomMajorTicks.Add(.8);
yScaleConfig.CustomMajorTicks.Add(1);

// finally, turn y-axis values into percentages
yScaleConfig.LabelValueFormatter.FormatSpecifier = "0%";

_nChartCtrl.Legends.Clear();
}

Here's how the labels are being configured:

public void AddLabels(string[] labels)
{
NAxis xAxis = _nChart.Axis(StandardAxis.PrimaryX);
NOrdinalScaleConfigurator xScaleConfig = (NOrdinalScaleConfigurator)xAxis.ScaleConfigurator;
xScaleConfig.LabelStyle.ContentAlignment = ContentAlignment.MiddleCenter;

for (int i = 0; i < labels.Length; i++)
{
xScaleConfig.Labels.Add((string)labels[i]);
}
}

When data is added to a chart, it uses this configuration:

barSeries.MultiBarMode = MultiBarMode.StackedPercent;

barSeries.Values.AddRange(values);

if ( _hasSeenClustered )
{
barSeries.DataLabelStyle.TextStyle.FontStyle.EmSize = new NLength( barSeries.DataLabelStyle.TextStyle.FontStyle.EmSize.Value - 2 );
barSeries.BorderStyle.Color = Color.Transparent;
}
else
{
barSeries.DataLabelStyle.TextStyle.FontStyle.Style = FontStyle.Bold;
barSeries.BorderStyle.Color = color.Start;
}

barSeries.DataLabelStyle.Visible = true;
barSeries.DataLabelStyle.VertAlign = Nevron.VertAlign.Center;
barSeries.DataLabelStyle.ArrowLength = new NLength(0);
barSeries.DataLabelStyle.TextStyle.BackplaneStyle.Visible = false;
barSeries.DataLabelStyle.TextStyle.FillStyle = new NColorFillStyle(Color.White);

// fix up our percentages
barSeries.DataLabelStyle.Format = "";
System.Globalization.CultureInfo newCulture = (System.Globalization.CultureInfo)barSeries.PercentValueFormatter.CultureInfo.Clone();
newCulture.NumberFormat.PercentSymbol = "";
newCulture.NumberFormat.PercentDecimalDigits = 0;
newCulture.NumberFormat.PercentPositivePattern = 1;
newCulture.NumberFormat.PercentNegativePattern = 1;
barSeries.PercentValueFormatter.CultureInfo = newCulture;

barSeries.FillStyle = new NGradientFillStyle(color.Start, color.End);



Thanks for your assistance!

Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,054, Visits: 4,009
Hi,

Which version of the chart control are you using? The PredefinedChartStyle property was changed to a method some time ago, so it is probably an older version. We tested your code with the current version, but we weren't able to reproduce the clipping.

By the way - from the image that you've posted it isn't quite clear whether the label texts are really clipped or they just cannot be seen on a white background (because they are white themselves). Can you please check what happens if the text is black (for example) and maybe attach a screenshot?

Best Regards,
Nevron Support Team



Mike M
Posted 11 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 5, Visits: 1
The Nevron Charts reference this app is using is v9.2.18.12. I think it was built in 2010.

I've attached a screenshot showing the problem with a black label color. Take special note of the upper chart third down from the top. Notice how the 2 and the 0 are overlapping each other?

The problem seems to be at its worst when displaying 0%. Is there a good way to tell the API to omit displaying the number when it is 0?

Thanks!

Attachments
clustered.PNG (101 views, 74.00 KB)
Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,054, Visits: 4,009
Hi,

So the problem is that the labels overlap with each other, not that they are clipped.

There are several possible approaches:

1. Exclude zeroes or smaller values using custom value formatting - that is, you can implement a custom formatter for the bar values that skips "small" values.

2. You can try the built-in label layout feature. It can automatically resolve overlaps by changing the initial label positions and by "pushing" labels apart from one another. However it also tends to push labels inside the chart area, which is not very appropriate in this case.

3. Hide the bar labels and paint them manually. This approach requires some custom painting code, but the benefit is that you will be able to measure a label before painting it and check if it fits in the respective bar. We have a similar example for regular (non-stacked) bar series, so please let us know if you are interested.


Best Regards,
Nevron Support Team



Mike M
Posted 11 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 5, Visits: 1
Thanks for the reply!

Option 1 sounds like the simplest solution to me. I'll start looking into this myself, but do you have any tips on how I'd go about doing this, or a specific related KB article I could be linked to? What are the applicable classes and properties I should be using to do this?

Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,054, Visits: 4,009
Hi,

Indeed it is the simplest option. You only need to override one method of the NNumericValueFormatter, something like this:


   class MyPercentValueFormatter : NNumericValueFormatter
   {
      public MyPercentValueFormatter()
         : base("P")
      {      
      }

      public override string FormatValue(double value)
      {
         if (value <= 0.02)
            return "";

         return base.FormatValue(value);
      }
   }


You have to assign an instance of the new type to the PercentValueFormatter property of each bar series:


   barSeries.PercentValueFormatter = new MyPercentValueFormatter();


You can still use the culture setting for this value formatter.


   barSeries.PercentValueFormatter.CultureInfo = newCulture;




Best Regards,
Nevron Support Team



Mike M
Posted 11 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)Forum Newbie (5 reputation)

Group: Forum Members
Last Active: 11 Years Ago
Posts: 5, Visits: 1
Thanks!! This will work just fine.



Similar Topics


Reading This Topic