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
- You must login to post comments
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
- Andrew Burnett-Thompson answered 8 years ago
- You must login to post comments
Hi Andrew,
I’ll try it, and if it works, I’ll let you know
Regards
- Jose Mora Almerich answered 8 years ago
- You must login to post comments
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
- Jose Mora Almerich answered 8 years ago
- You must login to post comments
Please login first to submit.