Back to Devexpress

How to: Use Custom Measure Units in an Automatic Date-Time Scale Mode

windowsforms-115273-controls-and-libraries-chart-control-examples-creating-charts-data-representation-how-to-use-custom-measure-units-in-an-automatic-date-time-scale-mode.md

latest5.3 KB
Original Source

How to: Use Custom Measure Units in an Automatic Date-Time Scale Mode

  • Nov 13, 2018
  • 3 minutes to read

To use a custom Date-Time measure unit for an Automatic scale mode, assign an object of a class implementing the IDateTimeMeasureUnitsCalculator interface to the DateTimeScaleOptions.AutomaticMeasureUnitsCalculator property of AxisBase.DateTimeScaleOptions.

csharp
private void Form1_Load(object sender, EventArgs e) {
        chart.Series.Add(GenerateSeries(10000));

        XYDiagram diagram = chart.Diagram as XYDiagram;
        if (diagram == null) return;

        diagram.AxisX.DateTimeScaleOptions.AggregateFunction = AggregateFunction.Average;
        diagram.AxisX.DateTimeScaleOptions.ScaleMode = ScaleMode.Automatic;
        diagram.AxisX.DateTimeScaleOptions.AutomaticMeasureUnitsCalculator = new CustomDateTimeMeasureUnitsCalculator();

        diagram.AxisY.WholeRange.AlwaysShowZeroLevel = false;
    }
class CustomDateTimeMeasureUnitsCalculator : IDateTimeMeasureUnitsCalculator {
    const int daysInWeek = 7;
    const int daysInMonth = 30;
    const int daysInQuarter = 4 * daysInMonth;
    const int daysInYear = 365;

    const int minCount = 5;

    public DateTimeMeasureUnit CalculateMeasureUnit(
            IEnumerable<Series> series, 
            double axisLength, 
            int pixelsPerUnit, 
            double visualMin, 
            double visualMax, 
            double wholeMin, 
            double wholeMax) {
        // Calculate visual range in msecs.
        double visualRange = visualMax - visualMin;
        TimeSpan ts = TimeSpan.FromMilliseconds(visualRange);
        if (ts.TotalDays >= 1.0d) {
            if (ts.TotalDays <= minCount * daysInWeek)
                return DateTimeMeasureUnit.Day;
            if (ts.TotalDays <= minCount * daysInMonth)
                return DateTimeMeasureUnit.Week;
            if (ts.TotalDays <= minCount * daysInQuarter)
                return DateTimeMeasureUnit.Month;
            if (ts.TotalDays <= minCount * daysInYear)
                return DateTimeMeasureUnit.Quarter;
            else
                return DateTimeMeasureUnit.Year;
        }
        else if (ts.TotalHours >= 20.0d)
            return DateTimeMeasureUnit.Hour;
        else if (ts.TotalMinutes >= 20.0d)
            return DateTimeMeasureUnit.Minute;
        else if (ts.TotalSeconds >= 20.0d)
            return DateTimeMeasureUnit.Second;
        else
            return DateTimeMeasureUnit.Millisecond;
    }
}
vb
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        Chart.Series.Add(GenerateSeries(10000))

        Dim diagram As XYDiagram = TryCast(Chart.Diagram, XYDiagram)
        If diagram Is Nothing Then
            Return
        End If

        diagram.AxisX.DateTimeScaleOptions.AggregateFunction = AggregateFunction.Average
        diagram.AxisX.DateTimeScaleOptions.ScaleMode = ScaleMode.Automatic
        diagram.AxisX.DateTimeScaleOptions.AutomaticMeasureUnitsCalculator = New CustomDateTimeMeasureUnitsCalculator()

        diagram.AxisY.WholeRange.AlwaysShowZeroLevel = False
    End Sub
Friend Class CustomDateTimeMeasureUnitsCalculator
    Implements IDateTimeMeasureUnitsCalculator

    Private Const daysInWeek As Integer = 7
    Private Const daysInMonth As Integer = 30
    Private Const daysInQuarter As Integer = 4 * daysInMonth
    Private Const daysInYear As Integer = 365

    Private Const minCount As Integer = 5

    Public Function CalculateMeasureUnit(
            ByVal series As IEnumerable(Of Series),
            ByVal axisLength As Double,
            ByVal pixelsPerUnit As Integer,
            ByVal visualMin As Double,
            ByVal visualMax As Double,
            ByVal wholeMin As Double,
            ByVal wholeMax As Double) As DateTimeMeasureUnit Implements IDateTimeMeasureUnitsCalculator.CalculateMeasureUnit
        ' Calculate visual range in msecs.
        Dim visualRange As Double = visualMax - visualMin
        Dim ts As TimeSpan = TimeSpan.FromMilliseconds(visualRange)
        If ts.TotalDays >= 1.0R Then
            If ts.TotalDays <= minCount * daysInWeek Then
                Return DateTimeMeasureUnit.Day
            End If
            If ts.TotalDays <= minCount * daysInMonth Then
                Return DateTimeMeasureUnit.Week
            End If
            If ts.TotalDays <= minCount * daysInQuarter Then
                Return DateTimeMeasureUnit.Month
            End If
            If ts.TotalDays <= minCount * daysInYear Then
                Return DateTimeMeasureUnit.Quarter
            Else
                Return DateTimeMeasureUnit.Year
            End If
        ElseIf ts.TotalHours >= 20.0R Then
            Return DateTimeMeasureUnit.Hour
        ElseIf ts.TotalMinutes >= 20.0R Then
            Return DateTimeMeasureUnit.Minute
        ElseIf ts.TotalSeconds >= 20.0R Then
            Return DateTimeMeasureUnit.Second
        Else
            Return DateTimeMeasureUnit.Millisecond
        End If
    End Function
End Class