Page 1 of 1

Real Time FastLine/Line slow performance

Posted: Wed Jun 02, 2010 3:51 pm
by 13047619
Hi,

Environment: VS2008 / WPF / C#
Software: TeeChart WPF Ver. 3.5.3700.30575

It is better to explain what I need to do, so you will have a better idea what I am trying to accomplish here.
I have hardware sending data packets at 40 hertz. Each data packet contains 25 sample points. Now, I am interested in displaying 4(four) series in a chart in real time. If I connect 2 more hardware components (a total of 3 hardware components), I would end up with 3 graphs with 4 series each. The number of points we wish to display for each series is 10 000. So, worst case scenario I will need to display 3 graphs, with 4 series each, and each series containing the last 10 000 points. All of this real time.

I noticed that every time I update the graph the CPU percent usage skyrockets at 100%, and noticed there is huge delay in the data being displayed and the actual hardware readings. I am copying the code I use to display the graph.

Code: Select all

    public class KChart
    {
        public Dictionary<String, int> SeriesIndex = new Dictionary<string, int>();

        /* Properties */
        public TChart MainChart {   get;    set;    }

        /* Constructors */
        public KChart() { this.MainChart = new TChart(); }

        public KChart(string name, string bottomTitle, string leftTitle)
        {
            this.MainChart = new TChart();
            this.MainChart.Header.Text = name;
            this.MainChart.Aspect.View3D = false;
            this.MainChart.Aspect.ZOffset = 0;
            this.MainChart.TabIndex = 0;

            this.MainChart.Panel.Bevel.Inner = BevelStyles.None;
            this.MainChart.Panel.Bevel.Outer = BevelStyles.None;
            this.MainChart.Panel.Gradient.Visible = false;
            this.MainChart.Panel.Color = Color.FromArgb(0xff, 0xf5, 0xf5, 0xf5);

            // Back wall
            this.MainChart.Walls.Back.Gradient.Visible = false;
            this.MainChart.Walls.Back.Color = Color.FromRgb(0x00, 0x00, 0x00);
 
            // Axis 
            this.MainChart.Axes.Bottom.Title.Caption = bottomTitle;
            this.MainChart.Axes.Left.Title.Caption = leftTitle;
            this.MainChart.Axes.Left.AutomaticMaximum = true;
            this.MainChart.Axes.Left.AutomaticMinimum = true;
            this.MainChart.Axes.Left.Labels.ValueFormat = "0.0000000";

            this.MainChart.Legend.Visible = true;

            this.MainChart.Zoom.Allow = true;
            this.MainChart.Zoom.Direction = Steema.TeeChart.WPF.ZoomDirections.Both;

            // Install custom handlers
            this.MainChart.Legend.LegendStyle = LegendStyles.Series;
            //this.MainChart.GetLegendText += new GetLegendTextEventHandler(_GetLegendText);
             
        }

        /************************************* Custom Handlers **************************************************/
        /*
        private void _GetLegendText(object sender, GetLegendTextEventArgs e) 
        {
            int index = e.Index;
           
            var key = from k in this.SeriesIndex
                       where k.Value == index
                       select k.Key;
            if(key!=null && index>=0)
                e.Text = (string)key;
        }
        */
        /************************************* Custom Functions **************************************************/
        public void DrawStyle(String seriesName, Series style, object xvalues, float[] yvalues)
        {
            if (!SeriesIndex.ContainsKey(seriesName))
            {
                SeriesIndex.Add(seriesName, SeriesIndex.Keys.Count);
                style.Color = this.GenerateColor(SeriesIndex.Keys.Count);

                if (style is Bar)
                    ((Bar)style).Chart = this.MainChart.Chart;
                else if (style is Line)
                {
                    ((Line)style).Chart = this.MainChart.Chart;
                    ((Line)style).Pointer.Style = PointerStyles.Circle;
                    ((Line)style).Pointer.Visible = true; ;
                    ((Line)style).Title = seriesName;
                    Legend leg = new Legend(((Line)style).Chart);
                    LegendItem li = new LegendItem(leg);
                    ((Line)style).Chart.Legend.Items.Add(li);
                }
                else if (style is FastLine)
                {
                    ((FastLine)style).Chart = this.MainChart.Chart;
                    ((FastLine)style).Title = seriesName;
                    Legend leg = new Legend(((FastLine)style).Chart);
                    LegendItem li = new LegendItem(leg);
                    ((FastLine)style).Chart.Legend.Items.Add(li);
                    
                }
                
            }
            if ((style is FastLine)||(style is Line))
            {
                //this.MainChart.Chart.AutoRepaint = false;
                this.MainChart.Chart.Series[SeriesIndex[seriesName]].Clear();

                if (xvalues != null)
                {
                    if (xvalues is uint[])
                        this.MainChart.Chart.Series[SeriesIndex[seriesName]].Add((uint[])xvalues, yvalues);
                    else if (xvalues is float[])
                        this.MainChart.Chart.Series[SeriesIndex[seriesName]].Add((float[])xvalues, yvalues);
                }
                else
                    this.MainChart.Chart.Series[SeriesIndex[seriesName]].Add(yvalues);

                //this.MainChart.Chart.AutoRepaint = true;
                // try to see performance
                this.MainChart.Chart.Series[SeriesIndex[seriesName]].RefreshSeries();
                // Update the axis range
                /*
                if (this.MainChart.Chart.Series[SeriesIndex[seriesName]].MaxYValue()>0.0)
                    this.MainChart.Axes.Left.Maximum = this.MainChart.Chart.Series[SeriesIndex[seriesName]].MaxYValue() * 1.0001;
                else
                    this.MainChart.Axes.Left.Maximum = this.MainChart.Chart.Series[SeriesIndex[seriesName]].MaxYValue() * 0.9999;

                if (this.MainChart.Chart.Series[SeriesIndex[seriesName]].MinYValue()>0.0)
                    this.MainChart.Axes.Left.Minimum = this.MainChart.Chart.Series[SeriesIndex[seriesName]].MinYValue() * 0.9999;
                else
                    this.MainChart.Axes.Left.Minimum = this.MainChart.Chart.Series[SeriesIndex[seriesName]].MinYValue() * 1.0001;
                 */

            }
        }
}
I am encapsulating the Tchart component in another class. I tried using FastLine for better performance with no success.

