SciChart WPF 2D Charts > Axis APIs > Axis Ticks - TickProvider and DeltaCalculator API
Axis Ticks - TickProvider and DeltaCalculator API

Full Control over Axis Ticks

In the previous article we showed you how to change the Axis.AutoTicksAxis.MajorDelta and Axis.MinorDelta properties to change the axis tick (label and gridline) interval. This is fine for static charts, but for dynamic charts where you need full customisation over the axis tick output, you need to use the Axis.TickProvider API.

Overriding the Axis.DeltaCalculator

To have full control over the calculator for MajorDelta and MinorDelta you will need to create a custom DeltaCalculator.

First, create a class that implements IDeltaCalculator for numeric axes or IDateDeltaCalculator for time axes. The IDeltaCalculator.GetDeltaFromRange method should be implemented to get min and max of visible range and amount of minor ticks for each major and amount of major ticks. So here, you can place the logic of delta values calculation.

Overriding the Axis.DeltaCalculator
Copy Code
/// <summary>
/// Provides an interface for Delta calculators
/// </summary>
public interface IDeltaCalculator
{
       /// <summary>
       /// Given an absolute Axis Min and Max, returns a TickRange instance
       /// containing sensible MinorDelta and MajorDelta values
       /// </summary>
       IAxisDelta GetDeltaFromRange(IComparable min, IComparable max,
                     int minorsPerMajor, uint maxTicks);
}

/// <summary>
/// Defines the interface for DateTime or TimeSpan Delta calculators
/// </summary>
public interface IDateDeltaCalculator : IDeltaCalculator
{
       /// <summary>
       /// Given an absolute Axis Min and Max, returns a TickRange instance
       /// containing sensible MinorDelta and MajorDelta values
       /// </summary>
       new TimeSpanDelta GetDeltaFromRange(IComparable min, IComparable max,
                    int minorsPerMajor, uint maxTicks);
}

Next, you will need to set your DeltaCalculator instance on the AxisBase.DeltaCalculator property.

 

Example – Creating a custom DeltaCalculator for a NumericAxis

For an example of creating a DeltaCalculator for a NumericAxis, see below:

Creating a custom DeltaCalculator for a NumericAxis
Copy Code
public class CustomNumericDeltaCalculator : IDeltaCalculator
{
       private const uint DefaultTicksCount = 10;

       /// <summary>
       /// Given an absolute Axis Min and Max, returns a TickRange instance containing sensible MinorDelta and MajorDelta values
       /// </summary>
       public IAxisDelta<double> GetDeltaFromRange(double min, double max, int minorsPerMajor, uint maxTicks = DefaultTicksCount)
       {
             // Given the min = Axis.VisibleRange.Min,
             //       the max = Axis.VisibleRange.Max
             //       minorsPerMajor = requested minor ticks per major ticks
             //       maxTicks = requested maximum number of major ticks
             //
             // Note: Your delta calculation here to calculate minorDelta, majorDelta
             double deltaMin, deltaMax;
            
             // Return an AxisDelta
             return new DoubleAxisDelta(deltaMin, deltaMax);
       }
      
       IAxisDelta IDeltaCalculator.GetDeltaFromRange(IComparable min, IComparable max, int minorsPerMajor, uint maxTicks)
       {
             return GetDeltaFromRange(min.ToDouble(), max.ToDouble(), minorsPerMajor, maxTicks);
       }

}

Custom DeltaCalculator Usage (Code)

Custom DeltaCalculator Usage
Copy Code
public class NumericAxisEx : NumericAxis
{
    private IDeltaCalculator _customDeltaCalculator = new CustomNumericDeltaCalculator();
    protected override IDeltaCalculator GetDeltaCalculator()
    {
        return _customDeltaCalculator;
    }
}

Custom DeltaCalculator Usage (XAML)

Custom DeltaCalculator Usage
Copy Code
<!-- where xmlns:s="http://schemas.abtsoftware.co.uk/scichart" -->
<!-- Assumes you have declared your custom NumericAxisEx in code -->
<s:SciChartSurface>      
    <s:SciChartSurface.XAxis>
           <yourNamespace:NumericAxisEx/>
     </s:SciChartSurface.XAxis>
     
     <!-- YAxis, RenderableSeries omitted for brevity -->
</s:SciChartSurface>

Example – Creating a custom DeltaCalculator for a DateTime or TimeSpanAxis

Creating a custom DeltaCalculator for a DateTime or TimeSpanAxis
Copy Code
public class CustomDateTimeDeltaCalculator : IDateDeltaCalculator
{
       IAxisDelta IDeltaCalculator.GetDeltaFromRange(IComparable min, IComparable max, int minorsPerMajor, uint maxTicks)
       {
             return GetDeltaFromRange(min.ToDouble(), max.ToDouble(), minorsPerMajor, maxTicks);
       }

       public TimeSpanDelta GetDeltaFromRange(IComparable min, IComparable max, int minorsPerMajor, uint maxTicks)
       {
             // Given the min = Axis.VisibleRange.Min,
             //       the max = Axis.VisibleRange.Max
             //       minorsPerMajor = requested minor ticks per major ticks
             //       maxTicks = requested maximum number of major ticks
             //
             // NOTE: Your delta calculation here to calculate minorDelta, majorDelta
             TimeSpan deltaMin, deltaMax;

             // Return an AxisDelta
             return new TimeSpanDelta(deltaMin, deltaMax);
       }
}

Custom DeltaCalculator Usage (Code)

Custom DeltaCalculator Usage
Copy Code
public class DateTimeAxisEx : DateTimeAxis
{
    private IDeltaCalculator _customDeltaCalculator = new CustomDateTimeDeltaCalculator();
    protected override IDeltaCalculator GetDeltaCalculator()
    {
        return _customDeltaCalculator;
    }
}

