Page 1 of 1

Performance of drawing

Posted: Fri Aug 21, 2009 11:20 am
by 9346725
Hi TeeChart Team,
In my application i have to draw huge amount of data (.25 millions of data/series. 10 series minimum). I am able to overcome the performance problem for drawing that much data at a time by using fastline series and data as double array. Now there is one requirement of drawing a vertical line on mouse down and on mouse move from the nearest mouse x point to the bottom axis. I cant use the Nearest point tool as this tool will return the nearest point from any direction. But i need the nearest point from the mouse x position. It is like - if i draw a vertical straight line at the mouse x position then out of the points where the line is intersecting the data serieses i have to find the nearest one. I have done that calculation as well. But i am drawing the line on AfterDraw event. Now that is the problem. Once i calculated the nearest point, i have to call TChart.Invalidate or TChart.Refresh function. In both cases, AfterDraw event is getting fired very late. i think it is because, on calling refresh function, TChart draws everything again. I am not sure though. Thats why it is taking time to draw the line. Can you suggest me any solution so that the line gets draws as soon as the mouse down or mouse move event is fired? irrespective of the size of data?

Re: Performance of drawing

Posted: Mon Aug 24, 2009 11:13 am
by narcis
Hi Nitin,

You could try with a CursorTool set to be vertical only, with snap property set to true and FastCursor set to true.

Hope this helps!

Re: Performance of drawing

Posted: Mon Aug 24, 2009 12:58 pm
by 9346725
Hi Narcís,
Will it be possible to specify the start point and end point of the cursor tool at runtime?

Can you please send me one sample code for 10 fastline series with 10000 data points in each series.

Re: Performance of drawing

Posted: Mon Aug 24, 2009 1:54 pm
by narcis
Hi Nitin,
Will it be possible to specify the start point and end point of the cursor tool at runtime?
I'm afraid not. The only solution I can think of is disabling it when mouse cursor is out of that range or use a series with a custom axis for restricting cursor's scope.
Can you please send me one sample code for 10 fastline series with 10000 data points in each series.
In that case I recommend you to have a look at the All Features\Welcome !\Chart styles\Standard\Line(Strip)\Interpolating line series example in the features demo, set the cursor tool to one of the series, set it to snap and FastCursor=true.

Re: Performance of drawing

Posted: Tue Aug 25, 2009 12:59 pm
by 9346725
Hi Narcís,
I have seen that example.
Problem is - i have to draw a dashed line from the nearest data point to the bottom axis. Getting the nearest data point is not at all a issue. But on mouse move i have draw the dashed line from the nearest data point to the bottom axis.
You can consider one example -
In TeeChart, when we press the left mouse button and move the mouse (for zooming) one rectangle is getting created. That rectangle drawing is not dependent on the size of the data. Is not it? I want to don something similar to it. When i am moving the mouse with right mouse button down, i want to draw a line from the nearest pointto the bottom axis. On mouse move, i am able to get the 2 points where i have to draw the line but i have call refresh after drawing it to make the line visible. I dont want to call that refresh or invalidate which in turn will draw everything.
It is like, when moving the mouse with left button down (for zooming again), we are not calling refresh still the 4 lines are getting draw in mouse move. Thats what i need to do. Instead of rectangle i want to draw line between 2 points.
please let me know if you understood what i am trying to tell you.

I have attached a sample project which you can use as is. To see the problem, just increase the number of data samples from 100 to 10000 or more.
MouseMove_Refresh.zip
MouseMove_Refresh
(15.1 KiB) Downloaded 783 times

Re: Performance of drawing

Posted: Tue Aug 25, 2009 1:03 pm
by 9346725
In the previously attached sample project, right click on the control and move your mouse. You will be able to see one line is getting drawn. To see the problem, increase the number of data per series from 100 to 10000. Then do the same operation of moving your mouse. You will be able to see the problem.

Re: Performance of drawing

Posted: Wed Aug 26, 2009 11:35 am
by narcis
Hi Nitin,

In that case the only solution I came up with is drawing a rectanlge as internal zoom feature does. It's a 1 pixel wide rectangle so that it looks like a line. Attached there's your project with those modifications implemented.

Re: Performance of drawing

Posted: Wed Aug 26, 2009 12:21 pm
by 9346725
Hi Narcís,
Thanks for your reply.
Thats is one of the way i tried initially. Using DrawReversibleLine/DrawReversibleFrame. That would work for drawing the line on mouse move but there is nothing like drawing a reversible circle (not sure if it is there). So i could not draw the small circles around the point. Even in your code also i am not seeing the circle. How can i draw the circle at the nearest point?

