How To: Customize Axes

This how-to guide shows you how to override a chart’s default look and feel as well as its behavior when it lays out tick marks on axes.

Like every other UI element in the chart, each axis has its own style object. The AxisStyle object has various methods on it that can be used to change the Axis’ look and feel, from changing the color of the axis line to setting the spacing between bars and column series. It also contains a number of sub-style objects, for example GridlineStyle and TickStyle, which can further change the axis’ appearance.

There are also two functional areas that you can customize: the frequency of the tick marks and the formatting of data values into text for the labels.

In its default out-of-box setup the chart takes complete responsibility for both of these. It calculates major (and minor) tick frequencies so that it will have space to draw the tick mark labels without them overlapping. In order to do this it needs to figure out what the longest label string should be, and how much screen space it will take up, given the tick mark style text font and size. It also determines an appropriate format for the labels depending on the frequency (e.g. a frequency of 0.001 would require 3 decimal places to format correctly) and this is taken into account when calculating the space required.

Important note. Tick mark calculation and label formatting is a sensitive area for performance, particularly when panning and zooming, as it must all be redone each time the axis range changes. As the internal Shinobi code has complete control over its own calculations it is able make assumptions which permit it to optimize this process. If you take control over the frequency or formatting, we can no longer rely on these assumptions and cannot safely apply these optimizations. This may impact performance, especially frame rate when panning and zooming. Users of the Xamarin binding may also find that they are impacted in performance by the additional crossings of the native/managed boundary that customization causes. On the other hand, many tick mark customization use cases involve fixing the frequencies and formatting, and are not intended for use with pan and zoom, so this may not be a great problem in practice.

The TickLabelFormatting sample app illustrates some of the options described below.

Styling the Axes

To obtain the AxisStyle object from an axis, simply call the getStyle() method. In the TickLabelFormatting sample app the setting up of the X and Y axes is done in the createXAxis() and createYAxis() methods respectively. For both axes, after being given a default range and a title, their style objects are used to customize the way they look.

The X axis is given a blue axis line, gridlines and its title is positioned to the right:

Java

axisX.getStyle().setLineColor(Color.argb(255, 60, 60, 215));
axisX.getStyle().getGridlineStyle().setGridlinesShown(true);
axisX.getStyle().getTitleStyle().setPosition(Position.TOP_OR_RIGHT);

C#

axisX.Style.LineColor = Color.Argb(255, 60, 60, 215);
axisX.Style.GridlineStyle.GridlinesShown = true;
axisX.Style.TitleStyle.Position = Com.ShinobiControls.Charts.Title.Position.TopOrRight;

The Y axis is given the same blue axis line and gridlines are also shown. Additionally, minor tick marks are shown on the Y axis:

Java

axisY.getStyle().setLineColor(Color.argb(255, 60, 60, 215));
axisY.getStyle().getGridlineStyle().setGridlinesShown(true);
axisY.getStyle().getTickStyle().setMinorTicksShown(true);

C#

axisY.Style.LineColor = Color.Argb(255, 60, 60, 215);
axisY.Style.GridlineStyle.GridlinesShown = true;
axisY.Style.TickStyle.MinorTicksShown = true;

Customizing Tick Mark Frequencies

The NumberAxis and DateTimeAxis APIs offer get/set methods (properties in the Xamarin bindings) allowing you to supply your own major and minor tick frequencies. If you supply these frequencies the chart will use them, without modification, rather than using the frequencies it calculates internally. Note that this means the frequencies will not change as the axis range changes, unless you explicitly change them in response to axis range change events.

It is the major tick frequency that determines whether or not your values are used. If you set the major tick frequency, the axis will use your major and minor values. If you do not set the major tick frequency, the internal values will be used, even if you have set a minor tick frequency. Minor tick frequencies may be null if you do not display minor tick marks.

Number axes use a frequency of type Double. DateTime axes use a frequency of type DateFrequency. Below shows how the X and Y axes’ tick frequencies are set in the TickLabelFormatting sample app:

Java

axisX.setMajorTickFrequency(2.0);

axisY.setMajorTickFrequency(1.0);
axisY.setMinorTickFrequency(0.25);

C#

axisX.MajorTickFrequency = new Java.Lang.Double(2.0);

axisY.MajorTickFrequency = new Java.Lang.Double(1.0);
axisY.MinorTickFrequency = new Java.Lang.Double(0.25);

You can return the chart to its default behavior by setting the frequencies to null.

Whether you have overridden the default frequencies or not, you can also find out what frequencies the chart is actually using. e.g.

Java

Double freq = axisX.getCurrentMajorTickFrequency();

C#

Java.Lang.Double freq = axisX.CurrentMajorTickFrequency;

Customizing Tick Mark Label Formatting

The NumberAxis and DateTimeAxis APIs also offer get/set methods (properties in the Xamarin bindings) allowing you to supply your own format object. If you supply a format the chart will use it, without modification, rather than using the format it manages internally. Note that this too means that the label formats will not change as the axis range changes, unless you explicitly change them in response to axis range change events.

Number axes use a format of type DecimalFormat. DateTime axes use a format of type DateFormat. e.g.

Java

DecimalFormat formatY = new DecimalFormat("$0.00");
formatY.setDecimalSeparatorAlwaysShown(true);
axisY.setLabelFormat(formatY);

C#

DecimalFormat formatY = new DecimalFormat("$0.00");
formatY.DecimalSeparatorAlwaysShown = true;
axisY.LabelFormat = formatY;

You can return the chart to its default behavior by setting the format object to null.

Below shows a screen shot of the chart with its customized axes:

Chart with customized axes

Important note. The default calculation of tick mark frequencies depends on knowing the expected longest label that will be displayed - we need to know how much space the labels will take up in order to choose a frequency where the labels do not overlap. If you do supply your own formatter the internal implementation can no longer predict what the expected longest label will be, and so you must tell the axis explicitly. Of course, if you are also fixing the frequencies yourself, the internal spacing calculation is not done at all and you yourself have to ensure that your labels do not overlap - you have taken control over this away from the chart. e.g.

Java

axisY.setExpectedLongestLabel("$100.00");

C#

axisY.ExpectedLongestLabel ="$100.00";

Once again, you can return the chart to its default behavior by setting the expected longest string null.

See related code sample: Tick Label Formatting Sample, in the samples/tick-label-formatting folder of your product download (Xamarin.Android/samples/TickLabelFormatting if you’re using Xamarin.Android).