Pre loader

NaN values in CustomRenderableSeries

Welcome to the SciChart Forums!

  • Please read our Question Asking Guidelines for how to format a good question
  • Some reputation is required to post answers. Get up-voted to avoid the spam filter!
  • We welcome community answers and upvotes. Every Q&A improves SciChart for everyone

WPF Forums | JavaScript Forums | Android Forums | iOS Forums

0
0

Hi All,

I have a linear graph which represents a measure in real time (I have a loop that gets a value at each iteration). I have a FastLineRenderableSeries with a DataSeries in which I append x and y vector. The y vector is full of Double.NaN values, and it is updated with valid values at each loop iteration. During the representation, I can only see valid values, and NaN values are not represented. Everything ok.

But now I have changed from FastLineRenderableSeries to CustomRenderableSeries (due to markers and other issues), and I have a strange effect on real time visualization (see attached picture). It seems that NaN values are represented as infinite, so I can see a vertical line at last real value.

I have set DrawNaNAs = LineDrawMode.Gaps but it doesn’t work. Am I doing something wrong? Is there something extra I have to set regarding CustomRenderableSeries?

Thanks in advance

Images
  • You must to post comments
0
0

Hi Manuel,

If you’ve switched to CustomRenderableSeries you’ll have to handle the NaNs yourself and start/stop the line segment. For example, taking the sample in our CustomRenderableSeries documentation and modifying it:

public class CustomRenderableSeriesSample : CustomRenderableSeries
{
    protected override void Draw(IRenderContext2D renderContext, IRenderPassData renderPassData)
    {
        base.Draw(renderContext, renderPassData);

        // The resampled data for this render pass
        var dataPointSeries = renderPassData.PointSeries as Point2DSeries;

        if (dataPointSeries == null) return;

        var xCalc = renderPassData.XCoordinateCalculator;
        var yCalc = renderPassData.XCoordinateCalculator;

        using (var pen = renderContext.CreatePen(Stroke, AntiAliasing, 1.0f))
        {
            IPathDrawingContext lineContext = null;

            // Iterate over the point series
            for (int i = 0; i < dataPointSeries.Count; i++)
            {                    
                // Get the X,Y value
                var x = dataPointSeries.XValues[i];
                var y = dataPointSeries.YValues[i];

                // This is a quick check for Y=NaN 
                // 
                // ReSharper disable once EqualExpressionComparison
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (y != y)
                {
                    // End the line segment if started 
                    if (lineContext != null)
                    {
                           lineContext.End();
                           lineContext = null;
                    }

                    // Skip to next point
                    continue;
                }

                // Transform to coordinate
                var xCoord = xCalc.GetCoordinate(x);
                var yCoord = yCalc.GetCoordinate(y);

                if (lineContext == null)
                {
                    // Start the line segment if not started 
                    lineContext = renderContext.BeginLine(pen, xCoord, yCoord);
                    continue;
                }

                // Move to next line X,Y
                lineContext.MoveTo(xCoord, yCoord);                    
            }

            if (lineContext != null)
            {
                lineContext.End();
                lineContext = null;
            }
        }
    }
}

Something like that.

I have to confess, I haven’t tested this code, I have just knocked it up from memory, because SciChart’s inner routines for this sort of thing are quite complex and too much to paste here.

Let me know if it works. If you modify it, do post the modification and I can update my solution!

By the way, is there a reason the built in series cannot handle what you want?

Best regards,
Andrew

  • You must to post comments
0
0

Hi Andrew,

I’ll try it, and if it works, I’ll let you know

Regards

  • You must to post comments
1
0

Hi again Andrew,

It works! Thank you very much for the solution

This is my “Draw” method:

        protected override void Draw(IRenderContext2D renderContext, IRenderPassData renderPassData)
    {
        this.mRenderContext = renderContext;

        base.Draw(renderContext, renderPassData);

        if (renderPassData.PointSeries.Count == 0) return;

        // Create a pen to draw the spline line. Make sure you dispose it!             
        using (var linePen = renderContext.CreatePen(this.SeriesColor, this.AntiAliasing, this.StrokeThickness))
        {
            // Create a line drawing context.
            IPathDrawingContext lineDrawingContext = null;

            for (int i = 0; i < renderPassData.PointSeries.Count; i++)
            {
                //Get x and y coordinates
                var point = GetCoordinatesFor(renderPassData.PointSeries[i].X, renderPassData.PointSeries[i].Y);

                //Check if y value is NaN
                if (point.Y.Equals(Double.NaN))
                {
                    if (lineDrawingContext != null)
                    {
                        lineDrawingContext.End();
                        lineDrawingContext = null;
                    }
                    continue;
                }

                //Begin line if linecontext is null
                if (lineDrawingContext == null)
                {
                    lineDrawingContext = renderContext.BeginLine(linePen, point.X, point.Y);
                    continue;
                }

                //Draw
                lineDrawingContext.MoveTo(point.X, point.Y);
            }

            if (lineDrawingContext != null)
            {
                lineDrawingContext.End();
                lineDrawingContext = null;
            }
        }

        //Draw markers
        for (int j = 0; j < this.xpos.Length; j++)
        {
            if (!this.xpos[j].Equals(Double.NaN)) this.DrawMarker(this.xpos[j], this.ypos[j]);
        }
    }

Best regards

  • You must to post comments
Showing 3 results
Your Answer

Please first to submit.

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies