Slow rendering of line series with large data

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Slow rendering of line series with large data

Post by Amol » Mon Oct 25, 2010 2:25 pm

Hi,

Thanks for the support you have provided so far.

I am having a problem while using Line Series. I am passing the X and Y values by using arrays of double type. The data i am passing to the line series is larger than usual. In my case it is around 2.5 to 3 lacs points. When data passed to line series is that large, it takes too much time to create chart. Is there any way to shorten this time?

Another thing is, in my application user can drag any point of line series with mouse. Since dragging or zooming in the chart results in repainting of chart again and again, dragging and zooming becomes to slow with such a large data. Can you suggest some way to make these actions faster?

It becomes worse when I have to show two line series on the chart with that large data.

Your suggestions will be highly appreciated.

Thank You
Yatendra

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Narcís » Mon Oct 25, 2010 2:33 pm

Hi Yatendra,

I recommend you to do as explained in the Real-time Charting and Boosting graphics-rendering performance in Windows Forms articles here. First one is based on TeeChart VCL but almost the same applies to TeeChart .NET. Second one uses new TeeChart.Direct2D.dll.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Re: Slow rendering of line series with large data

Post by Amol » Tue Oct 26, 2010 10:31 am

Hi Narcis,

I am pleased to hear from you so fast.

I went through the article on "Boosting graphics-rendering performance in Windows Forms". The article says that I require a Direct2d compatible operating system to use that feature of Teechart. But my problem is, I cant't leave Windows Xp as my clients are very comfortable with it.

I also gone through the "Real-time Charting" example in the Demo Application. The example holds only 50 points of a line series and deletes the rest. In my case I have to show all the points of the series visible with series.Pointer.visible property set to true.

I hope you will reply soon with some alternative solution to my problem.

Thank You
Yatendra

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Narcís » Tue Oct 26, 2010 1:54 pm

Hi Yatendra,

What about the example below?

Code: Select all

        public Form1()
        {
            InitializeComponent();
            InitializeChart();
        }

        int nrOfSamples = 10000;
        private Steema.TeeChart.Styles.FastLine fastline1;
        private Steema.TeeChart.Styles.FastLine fastline2;
        private System.Diagnostics.Stopwatch stopWatch;

        private void InitializeChart()
        {
            stopWatch = new System.Diagnostics.Stopwatch();

            tChart1.Aspect.View3D = false;
            tChart1.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;

            fastline1 = new Steema.TeeChart.Styles.FastLine(tChart1.Chart);
            fastline2 = new Steema.TeeChart.Styles.FastLine(tChart1.Chart);

            //pre-assign ChartPens
            Pen rPen = new Pen(Color.Red);
            Pen bPen = new Pen(Color.Blue);
            Steema.TeeChart.Drawing.ChartPen redPen = new Steema.TeeChart.Drawing.ChartPen(tChart1.Chart, rPen);
            Steema.TeeChart.Drawing.ChartPen bluePen = new Steema.TeeChart.Drawing.ChartPen(tChart1.Chart, bPen);
            fastline1.LinePen = redPen;
            fastline2.LinePen = bluePen;

            fastline1.FillSampleValues(nrOfSamples);
            fastline2.FillSampleValues(nrOfSamples / 2);

            //tChart1.Axes.Left.SetMinMax(-5.0, 5.0);

            tChart1.AfterDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_AfterDraw);
        }

        void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
            //calculate elapsed time
            //stopWatch.Stop();
            TimeSpan elapsedTime = stopWatch.Elapsed;
            string total = elapsedTime.TotalSeconds.ToString();
            label1.Text = "Elapsed time: " + total + " s";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;

            stopWatch.Reset();
            stopWatch.Start();

            tChart1.AutoRepaint = false;

            double[] x1 = new double[nrOfSamples];
            for (int i = 0; i < x1.Length; i++)
            {
                x1[i] = i;
            }
            double[] x2 = new double[nrOfSamples / 2];
            for (int i = 0; i < x2.Length; i++)
            {
                x2[i] = i;
            }
            double[] random1 = new double[nrOfSamples];
            double[] random2 = new double[nrOfSamples / 2];

            for (int i = 0; i < 100; i++)
            {
                FillArray(random1);
                FillArray(random2);
                fastline1.Add(x1, random1);
                fastline2.Add(x2, random2);
                tChart1.AutoRepaint = true;
                //tChart1.Refresh();
                Application.DoEvents();
            }

            stopWatch.Stop();

            button1.Enabled = true;
        }

        private static void FillArray(double[] myArray)
        {
            Random y = new Random();
            for (int i = 0; i < myArray.Length; i++)
            {
                myArray[i] = y.Next();
            }
        }
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Re: Slow rendering of line series with large data

Post by Amol » Wed Oct 27, 2010 1:09 pm

Hi Narcis,

Thank You for code you provide.

I know fast lines can be used where fast rendering of lines on screen is required. But with fastline I can not show line pointers in the chart as it does not have feature to show the line pointers.

