views:

1800

answers:

6

I am writing WPF code to show a real-time plot which is a connected line containing about 10,000 points. It takes about 5 seconds to show a picture in my computer. Does anyone have an idea to make it quicker and within 0.5 second?

class eee : FrameworkElement
{

    public eee()
    {
        _children = new VisualCollection(this);
        Random rand = new Random();
        DrawingVisual dv = new DrawingVisual();
        using (DrawingContext dx = dv.RenderOpen())
        {
            Pen drawingPen = new Pen(Brushes.Black, 1);
            double x=rand.Next(300);
            double y = rand.Next(300);
            for (double i = 0; i < 1000; i = i + 0.1)
            {
                y = 100 + rand.Next(100);
                dx.DrawLine(drawingPen, new Point(i, x), new Point(i + 1, y));
                x = y;
            }
        }
         _children.Add(dv);
    }
+16  A: 

Charles Petzold does exactly that. It is even faster on my host (< 0.3 secs), and the point's are even DataBound!! ;)

Tamir Khason does this also, with lines and goes into more depth about Bitmap style performance WPF here.

Rico Mariani has some guidance for 3D high performance graphics, essentially leveraging value types can improve your throughput if well thought out.

Jianzhong Zhang gives my new favourate tutorials on this subject, 3D scatter plot several tens of thousands of data points animated and interactive.

RandomNickName42
A: 

Should the lines be selectable? You can draw lines in the image, then give it as a source to Image control. It will draw faster but you will lose ability to interact with lines.

ArsenMkrt
A: 

Have you considered XNA? Using a graphics card will speed up things.

Marcom
WPF uses hardware acceleration too.
romkyns
A: 

I guess the code sample is 1) a test to try a something that isn't really the sample or 2) a homework.

Try to override the OnRender and do something like:

Pen drawingPen = new Pen(Brushes.Black, 1);

protected override void OnRender(DrawingContext dc)
{
    dc.DrawRectangle(Background, null, new Rect(RenderSize));


            double x=rand.Next(300);
            double y = rand.Next(300);
            for (double i = 0; i < 1000; i = i + 0.1)
            {
                y = 100 + rand.Next(100);
                dc.DrawLine(drawingPen, new Point(i, x), new Point(i + 1, y));
                x = y;
            }


}

or for something with real data, consider if you really need to show every point depending on the resolution of the visual context. ( If your scale is 0-10 and you are producing points 0.0001,0.00015 are they really gone differ on your scale)

Jonke
A: 

Who can even see 10,000 points?

Can't you just show a representative sample? Or, if two points are close enough together, you only need to draw one of them.

ADDED: Another thing I do is render to a memory bitmap, and then copy that to the screen. That makes it look as if it's fast, and it may even be faster, because it's not applying clipping logic to each small line segment.

Mike Dunlavey
... and the reason for the drive-by?
Mike Dunlavey
10,000 points is not even that many for certain types of visualisation, e.g. where the density of the points communicates the information.
romkyns
@romkyns: OK, I can see that - 100x100. Still, as a matter of course, I render to a memory bitmap and then blt that to the window. Even if it's slow, it doesn't look slow.
Mike Dunlavey
A: 

Thanks a lot for those helpful responses. The linked articles really helped open my mind.

The test code is to simulate the real application, although two points may be close enough and difficult to distinguish, but the density of points can help the user know if the baseline noise is high or low. I tried to show only 1280 point in my screen, it does not look professional, so I would like to increase the sampling amount, of course not to more than 10,000.

Also it is better to be able to move the line up/down and scale. But if the speed is too low, then this function would be ignored.

You seem to have two accounts. Contact [email protected] to get them merged.
ChrisF