Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Binding the graph to data object causing out of memory

Solved!
Go to solution

Hi,

I want to create a WPF application that uses Measurement Studio to display the points of the measurements on the graph.

 

We have already implemented a HAL that reports the data to the UI (after doing some manipulations), using the DAQmx.

 

I saw in your examples that you display only points of the last second, but my users can choose to see data of one hour, and if I keep in memory data of points for the last hour I get out of memory (the data object become very big).

 

How can I show in the graph data of the last X minutes / hours without keeping all the data in memory?

 

0 Kudos
Message 1 of 12
(6,281 Views)

The short answer is this will require a custom data type that references data on disk and only loads a subset into memory as needed. To implement this, you will need a descriptor (similar to the WPF binding to object question) that uses a RawDataStore<TData> referencing the custom data.

 

It would be good to know what type of data you are collection (e.g. double[]? AnalogWaveform<double> with precision timing?). It would also be good to verify that the graph is the only source of memory pressure (i.e. if you remove the data assignment to the graph, does that completely remove the out-of-memory exception?).

~ Paul H
0 Kudos
Message 2 of 12
(6,254 Views)

Hi Paul,

I played with your example of WPF project called DaqGraph which I found in the documentation.

I change the logic so the waveform will append data and not assigned to new data each time, then I saw that after some seconds the application hangs.

If I just append the data to the AnalogWaveForm without binding to the graph it seems to be ok.

 

I tried to do the same in my project but the graph doesn't display anything. The data source is being filled with points but nothing is shown.

 I attached the view and view model of the graph, can you see what is the problem ?

 

I didn't dind any example of WPF projects that shows how to use the graph features , I would really appriciate if you can point me to such examples.

Thanks.

0 Kudos
Message 3 of 12
(6,229 Views)

For WPF examples, they are installed under the \Documents\National Instruments\MStudio\DotNET\Examples\WPF\ directory (there should be a link to the root examples directory in the start menu).



Regarding the "graph doesn't display anything" issue, I see two potential problems in DataViewModel:


  • In HandleDaqControlConfigured, you create a new _channelsData array (which is fine), but you do not call RaisePropertyChanged after you have initialized the array, so WPF will not know to update any bindings involving the ChannelsData property.
  • In HandleDaqControlStoppedMeasuring, you are assigning a new waveform to the existing _channelsData array. Arrays do not provide change notifications, so there is no way for the graph to automatically know that new data has been assigned.

In the first case, if you add ChannelsData = _channelsData; at the end of HandleDaqControlConfigured, that should raise the property change event. In the second case, there are a few options: you can manually call Refresh to tell the graph to re-examine the contents of the array; you can create a new array instance containing the new waveforms and assign it to ChannelsData; or you could change from an array to a collection that supports change notifications, like ObservableCollection<AnalogWaveform<double>>.



Once the graph has access to the waveforms in the collection, calling Append on the waveforms should be enough to update the graph. Note that Append is just going to naively grow the waveform in memory every time you call it, without limit. Another option would be to use a ChartCollectionAnalogWaveform<double>, which involves fewer copies and can be scoped to a fixed capacity.

~ Paul H
0 Kudos
Message 4 of 12
(6,220 Views)

Thanks Paul, your seggestions solvedthe display issues.

 

I have another issue with the timing. The ticks in x axis looks like random date times, I don't understand how the timing in AnalogWaveform works.

 

To overcome the memory issue, I'mgoing to ask the user to define window size of the last X minutes, and I'll show data only of this time range (Now - x min).

 

How do you suggest to imlement the Data object in this case? does ChartCollectionAnalogWaveform<double> fit here?

 

I need to keep in the Data only the samples of the last X minutes. I can calculate the amount of all samples affront.

 

Regarding the examples:

1. It's not intuitive to search for a feature there. Let's say now I need to implement changing visibility of specific waveform (keep saving samples of it, but choose to display / not display in graph), how can I find such thing in the examples?

2. It would be very helpful if there was a documentation of all features of the graph, then I can decide to add feature to my project that I didn't think about in first place.

 

Thanks.

 

 

0 Kudos
Message 5 of 12
(6,214 Views)

Looking at the HandleDataReport method in DataViewModel, it looks like you are doing a multi-sample read from DAQ and then manually applying timing to the waveforms. Your call to WaveformTiming.CreateWithRegularInterval looks correct, although your _increment sample rate of one second seems like it might be low. At the very least, I would expect the first time stamp shown in the axis to display correctly (the result will be offset by _increment * sample count).


Similarly for your window size, this just depends on the time and your sample rate. For example, if you were acquiring ten samples per second (increment = 0.1s), and you wanted a window of two minutes, you would set the Capacity of your chart collections to 10 * 2 * 60 samples.


We have general feature documentation in the WPF Graph Controls Overview topic, and in the WPF section of the Getting Started Guide. Does that match the kind of feature list you are looking for?

~ Paul H
0 Kudos
Message 6 of 12
(6,209 Views)

I managed to fix the timing issue while using  AnalogWaveform<double>[].

 

But I now changed to ChartCollectionAnalogWaveform<double>[] and the timing is a mess again.

 

Can you show me an example hou I supposed to define the timing when appending new wavefrom to ChartCollectionAnalogWaveform ?

 

I create each ChartCollectionAnalogWaveform only once and when data is reported I append new waveform to each  ChartCollectionAnalogWaveform .

0 Kudos
Message 7 of 12
(6,195 Views)

Working on an example, I found that using a waveform chart collection caused the axis to display the time in seconds (i.e. "6.36e10" for all the labels), while using the waveforms directly showed the time stamp. I assume this is the timing mess you were referring to? This appears to be an issue with how the chart is providing data to the graph. I have create a task to correct this issue for the next Measurement Studio release.


As a workaround, you can explicitly provide the waveform start time to the graph with a custom axis:


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

        object ISourceDataProvider.TryGetSourceDataStart( ) {
            return this.StartTime;
        }
    }


When you initialze _startTime in your code, also set the StartTime property on the custom axis. (I used a .NET property for simplicity, but you could make it a dependency property and bind it to your view model instead.)

~ Paul H
0 Kudos
Message 8 of 12
(6,191 Views)

Thanks Paul,

There is a progress, I used the work-around that you suggested and it seems working, I see the x axis timing which progress each 1 sec.

 

But the displayed date time is wrong. the time is like one hour earlier thean should be and the day is somthing in year 4031.

 

When I debug the code I see that I set the right datetime to each waveform and not the one that displayed.

 

I attached my files, is it my bug or yours?

 

I appriciate your help.

 

0 Kudos
Message 9 of 12
(6,178 Views)
Solution
Accepted by topic author Dudiamar

Sorry, that was my fault (the years were faulty in my local test as well, I just hadn't noticed). Luckily, this makes the workaround even simpler: the CustomXAxis implementation can change to just object ISourceDataProvider.TryGetSourceDataStart() { return default(DateTime); }.


Also, for future reference: for property changes in WPF, you need either a dependency property or INotifyPropertyChanged, but not both (i.e. you didn't need OnStartTimePropertyChanged in CustomXAxis).

~ Paul H
0 Kudos
Message 10 of 12
(6,168 Views)