In this post I will discuss labeling of the categorical axes in SQL Reporting Services (SSRS) and .NET Chart controls. Same engine is used between these two products and they have exactly the same behavior. You can find detailed steps and sample code at the end of the post.
Before we start, lets have a look how automatic chart axis labels work... When you data bind your chart, axis automatically calculates data scale and sets axis Minimum and Maximum values. Based on the axis scale, chart determines axis labels text, interval (how often labels are shown), font size and label rotation, so that labels do not overlap each other. Below you can see a simple chart with categorical values (countries) shown on the bottom axis:
As you can see, there is not enough space to show all the labels and chart only displays every other country. For categorical axis it is important to show as many categories as possible and here are few different tricks which will help you achieving that.
Solution 1: Force chart axis to display every category.
Chart axis Interval property allows you to provide your own custom interval for axis labels, grid lines and tick marks. Our first solution is to set this property to 1, which will force the chart to display every single category. As you can see on the chart below, every country will become visible and chart will automatically rotate labels to better fit them. If you are using Column chart type you can also switch to Bar chart type to avoid labels rotation.
This is a very simple approach but you should also be aware of the possible down sides. In case you have too many categories, labels auto-fit algorithm may not be able to completely avoid labels overlapping and they will be very hard to read. I simulated this by reducing our original chart width in half and as you can see it is very hard to read the labels. If we double number of data points (countries) it will be even harder to read this chart.
Solution 2: Enable Variable Count interval and set preferred labels appearance
Second solution keeps the axis Interval in automatic mode, so that in extreme cases we can still reduce number of labels on the axis. First step is to disable labels auto fitting and specify the preferred font size and rotation. In our case we are trying to fit as much labels as possible, so we will set axis labels rotation angle to 90 degrees. And the last step is to enable Variable Interval calculation mode on the axis. By default, chart displays about 5 labels on the axis no matter how long it is, Variable Interval mode will allow you display as many labels as we can fit into the axis. After all this changes you should see something very similar to the Solution 1 chart:
Now let's try to reduce the size of the chart and see what will be different... As you can see in the image below, when chart cannot fit more vertically oriented labels it starts skipping them to avoid making chart completely unreadable.
When categories are displayed on the axis, there is no grantee that all of them will be shown. You can set axis interval to 1 if it is extremely important to see every category but keep in mind that labels may overlap if there are too many categories. Use Variable Interval and labels rotation if you want to fit as many labels as possible and still have labels skipping in extreme cases.
Steps to apply Solution 1:
- Right click on the bottom axis and choose Axis Properties from the context menu
- Set Interval field to 1 in the Axis Options property page
- Press Ok to close property dialog
Steps to apply Solution 2:
- Make sure Properties View is enabled
- Click on the axis to select it and display it's properties in the Properties View
- Set VariableAutoInterval property to True
- Set LabelsAngle property to 90
- Click Yes on the pop-up dialog to labels disable auto fitting
.NET Chart Sample Code
|// Solution 1: Setting axis Interval|
|this.Chart1.ChartAreas.AxisX.Interval = 1;|
|// Solution 2: Enable variable interval|
|this.Chart1.ChartAreas.AxisX.Interval = double.NaN;|
|this.Chart1.ChartAreas.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;|
|this.Chart1.ChartAreas.AxisX.LabelStyle.Angle = 90;|