|
Multichart zoom by mouse rectangle |
| Posted by Michael P. on May-15-2025 19:50 |
|
Hi there,
with ChartDirector C++ 6.3, we show a graph with certain channels as line layers and with a time x-axis. Zooming scrolling by keys and mouse works fine and exact.
We also allow an overlayed view which stacks multiple line layers in multiple charts in a multichart which combines certain time areas and show those with a common zero start time.
In this view, zooming scrolling by keys works also fine, but the mouse area zoom does not fit the selected time area.
If I let's say zoom into a custom time area representing 0.5 to 1.5 seconds, the graph after the zooming displays a different timespan.
See attachments 01 and 02 as before and after.
Which zoom and viewport settings do I have to sync/fix to achieve an ideal zooming experience?
thanks in advance,
Michael
|
Re: Multichart zoom by mouse rectangle |
| Posted by Peter Kwan on May-16-2025 02:31 |
|
Hi Michael P,
There is a Realtime MultiChart with Zooming and Scrolling example included in ChartDirector 7:
https://www.advsofteng.com/doc/cdcpp.htm#realtimemultichart.htm
So we know it works in ChartDirector 7. I will try ChartDirector 6.3 to see if there is any difference.
My speculation is that ChartDirector 6 may not know where is the plot area in a MultiChart. A MultiChart can contain various chart types (PieChart, PolarChart, XYChart, etc), and the charts can be positioned freely (not necessarily stacked up vertically). If ChartDirector 6 does not know where is the plot area, it may interpret the mouse position incorrectly.
To address this problem, there is an API MultiChart.setMainChart to configure which XYChart to use to determine the plot area location in a MultiChart. See:
https://www.advsofteng.com/doc/cdcpp.htm#MultiChart.setMainChart.htm
May be you can try to add a line "myMultiChart->setMainChart(myFirstXYChart);" to see if it makes any difference.
Best Regards
Peter Kwan |
Re: Multichart zoom by mouse rectangle |
| Posted by Michael P. on May-19-2025 18:24 |
|
Hi Peter,
thanks for the reply.
setMainChart was already set, BUT: we have a bit of a MultiChart inception as there is an outer MultiChart and an inner one which has all the child charts and is set as main chart.
This was presumably done for resizing depending on legend and title visiblity and sizes.
I tried switching those as main chart but no difference.
Anyway, checking out the realtime multichart with zoom/scroll & trackline, I encountered the "same" problem: I selected a region from 12:01:40 to 12:01:45 and the zooming in changed to a bigger region, 12:01:37.50 to 12:01:47.25. See attached files.
This may be because the max zoom level was exceeded, more zooming in is not possible.
But in our program we do allow deeper zooms which can be reached using other zoom means (scroll wheel on axis, keyboard shortcuts).
Due to scattered code files I cannot provide a full example, but these are our zoom settings:
setMouseWheelZoomRatio(1.1);
setZoomInRatio(1.01);
setZoomOutRatio(0.99);
setZoomDirection(Chart::DirectionHorizontal);
setScrollDirection(Chart::DirectionHorizontalVertical);
setZoomInWidthLimit(1.0 / std::numeric_limits<double>::max());
setZoomInHeightLimit(getZoomInWidthLimit());
And since we are using our own customized of the original QChartViewer I expect this won't be easy to solve, so I better just ask which settings/adaptions would be important for getting the mouse rectangle zoom to be exact?
thanks, Michael
|
Re: Multichart zoom by mouse rectangle |
| Posted by Peter Kwan on May-20-2025 18:46 |
|
Hi Michael P,
In the Real Time MultiChart sample code, the zoom in limit is set to 10 seconds. It is set in the header file "realtimemultichart.h". That can explain why after zoom in, the range is arouind 10 seconds.
The zoom in limit is set as a ratio to the full range. In a real-time chart, the full range can change. So the sample code re-compute and update the zoom in limit every time the chart is changed (in onChartUpdateTimer). This will overwrite your setZoomInWidthLimit line which I assume run only during initialization.
After I commented out the setZoomInWidthLimit line in onChartUpdateTimer, it can zoom in much deeper.
For your case, you mentioned you have nested MultiCharts. Suppose there is an outer MultiChart that contains an Inner MultiChart, which in turn contains an XYChart that owns the x-axis for zooming. The setMainChart of the outermost MultiChart should point to the Inner MultiChart. The setMainChart of the Inner MultiChart should point to the XYChart.
The XYChart will return its plot area coordinates. Because the XYChart is offseted within the inner MultiChart, the inner MultiChart needs to adjust the coordinates by including the offsets. Similarly, the outer MultiChart needs adjust the coordinates to account for the inner MultiChart offsets.
I am also a bit worry about the following line, although I did not find any problem in my testing:
setZoomInWidthLimit(1.0 / std::numeric_limits<double>::max());"
The code performs some computation with a numeric limit. ChartDirector may also perform some computation with the zoom in limit. It can potentially trigger numeric overflow or underflow. it may be safer to set it to 1E-10. This is equivalent to 10 billion times zoom in, which should be sufficient for most applications.
Best Regards
Peter Kwan |
Re: Multichart zoom by mouse rectangle |
| Posted by Michael P. on May-20-2025 19:32 |
|
Great, that seems to work: multichart1 gets multichart2 set as main and multichart2 gets the first XYChart as main chart, together with the new zoom limit.
But there's always a but: the zoom rectangle can only be activated (and gets drawn) on the one XYChart which is set as mainchart.
So I guess this needs some more changes to the QChartViewer drawing process, right?
thanks & best regards
Michael |
Re: Multichart zoom by mouse rectangle |
| Posted by Peter Kwan on May-20-2025 21:06 |
|
Hi Michael,
Please try the followings to see if it works:
outerMultiChart->setMainChart(outerMultiChart);
innerMultiChart->setMainChart(innerMultiChart);
If the mainChart is set to the MultiChart itself, it will get the plot area bounds of all the charts it contains, and return a rectangle that bounds all the plot areas.
See:
https://www.advsofteng.com/doc/cdcpp.htm#MultiChart.setMainChart.htm
With the above code, the outerMultiChart will get the plot area bounds of all the innerMultiCharts and combine them. The innerMultiChart will get the plot area bounds by combining the plot areas of all the XYCharts it contains.
If all the plot areas happened to be vertically aligned with the same x-axis scale, then the combined plot area can be used for the purpose of zooming and scrolling.
Note that the MultiCharts must only contain other MultiCharts or XYCharts. If they has other chart types (such as PieCharts or PolarCharts), the combined plot area will not be suitable for zooming and scrolling.
Best Regards
Peter Kwan |
Re: Multichart zoom by mouse rectangle |
| Posted by Michael P. on May-20-2025 21:51 |
|
Now that seems to have done it.
Should have read the doc more carefully.
Thanks! |
|