Page 1 of 1

Slow rendering of line series with large data

Posted: Mon Oct 25, 2010 2:25 pm
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Mon Oct 25, 2010 2:33 pm
by narcis
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.

Re: Slow rendering of line series with large data

Posted: Tue Oct 26, 2010 10:31 am
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Tue Oct 26, 2010 1:54 pm
by narcis
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();
            }
        }

Re: Slow rendering of line series with large data

Posted: Wed Oct 27, 2010 1:09 pm
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Wed Oct 27, 2010 2:43 pm
by narcis
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.

Re: Slow rendering of line series with large data

Posted: Thu Oct 28, 2010 1:10 pm
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Thu Oct 28, 2010 1:28 pm
by narcis
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.

Re: Slow rendering of line series with large data

Posted: Tue Nov 16, 2010 11:41 am
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Tue Nov 16, 2010 2:45 pm
by yeray
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
        }

Re: Slow rendering of line series with large data

Posted: Thu Nov 18, 2010 1:01 pm
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Mon Nov 22, 2010 10:58 am
by yeray
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.

Re: Slow rendering of line series with large data

Posted: Thu Nov 25, 2010 1:48 pm
by 9641422
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

Re: Slow rendering of line series with large data

Posted: Fri Nov 26, 2010 12:10 pm
by yeray
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.