Also you have just use 10000 points to draw lines but I already told you that my data contains 2.5 to 3 lacs points. When I edited your code to make the number of points 2 lacs, it also slowed down.

Thanks & Regards
Yatendra

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Narcís » Wed Oct 27, 2010 2:43 pm

Hi Yatendra,

Yes, of course. I wonder if it makes much sense displaying 250000-300000 pointers in a chart. I think it's more "readable" having a line than so many pointers where many of them may be overlapped by others. Moreover, with FastLine series you can disable DrawAllPoints property for increased performance. Also, with other series styles you could try using DownSampling function as in the examles at the Welcome !\Functions\Extended\Reducing number of points section at the features demo, available at TeeChart's program group.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Re: Slow rendering of line series with large data

Post by Amol » Thu Oct 28, 2010 1:10 pm

Hi Narcis,

I can not reduce the number of points by downsampling or any other method because in my application the shape of the curve is very critical aspect. Also my user wants to visualize the curve both at macro level and micro level by zooming inside. So downsampling will not work.

The reason behind showing the pointers is to allow the user to drag a specific point of the curve. Yes it is true when there are that much pointers lots of the are overlapping on one another but when we zoom inside the curve to a considerable amount, distinct pointers can be visualized.

I know You will find some other solution to my problem.

Thanks & Regards
yatendra

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Narcís » Thu Oct 28, 2010 1:28 pm

Hi yatendra,

Given your constraints the only solution I can think of is doing as in the All Features\Welcome !\Functions\Extended\Reducing number of points\DownSampling Additions example at the features demo. There you'll see that DownSampling function is recalculated at each zoom label to display DisplayedPointCount points whenever it's possible.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Re: Slow rendering of line series with large data

Post by Amol » Tue Nov 16, 2010 11:41 am

Hi Narcis,

Sorry for replying late. After much brainstorming I came to the point that you were right. It seems that downsampling of points is the only way to tackle this issue. I tried each of the downsampling function provided in the tee-chart library, but i could not find one that fulfill my requirements.

Hence I need one more favour from you. Please suggest a downsampling method which down sample the total number of points on the basis of their pixel value. That means if pointers of two consecutive points on the screen are close enough to overlap on one another then one of the two points should not be drawn. In that way I think the number of points will be reduced to small enough to be drawn instantly on the screen. Please note i can not use FastLine series as it does not allow to make pointers visible.

I am eager to hear from you.

Thanks & Regards
yatendra

Yeray
Site Admin
Site Admin
Posts: 9614
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Yeray » Tue Nov 16, 2010 2:45 pm

Hi yatendra,
Amol wrote:Hence I need one more favour from you. Please suggest a downsampling method which down sample the total number of points on the basis of their pixel value. That means if pointers of two consecutive points on the screen are close enough to overlap on one another then one of the two points should not be drawn. In that way I think the number of points will be reduced to small enough to be drawn instantly on the screen. Please note i can not use FastLine series as it does not allow to make pointers visible.
FastLine's DrawAllPoints is the easiest reducing point method supported by TeeChart. But it's only available with FastLine series.
For Line series, you have the methods shown in the example Narcis mentioned above, at "All Features\Welcome !\Functions\Extended\Reducing number of points". Here you have an example that achieves what I understood you are trying to do:

Code: Select all

        private Steema.TeeChart.Styles.Points points1;
        private Steema.TeeChart.Styles.Line line1;
        private Steema.TeeChart.Functions.DownSampling downsampling1;
        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;

            points1 = new Steema.TeeChart.Styles.Points(tChart1.Chart);
            points1.Pointer.HorizSize = 2;
            points1.Pointer.VertSize = 2;
            points1.FillSampleValues(10000);

            line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
            line1.Pointer.Visible = true;
            line1.Pointer.HorizSize = 2;
            line1.Pointer.VertSize = 2;
            downsampling1 = new Steema.TeeChart.Functions.DownSampling();
            line1.DataSource = points1;
            downsampling1.Tolerance = 10.0;
            downsampling1.Method = Steema.TeeChart.Functions.DownSamplingMethod.Average;
            line1.Function = downsampling1;

            //points1.Visible = false; //hide the source for a clearer result
        }
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Re: Slow rendering of line series with large data

Post by Amol » Thu Nov 18, 2010 1:01 pm

Hi Yeray,

Thanks for the response.

My requirement is slightly different from the example you provided. Your example and also all of the other downsampling methods that Tee-Chart provides, do downsampling over the data supplied to the Tee-Chart. But I need a downsampling method that works on the pixel values of the data supplied. That is, I want the points that are overlapping on some other point shou not be painted.

Is there something to achieve that with Tee-Chart?

One more thing I want to ask that, whether there is a way in tee-Chart to repaint only one line series if there are more than one Line series on the chart. It will improve the performance of my application if I am able to repaint only single Line series of which I am changing the values, leaving the other elements of the chart including other Line series and axes and gridlines.

Please help.

Thanks & Regards
yatendra

Yeray
Site Admin
Site Admin
Posts: 9614
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Yeray » Mon Nov 22, 2010 10:58 am

