Reputation: 100
I'm trying to implement a chart that can handle real time data, which comes in every 1 ms. I poll for 50ms of data so that I'm not trying to redraw the screen every single ms. I am using a PathGeometry on a Canvas to add line segments. I always see the framerate steadily tick downwards, as the redraws grow slower and slower. I did not think that a Line with roughly 10,000 points would be so difficult for my computer to render. Is there something I'm doing wrong? Or is there some other design philosophy that may be more adept at handling real time data in WPF?
In the ViewModel I have:
public PointCollection LinePoints;
In the View I listen to this collection being changed and add line segments:
_viewModel.LinePoints.Changed += LinePoints_Changed;
void LinePoints_Changed(object sender, System.EventArgs e)
{
while (_viewModel.LinePoints.Count - 1 > pathFigure.Segments.Count)
{
// pathFigure is part of the PathGeometry on my canvas
pathFigure.Segments.Add(new LineSegment(_viewModel.LinePoints[pathFigure.Segments.Count], true));
}
}
For simulation purposes I am injecting points using a BackgroundWorker:
void addPointsWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
DateTime startTime = DateTime.Now;
int numPointsAdded = 0;
while (!bw.CancellationPending && (DateTime.Now - startTime).Seconds < 10)
{
List<Point> points = new List<Point>();
for (int i = 0; i < 50; i++)
{
Math.Sin(numPointsAdded++/(500*Math.PI))));
}
System.Threading.Thread.Sleep(50);
bw.ReportProgress(0, points);
}
}
public void addPointsWorker_ProgressChanged(List<Point> pointsToAdd)
{
foreach(Point point in pointsToAdd)
{
// triggers CollectionChanged which will add the line segments
ViewModel.LinePoints.Add(point);
}
}
Along with slowdown I also experience UI unresponsiveness. I figured it's because I'm making too many ReportProgress calls and filling up the message pump, but if I could resolve the slow rendering I think this other issue would go away as well. I am open to any suggestions!
Upvotes: 1
Views: 1694
Reputation: 100
After a bit of time tweaking things, I've found that Charlie's is the best solution. I also discovered that instead of using a LineSegment every time a point is added, using a PolyLineSegment with the 50 or so points of data I'm already queuing up does wonders for performance.
However, it doesn't delay the inevitable slowdown that occurs. But using a combination of PolyLineSegment with only the last several hundred or even thousand points has given me the best performance while showing the most amount of data possible.
Upvotes: 0
Reputation: 15247
I have two suggestions:
Upvotes: 2