Profile Picture

Change MajorTickMode After RulerRangeChanged

Posted By Lance Levendowski 8 Years Ago
Author
Message
Lance Levendowski
Posted 8 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)

Group: Forum Members
Last Active: 6 days ago @ 1:19 PM
Posts: 59, Visits: 155
I want change the MajorTickMode that is used by an axis if data are zoomed along that axis and then restore the axis' MajorTickMode if data are un-zoomed along that axis.

I need help finding a way to set Axis.ScaleConfigurator.MajorTickMode after data are zoomed by the user (via the NDataZoomTool) and have the changes take effect before the chart is refreshed.  If I change Axis.ScaleConfigurator.MajorTickMode after handling the axis' RulerRangeChanged event then the new MajorTickMode doesn't seem to take effect until the second time that the chart is refreshed after the MajorTickMode is changed.

The behavior of ScrollBar visibility is a good example of the behavior that I'm looking for.  I can't use ScrollBars because I always set Chart.Enable3D = True, but the idea is that if ScrollBars would be visible then I want to use MajorTickMode = AutoMinDistance and if ScrollBars would not be visible then I want to use MajorTickMode = CustomStep.

Please see the following example.  Note that MajorTickMode of the Y axes is set in the UpdateTickMode method.  ChartControl.Refresh is always called after UpdateTickMode is called, but changes to MajorTickMode don't seem to take effect until the second time the chart is refreshed (e.g., if the form's size is changed or the user right clicks on the chart in order to interact with the chart via the NDataPanTool).  Also note that the form's Text shows the current values of the MajorTickMode property for the Y axes.

