Support for double.NaN's

Sep 15, 2009 at 10:32 PM

When plotting some data with NaNs I was having some display issues. This is the code I used to draw only values that are not double.NaN. The NaNs appear as a break in the linegraph. 

 

I put this code in the LineGraph class:

 

 

protected override void OnRenderCore(DrawingContext dc, RenderState state)
{
if (DataSource == null) return;
if (filteredPoints.HasPoints)
{
                if (IsTranslated)
         dc.PushTransform(new TranslateTransform(Offset.X, Offset.Y));
                
                using (StreamGeometryContext context = streamGeometry.Open())
                {
                    Point lastPoint = new Point(0, double.NaN);
                    foreach (var point in filteredPoints)
                    {
                        if(!double.IsNaN(point.Y) && double.IsNaN(lastPoint.Y))
                            context.BeginFigure(point, false, false);
                        else if(!double.IsNaN(point.Y))
                            context.LineTo(point, true, true);
                        lastPoint = point;
                    }
                }
                dc.DrawGeometry(null, LinePen, streamGeometry);
                if (IsTranslated)
   dc.Pop();
}
}

protected override void OnRenderCore(DrawingContext dc, RenderState state)

{

if (DataSource == null) return;

 

if (filteredPoints.HasPoints)

{

                 if (IsTranslated)

         dc.PushTransform(new TranslateTransform(Offset.X, Offset.Y));

 

                 using (StreamGeometryContext context = streamGeometry.Open())

                 {

                     Point lastPoint = new Point(0, double.NaN);

                     foreach (var point in filteredPoints)

                     {

                         if(!double.IsNaN(point.Y) && double.IsNaN(lastPoint.Y))

                             context.BeginFigure(point, false, false);

 

                         else if(!double.IsNaN(point.Y))

                             context.LineTo(point, true, true);

 

                        lastPoint = point;

                     }

                 }

 

                 dc.DrawGeometry(null, LinePen, streamGeometry);

 

                if (IsTranslated)

   dc.Pop();

}

}

 

Just thought I would post incase anyone else wanted something like this. 

 

Editor
Oct 14, 2009 at 4:23 PM

Rather good solution, though this can be performed by filters, which will return only those points which coordinates are not NaNs, and also these filters should support line breaks. This feature is included in our plans.

Mikhail.

Feb 19, 2010 at 12:40 PM

Hi Mikhail,

I'm getting completely blank charts when I have NaNs in my data source.

After reading this thread, I created a Filter to display only points that are not NaN, but I still have the same results (blank chart).

I also tried Kells solution with no success.

It seems that something happens before the filter, because the filter is called and it seems to work (I checked with unit tests and debug). I also noticed that "FilteredPoints.HasPoints" is returning false on the OnRenderCore of LineGraph class.

Here is my filter:

 

public class NanFilter : PointsFilterBase {
	public override List<Point> Filter(List<Point> points) {
		return points.Where(point => !point.X.Equals(Double.NaN) && !point.Y.Equals(Double.NaN)).ToList();
	}
}

I'm using this solution to bind the LineGraphs to the ChartPlotter: http://dynamicdatadisplay.codeplex.com/Thread/View.aspx?ThreadId=78607

Any thoughts?

Cheers,

André Carlucci

 

May 27, 2010 at 6:29 AM

To make Kells solution work on the current builds, you also need to change the static method GetViewportBounds in the BoundsHelper class.

GetViewportBounds doesn't check if X & Y values are NaN before doing its min/max calculation.

 

 

foreach (Point p in viewportPoints)
{	
	if (!Double.IsNaN(p.X))  // Check added by GHD
	{
		xMin = Math.Min(xMin, p.X);
                xMax = Math.Max(xMax, p.X);
	}
	if (!Double.IsNaN(p.Y))  // Check added by GHD
	{
		yMin = Math.Min(yMin, p.Y);
        	yMax = Math.Max(yMax, p.Y);
        }
}