Hi yatendra,
Amol wrote:My requirement is slightly different from the example you provided. Your example and also all of the other downsampling methods that Tee-Chart provides, do downsampling over the data supplied to the Tee-Chart. But I need a downsampling method that works on the pixel values of the data supplied. That is, I want the points that are overlapping on some other point shou not be painted.

Is there something to achieve that with Tee-Chart?
If I understood well, you want exactly the functionality of FastLine's DrawAllPoints but you would also like to draw pointers. Am I correct?
A solution would be available with the feature request [TF02013234] that demands a DrawAllPoints for the Points series. This would allow you to draw a FastLine and a Points series both with the same datasource and both with DrawAllPoints to false.
Another solution would be to create your own series (ie. inherit from FastLine series and override the DrawValue method to draw the pointers too). You can see how this functionality works with .NET Reflector.
Amol wrote:One more thing I want to ask that, whether there is a way in tee-Chart to repaint only one line series if there are more than one Line series on the chart. It will improve the performance of my application if I am able to repaint only single Line series of which I am changing the values, leaving the other elements of the chart including other Line series and axes and gridlines.
I'm afraid not.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Amol
Advanced
Posts: 176
Joined: Mon May 29, 2006 12:00 am

Re: Slow rendering of line series with large data

Post by Amol » Thu Nov 25, 2010 1:48 pm

Hi Yeray,

Thanks for the response.

I used the idea you suggested sometimes ago. Downsampling of the oriiginal data worked for me. However none of the downsampling method provided by Tee-Chart satisfied my needs. Hence I developed my own downsampling method to reduce the actual number of data points on the screen. My downsampling method works fine. It reduces 300000 data points to just around 1000 data points on the basis of their pixel value.

In my application there is a functionality to drag a particular pointer of a series over the chart(I can not use dragpoint tool for this due to some other constraints, I used my own logic for this), hence I require repainting of chart on mouse move event. Dragging was not smooth previously, when I was not doing downsampling of data points, because repainting of very arge data is a time taking process. Downsampling made the dragging of points smoother but still it is not up to the expectations. Is there some way to make this faster?

Thanks in advance.

Thanks & Regards
yatendra

Yeray
Site Admin
Site Admin
Posts: 9614
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Slow rendering of line series with large data

Post by Yeray » Fri Nov 26, 2010 12:10 pm

Hi yatendra,

Please, take a look at the following example. I reduce the number of points in a source and use a unique series to draw it. Then, the DragPoint tool works without problems.

Code: Select all

        private Steema.TeeChart.Styles.Points points1;
        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;

            int PointerSize = 2;
            int nSource = 300000;
            double[] XSource = new double[nSource];
            double[] YSource = new double[nSource];

            Random r = new Random();

            XSource[0]= 0;
            YSource[0]= r.Next(1000);
            for (int i = 1; i < nSource; i++)
            {
                XSource[i] = i;
                YSource[i] = YSource[i-1] + r.Next(10) - 4.5;
            }

            double minX = XSource.Min();
            double maxX = XSource.Max();
            double minY = YSource.Min();
            double maxY = YSource.Max();

            tChart1.Axes.Bottom.SetMinMax(minX, maxX);
            tChart1.Axes.Left.SetMinMax(minY, maxY);
            tChart1.Axes.Bottom.MinimumOffset = PointerSize + 1;
            tChart1.Axes.Bottom.MaximumOffset = PointerSize + 1;
            tChart1.Axes.Left.MinimumOffset = PointerSize + 1;
            tChart1.Axes.Left.MaximumOffset = PointerSize + 1;

            tChart1.Draw();

            List<double> XVal = new List<double>(100);
            List<double> YVal = new List<double>(100);

            XVal.Add(XSource[0]);
            YVal.Add(YSource[0]);
            for (int i = 1; i < XSource.Length; i++)
            {
                int pos1 = tChart1.Axes.Bottom.CalcPosValue(XSource[i]);
                int pos2 = tChart1.Axes.Bottom.CalcPosValue(XSource[i-1]);
                if (tChart1.Axes.Bottom.CalcPosValue(XSource[i]) > tChart1.Axes.Bottom.CalcPosValue(XSource[i - 1]))
                {
                    XVal.Add(XSource[i]);
                    YVal.Add(YSource[i]);
                }
            }

            points1 = new Steema.TeeChart.Styles.Points(tChart1.Chart);
            points1.Pointer.HorizSize = PointerSize;
            points1.Pointer.VertSize = PointerSize;

            points1.Add(XVal.ToArray(), YVal.ToArray());

            Steema.TeeChart.Tools.DragPoint dragpoint1 = new Steema.TeeChart.Tools.DragPoint(tChart1.Chart);

            tChart1.Header.Text = "Number of Points reduced from " + nSource.ToString() + " to: " + points1.Count.ToString();
        }
Amol wrote:I can not use dragpoint tool for this due to some other constraints, I used my own logic for this
If you can explain the problem you found with this, maybe we can think on a way to make all work together.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

Post Reply