Thanks,

RayDeveloper

Re: Real Time FastLine/Line slow performance

Posted: Fri Jun 04, 2010 11:32 am
by 10050769
Hello RayDeveloper,

I have made a simple project, please, could you say us if using next code you could reproduce your problem too?

Code: Select all

    private void InitializeChart()
        {
            for (int i = 0; i < 4; i++)
            {   
                Steema.TeeChart.WPF.Styles.Line line = new Steema.TeeChart.WPF.Styles.Line(tChart1.Chart);
                 line.FillSampleValues(10000);
            }
        }
Thanks,

Re: Real Time FastLine/Line slow performance

Posted: Mon Jun 07, 2010 11:14 pm
by 13047619
Hi Sandra,

I was able to replicate the problem using your code:

Code: Select all

Steema.TeeChart.WPF.Styles.Line line = new Steema.TeeChart.WPF.Styles.Line(tChart1.Chart);
line.FillSampleValues(10000);
In addition, I identified the culprit of the delay, the Series.Add function. Eventhough I am using FastLine, it is still slow.

I read Steema Software Article about Real-Time charting (http://www.teechart.net/reference/articles/index.php), and it states:

"Another way of adding a large number of points is to use direct dynamic arrays. In this case we're bypassing the AddXY method and accessing the Series x,y values directly, and thus avoid AddXY method overhead."

I was reading about TeeChart.Series.XValues and TeeChart.Series.YValues properties in the help file and it states:

"WARNING:

You CAN NOT Delete, Clear or Add values DIRECTLY. You need to call the Series equivalent methods to do this. "

This contradicts what it says in the article. I even try to do it but I got an "index out of bounds exception" of some sort. What else I can try?

Regards,
RayDeveloper

Re: Real Time FastLine/Line slow performance

Posted: Tue Jun 08, 2010 12:16 pm
by 10050769
Hello RayDeveloper ,
"Another way of adding a large number of points is to use direct dynamic arrays. In this case we're bypassing the AddXY method and accessing the Series x,y values directly, and thus avoid AddXY method overhead."
I was reading about TeeChart.Series.XValues and TeeChart.Series.YValues properties in the help file and it states:
"WARNING:

You CAN NOT Delete, Clear or Add values DIRECTLY. You need to call the Series equivalent methods to do this. This contradicts what it says in the article. I even try to do it but I got an "index out of bounds exception" of some sort."
Information that give warning, is not correctly and I have added it in wish-list with number [TF02014946]to be considered as an enhancement for future releases.

On the other hand, you could try to add values directly with arrays, as next example:

Code: Select all

  Steema.TeeChart.WPF.Styles.Line line1;
        int[] XValues = new int[10000];
        int[] YValues = new int[10000];
        private System.Diagnostics.Stopwatch stopWatch;
        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            line1 = new Steema.TeeChart.WPF.Styles.Line(tChart1.Chart);
            tChart1.Legend.Visible = false;
            tChart1.AutoRepaint = false;
            Random rnd = new Random();
               for (int i = 0; i < 10000; ++i)
            {
                xValues[i] = i;
                yValues[i] = rnd.Next(10000);

            }
            fastline1.Add(xValues, yValues,true);
           tChart1.AutoRepaint = true;
}
Or also, you could add values directly with fastline.XValues and fastlineYValues, Always that you add its count lengths,before add fastline values, as next example:

