|
Two angular meters in one CChartViewer |
Posted by al072 on Jan-08-2021 14:11 |
|
Hi Peter!!!
I am using MFC C++ Chart Director 6.0 library. I want to ask is it possible to set two Angular meters to the same CChartViwer?
I use Angular meters for showing the real time data from revMeter and Fuel level, and the problem is in blinking of Fuel level meter on top of revMeter during the animation process., i animate the arrow position in the FOR Loops and every time the loops starting, the last loop (with Fuel leve) causing the animation problem one CChartViewer blinks on top of another CChartViwer...
Here are the function prototypes i use to draw the meters (i will post the full code if you need):
// revMeter
void drawRevMeter(CChartViewer* viewer, double pointer_value)
{
AngularMeter* m = new AngularMeter(500, 500, 0x000000);
///Here is a code from example "Neon Round Meters"///
// Output the chart
viewer->setChart(m);
//free up resources
delete m;
}
// Fuel Level
void drawFuel(CChartViewer* viewer, double pointer_value)
{
AngularMeter* m = new AngularMeter(80, 65, Chart::Transparent, Chart::Transparent, 0);
///Here is a code from example "Icon Angular mater"///
// Output the chart
viewer->setChart(m);
//free up resources
delete m;
}
Here are the loop to make the animation:
for (i = _last_rev; i < 6.0; i+=0.1)
{
drawRevMeter(&m_revMeterChartViewer, i);
drawFuel(&m_FuelChartViewer, i);
sleep (1 millisecond);
}
Below attached the final image (but the Fuel level is blinking because it is called last in the loop).
|
Re: Two angular meters in one CChartViewer |
Posted by Peter Kwan on Jan-08-2021 16:04 |
|
Hi al072,
MFC will flicker for overlapping transparent controls. It occurs for all MFC controls. It is a limitation of MFC.
The method you mentioned is the best method to solve the problem, that is, combine the two meters into a single chart displayed in a single CChartViewer. As there is one control, if you make it non-transparent, it will not flicker. (It may not flicker even if you make it transparent.)
There are several methods to combine two charts into one. One method is to use a MultiChart. However, for your case, I think it is easier to use the DrawArea.merge method. It is like:
# put chart "c2" onto chart "c", where the top left corner of "c2" will be positioned
# at (50, 90) on "c"
c.makeChart3().merge(c2.makeChart3(), 50, 90, Chart.TopLeft, 0);
The "Concentric Donut Chart" sample code is an example using DrawArea.merge. The concentric donuts are achieved by putting one donut chart on the other.
https://www.advsofteng.com/doc/cdcpp.htm#concentric.htm
For the code to make the animation, I am not sure how it is run. If you run it in the main thread, there GUI will appear to hang during animation, that is, the GUI will not response to any mouse or keyboard events. It is because during animation, your code keep holding the thread, so all GUI events that occur in the same thread cannot respond.
If you run the animation in a separate thread, note that the MFC GUI is not thread safe. You can run anything in the other thread but it must not touch the GUI, which means it cannot use any GUI controls (including the CChartViewer or any MFC controls), otherwise there may be random crashes.
There easiest method to solve the above problems is to use a timer to trigger the animation. Your code only updates the chart when the timer tick, and return afterwards. This is like in our realtime chart example. You can set the timer to run very fast if you like.
Hope this can help.
Regards
Peter Kwan |
Re: Two angular meters in one CChartViewer |
Posted by al072 on Jan-08-2021 17:20 |
|
Peter, thank you for a quick reply!!! I knew i knew there is a trick)) here we go...
Great library, very powerfull and comfortable to use i love it...
Now the animation is smooth and no flicker., and sure i use a separate boost::threads to run the animation routine.
Also you mentioned about MultiChart, i am really interested to test it and know how it works, if it possible post a code sample or link please.
Thank you!!! |
Re: Two angular meters in one CChartViewer |
Posted by al072 on Jan-08-2021 18:01 |
|
Ok, i found the example by myself.. thank you
//=============================================================
// Use a MultiChart to contain both bar charts
//=============================================================
// Create a MultiChart object of size 590 x 320 pixels.
MultiChart *m = new MultiChart(590, 320);
// Add a title to the chart using Arial Bold Italic font
m->addTitle("Demographics Hong Kong Year 2002", "arialbi.ttf");
// Add another title at the bottom using Arial Bold Italic font
m->addTitle(Chart::Bottom, "Population (in thousands)", "arialbi.ttf", 10);
// Put the right chart at (270, 25)
m->addChart(270, 25, c);
// Put the left chart at (0, 25)
m->addChart(0, 25, c2);
// Output the chart
m->makeChart("dualhbar.png");
//free up resources
delete c;
delete c2;
delete m;
return 0; |
Re: Two angular meters in one CChartViewer |
Posted by Peter Kwan on Jan-08-2021 20:46 |
|
Hi al072,
DrawArea.merge is simpler but requires the chart below to completely contain the chart above. If the above condition is not met, we have to use MultiChart.
Regards
Peter Kwan |
|