From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF IntensityGraph explodes memory

Solved!
Go to solution

Hello, we have been using Measurement Studio for windows forms for a long time, but has recently started to use the WPF library. However, we now have a problem with the WPF version of the IntensityGraph. We are using it to display a real time version of a waterfall plot. Essentially the same code as used in M19753, however we have upscaled it such that we have a capacity of 2000 in each collection and a length of 2500 samples in each appended element. This to improve resolution. However, the result is that the memory explodes after a short while(> 2Gb), crashing the application. Doing the same plot using the windows form version of the IntensityGraph is no problem. We then set X and Y history to 2000 and 2500 and use the append function to add new elements to the graph. The memory usage is less than 100 Mb and code runs smoothly. What seems to be the problem here? Is it we that do something wrong or is it not possible to gain the same efficiency with the WPF version as with the append function in the windows forms version? If necessary I can provide simple code examples of both version to demonstrate issue.

Message 1 of 8
(3,277 Views)

Unfortunately, the current WPF graph implementation is optimized for horizontal chart data, and will not perform well as loads increase for vertical data (effectively, the graph ends up re-processing the entire collection on every append).

 

I have attached a simplified fixed-size intensity chart collection implementation. This has better memory performance than the code from M19753 when the collection Orientation is set to Vertical, but it is still far below the performance for Horizontal. It should be possible to create a chart collection that presents the data in a horizontal orientation for the graph, while appending new data vertically, but that would require a more sophisticated data storage implementation. (Also note that, because this collection implementation returns the underlying chart collection’s data buffer directly to the graph, you should set GraphConfiguration.UseBackgroundProcessingProperty to false.)

 

You may also want to try the fixed-rate chart collection from a similar question. Or, if the Windows Forms intensity graph meets your display needs, you may want to try hosting the Windows Forms in your WPF application.

~ Paul H
0 Kudos
Message 2 of 8
(3,140 Views)
Solution
Accepted by topic author OddvarC

@phansen wrote:

...It should be possible to create a chart collection that presents the data in a horizontal orientation for the graph, while appending new data vertically, but that would require a more sophisticated data storage implementation...


Here is an updated version of the fixed-size intensity chart collection, which does use the optimized index order for both horizontal and vertical Orientation values.

 

I hope this is a better fit for your application!

~ Paul H
Message 3 of 8
(3,095 Views)

Thanks, didn't see this post before now! Will try this immediately!

0 Kudos
Message 4 of 8
(3,016 Views)

Thanks Paul, this solved the problem! Memory is stable and the intensity chart updates smoothly. I can now drop the old windows forms chart 🙂

0 Kudos
Message 5 of 8
(2,992 Views)

Hi Paul, trying to get time along the X-axis. What would be the best way to achive this?

0 Kudos
Message 6 of 8
(2,927 Views)

(For future reference, to make sure your question is seen it would be best to create a new post with a link to an old one, rather than reply to one that is already marked resolved.)

 

There are two main approaches to changing the values displayed by the axis:

  • Supply a custom formatter to MajorDivisions.LabelPresenter (where you can format the division values however you like).
  • Use a custom axis that implements ISourceDataProvider (specifying a start value that will be applied to the divisions automatically).

The second approach is probably simpler for your needs (pulled from this answer😞

 

public class CustomAxis : AxisDouble, ISourceDataProvider {
    public DateTime? StartTime { get; set; }

    object ISourceDataProvider.TryGetSourceDataStart( ) => this.StartTime;
}

 

~ Paul H
0 Kudos
Message 7 of 8
(2,922 Views)

Thanks Paul, I'll try this! I'll remember to create a link next time 🙂

0 Kudos
Message 8 of 8
(2,898 Views)