|
Zoom and scroll with multiple axes and uneven data |
Posted by Stephan Bielmann on Jun-05-2014 14:07 |
|
Hello all,
I am using CD C++ to draw line charts with multiple Y axes. Each of these axes may have
one or multiple datasets in it. However datasets on one given Y axis do have the same
datatype, so for example the first Y axis on the left of the chart may be contain
temperatures, like outside temperature and inside temperature.
All these datasets contain data that is recorded within the very same time span, so for
example for 10 am to 10 pm. But these datasets do not have the same sampling frequency.
So the outside temperature could be taken every 15 minutes, the inside temperature however every 8 minutes.
Now I implemented zoom in horizontal and vertical direction, and scrolling in horizontal direction. Both as documented in the CD doc. But I have not found yet a way how CD could support me with my uneven data.
Please have a look at the two attached images, sample1 shows what I get, sample2 what I
would like to see. I have in black one dataset with only 9 data points, and in pink another
one with about 1000 data points. When zooming into a region of interest, using
Chart::bSearch() to narrow the data points to be drawn, I get of course two different
start and end indices, as the data points are distributed uneven and do not have overlapping
data points for the given zoom area.
Does CD provide functions to work with this use case?
Thanks in advance for any help.
Stephan
|
Re: Zoom and scroll with multiple axes and uneven data |
Posted by Peter Kwan on Jun-06-2014 02:18 |
|
Hi Stephan,
It is normal that you have two start and end indices for your two data series. It should
not affect the zooming and scrolling of the chart. (If you examine the charting code, you
would notice that the start and end indices are used only to obtain the visible data, but
are never actually used in the charting code.)
For example, suppose you have two data series (xData1, yData1) and (xData2, yData2).
The code would be like:
//extract the visible part of (xData1, yData1)
int startIndex = (int)floor(Chart::bSearch(xData1, viewPortStartDate));
int endIndex = (int)ceil(Chart::bSearch(xData1, viewPortEndDate));
int noOfPoints = endIndex - startIndex + 1;
DoubleArray viewPortXData1 = DoubleArray(xData1.data + startIndex, noOfPoints);
DoubleArray viewPortYData1 = DoubleArray(yData1.data + startIndex, noOfPoints);
//extract the visible part of (xData2, yData2)
startIndex = (int)floor(Chart::bSearch(xData2, viewPortStartDate));
endIndex = (int)ceil(Chart::bSearch(xData2, viewPortEndDate));
noOfPoints = endIndex - startIndex + 1;
DoubleArray viewPortXData2 = DoubleArray(xData2.data + startIndex, noOfPoints);
DoubleArray viewPortYData2 = DoubleArray(yData2.data + startIndex, noOfPoints);
You can then use (viewPortXData1, viewPortYData1) for the first line, and
(viewPortXData2, viewPortYData2) for the second line.
Note that extract the visible data above is optional. You can pass all the data to
ChartDirector, and ChartDirector would still plot only the visible part. For example, the
sample code "XY Zooming and Scrolling" does not extract the data (and it also uses
uneven data) and it still works normally.
Extracting visible data for plotting are useful if there are a huge number of data points.
Applications emplying zoomable and scrollable charts often have a lot of data (like millions
or hundreds of thousands of data points). In this case, extracting the visible data points
can help to improve performance. If the chart contains a few thousand points, it may
work quite fast even without extracting visible data.
Hope this can help.
Regards
Peter Kwan |
Re: Zoom and scroll with multiple axes and uneven data |
Posted by Stephan Bielmann on Jun-10-2014 21:16 |
|
Hello Peter,
thank you for that hint, although your documentation says that it is in fact a logical zoom, I thought that I have to extract the visible data all the time. So I removed that extraction part and have made a simple test where it works with these steps:
- create chart
- sync axes in viewer
- set chart in viewer
But for whatever reason it does not work that way in my program, which is more complex, thus I am unable to provide you some source code here. However the steps are the very same. And when printing out the current view port properties on my debug console, like left, top and so one all looks ok, however the chart is always rendered as the view port left and top would be 0, and width and height 1.
Do you have a tip for me where I could look, why the chart is not zoomed, although the view port tells me that it should have been? |
Re: Zoom and scroll with multiple axes and uneven data |
Posted by Peter Kwan on Jun-11-2014 04:26 |
|
Hi Stephan,
From your description, I assume you have called "sync axes" after you have added all the
data and layers to the chart, but before chart layout was performed (calling
BaseChart.layout or layoutAxes) or the chart was drawn (calling BaseChart.makeChart or
set the chart to the ChartViewer). If the "sync axis" is called after the chart is set to the
viewer, then the effect of "sync axes" would not be visible.
Please check if your code never calls "setFullRange" or calls it only one time.
Please also check that the QChartViewer is persistent. If your code creates a new
QChartViewer everytime a new chart is drawn (instead of using the existing
QChartViewer), the view port will also be reset (as the view port are properties of the
QChartViewer).
To trouble-shoot the problem, one method is to display a serial number and other the
useful parameters on the chart title. (The serial number is to confirm that the chart has
in fact been updated as expected and that there is no spurious updates.) For example:
static int serial_number = 0;
viewer->syncLinearAxisWithViewPort("x", c->xAxis());
viewer->syncLinearAxisWithViewPort("y", c->yAxis());
char buffer[4096];
sprintf(buffer, "Serial=%d, xMin=%f, xMax=%f, vpLeft=%f, vpWidth=%f", (++serial), c-
>xAxis()->getMinValue(), c->xAxis()->getMaxValue(), viewer->getViewPortLeft(),
viewer->getViewPortWidth());
c->addTitle(buffer, "arial.ttf", 8);
// Set the chart image to the QChartViewer
delete viewer->getChart();
If your code is too complicated, for further trouble-shoot, you may need to simplify your
code by removing or commenting out unnecessary parts, and by replacing everything
with hard coded data. (As ChartDirector does not know how you obtain the data in any
case, so it cannot change its behaviour whether your data are obtained from a database,
or from a hard coded array, or from a random data generator.)
Regards
Peter Kwan |
Re: Zoom and scroll with multiple axes and uneven data |
Posted by Stephan Bielmann on Jun-12-2014 15:47 |
|
Hello Peter,
thanks for the hint, I did actually use layout() before calling the sync functions.
Zoom and scroll do now work fine as expected. |
|