|
Real-time chart with zoom and scroll |
Posted by Darryl on Feb-25-2011 08:32 |
|
I have a fairly straightforward real-time MFC XY chart with clickable image maps.
It has multiple data sets, each in their own line or step line layers, and two Y axes.
I implemented scroll by using a slider control and copying the appropriate timestamp and value data from larger sets (the chart displays one hour's worth of data, the larger sets store 30 days of data - the collection interval is 30 seconds so there are 120 data points and timestamps in the chart arrays and 86400 data points and timestamps in the larger sets).
If the chart is scrolled, I suspend updating the chart but still collect the data and store it in the larger sets. When the scroll is at the upper limit or if a reset button is pressed, the appropriate (most recent) data chunks are copied to the chart's arrays and real time updating resumes.
I didn't use the viewport message handlers to implement scrolling because I anticipated that the zoom part of this would be easier if I operated on a chart that has a view port that is in a default state regardless of the scroll position.
I may be wrong about that, I'm still learning the view port mechanism.
Anyway, scroll is working well and now I wish to implement zoom in both X and Y axes.
The ideal goal and first question, I suppose, is this... I would like to have the user be able to click (or click-and-drag) the left mouse button down in the plot area and that would change the mouse usage from default to Chart::MouseUsageZoomIn. If the user clicks the right mouse button it should change the mouse usage to Chart::MouseUsageZoomOut. The reset button will cause the chart to reset the zoom and scroll to default values and resume real-time display.
Is that possible? I've tried to intercept the WM_LBUTTONDOWN message but that hasn't worked so far (though I haven't tried using PreTranslateMessage yet).
I would rather not have to use other controls to set the mouse usage, but if I have to, then I guess I just have to...
I can provide the code for the chart and related functions if necessary.
Thank you in advance for any advice you can offer. |
Re: Real-time chart with zoom and scroll |
Posted by Peter Kwan on Feb-26-2011 00:48 |
|
Hi Darryl,
You may just set the mouse usage to Zoom In. In this way, the user can use the left mouse button to drag a zoom rectangle. The CChartViewer will then send a CVN_ViewPortChanged message the parent, which it can handle to perform the zooming. You may refer to the sample code "Zooming and Scrolling Demonstration" and "Zooming and Scrolling Demonstration (2)" for reference.
The CChartViewer is intentionally designed not to use the right mouse button, so that the developers can use it for any purpose they like. You can use it for zoom out if you like. For example, you can override the OnRButtonDown method to handle the right mouse click, and increase the width/height of the view port (which means increasing the data range displayed, which means zooming out).
The view port mechanism is just a way to inform you what the user has selected during zoom in. For example, suppose your code initializes the view port width to 0.7 (I just use an arbitrary number between 0 to 1 as an example). The user then drags a rectangle to zoom in, and in the view port changed event, the CChartViewer informs you to new view port width is 0.07. Your code then knows the user has selected 10% of the initial plot area. (For simplicity, I just mention the view port width. CChartViewer will also update the view port left, top, and height as well.)
Your code can then get the appropriate data to redraw the chart, and sets the axis scale to 10% of the original scale.
Your code can also handle the reset button by resetting the view port to its initial value and update the chart accordingly.
Hope this can help.
Regards
Peter Kwan |
Re: Real-time chart with zoom and scroll |
Posted by Darryl on Feb-26-2011 01:20 |
|
Thank you Peter;
I was able to intercept the mouse events using PreTranslateMessage (this is a bit of an odd case, the charts are drawn in property pages (tabbed dialogs) so some handlers need to be implemented differently than other windows or dialogs).
I was able to get the behavior I was looking for.
Peter Kwan wrote:
The CChartViewer is intentionally designed not to use the right mouse button, so that the developers can use it for any purpose they like. You can use it for zoom out if you like. For example, you can override the OnRButtonDown method to handle the right mouse click, and increase the width/height of the view port (which means increasing the data range displayed, which means zooming out).
That is the behavior I am looking for, and I think (with your help) I have a good idea of how to make it happen.
Peter Kwan wrote:
The view port mechanism is just a way to inform you what the user has selected during zoom in. For example, suppose your code initializes the view port width to 0.7 (I just use an arbitrary number between 0 to 1 as an example). The user then drags a rectangle to zoom in, and in the view port changed event, the CChartViewer informs you to new view port width is 0.07. Your code then knows the user has selected 10% of the initial plot area. (For simplicity, I just mention the view port width. CChartViewer will also update the view port left, top, and height as well.)
Your code can then get the appropriate data to redraw the chart, and sets the axis scale to 10% of the original scale.
That was VERY informative, and makes the situation much more understandable. I reviewed the documentation and the sample code, and though it is thorough and quite detailed, I still had some basic questions, which you just answered above.
Peter Kwan wrote:
Your code can also handle the reset button by resetting the view port to its initial value and update the chart accordingly.
Yep, the plan is quite clear now, thank you very much again. This is an awesome product and your support is stellar. |
|