Nevron Forum

Marker on cursor

https://www.nevron.com/Forum/Topic4192.aspx

By Neil Rickards - Wednesday, September 15, 2010

Hi,

Can anyone recommend a good way to display the current position of a cursor? I can get the value easily enough, but would like to display it as a floating number near the axis that follows the cursor

Is this something that's possible?

Many thanks,
Neil
By Nevron Support - Wednesday, December 15, 2010

Hi Neil,

You can achieve this by using the custom values labels - the following code snippets shows a simple point with two dynamic cursors that display the current cursor value at its respective axis:

  private void Form1_Load(object sender, EventArgs e)
  {
   NCartesianChart chart = (NCartesianChart)nChartControl1.Charts[0];
   chart.Dock = DockStyle.Fill;
   chart.BoundsMode = BoundsMode.Stretch;
   chart.MinDockZoneMargins = new NMarginsL(45, 0, 0, 30);

   // sample data
   double[] pointYValues = new double[] { 10, 20, 30 };
   double[] pointXValues = new double[] { 10, 20, 30 };

   NPointSeries point = new NPointSeries();
   point.UseXValues = true;
   chart.Series.Add(point);

   for (int i = 0; i < pointYValues.Length; i++)
   {
    point.Values.Add(pointYValues[i]);
    point.XValues.Add(pointXValues[i]);
   } 

   NAxisCursor cursor1 = new NAxisCursor();
   cursor1.BeginEndAxis = (int)StandardAxis.PrimaryY;
   cursor1.SynchronizeOnMouseAction = MouseAction.Move;
   cursor1.ValueSnapper = new NAxisRulerClampSnapper();
   cursor1.ValueChanged += new EventHandler(cursor1_ValueChanged);
   chart.Axis(StandardAxis.PrimaryX).Cursors.Add(cursor1);

   NAxisCursor cursor2 = new NAxisCursor();
   cursor2.BeginEndAxis = (int)StandardAxis.PrimaryX;
   cursor2.SynchronizeOnMouseAction = MouseAction.Move;
   cursor2.ValueSnapper = new NAxisRulerClampSnapper();
   cursor2.ValueChanged += new EventHandler(cursor2_ValueChanged);
   chart.Axis(StandardAxis.PrimaryY).Cursors.Add(cursor2);

   nChartControl1.Controller.Tools.Add(new NSelectorTool());
   nChartControl1.Controller.Tools.Add(new NDataCursorTool());
  }

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

   NStandardScaleConfigurator scale = chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator as NStandardScaleConfigurator;
   scale.CustomLabels.Clear();

   NCustomValueLabel label = new NCustomValueLabel();
   label.Value = ((NAxisCursor)sender).Value;
   label.Text = label.Value.ToString("N2");
   scale.CustomLabels.Add(label);

   nChartControl1.Refresh();
  }

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

   NStandardScaleConfigurator scale = chart.Axis(StandardAxis.PrimaryY).ScaleConfigurator as NStandardScaleConfigurator;
   scale.CustomLabels.Clear();

   NCustomValueLabel label = new NCustomValueLabel();
   label.Value = ((NAxisCursor)sender).Value;
   label.Text = label.Value.ToString("N2");
   scale.CustomLabels.Add(label);

   nChartControl1.Refresh();
  }

Note that the left and bottom axis zones have fixed min width:

chart.MinDockZoneMargins = new NMarginsL(45, 0, 0, 30);

this is done to prevent the chart from bouncing off the edges when the cursor values change.

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

By Plamen Dimitrov - Wednesday, February 2, 2011

Guys,

Is it possible to achieve the same without drawing the crosshair added by the NDataCursorTool?

Thanks,
Plamen

By Nevron Support - Wednesday, February 2, 2011

Hi Plamen,

Yes - in this case you have to implement the following steps:

1. Intercept the mouse move event fired by the control.

2. Transform the passed view coordinates to scale coordinates.

The following code snippet shows how to achieve this:

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


   NBarSeries bar = new NBarSeries();

   bar.Values.Add(10);
   bar.Values.Add(20);
   bar.Values.Add(30);

   chart.Series.Add(bar);

   nChartControl1.MouseMove += new MouseEventHandler(nChartControl1_MouseMove);
  }

  void nChartControl1_MouseMove(object sender, MouseEventArgs e)
  {
   NHitTestResult result = nChartControl1.HitTest(e.X, e.Y);

   if (result.Chart != null)
   {
    NCartesianChart chart = (NCartesianChart)result.Chart;

    NStandardScaleConfigurator scale = chart.Axis(StandardAxis.PrimaryY).ScaleConfigurator as NStandardScaleConfigurator;
    scale.CustomLabels.Clear();

    NViewToScale2DTransformation transform = new NViewToScale2DTransformation(nChartControl1.View.Context, chart, (int)StandardAxis.PrimaryX, (int)StandardAxis.PrimaryY);
    NPointF point = new NPointF(e.X, e.Y);

    NVector2DD pointScale = new NVector2DD();

    transform.Transform(point, ref pointScale);

    NCustomValueLabel label = new NCustomValueLabel();
    label.Value = pointScale.Y;
    label.Text = label.Value.ToString("N2");
    scale.CustomLabels.Add(label);

    nChartControl1.Refresh();
   }
  }

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

By Plamen Dimitrov - Wednesday, February 2, 2011

I think I've figured it out - I looks like that the code below cures the issue.

NAxisCursor cursor = new NAxisCursor();
cursor.StrokeStyle = new NStrokeStyle(0);