Create a custom axis view that updates the Y axis range

Applies to: Nevron Chart for .NET

How to create a custom axis view that updates the Y axis range?

Often, there is a requirement to have custom axis view that updates the Y axis range to match the range of data points currently visible on chart the x axis. This feature is useful when you are building charts with zooming and scrolling that show only a partial view of the data on the x axis.



The following code example shows how to create a custom axis view that updates the Y axis range to match the range of data points currently visible on the x axis:

[C#]

using System;
using System.Windows.Forms;
using Nevron.Chart;
using Nevron.Chart.WinForm;
using Nevron.GraphicsCore;
...
/// <summary>
/// Configures the axis to display the range of the content that scales on it
/// </summary>
[Serializable]
public partial class NCustomAxisView : NRangeAxisView
{
      #region Constructors
 
      /// <summary>
      /// Constructor
      /// </summary>
      /// <param name="chartControl"></param>
      public NCustomAxisView(NChartControl chartControl)
      {
            m_ChartControl = chartControl;
      }
 
      #endregion
 
      #region Overrides
 
      /// <summary>
      /// Obtains the Y range displayed by the axis given the current X content range
      /// </summary>
      /// <param name="range"></param>
      /// <param name="isZoomed"></param>
      /// <returns></returns>
      public override NRange1DD GetViewRange(NRange1DD range, ref bool isZoomed)
      {
            NChart chart = (NChart)this.ProvideReference(typeof(NChart));
 
            // recalculate the x axis - this ensures the RulerRange is valid
            chart.Axis(StandardAxis.PrimaryX).CalculateAxis(m_ChartControl.View.Context);
 
            NRange1DD xRange = chart.Axis(StandardAxis.PrimaryX).Scale.RulerRange;
            NLineSeries line = chart.Series[0] as NLineSeries;
 
            if (line.Values.Count == 0)
                  return range;
 
            // then compute min / max
            bool hasMinMax = false;
            double min = 0;
            double max = 0;
 
            for (int i = 0; i < line.Values.Count; i++)
            {
                  if (!xRange.Contains((double)line.XValues[i]))
                        continue;
 
                  double value = (double)line.Values[i];
 
                  if (hasMinMax)
                  {
                        max = Math.Max(max, value);
                        min = Math.Min(min, value);
                  }
                  else
                  {
                        max = value;
                        min = value;
                        hasMinMax = true;
                  }
            }
 
            isZoomed = hasMinMax;
 
            if (hasMinMax)
            {
                  range = new NRange1DD(min, max);
            }
 
            // return the computed range
            return range;
      }
 
      #endregion
 
      #region Fields
 
      NChartControl m_ChartControl;
 
      #endregion
}
 
private void Form1_Load(object sender, EventArgs e)
{
      NCartesianChart chart = (NCartesianChart)nChartControl1.Charts[0];
 
      // configure chart
      chart.BoundsMode = BoundsMode.Stretch;
      chart.Axis(StandardAxis.PrimaryX).ScrollBar.Visible = true;
 
      // install custom axis view
      chart.Axis(StandardAxis.PrimaryY).View = new NCustomAxisView(nChartControl1);
 
      // add dummy data
      NLineSeries line = new NLineSeries();
      line.UseXValues = true;
      line.DataLabelStyle.Visible = false;
 
      for (int i = 0; i < 200; i++)
      {
            line.Values.Add(Math.Sin(2 * Math.PI * i / 200.0));
            line.XValues.Add(i);
      }
 
      chart.Series.Add(line);
 
      // configure interactivity
      NRangeSelection rs = new NRangeSelection();
      rs.VerticalValueSnapper = new NAxisRulerMinMaxSnapper();
      chart.RangeSelections.Add(rs);
 
      nChartControl1.Controller.Tools.Add(new NSelectorTool());
      nChartControl1.Controller.Tools.Add(new NAxisScrollTool());
      nChartControl1.Controller.Tools.Add(new NDataZoomTool());
}

[VB.NET]
Imports System
Imports System.Windows.Forms
Imports Nevron.Chart
Imports Nevron.Chart.WinForm
Imports Nevron.GraphicsCore
    ''' <summary>
    ''' Configures the axis to display the range of the content that scales on it
    ''' </summary>
    <Serializable()> _
    Partial Public Class NCustomAxisView
        Inherits NRangeAxisView
#Region "Constructors"
 
        ''' <summary>
        ''' Constructor
        ''' </summary>
        ''' <param name="chartControl"></param>
        Public Sub New(chartControl As NChartControl)
            m_ChartControl = chartControl
        End Sub
 
#End Region
 
#Region "Overrides"
 
        ''' <summary>
        ''' Obtains the Y range displayed by the axis given the current X content range
        ''' </summary>
        ''' <param name="range"></param>
        ''' <param name="isZoomed"></param>
        ''' <returns></returns>
        Public Overrides Function GetViewRange(range As NRange1DD, ByRef isZoomed As Boolean) As NRange1DD
            Dim chart As NChart = DirectCast(Me.ProvideReference(GetType(NChart)), NChart)
 
            ' recalculate the x axis - this ensures the RulerRange is valid
            chart.Axis(StandardAxis.PrimaryX).CalculateAxis(m_ChartControl.View.Context)
 
            Dim xRange As NRange1DD = chart.Axis(StandardAxis.PrimaryX).Scale.RulerRange
            Dim line As NLineSeries = TryCast(chart.Series(0), NLineSeries)
 
            If line.Values.Count = 0 Then
                Return range
            End If
 
            ' then compute min / max
            Dim hasMinMax As Boolean = False
            Dim min As Double = 0
            Dim max As Double = 0
 
            For i As Integer = 0 To line.Values.Count - 1
                If Not xRange.Contains(CDbl(line.XValues(i))) Then
                    Continue For
                End If
 
                Dim value As Double = CDbl(line.Values(i))
 
                If hasMinMax Then
                    max = Math.Max(max, value)
                    min = Math.Min(min, value)
                Else
                    max = value
                    min = value
                    hasMinMax = True
                End If
            Next
 
            isZoomed = hasMinMax
 
            If hasMinMax Then
                range = New NRange1DD(min, max)
            End If
 
            ' return the computed range
            Return range
        End Function
 
#End Region
 
#Region "Fields"
 
        Private m_ChartControl As NChartControl
 
#End Region
    End Class
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Dim chart As NCartesianChart = DirectCast(NChartControl1.Charts(0), NCartesianChart)
 
        ' configure chart
        chart.BoundsMode = BoundsMode.Stretch
        chart.Axis(StandardAxis.PrimaryX).ScrollBar.Visible = True
 
        ' install custom axis view
        chart.Axis(StandardAxis.PrimaryY).View = New NCustomAxisView(NChartControl1)
 
        ' add dummy data
        Dim line As New NLineSeries()
        line.UseXValues = True
        line.DataLabelStyle.Visible = False
 
        For i As Integer = 0 To 199
            line.Values.Add(Math.Sin(2 * Math.PI * i / 200.0))
            line.XValues.Add(i)
        Next
 
        chart.Series.Add(line)
 
        ' configure interactivity
        Dim rs As New NRangeSelection()
        rs.VerticalValueSnapper = New NAxisRulerMinMaxSnapper()
        chart.RangeSelections.Add(rs)
 
        NChartControl1.Controller.Tools.Add(New NSelectorTool())
        NChartControl1.Controller.Tools.Add(New NAxisScrollTool())
        NChartControl1.Controller.Tools.Add(New NDataZoomTool())
    End Sub


Article ID: 219, Created On: 5/16/2012, Modified: 5/16/2012