12-24-2018 05:48 AM
Hi,
We are using VerticalIntensityChartCollection described in M19753 question.
Everything looks fine except we have to use ChartCollection<double, double> against double[] because we want to show calculated frequency values in X-Axis (for example our chart range between 750 MHz to 1250 MHz). When we use double[], graph range always starts from zero.
We are calculating frequency and amplitude values as double values with graph size and store them in a ChartCollection<double,double> and we want to use this collection to print VerticalIntensityGraph.
When we change double[] to ChartCollection<double,double> VerticalIntensityChartCollection's Append method has error.
How could we accomplish this,
Best Regards,
Hakan,
Solved! Go to Solution.
12-26-2018 10:01 AM
If you look at the example, you'll see that they use chart.Append( 0, new double[] ). Is this the part that is throwing you an error? If so, it might me because you're now using two doubles in ChartCollection so you'll need to pass two doubles into chart.Append instead of a double and an array of doubles.
12-26-2018 11:15 AM - edited 12-26-2018 11:16 AM
Since you did not share the error message, I cannot be certain of the problem, but I would suspect you were trying to treat the chart collection as an unordered data collection (e.g. appending (750, 1)
, (850, 2)
, …, (1250, 6)
, then back to (750, 7)
). The chart collection would raise an error here, because the append would break the ordering that the chart collection tries to enforce.
Looking at the wrapper collection for the other question, I was definitely concentrating on getting the implementation correct (using names consistent with chart terminology, rather than names that were meaningful for the problem), which makes it unclear what all the pieces are doing. If the X, Y, and Z values had been labeled directly, I expect you would have had an easier time of modifying the collection to suit your needs.
So, here is an updated version of the vertical intensity collection, with better names and new properties to control the X values:
using TX = System.Double; [DataTypeDescriptor( typeof( GraphDataCollectionDescriptor<> ) )] public sealed class VerticalIntensityChartCollection<TY, TZ> : IGraphDataCollection where TY : IComparable<TY> { private readonly ChartCollection<TY, TZ[]> _chartCollection; public VerticalIntensityChartCollection( int capacity ) { _chartCollection = new ChartCollection<TY, TZ[]>( capacity ); XStart = 0.0; XIncrement = 1.0; } public TX XStart { get; set; } public TX XIncrement { get; set; } public int Count { get { return DataCollection.Count; } } public Sample<TY, TZ[]> this[int index] { get { return _chartCollection[index]; } } public void Append( TY y, TZ[] zArray ) { _chartCollection.Append( y, zArray ); } #region IGraphDataCollection Members private static readonly ReadOnlyCollection<Type> _dataTypes = new ReadOnlyCollection<Type>( new[] { typeof( TX ), typeof( TY ), typeof( TZ ) } ); 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. using( var buffers = DataCollection.GetDataBuffers( decomposeOption ) ) { var yData = (Buffer<TY>)buffers[0]; var zData = (Buffer<TZ[]>)buffers[1]; int size = yData.Size; var xValues = new Buffer<TX>[size]; var yValues = new Buffer<TY>[size]; var zValues = new Buffer<TZ>[size]; for( int i = 0; i < size; ++i ) { TZ[] zArray = zData[i]; xValues[i] = SequenceBufferPool.CreateIntervalBuffer( zArray.Length, Unit.None, XStart, XIncrement ); yValues[i] = SequenceBufferPool.CreateConstantBuffer( zArray.Length, Unit.None, yData[i] ); zValues[i] = BufferPool.Default.GetBuffer( zArray, Unit.None ); } using(new BufferCollection(xValues.Concat<IBuffer>(yValues).Concat(zValues))) { var expandedBuffers = new BufferCollection( BufferPool.Join( xValues, Unit.None ), BufferPool.Join( yValues, Unit.None ), BufferPool.Join( zValues, Unit.None ) ); if( MarkIndexData ?? true ) expandedBuffers[0].Traits.Add( IndexBufferTrait.Instance ); return expandedBuffers; } } } void IGraphDataCollection.LoadDataBuffers( IList<IBuffer> dimensionValues ) { throw new NotSupportedException( ); } #endregion }
And here is the updated usage example, with corrected variable names:
public partial class MainWindow : Window { private const double YIncrement = 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.XStart = 750.0; chart.XIncrement = 100.0; chart.Append( 0, new double[0] );
// Tell graph about data, and intervals. xAxis.MajorDivisions = new RangeLabeledDivisions { Mode = RangeDivisionsMode.CreateIntervalMode( chart.XStart, chart.XIncrement ) };
graph.DefaultHorizontalInterval = chart.XIncrement; graph.DefaultVerticalInterval = YIncrement; 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 y = previous.Index + YIncrement; int length = 6; double[] z = Enumerable.Repeat( y * 2.0, length ).Select( ( v, i ) => v + i ).ToArray( ); chart.Append( y, z ); } }
12-28-2018 06:54 AM
Thanks Paul ,
Its working, You are the best!
Hakan,