Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronized zoom between graphs

I need a way to put two graphs with scatter plots above each other and give them an XAxis that has the same range. Then I need to make sure that when one of they is zoomed, the others XZoom is automatically zoomed to match. The idea is to lock the XAxis together.

I tried using the same XAxis object on both graphs and get an exception.

I could not find a way to connect them in code.

So I looked at subscribing to the zoom event and getting info to set the other zoom. However, you don't really get the right information.

Does anyone have any idea how to do this?

Mike
0 Kudos
Message 1 of 13
(6,883 Views)
Mike,

Using the event callbacks is the right course of action.  However, you may get better results if you capture the XAxisRangeChanged and YAxisRangeChanged events.  I am attaching a Visual C# example that demonstrates the difference between capturing the Zoom event and the RangeChanged events.

Please let me know if you have any questions.

Tyler Tigue
Applications Engineer
National Instruments
Message 2 of 13
(6,873 Views)
Do you have any hints on how to handle unzoom? For example, if there are two graphs and you zoom #1 and sync up #2, there is no way to unzoom from #2? Or will the fact that I changed the ranges on #2 add the info to its unzoom stack? And even if it did, then when I did an unzoom on #2, it would change the range of #1 and it would add to its unzoom stack, etc

I think I can make the zooms synchronize, but I fail to see how unzoom could work.

Any hints on unzoom?
0 Kudos
Message 3 of 13
(6,858 Views)
Tyler I tried your example and it's great. I would be interested in finding out how to zoom out also. Any hints?
0 Kudos
Message 4 of 13
(6,832 Views)
Mike and Katy,

Make sure that the switch selects "Capture Range Change" instead of "Capture Zoom Only".  As you may have noticed, the "Capture Zoom Only" does not handle the zoom out events.  That is why it is better to capture the range change events so that both graphs are always synchronized.  You will notice that if you hold down the <Ctrl> key and drag across a graph it will pan which also effects the other graph.  If you hold down <Shift> and the Right Mouse Button, then it will zoom out and you should notice the change on both plots.  I tested this behavior again and it works fine on my machine.

Let me know if you have any questions.

Thanks,

Tyler Tigue
Applications Engineer
National Instruments

Message Edited by Tyler T. on 03-08-2006 08:35 AM

Message 5 of 13
(6,809 Views)

I implemented the suggested event handler code from the example zip.

 

My application could have an array of graphs that I need to keep in synch with the graph that is panning/zooming. Zooming works like a champ but panning is a bit quirky. The other items in the array of graphs seem to paint the new range before the item that is actually panning. I toyed with SuspendLayout/ResumeLayout and the drawing improved somewhat but not completely.

 

It seems line the *RangeChanged event is bubbled up too soon.

 

I am using v8.0.20.334

 

Cheers.

 

Joe
0 Kudos
Message 6 of 13
(6,233 Views)

I think I can make the zooms synchronize, but I fail to see how unzoom could work.
Any hints on unzoom?

I too would like to hear any hints on how to sync two graphs via the range changes while keeping unzoom useable.

0 Kudos
Message 7 of 13
(5,921 Views)

Hello furmar,

 

You can use the same logic as in the example program, but you will want to add an event handler for the ZoomPanUndone event.  Within this event handler you can set the ranges of the two graphs to be equal, as in the other event handlers.

 

NickB

National Instruments 

0 Kudos
Message 8 of 13
(5,912 Views)

This is a code snippet from the 'ZoomFactor' example from a few posts up.

 

private void waveformGraph1_XAxisRangeChanged(object sender, NationalInstruments.UI.XAxisEventArgs e)
{   

      if (switch1.Value == false){

         waveformGraph2.XAxes[0].Range = waveformGraph1.XAxes[0].Range;}

}

 

I would like to know if there's a way of matching the waveformGraph2's x-axis range to the waveformGraph1's x-axis range in such a way that it adds an entry to waveformGraph2's undo buffer.

0 Kudos
Message 9 of 13
(5,847 Views)

Hello furmar,

 

As I looked into this for you, I have found that the implementation and resulting behavior necessary to achieve what you want could use some improvement.  It is certainly possible, but it's also not quite as easy as it should be.  I have filed a couple feature improvement requests as a result of my investigation, and hopefully this operation will become a little more intuitive in the future.  Please see the code below for how to mirror the zoom to a second graph such that the zoom adds an entry to the second graph's undo buffer:

 

 

        private void scatterGraph1_XAxisRangeChanged(object sender, XAxisEventArgs e)
        {
            RectangleF zoomRect;
            Rectangle rect = new Rectangle();
            
            // because the range has already changed at this point, we must call MapRange
            // on the 2nd graph, but supply the bounds and range information from the 1st
            // graph.  As long as you intend for your graphs to stay in sync, this should
            // not be a problem.  The resulting RectangleF is the range of interest mapped
            // to device coordinates, where the device is the plot area.

            zoomRect = scatterGraph2.Plots[0].MapRange(scatterPlot1.GetBounds(),
                scatterPlot1.XAxis.Range, scatterPlot1.YAxis.Range);
            // We must convert the RectangleF to a Rectangle for the call to RectangleToVirtual
            rect.X = (int)zoomRect.X;
            rect.Y = (int)zoomRect.Y;
            rect.Width = (int)zoomRect.Width;
            rect.Height = (int)zoomRect.Height;
            // RectangleToVirtual takes the device coordinates from MapRange and converts
            // Them to virtual coordinates, which are values from 0.0 to 1.0, where
            // (0.0, 0.0) represents the left-bottom corner of the plot area and (1.0, 1.0)
            // represents the right-top corner of the plot area.  We do this because ZoomXY
            // needs virtual coordinates

            zoomRect = scatterGraph1.RectangleToVirtual(rect);
            scatterGraph2.ZoomXY(zoomRect);
            // You only need to use the following line if the small resulting imperfections
            // in the ZoomXY call are unacceptable

            scatterPlot2.XAxis.Range = new Range(e.XAxis.Range.Minimum, e.XAxis.Range.Maximum);
        }

 

Another important thing to note is that to interactively (shift + right-click) undo the zoom - the graph of interest must have focus in order to be able to interactively undo. 

 

Please let me know if anything remains unclear, or if I can help with anything else

 

NickB

National Instruments 

Message 10 of 13
(5,831 Views)