Page 1 of 1

chart stops auto refreshing

Posted: Thu Oct 22, 2009 8:30 am
by 13052929
Hi,
I have a chart with a Points3D series that contains 1000 points. I modify these points in separate thread as fast as possible (performance test application). I tested 2 approaches:

1. Set Chart.AutoRepaint=false and force chart to refresh itself from thread using InvokeRequired/Invoke technique.
2. Set Chart.AutoRepaint=true and do not force chart refresh from the thread.

- Now, disadvantage of first approach is that I can update data only about 10 times per second.
- Second approach let me update data about 90-100 times per second but ocasionally chart stops refreshing. It starts again after moving a window in such a way that forces part of chart to be redrawn (move out of the screen and back). After some time it stops again.

Does anyone can help me either making first approach faster or solving auto refresh problem in second one?!

My code looks like this. To test first approach set autoRepaint=false in Form1 constructor. For second approach set autoRepaint=true:

Code: Select all

namespace TChart3DAnimation
{
    public partial class Form1 : Form
    {
        private bool autoRepaint;
 
        public Form1()
        {
            InitializeComponent();

            this.autoRepaint = false;
            //Here goes data initialisation and thread is started
        }

        public static void AnimationThreadProc(object data)
        {
            Form1 _this = data as Form1;
            if (_this != null)
            {
                while (!_this.stopAnimationThread)
                {
                    _this.points3D1.BeginUpdate();  //Steema.TeeChart.Styles.Points3D object created by designer
                    //here goes data modification
                    _this.points3D1.EndUpdate();
                    if (!_this.autoRepaint)
                        _this.ThreadChartInvoker(_this.tChart1, eTCI.e_TCI_Refresh, null);

                    System.Threading.Thread.Sleep(5);
                }
            }
        }

        private enum eTCI { e_TCI_Refresh };
        private delegate void ThreadChartInvokerDelegate(Steema.TeeChart.TChart chart, eTCI method, object[] parameters);
        private void ThreadChartInvoker(Steema.TeeChart.TChart chart, eTCI method, object[] parameters)
        {
            if (InvokeRequired)
            {
                Invoke(new ThreadChartInvokerDelegate(ThreadChartInvoker), new object[] { chart, method, parameters });
            }
            else
            {
                switch (method)
                {
                    case eTCI.e_TCI_Refresh:
                        //this.points3D1.Repaint();
                        chart.Invalidate();
                        //this.points3D1.RefreshSeries();
                        //chart.Refresh();
                        break;
                }
            }
        }
    }
}

Re: chart stops auto refreshing

Posted: Thu Oct 22, 2009 1:37 pm
by yeray
Hi jarp,

We usually recommend to manually control the repaint process when a big amount of data has to be added to a chart. So your first approach would be the most optimal.
Also note that, in the second approach, you should take care to not access to the chart while it is being repainted. So you should probably make your thread sleep after each chart modification (that forces a chart repaint) and wake up the thread, for example at OnAfterDraw event.

Please, if you still have problems with it, try to attach a simple example project we can run as-is to reproduce the issue here.

Re: chart stops auto refreshing

Posted: Fri Oct 23, 2009 6:40 am
by 13052929
Hi Yeray,
I modified my code so thread is waiting for OnAfterDraw. It hasn't changed anything.

Here comes executables:
TChart3DAnimation exe.zip
application executable
(114.26 KiB) Downloaded 4021 times
Because of file size restriction attached zip doesn't contain "TeeChart.dll". Please include it yourself. My version is "3.5.3425.20245"

Application starts in "auto repaint" mode. Sometimes it doesn't repaint just after start, sometimes you need to wait (up to one minute). When it stops auto repainting you can use "Kick the chart" button. It calls "Chart.Invalidate" and chart starts auto repainting for some time until it stops again.

To switch to second approach with "Invoke" technique just uncheck "auto update" check box.

Here comes the code of test application:
TChart3DAnimation code.zip
application code
(34.18 KiB) Downloaded 543 times
Regards,

Re: chart stops auto refreshing

Posted: Fri Oct 23, 2009 11:31 am
by yeray
Hi jarp,

Thanks for the test application.
First I've tested it in a Core 2Quad (3 GB RAM) and the application worked as you said except for the refreshing stops with the second approach (autorepaint=true).
That made me think that this could be a performance related issue so I've tried in a slower machine.
In an AMD 3000+ I could reproduce both behaviours and the only thing I can't think right now is to use autorepaint=true and call the invalidate routine after modifying the data.

Re: chart stops auto refreshing

Posted: Mon Oct 26, 2009 9:37 am
by 13052929
Hi Yeray,
First of all thanks for your answer!

What do you mean by "call invalidate routine after modifying the data"? Should I call it from thread? In such case I would have the same situation that I have in first approach. Calling "Invoke" from thread (and changing thread context) is what takes time and causes performance issue.
In fact I prefer such solution (with thread refreshing the chart) because it is much more easy to keep data synchronized in case of many series. Unfortunately 10 fps (on P4 3GHz) is not acceptable. I need at least 30 fps. Any ideas how to improve first approach?

Due to second approach workaround could be to call "Invalidate" on timer (500 ms). It would "kick" the chart to start refreshing again in case it stopped. But it is very inelegant solution.

Regards,

Re: chart stops auto refreshing

Posted: Mon Oct 26, 2009 12:43 pm
by Marc
Hello,

TeeChart will not repaint unless provoked to do so when data is being continually added. You can confirm that by testing it on a non-threaded application with your data update cycle. The Chart won't repaint unless you add a Chart1.Refresh(); into the cycle. For your threaded application you can call invalidate at an appropriate time in the cycle. BeginUpdate/EndUpdate would be superfluous here unless dependent functions exist.

eg.

Code: Select all

if (!_this.autoRepaint)
  _this.ThreadChartInvoker(_this.tChart1, eTCI.e_TCI_Refresh, null);
else
  _this.tChart1.Invalidate();
I agree there is an advantage to adding more control to the thread cycle but if you require maximum frequency for your cpu capability then adjusting the Thread.Sleep delay with above technique may be the best option. We haven't tested this for robustness; TeeChart isn't internally thread enabled so cycle control is important in a threaded application (chart paint cycle needs to complete before next begins).

Regards,
Marc Meumann

Re: chart stops auto refreshing

Posted: Mon Oct 26, 2009 2:03 pm
by 13052929
I haven't known Chart.Invalidate can be called directly by thread. In such case performance is same for both approaches.

Code: Select all

if (!_this.autoRepaint)
{ 
   //_this.ThreadChartInvoker(_this.tChart1, eTCI.e_TCI_Refresh, null);
   _this.tChart1.Invalidate();
}
else
  _this.tChart1.Invalidate();
The question is if it is safe to call Invalidate this way?

Regards,

Re: chart stops auto refreshing

Posted: Fri Oct 30, 2009 9:41 am
by Marc
Hello,

The safest way would be to regulate entrance and exit from the paint routine. If two simultaneous arrivals via different threads are possible to onw invalidate location then I would consider that unsafe.

Regards,
Marc