Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF graph - show multiple plots with same x axis, each plot has own y axis.

Solved!
Go to solution

Hi,

I use WPF graph from MS2015. I want to add plots to the graph programatically, the x axis ahould be synchronized for all plots but the y axis is different (according to the plot scale).

I attached an example.

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

The graph does not support a configuration option for the kind of scale stacking shown in your image (you can show scales on different sides of a graph using Location, but you can't show two different vertical scales in the same "column" on one side of a graph). To achieve that exact effect, you can use multiple graphs instead of multiple plots, with a binding between the Range of each horizontal axis.


If your vertical ranges have the same magnitude, then that is all you would need to do. If your vertical ranges differ significantly though, the plot area of each graph would not align without some additional work to adjust the margin.

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

I'm trying to do that with multiple graphs.

 

I want that only the x axis of the graph in the bottom will be visible. I tried this code in the seconf graph to try hiding the lables, but I till see lables of some divisions in the second graph:

<ni:Graph.Axes>

<chart:CustomXAxis x:Name="Graph1XScale" Orientation="Horizontal" Adjuster="FitVisibleExactly" >

<chart:CustomXAxis.MajorDivisions>

<ni:RangeLabeledDivisions LabelPresenter=""/>

</chart:CustomXAxis.MajorDivisions>

 

I attached a print screen.

Thanks.

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

No need to hide the individual elements; just set the Visibility of your custom X axis to Collapsed.

~ Paul H
0 Kudos
Message 4 of 12
(6,510 Views)
Didn't think on that 🙂 Now it works fine, also the binding of all X axis to the lowest graph range. Thanks!!
0 Kudos
Message 5 of 12
(6,492 Views)

I'm trying to implement RangeCursor that will apear only in the graph in the bottom but will RetrieveValues of plots from the other graphs.

There is an exception if I try to do RetrieveValues of plot not from the parent graph.

 

I guess I need to add RangeCursor also for the rest of the graphs and set it to be invisible, and do RetrieveValues for each RangeCursor . Is there a way to bind the range of RangeCursor  to other RangeCursor ?

 

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

First, to answer your binding question, you can bind the HorizontalRange of your hidden cursors to the ActualHorizontalRange of the main cursor.


However, RetrieveValues is just a convenience method for the FindValues method on the graph. Since you have the horizontal ranges aligned, you can call otherGraph.FindValues( otherPlot, cursor.ActualHorizontalRange, null, true ) to get the values in the other graphs.

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

The  otherGraph.FindValues( otherPlot, cursor.ActualHorizontalRange, null, true ) sounds like a better solution, thanks for the advice.

 

It works for me except one thing.

 

In case that the DataSource of the graphs being updated (appending new sampels to the collection) the other graphs that the Range of their x axis is binded to the Range of the main graph x axis return array with no y values (only x values returned) when calling to otherGraph.FindValues .

If I pause the appending of sampels it works fine.

 

It make sense that user will pause the sampeling when playing with the RangeCursor but if he didn't do that he won't understand what is going on.

 

 

0 Kudos
Message 8 of 12
(6,427 Views)

Based just on your description, it's not clear to me what order data updates/synchronization/queries are taking place. If you could share an example that reproduces the issue, it would be easier to determine where the problem is occuring.

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

I have one RangeCursor that is child of the main graph.

I subscribe:

rangeCursor.PositionChanged += rangeCursor_PositionChanged

 

Inside the handler I call to:

public static void SendPlotsData(RangeCursor rangeCursor, Graph[] graphs)

{

...

...

foreach (var graph in graphs.Where(graph => graph != null))

{

for (int i = 0; i < graph.AllPlots.Count; i++)

{

var values = graph.FindValues(graph.AllPlots[i], rangeCursor.ActualHorizontalRange, null, true);

if (values.Count < 2)

{

 

return;

}

var yValues = (Buffer<double>)values[1];

...

...

 

The DataSource of the graphs updated every second with new samples.

If I show the RangeCursor and the DataSource being updated (appending new sampels to the ChartCollectionAnalogWaveform) so  the handler rangeCursor_PositionChanged is being called (even that I didn't move the cursor).

In this case the graph.FindValues of otherr graphs return only x values.

The problem occures when the handler rangeCursor_PositionChanged  is raised due to DataSource update, If I move the cursors with the mouse (and so trigger rangeCursor_PositionChanged) it works ok.

 

 

 

 

0 Kudos
Message 10 of 12
(6,403 Views)