NRangeSeries - Misplaced points on refresh


https://www.nevron.com/Forum/Topic9194.aspx
Print Topic | Close Window

By Joël Golinucci - 9 Years Ago
Hello,

I'm using sevral Nevron Charts on a Windows form to display stock of coal and here is a representation of when it works:
https://www.nevron.com/forum/uploads/images/7ca42ffa-534d-44a4-8b14-7406.png

The images arent really pretty because they contain lots of tests but for the purpose of this explaination it is good enough.
Every once and a while I refresh some of thoses graphs and for every graph refreshed I sometimes have something like that:
https://www.nevron.com/forum/uploads/images/63ff225e-e9d9-4c55-8dee-b2ff.png

Lots of misplaced points around the graph for no apparent reason.

Here is the code I use for refreshing (executed in separate threads, one for each graph):
  If fRangeSeries IsNot Nothing Then
    Dim ptList As List(Of tGraphPoint) = fDataStorage.GetCells(fSubPile, fCurrentPlotVariable, layer, grid, fLastUpdateDate)
    If ptList IsNot Nothing AndAlso ptList.Count > 0 Then fCurrentPointList = ptList

    If ptList IsNot Nothing AndAlso ptList.Count > 0 Then
    fChartControl.SuspendLayout()

    'If its a full refresh, we clear all points before because we might have changed the grid and receive less points as before
    If fLastUpdateDate = DateTime.MinValue Then
     fRangeSeries.Values.Clear()
     fRangeSeries.Y2Values.Clear()
     fRangeSeries.XValues.Clear()
     fRangeSeries.X2Values.Clear()
     fRangeSeries.ZValues.Clear()
     fRangeSeries.Z2Values.Clear()
    End If
    fLastUpdateDate = Now()

    For i As Integer = 0 To ptList.Count - 1
     Dim pt As tGraphPoint = ptList(i)

     'Nevron Y start - Depth (Z axis)
     If fRangeSeries.Values.Count > i Then
      fRangeSeries.Values(i) = pt.Z
     Else
      fRangeSeries.Values.Add(pt.Z)
     End If

     'Nevron Y end
     If fRangeSeries.Y2Values.Count > i Then
      fRangeSeries.Y2Values(i) = pt.Z + CDbl(fDataStorage.CellDimZ.Value)
     Else
      fRangeSeries.Y2Values.Add(pt.Z + CDbl(fDataStorage.CellDimZ.Value))
     End If

     'Nevron X start - Horizontal (X axis)
     If fRangeSeries.XValues.Count > i Then
      fRangeSeries.XValues(i) = pt.X
     Else
      fRangeSeries.XValues.Add(pt.X)
     End If

     'Nevron X end
     If fRangeSeries.X2Values.Count > i Then
      fRangeSeries.X2Values(i) = pt.X + CDbl(fDataStorage.CellDimX.Value) * grid.X
     Else
      fRangeSeries.X2Values.Add(pt.X + CDbl(fDataStorage.CellDimX.Value) * grid.X)
     End If

     'Nevron Z start - Vertical (Y axis)
     If fRangeSeries.ZValues.Count > i Then
      fRangeSeries.ZValues(i) = pt.Y
     Else
      fRangeSeries.ZValues.Add(pt.Y)
     End If

     'Nevron Z end
     If fRangeSeries.Z2Values.Count > i Then
      fRangeSeries.Z2Values(i) = pt.Y + CDbl(fDataStorage.CellDimY.Value) * grid.Y
     Else
      fRangeSeries.Z2Values.Add(pt.Y + CDbl(fDataStorage.CellDimY.Value) * grid.Y)
     End If

     'Quality value (color of the point)
      If fRangeSeries.FillStyles.Count > i Then
      Dim colorFill As NColorFillStyle = fRangeSeries.FillStyles(i)
      If colorFill IsNot Nothing Then colorFill.Color = fDataStorage.GetColorFromValue(fCurrentPlotVariable, pt.Value, pt.NaLimit)
     Else
      fRangeSeries.FillStyles.Add(i, New NColorFillStyle(fDataStorage.GetColorFromValue(fCurrentPlotVariable, pt.Value, pt.NaLimit)))
     End If
    Next

    End If
   End If

   fChartControl.ResumeLayout()
   fChartControl.Refresh()




Here is the type of the diffrent variable used:
Protected fChartControl As NChartControl
Protected fChart As NCartesianChart
Protected fRangeSeries As NRangeSeries


The series is created like this:
  fRangeSeries = New NRangeSeries()
  fRangeSeries.Name = String.Format("nRangeSeries_{0}", fSubPile.ToString())
  fRangeSeries.InflateMargins = False
  fRangeSeries.DataLabelStyle.Visible = False
  fRangeSeries.Legend.Mode = SeriesLegendMode.None
  fRangeSeries.BorderStyle.Width = New NLength(0)
  fRangeSeries.UseXValues = True

  fRangeSeries.UseZValues = True
  fRangeSeries.Shape = BarShape.Bar


Thank you very much for any help provided on this issue.

Best regards,
Joël

By Nevron Support - 9 Years Ago
Hi Joel,
This can be caused by multithreading - the control is not thread safe so you need to protect the state from being accessed from different threads - for example suppose that the control render at the time when you modify it. In order to synchronize access to the control state you can use the document Lock/Unlock methods:

nChartControl1.document.Lock();

// modify the chart state here if this code is executed from a different thread

nChartControl1.document.Unlock();

Other than that the problem may be related to incorrect data / incorrect feed of data - to check if this is the reason, simply always feed the whole data - if this fixes the problem then it is related to the code that updates the data partially.

Hope this - let us know if you meet any problems.


By Joël Golinucci - 9 Years Ago
Hi,

Thank you for your quick reply. I protected each access to a graph object with the suggested lock and it seems to work better for now on.

There was a thread by graph used for the data refresh, but I used other functions like hitTest on mouse move / mouse click on the graph and these where handled by the main thread of course. So maybe that was the reason,

Best regards,
Joël