Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Intensity Graph Continious YAxis

Solved!
Go to solution

Hi, 

We have an asynchronous method  that produces Frequency data and plotting then in a GraphControl.

We want to split window and show another Intensity graph with same data changing over time.

Our intensity graphs XAxis  is Frequency and YAxis is Time (TimeSpan or some round trip count) and color scale contains amplitude values.

 I found this question M18436. its similar to my request .

How do we configure this example code to scroll (flow) YAxis over time?

 

Best Regards,

Muhammed,

0 Kudos
Message 1 of 6
(3,160 Views)
Solution
Accepted by topic author clsmd

M18436 is the most appropriate example. Unfortunately, the graphs and data collections do not currently have any built-in configuration support for vertical scroll/history. However, you can use a custom data collection to achieve that effect:

 

[DataTypeDescriptor( typeof( GraphDataCollectionDescriptor<> ) )]
public sealed class VerticalIntensityChartCollection<TIndex, TSample> : IGraphDataCollection
    where TIndex : IComparable<TIndex> {

    private readonly ChartCollection<TIndex, TSample[]> _chartCollection;

    public VerticalIntensityChartCollection( int capacity ) {
        _chartCollection = new ChartCollection<TIndex, TSample[]>( capacity );
    }

    public int Count { get { return DataCollection.Count; } }

    public Sample<TIndex, TSample[]> this[int index] { get { return _chartCollection[index]; } }

    public void Append( TIndex index, TSample[] value ) { _chartCollection.Append( index, value ); }


    #region IGraphDataCollection Members

    private static readonly ReadOnlyCollection<Type> _dataTypes
                      = new ReadOnlyCollection<Type>( new[] { typeof( int ), typeof( TIndex ), typeof( TSample ) } );

    private IGraphDataCollection DataCollection { get { return _chartCollection; } }


    public bool? MarkIndexData {
        get { return DataCollection.MarkIndexData; }
        set { DataCollection.MarkIndexData = value; }
    }

    event EventHandler<GraphCollectionChangedEventArgs> IGraphDataCollection.DataChanged {
        add { DataCollection.DataChanged += value; }
        remove { DataCollection.DataChanged -= value; }
    }

    ReadOnlyCollection<Type> IGraphDataCollection.GetDataTypes( ) { return _dataTypes; }

    BufferCollection IGraphDataCollection.GetDataBuffers( Trait decomposeOption ) {
        // Expand and re-order the buffers from the chart collection, so that we produce intensity data with the form:
        // - array indices (0,1,2,..., for each array)
        // - chart indices (TIndex, repeated for each array)
        // - array data (the TSample[] values in each array)
        using( var buffers = DataCollection.GetDataBuffers( decomposeOption ) ) {
            var indexData = (Buffer<TIndex>)buffers[0];
            var arrayData = (Buffer<TSample[]>)buffers[1];

            int size = indexData.Size;
            var arrayIndexBuffers = new Buffer<int>[size];
            var chartIndexBuffers = new Buffer<TIndex>[size];
            var arrayDataBuffers = new Buffer<TSample>[size];
            for( int i = 0; i < size; ++i ) {
                TSample[] array = arrayData[i];
                arrayIndexBuffers[i] = SequenceBufferPool.CreateIntervalBuffer( array.Length, Unit.None, 0, 1 );
                chartIndexBuffers[i] = SequenceBufferPool.CreateConstantBuffer( array.Length, Unit.None, indexData[i] );
                arrayDataBuffers[i] = BufferPool.Default.GetBuffer( array, Unit.None );
            }

            using(new BufferCollection(arrayIndexBuffers.Concat<IBuffer>(chartIndexBuffers).Concat(arrayDataBuffers))) {
                var expandedBuffers = new BufferCollection(
                    BufferPool.Join( arrayIndexBuffers, Unit.None ),
                    BufferPool.Join( chartIndexBuffers, Unit.None ),
                    BufferPool.Join( arrayDataBuffers, Unit.None ) );

                if( MarkIndexData ?? true )
                    expandedBuffers[0].Traits.Add( IndexBufferTrait.Instance ); 

                return expandedBuffers;
            }
        }
    }

    void IGraphDataCollection.LoadDataBuffers( IList<IBuffer> dimensionValues ) { throw new NotSupportedException( ); }

    #endregion

}

Extending the example from M18436, you can use the collection this way:

 

public partial class MainWindow : Window {
    private const double Interval = 0.2;
    private readonly DispatcherTimer timer;
    private readonly VerticalIntensityChartCollection<double, double> chart
               = new VerticalIntensityChartCollection<double, double>( capacity: 25 );

    public MainWindow( ) {
        InitializeComponent( );

        // Initialize chart with data.
        chart.Append( 0, new double[0] );

        // Tell graph about data, and interval.
        graph.DefaultVerticalInterval = Interval;
        graph.DataSource = chart;

        // Use a timer to update chart data.
        timer = new DispatcherTimer( TimeSpan.FromSeconds( 0.1 ), DispatcherPriority.Normal, OnTimerTick, Dispatcher );
    }

    private void OnTimerTick( object sender, EventArgs e ) {
        // Add a new set of data after the previous point.
        var previous = chart[chart.Count - 1];
        double x = previous.Index + Interval;
        int length = 3;
        double[] y = Enumerable.Repeat( x * 2.0, length ).Select( ( v, i ) => v + i ).ToArray( );
        chart.Append( x, y );
    }
}

 

(Note that this simplified implementation does require every appended array to use the same length.)

~ Paul H
Message 2 of 6
(3,130 Views)

Thank you Paul,

 

You are the best.

 

Muhammed.

0 Kudos
Message 3 of 6
(3,121 Views)

Hi Paul,

This is work properly. 

We are working with MVVM pattern but we can't use binding method for VerticalIntenstyChartCollection.

When we define chart inside view model and bind it to Intensity Graph we get the attached error.

How  to bind VerticalIntenstyChartCollection to graph?

 

Thank you very much,

Muhammed,

 

 

0 Kudos
Message 4 of 6
(3,105 Views)
Solution
Accepted by topic author clsmd

From the code I can see in the screenshot, it appears you have everything setup correctly on the graph side. I cannot see the definition of the chart type in that screenshot: does it still have the DataTypeDescriptor attribute at the top?

~ Paul H
0 Kudos
Message 5 of 6
(3,099 Views)

Thanks Paul.

We added DataTypeDescriptor and its working.

Our mistake .

 

 

0 Kudos
Message 6 of 6
(3,088 Views)