Public Class ChangeTickModeAfterDataZoomForm
  Inherits System.Windows.Forms.Form

  Protected _ChartControl As Nevron.Chart.WinForm.NChartControl
  Private components As System.ComponentModel.Container = Nothing

  Public Sub New()
    InitializeComponent()
  End Sub

  ''' <summary>
  ''' Clean up any resources being used.
  ''' </summary>
  Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing Then
      If Not components Is Nothing Then
        components.Dispose()
      End If
    End If
    MyBase.Dispose(disposing)
  End Sub


#Region "Component Designer generated code"
  ''' <summary>
  ''' Required method for Designer support - do not modify
  ''' the contents of this method with the code editor.
  ''' </summary>
  Private Sub InitializeComponent()
    Me.SuspendLayout()
    '
    ' ChangeTickModeAfterDataZoomForm
    '
    Me.Name = "ChangeTickModeAfterDataZoomForm"
    Me.Size = New System.Drawing.Size(1000, 800)
    Me.ResumeLayout(False)
    Me.StartPosition = FormStartPosition.CenterScreen

    Call Me.Initialize()
  End Sub
#End Region

  Public Overridable Sub Initialize()
    Me._ChartControl = New Nevron.Chart.WinForm.NChartControl
    Me._ChartControl.Dock = DockStyle.Fill
    'Me._ChartControl.Settings.ShapeRenderingMode = Nevron.GraphicsCore.ShapeRenderingMode.Default
    Me._ChartControl.Settings.JitterMode = Nevron.Chart.JitterMode.Disabled
    'Me._ChartControl.Settings.AutoJitterInterval = 2000
    Me._ChartControl.Settings.RenderSurface = Nevron.GraphicsCore.RenderSurface.Window
    Me.Controls.Add(Me._ChartControl)


    ' set a chart title
    Dim title As Nevron.Chart.NLabel = Me._ChartControl.Labels.AddHeader("Multiple Axes Zooming and Scrolling")
    title.TextStyle.FontStyle = New Nevron.GraphicsCore.NFontStyle("Times New Roman", 18, Drawing.FontStyle.Italic)
    title.ContentAlignment = Drawing.ContentAlignment.BottomCenter
    title.Location = New Nevron.GraphicsCore.NPointL(New Nevron.GraphicsCore.NLength(50, Nevron.GraphicsCore.NRelativeUnit.ParentPercentage), New Nevron.GraphicsCore.NLength(2, Nevron.GraphicsCore.NRelativeUnit.ParentPercentage))

    ' configure chart
    Dim chart As Nevron.Chart.NCartesianChart = CType(Me._ChartControl.Charts(0), Nevron.Chart.NCartesianChart)
    '
    chart.Enable3D = True
    chart.Projection.SetPredefinedProjection(Nevron.GraphicsCore.PredefinedProjection.Orthogonal)
    '
    chart.RangeSelections.Add(New Nevron.Chart.NRangeSelection())

    ' 2D line chart
    chart.BoundsMode = Nevron.GraphicsCore.BoundsMode.Stretch

    ' configure axis paging and set a mimimum range length on the axisthis will prevent the user from zooming too much
    chart.Axis(Nevron.Chart.StandardAxis.PrimaryX).ScrollBar.Visible = True

    Dim palette As Nevron.Chart.NChartPalette = New Nevron.Chart.NChartPalette(Nevron.Chart.ChartPredefinedPalette.Fresh)
    Dim color1 As Drawing.Color = palette.SeriesColors(0)
    Dim color2 As Drawing.Color = palette.SeriesColors(3)

    Dim primaryY As Nevron.Chart.NAxis = chart.Axis(Nevron.Chart.StandardAxis.PrimaryY)
    primaryY.ScaleConfigurator.Title.Text = "Primary Y Axis"
    ApplyColorToAxis(primaryY, color1)
    primaryY.ScrollBar.Visible = True
    AddHandler primaryY.Scale.RulerRangeChanged, AddressOf Scale_RulerRangeChanged

    Dim secondaryY As Nevron.Chart.NAxis = chart.Axis(Nevron.Chart.StandardAxis.SecondaryY)
    secondaryY.ScaleConfigurator.Title.Text = "Secondary Y Axis"
    ApplyColorToAxis(secondaryY, color2)
    secondaryY.Visible = True

    Dim line1 As Nevron.Chart.NLineSeries = New Nevron.Chart.NLineSeries()
    line1.BorderStyle.Color = color1
    line1.BorderStyle.Width = New Nevron.GraphicsCore.NLength(2)
    chart.Series.Add(line1)

    line1.DataLabelStyle.Visible = False

    Dim line2 As Nevron.Chart.NLineSeries = New Nevron.Chart.NLineSeries()
    line2.BorderStyle.Color = color2
    line2.BorderStyle.Width = New Nevron.GraphicsCore.NLength(2)
    chart.Series.Add(line2)

    line2.DataLabelStyle.Visible = False
    line2.DisplayOnAxis(Nevron.Chart.StandardAxis.PrimaryY, False)
    line2.DisplayOnAxis(Nevron.Chart.StandardAxis.SecondaryY, True)

    For i As Integer = 0 To 719
      Const degree2Rad As Double = Math.PI / 180.0#
      Dim angle As Double = i * degree2Rad

      Dim value1 As Double = Math.Sin(angle)
      Dim value2 As Double = Math.Sin(4.0# * angle + 40) * 50 + 1234

      line1.Values.Add(value1)
      line2.Values.Add(value2)
    Next i

    Me._ChartControl.Controller.Tools.Add(New Nevron.Chart.Windows.NSelectorTool())
    Me._ChartControl.Controller.Tools.Add(New Nevron.Chart.Windows.NAxisScrollTool())
    Me._ChartControl.Controller.Tools.Add(New Nevron.Chart.Windows.NDataZoomTool())
    Me._ChartControl.Controller.Tools.Add(New Nevron.Chart.Windows.NDataPanTool())

    Call Me.UpdateTickMode()
    Me._ChartControl.Refresh()
  End Sub

  Private Sub ApplyColorToAxis(ByVal axis As Nevron.Chart.NAxis, ByVal color As Drawing.Color)
    Dim scale As Nevron.Chart.NLinearScaleConfigurator = CType(axis.ScaleConfigurator, Nevron.Chart.NLinearScaleConfigurator)

    scale.InnerMajorTickStyle.LineStyle.Color = color
    scale.InnerMinorTickStyle.LineStyle.Color = color
    scale.OuterMajorTickStyle.LineStyle.Color = color
    scale.OuterMinorTickStyle.LineStyle.Color = color
    scale.LabelStyle.TextStyle.FillStyle = New Nevron.GraphicsCore.NColorFillStyle(color)
    scale.Title.TextStyle.FillStyle = New Nevron.GraphicsCore.NColorFillStyle(color)
    scale.RulerStyle.BorderStyle.Color = color
  End Sub

  Private Sub Scale_RulerRangeChanged(ByVal sender As Object, ByVal e As EventArgs)
    Dim chart As Nevron.Chart.NChart = Me._ChartControl.Charts(0)

    Dim contentRange As Nevron.GraphicsCore.NRange1DD = chart.Axis(Nevron.Chart.StandardAxis.PrimaryY).ContentRange
    Dim viewRange As Nevron.GraphicsCore.NRange1DD = chart.Axis(Nevron.Chart.StandardAxis.PrimaryY).Scale.RulerRange

    ' compute factors
    Dim beginFactor As Double = contentRange.GetValueFactor(viewRange.Begin)
    Dim endFactor As Double = contentRange.GetValueFactor(viewRange.End)

    ' then for all other y axes make sure their view range factor equals to begin/end factor
    If beginFactor = 0.0 AndAlso endFactor = 1.0 Then
      ' disable zoom
      For Each axis As Nevron.Chart.NAxis In chart.Axes
        If axis.AxisId <> CInt(Nevron.Chart.StandardAxis.PrimaryY) AndAlso axis.AxisOrientation = Nevron.Chart.AxisOrientation.Vertical Then
          axis.PagingView.Enabled = False
        End If
      Next axis
    Else
      ' disable zoom
      For Each axis As Nevron.Chart.NAxis In chart.Axes
        If (axis.AxisId <> CInt(Nevron.Chart.StandardAxis.PrimaryY)) AndAlso (axis.AxisOrientation = Nevron.Chart.AxisOrientation.Vertical) Then
          axis.PagingView.Enabled = True

          ' compute the new range based on factor
          Dim axisContentRange As Nevron.GraphicsCore.NRange1DD = axis.ContentRange
          Dim rangeLength As Double = axisContentRange.End - axisContentRange.Begin

          Dim begin As Double = axisContentRange.Begin + beginFactor * rangeLength
          Dim [end] As Double = axisContentRange.Begin + endFactor * rangeLength

          axis.PagingView.ZoomIn(New Nevron.GraphicsCore.NRange1DD(begin, [end]), 0.0001)
        End If
      Next axis
    End If

    Call Me.UpdateTickMode()
    Me._ChartControl.Refresh()
  End Sub

  Private Sub UpdateTickMode()
    Dim chart As Nevron.Chart.NCartesianChart = CType(Me._ChartControl.Charts(0), Nevron.Chart.NCartesianChart)

    Dim axis As Nevron.Chart.NAxis
    Dim scaleConfigurator As Nevron.Chart.NNumericScaleConfigurator
    Dim tickModePrimaryY As Nevron.Chart.MajorTickMode
    Dim tickModeSecondaryY As Nevron.Chart.MajorTickMode

    axis = chart.Axis(Nevron.Chart.StandardAxis.PrimaryY)
    scaleConfigurator = DirectCast(axis.ScaleConfigurator, Nevron.Chart.NNumericScaleConfigurator)
    scaleConfigurator.CustomStep = 0.5
    scaleConfigurator.MajorTickMode = GetTickMode(axis)
    tickModePrimaryY = scaleConfigurator.MajorTickMode

    axis = chart.Axis(Nevron.Chart.StandardAxis.SecondaryY)
    scaleConfigurator = DirectCast(axis.ScaleConfigurator, Nevron.Chart.NNumericScaleConfigurator)
    scaleConfigurator.CustomStep = 25
    scaleConfigurator.MajorTickMode = GetTickMode(axis)
    tickModeSecondaryY = scaleConfigurator.MajorTickMode

    Static cnt As Integer : cnt += 1
    Dim message As String = System.String.Format("{0} UpdateTickMode: PrimaryY={1}, SecondaryY={2}", cnt.ToString("000"), tickModePrimaryY, tickModeSecondaryY)
    Me.Text = message
  End Sub
  Private Function GetTickMode(ByVal axis As Nevron.Chart.NAxis) As Nevron.Chart.MajorTickMode
    If (axis.PagingView.Enabled) Then
      Return Nevron.Chart.MajorTickMode.AutoMinDistance
    Else
      Return Nevron.Chart.MajorTickMode.CustomStep
    End If
  End Function

End Class



Nevron Support
Posted 8 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)

Group: Forum Members
Last Active: Last Year
Posts: 3,039, Visits: 3,746
Hi Lance,

You cannot modify the major tick mode in response to ruler range change event. This is because at the time when it is fired the axis is already configured and there is no way to skip a paint that has already commenced.

We just released a SP that allows you to install a custom step provider to the axis - the following code shows how to use the MajorTickMode.CustomStepProvider feature:

using System;
using System.Windows.Forms;
using Nevron.Chart;
using Nevron.Chart.Windows;
using Nevron.Collections;
using Nevron.Reflection;

namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public class CustomStepProvider : NNumericStepProvider
        {
            #region Constructors

            public CustomStepProvider(NAxis axis)
            {
                m_Axis = axis;

                NDoubleList steps = new NDoubleList();

                steps.Add(5);

                m_CustomStepProvider.Steps = steps;
            }

            #endregion

            #region Overrides


            public override void CalculateSteps(Nevron.GraphicsCore.NLengthConverter lengthConverter, Nevron.GraphicsCore.NRange1DD range, float length)
            {
                if (m_Axis.PagingView.Enabled)
                {
                    m_CustomStepProvider.CalculateSteps(lengthConverter, range, length);
                }
                else
                {
                    m_AutoStepProvider.CalculateSteps(lengthConverter, range, length);
                }               
            }

            public override Nevron.Collections.NDoubleList ProvideSteps()
            {
                if (m_Axis.PagingView.Enabled)
                {
                    return m_CustomStepProvider.ProvideSteps();
                }
                else
                {
                    return m_AutoStepProvider.ProvideSteps();
                }
            }

            public override object Clone()
            {
                CustomStepProvider newStepProvider = new CustomStepProvider(m_Axis);

                newStepProvider.m_AutoStepProvider = (NAutoNumericStepProvider)m_AutoStepProvider.Clone();
                newStepProvider.m_CustomStepProvider = (NCustomNumericStepProvider)m_CustomStepProvider.Clone();

                return newStepProvider;
            }

            #endregion

            #region Fields

            [NReferenceField]
            NAxis m_Axis;
            NAutoNumericStepProvider m_AutoStepProvider = new NAutoNumericStepProvider();
            NCustomNumericStepProvider m_CustomStepProvider = new NCustomNumericStepProvider();

            #endregion
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            NCartesianChart chart = (NCartesianChart)nChartControl1.Charts[0];

            NRangeSelection rs = new NRangeSelection();
            chart.RangeSelections.Add(rs);
           
            NBarSeries bar = new NBarSeries();

            chart.Series.Add(bar);

            for (int i = 0; i < 100; i++)
            {
                bar.Values.Add(i);
            }

            NLinearScaleConfigurator scaleY = (NLinearScaleConfigurator)chart.Axis(StandardAxis.PrimaryY).ScaleConfigurator;

            scaleY.MajorTickMode = MajorTickMode.CustomStepProvider;
            scaleY.CustomStepProvider = new CustomStepProvider(chart.Axis(StandardAxis.PrimaryY));

            nChartControl1.Controller.Tools.Add(new NPanelSelectorTool());
            nChartControl1.Controller.Tools.Add(new NDataZoomTool());
        }
    }
}

Hope this helps - let us know if you meet any problems or have any questions.


Best Regards,
Nevron Support Team



Lance Levendowski
Posted 8 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)

Group: Forum Members
Last Active: 6 days ago @ 1:19 PM
Posts: 59, Visits: 155
The custom step provider works great!  Thanks.




Similar Topics


Reading This Topic