Custom DeltaCalculator Usage (XAML)

Custom DeltaCalculator Usage
Copy Code
<!-- where xmlns:s="http://schemas.abtsoftware.co.uk/scichart" -->
<!-- Assumes you have declared your custom DateTimeAxisEx in code -->
<s:SciChartSurface>      
    <s:SciChartSurface.XAxis>
           <yourNamespace:DateTimeAxisEx/>
     </s:SciChartSurface.XAxis>
     
     <!-- YAxis, RenderableSeries omitted for brevity -->
</s:SciChartSurface>

 

Overidding the Axis.TickProvider

By default each Axis type has it’s own TickProvider type, e.g.

Axis Type TickProvider Type
NumericAxis NumericTickProvider
DateTimeAxis DateTimeTickProvider
TimeSpanAxis TimeSpanTickProvider
CategoryDateTimeAxis NumericTickProvider
LogarithmicNumericAxis LogarithmicNumericTickProvider
PolarXAxis NumericTickProvider
PolarYAxis NumericTickProvider

 

You can create your own, or inherit one of our TickProvider types to completely control the generation of axis ticks (label and gridline intervals).

The easiest way to create new tick provider is to use TickProvider base class where T is the axis data-type, e.g. DateTime for DateTimeAxis, double for NumericAxis etc.

Next, you need to implement two abstract methods for the generation of major and minor ticks. In these methods you need to place the logic of tick generation and return arrays with data-values where ticks (gridlines, labels) should be displayed.

Example – Creating a NumericAxis TickProvider

For a demonstration of using the TickProvider API we are going to create TickProvider for the NumericAxis type by inherting NumericTickProvider. This tick provider should divide the axis into 5 equal parts, using major tick gridlines and without minor ticks.

Creating a NumericAxis TickProvider
Copy Code
public class CustomTickProvider : NumericTickProvider
{
    private const int MajorTickCount = 5;

    public override double[] GetMajorTicks(IAxisParams axis)
    {
        var visibleRange = (DoubleRange) axis.VisibleRange;

        var ticks = new double[MajorTickCount + 1];

        var step = visibleRange.Diff / MajorTickCount;
        var min = visibleRange.Min;

        for (int i = 0; i < MajorTickCount + 1; i++)
        {
            ticks[i] = min + step * i;
        }

        return ticks;
    }

    public override double[] GetMinorTicks(IAxisParams axis)
    {
        return new double[0];
    }
}

Usage (XAML)

Usage
Copy Code
<!-- where xmlns:s="http://schemas.abtsoftware.co.uk/scichart" -->
<s:SciChartSurface>
    <s:SciChartSurface.Resources>
           <local:CustomTickProvider  x:Key="CustomTickProvider "/>
       </s:SciChartSurface.Resources>
      
    <s:SciChartSurface.XAxis>
           <s:NumericAxis DeltaCalculator="{StaticResource CustomTickProvider "/>
     </s:SciChartSurface.XAxis>
      
     <!-- YAxis, RenderableSeries omitted for brevity -->
</s:SciChartSurface>

Usage (Code)

Usage
Copy Code
var axis = new NumericAxis();
axis.TickProvider = new CustomTickProvider();

Result

The Custom Tickprovider divides the axis into five sections, and removes minor gridlines

Note: Obviously there’s a lot more you coul do with this API, for instance, if you want to dynamically control the tick frequency as you zoom, this would be the place to do it!

Creating a custom TickProvider for a TimeSpanAxis or DateTimeAxis

The process for creating a TickProvider for a TimeSpanAxis or DateTimeAxis is similar, except you need to change the base class and return TimeSpan, or DateTime arrays.

Custom TickProvider for a TimeSpanAxis
Custom TickProvider for a TimeSpanAxis
Copy Code
// 1. Create a class which inherits TimeSpanTickProvider
// 2. Return an array of IComparable, but actual elements must be TimeSpans
// 3. Assign to the TimeSpanAxis.TickProvider property
public class CustomTimeSpanTickProvider : TimeSpanTickProvider
{
       public override IComparable[] GetMajorTicks(IAxisParams axis)
       {
             // TODO: calculate ticks
             return new IComparable[]
             {
                    new TimeSpan(2015, 01, 01),
                    new TimeSpan(2015, 01, 02),
                    new TimeSpan(2015, 01, 03),
                    // ...
             };
       }

       public override IComparable[] GetMinorTicks(IAxisParams axis)
       {
             // TODO: calculate ticks
             return new IComparable[]
             {
                    new TimeSpan(2015, 01, 01),
                    new TimeSpan(2015, 01, 02),
                    new TimeSpan(2015, 01, 03),
                    // ...
             };
       }
}

Custom TickProvider for a DateTimeAxis

Custom TickProvider for a DateTimeAxis
Copy Code
// 1. Create a class which inherits DateTimeTickProvider
// 2. Return an array of IComparable, but actual elements must be DateTimes
// 3. Assign to the DateTimeAxis.TickProvider property
public class CustomDateTimeTickProvider : DateTimeTickProvider
{
       public override IComparable[] GetMajorTicks(IAxisParams axis)
       {
             // TODO: calculate ticks
             return new IComparable[]
             {
                    new DateTime(2015, 01, 01),
                    new DateTime(2015, 01, 02),
                    new DateTime(2015, 01, 03),
                    // ...
             };
       }

       public override IComparable[] GetMinorTicks(IAxisParams axis)
       {
             // TODO: calculate ticks
             return new IComparable[]
             {
                    new DateTime(2015, 01, 01),
                    new DateTime(2015, 01, 02),
                    new DateTime(2015, 01, 03),
                    // ...
             };
       }
}

 

See Also