Hi all,
I have a cursor implemented like the example from phansen (SqlDataExample.zip), but I don't seem to have quite understood, what exactly is happening there at some points. As recommended, I use an ObservableCollection of DataPoints[] as DataSource of my Graph, which are implemented as follows:
namespace HansDataAnalyzer { [DataTypeDescriptor( typeof( DataPointDescriptor ) )] public struct DataPoint { public const int PropertyCount = 3; // ID, tan_delta, U_rms public int ID { get; set; } public double U_scaled { get; set; } public double tan_delta { get; set; } public DataPoint(MeasurementValue value, double dividerFactor) : this() { this.ID = value.ID; this.U_scaled = value.U_rms * dividerFactor / 1000; //Anzeige in *10^(-3); this.tan_delta = value.tan_delta * 1000; } } public struct DataPointDescriptor : IOpMultiDimensional<DataPoint> { private static readonly ReadOnlyCollection<Type> _dimensionDataTypes = new ReadOnlyCollection<Type>( Enumerable.Repeat( typeof( double ), DataPoint.PropertyCount ).ToArray( ) ); public ReadOnlyCollection<Type> GetDimensionDataTypes( DataPoint value, Trait decomposeOption ) { throw new NotImplementedException( ); } public DataPoint GetDefaultValue( ) { return default( DataPoint ); } public IList<IBuffer> DecomposeValues( Buffer<DataPoint> values, Trait decomposeOption ) { int size = values.Size; double[] U_scaled = new double[size]; double[] tan_delta = new double[size]; int[] ID = new int[size]; for( int i = 0; i < size; ++i ) { DataPoint value = values[i]; U_scaled[i] = value.U_scaled; tan_delta[i] = value.tan_delta; ID[i] = value.ID; } return new IBuffer[] { // Dimensions rendered by graph are listed first. BufferPool.Default.GetBuffer(U_scaled, Unit.None), BufferPool.Default.GetBuffer(tan_delta, Unit.None), // Other values are saved by graph, and displayed by cursor. BufferPool.Default.GetBuffer(ID, Unit.None) }; } public Buffer<DataPoint> ComposeValues( IList<IBuffer> dimensionValues, Trait composeOption ) { throw new NotSupportedException( ); } } }
(Btw: Where does the Graph "know" from, which values of a DataPoint are plotted? As from the comment above (Dimensions rendered by graph are listed first) it seems clear, but if I maybe want to save more data in one point without displaying it in the cursor this will not work (Deleting the line "BufferPool.Default.GetBuffer(ID, Unit.None)" leads to plots where tan delta is plotted over ID but shown as U_scaled...))
The cursor with the XAML code:
<ni:Cursor Name="tandCursor" PositionChanged="tandCursor_PositionChanged">
<ni:Cursor.ValuePresenter>
<local:CustomValueFormatterGroup>
<ni:ValueFormatterGroup Separator="
">
<ni:GeneralValueFormatter Format="U_scaled={0:0.00} [kV]" />
<ni:GeneralValueFormatter Format="tan delta={0:0.00} [10⁻³]" />
<ni:GeneralValueFormatter Format="ID: {0}" />
</ni:ValueFormatterGroup>
</local:CustomValueFormatterGroup>
</ni:Cursor.ValuePresenter>
</ni:Cursor>
And the according implementation of the CustomValueFormatterGroup:
namespace HansDataAnalyzer { [ContentProperty( "Group" )] public class CustomValueFormatterGroup : ValuePresenter { public ValueFormatterGroup Group { get; set; } protected override UIElement VisualizeCore<TData>( TData value, ValuePresenterArgs args, UIElement existingVisual ) { var element = (TextBlock)Group.Visualize<TData>( value, args, existingVisual ); // Align numeric values on the right side of the cursor's value label. element.TextAlignment = TextAlignment.Right; return element; } protected override Freezable CreateInstanceCore( ) { return new CustomValueFormatterGroup( ); } } }
Every time the cursor is moved, I need to do some stuff with the ID "saved" in the according datapoint (Get the whole line out of a database with this ID and plot some data from there). My problem is: I don't know how I can access the "actual" datapoint from within my main window via e.g. the PositionChanged event, nor can I access any method of my window, when the CustomValueFormatterGroup is updated (?) via the VisualizeCore call.
(I can get the ID by splitting element.Text, but I do not understand, how I could pass this on to my main programme). I hope you can understand what I mean...
Any advice would be welcome, thanks!