Code: Select all

 private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            stopWatch = new System.Diagnostics.Stopwatch();
            stopWatch.Reset();
            stopWatch.Start();
            Steema.TeeChart.WPF.Styles.FastLine fastline1 = new Steema.TeeChart.WPF.Styles.FastLine(tChart1.Chart);
            tChart1.AutoRepaint = false;
            Random rnd = new Random();

            for (int i = 0; i < xValues.Length; ++i)
            {
                xValues[i] = i;
                yValues[i] = rnd.Next(10000);
            }
            fastline1.XValues.Count = xValues.Length;
            fastline1.XValues.Value = xValues;
            fastline1.YValues.Count = yValues.Length;
            fastline1.YValues.Value = yValues;
            fastline1.FillSampleValues(10000);
            fastline1.AutoRepaint = true;
}
You can see method you have indicated with .NET Reflector and see the small differences between the previous code and methods of fastline1.AddXY() or fastline1.Add(xValues,yValues,bool).

Please, check if your application works faster with previous codes than code I have added before, in this thread.

I hope will helps.

Thanks,

Re: Real Time FastLine/Line slow performance

Posted: Tue Jun 08, 2010 5:01 pm
by 13047619
Hi Sandra,

I used your last code segment for my testing, but without the "fastline1.FillSampleValues(10000);" line.

Code: Select all

            Steema.TeeChart.WPF.Styles.FastLine fastline1 = new Steema.TeeChart.WPF.Styles.FastLine(tChart1.Chart);
            tChart1.AutoRepaint = false;
            Random rnd = new Random();

            for (int i = 0; i < xValues.Length; ++i)
            {
                xValues[i] = i;
                yValues[i] = rnd.Next(10000);
            }
            fastline1.XValues.Count = xValues.Length;
            fastline1.XValues.Value = xValues;
            fastline1.YValues.Count = yValues.Length;
            fastline1.YValues.Value = yValues;
            fastline1.FillSampleValues(10000);
            fastline1.AutoRepaint = true;
In addition I added these lines

Code: Select all

 fastline1.XValues.Order = ValueListOrder.None;
 fastline1l.YValues.Order = ValueListOrder.None;
But It is still really slow and have huge delays. Is there anything else I can try?
Is WPF version of TeeChart that slow?

Regards,

RayDeveloper

Re: Real Time FastLine/Line slow performance

Posted: Wed Jun 09, 2010 11:22 am
by 10050769
Hello RayDeveloper,
But It is still really slow and have huge delays. Is there anything else I can try?
Is WPF version of TeeChart that slow?
We are constantly working in increasing TeeChart.WPF.dll performance. However, WPF is slower than GDI+ and WinForms applications. Although WPF is faster in some areas, such as painting, it is slower in other areas as extra objects have to be created to be passed to the painting method. All WPF pen objects expect a brush to define their appearance. This makes pens very flexible, but means that just to set a pen to a red color, for example, a new brush has to be created. On balance, therefore, as for the investigation and tests we have done so far, we do not expect the WPF chart to be as quick as the GDI+ chart for large datasets. We don’t think WPF was designed for intensive drawing, it was designed for aesthetic drawing.

For enhancing your applications performance you could also filter your data using DownSampling function as shown in the All Features\Welcome !\Functions\Extended\Reducing number of points examples at the features demo, available at TeeChart's program group.

Recently we have been working on enhancing TeeChart.dll and TeeChart.WPF.dll performance for next TeeChart for .NET 2010 maintenance release. Also, we are working on a new fast-rendering option for TeeChart for .NET using Direct 2D which is now being prototyped. Tests proved it to be much quicker than TeeChart for WinForms and WPF.

Thanks,

Re: Real Time FastLine/Line slow performance

Posted: Wed Jun 09, 2010 5:21 pm
by 13047619
Hi Sandra,

Does the windows form version of TeeChart is faster? and the GDI/GDI+ engine would work and have the performance we required? If so, Can I use winform version in a windows form objects inside my WPF GUI and have great TeeChart performance?

Regards,

RayDeveloper

Re: Real Time FastLine/Line slow performance

Posted: Thu Jun 10, 2010 9:59 am
by 10050769
Hello RayDeveloper
Does the windows form version of TeeChart is faster?and the GDI/GDI+ engine would work and have the performance we required?
In some cases winForms is faster than WPf, I recommend you try to make a simple example using WPF and WinForms, and check which platform is the quickest.
if so, Can I use winform version in a windows form objects inside my WPF GUI and have great TeeChart performance?
I found this link which explains how to insert winforms into WPF applications, I think it may be useful for you.

I hope it helps.

Thanks,