Re: Performance of drawing

Posted: Wed Aug 26, 2009 12:56 pm
by 9346725
Also, i am not able to remove the last drawn line on mouse move event. Can you help me on this?

Re: Performance of drawing

Posted: Thu Aug 27, 2009 8:41 am
by narcis
Hi Nitin,
Thats is one of the way i tried initially. Using DrawReversibleLine/DrawReversibleFrame. That would work for drawing the line on mouse move but there is nothing like drawing a reversible circle (not sure if it is there). So i could not draw the small circles around the point. Even in your code also i am not seeing the circle. How can i draw the circle at the nearest point?
Yes, you are right. The only solution I can think of is drawing a small rectangle using DrawReversibleFrame instead of a circle, for example:

Code: Select all

							DrawRectangle(new Point(p0.X - 3, p1.Y - 3), new Point(p0.X + 3, p1.Y + 3), color);
							DrawRectangle(p0, p1, color);
							p0 = new Point(xPosValue, BottomPosVal);
							p1 = new Point(xPosValue+1, yPosValue);
							color = g.Pen.Color;
							DrawRectangle(new Point(p0.X - 3, p1.Y - 3), new Point(p0.X + 3, p1.Y + 3), color);
							DrawRectangle(p0, p1, color);	
Also, i am not able to remove the last drawn line on mouse move event. Can you help me on this?
Yes, behaviour is not perfect but it can be highly improved painting the line and rectangle in the MouseDown and MouseUp events too as in attached project. Also, removing Invalidate call from MouseDown event improves performance significantly.

Hope this helps!

Re: Performance of drawing

Posted: Thu Aug 27, 2009 11:15 am
by 9346725
Thanks Narcís.
I think for the time being i have to draw a rectangle instead of a circle.
Lets hope Microsoft will come up with DrawReversibleCircle() soon. :D

Re: Performance of drawing

Posted: Wed Sep 09, 2009 8:35 am
by 9346725
Hi,
One question.
If my x axis value is of date time and if i have one date time value, can i get the index of that value directly?
For example - suppose i am assigning the x axis with a double array. That double array is nothing but the date time values converted to double.
Now, on mouse click, i am able to get the x value directly at that mouse position. But, is it possible to get the index of that x value so that i can get the corresponding y value also easily?

Re: Performance of drawing

Posted: Wed Sep 09, 2009 8:52 am
by narcis
Hi Nitin,

Yes, if I understand correctly what you are trying to do you should be able to do something like that:

Code: Select all

			double xVal = DateTime.Parse("09/09/2009").ToOADate();
			int index = tChart1[0].XValues.IndexOf(xVal);
			double yVal = tChart1[0].YValues[index];

Re: Performance of drawing

Posted: Wed Sep 09, 2009 9:13 am
by 9346725
Thanks for your quick reply.

When i am clicking on the screen i am not getting the correct x value.
I am doing this -

Code: Select all

        private int GetNearestPointFromMouseLocation(Series _Series, int XPos, int YPos)
        {
            int yPosinCo = -1;
            double XVal = _Series.XScreenToValue(XPos);
            int index = _Series.XValues.IndexOf(XVal);
            double YVal = _Series.YValues[index];
            yPosinCo = _Series.CalcYPosValue(YVal);
            return yPosinCo;
        }
XScreenToValue(XPos) call returns a value that is not existing in the xvalues. Thats why the IndexOf is returning -1.
Please let me know if i am doing something wrong here.

Re: Performance of drawing

Posted: Wed Sep 09, 2009 9:50 am
by narcis
Hi Nitin,

In that case you can do something like this:

Code: Select all

		void tChart1_MouseMove(object sender, MouseEventArgs e)
		{
			Steema.TeeChart.Tools.CursorTool cursor1 = new Steema.TeeChart.Tools.CursorTool();
			cursor1.Series = tChart1[0];
			cursor1.Snap = true;
			cursor1.FollowMouse = true;
			cursor1.Style = Steema.TeeChart.Tools.CursorToolStyles.Vertical;
			cursor1.XValue = tChart1[0].GetHorizAxis.CalcPosPoint(e.X);
			cursor1.YValue = 0;
			cursor1.XValue = tChart1[0].GetHorizAxis.CalcPosPoint(e.X);
			cursor1.SnapToPoint();
			double xVal = cursor1.XValue;
			int index = tChart1[0].XValues.IndexOf(xVal);
			double yVal = tChart1[0].YValues[index];
			tChart1.Header.Text = xVal.ToString() + " - " + yVal.ToString();
		}