How do I optimize the Map series with many polygons?

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

How do I optimize the Map series with many polygons?

Post by AndrewP » Mon Jul 13, 2009 7:02 pm

I am trying to display state information in a chart that is related to the data in a line series. What I want to do is display vertical bars in the background behind the line series that will stretch the full height of the y axis, and change colors as the state changes (if the line series contains tempuratures over time, the vertical bars will change colors as the tempurature passes certain threshholds). I have tried to use a Map series to do this, creating polygons for each state, but I have noticed that the performance of chart tool interactions (dragging of a cursor, etc...) start to degrade at about 100 polygons. It is possible that I could be required to display several of these "State" style series on one chart, with many more than 100 polygons per.

Can anyone tell me...
a. how to optimize the performance of the tool interactions with the Map series or the Map series itself?
b. if there is a better, faster series type that is more suited to this type of application?
c. if this is a candidate for extending a base class? If so, can you point me to an example of how to do this and the best base class to use?
d. if there is a better way to draw polygons to the background of an axis?
e. if there is a option I have not thought of?

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

Re: How do I optimize the Map series with many polygons?

Post by Yeray » Tue Jul 14, 2009 11:45 am

Hi Andrew,

A simple example project or a code we could run as-is to reproduce your situation here would be really helpful to understand it.

Is something like that what you are doing?

Code: Select all

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

        FastLine fast1;
        Map map1;
        CursorTool cursor1;

        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;

            map1 = new Map(tChart1.Chart);

            fast1 = new FastLine(tChart1.Chart);
            fast1.FillSampleValues(300);

            PolygonList shapes = new PolygonList(map1);
            Polygon poly1;

            double threshold1, threshold2;

            threshold1 = fast1.YValues.Minimum + (fast1.YValues.Maximum - fast1.YValues.Minimum) / 3;
            threshold2 = fast1.YValues.Minimum + (fast1.YValues.Maximum - fast1.YValues.Minimum) / 3 * 2;

            for (int i = 0; i < fast1.Count; i++)
            {
                poly1 = new Polygon(shapes,tChart1.Chart);
                poly1.Add(fast1.XValues.Value[i] - 0.5, fast1.YValues.Minimum);
                poly1.Add(fast1.XValues.Value[i] + 0.5, fast1.YValues.Minimum);
                poly1.Add(fast1.XValues.Value[i] + 0.5, fast1.YValues.Maximum);
                poly1.Add(fast1.XValues.Value[i] - 0.5, fast1.YValues.Maximum);
                map1.Shapes.Add(poly1);
                
                if (fast1.YValues.Value[i] > threshold2)
                {
                    map1.Colors[i] = Color.Red;
                }
                else
                {
                    if (fast1.YValues.Value[i] > threshold1) map1.Colors[i] = Color.Blue;
                    else map1.Colors[i] = Color.Green;
                }
            }

            map1.Pen.Visible = false;

            tChart1.Draw();

            cursor1 = new CursorTool(tChart1.Chart);
            cursor1.XValue = fast1.Count / 2;
            cursor1.YValue = (fast1.YValues.Maximum - fast1.YValues.Minimum) / 2 + fast1.YValues.Minimum;
            //cursor1.FastCursor = true;  //this could help you to improve the cursor movements        
        }
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

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Tue Jul 14, 2009 5:34 pm

Yes, your sample project is almost exactly what I am trying to do.

First of all, I am trying to do this on the web, not a desktop application.
Second, my cursor is actually a ColorLine hooked up to some mouse events (is this something I should change? Can the CursorTool display only a vertical line?)
Next, I was using...

Code: Select all

                polygon = new Polygon(MapSeries.Shapes, MapSeries.Chart);

                polygon.Add(x, maximumY);            
...
                polygon.Color = GetColor(y);
...
                MapSeries.Shapes.Add(polygon);
Is this way less efficient when building the objects than the one you outlined in your post (external PolygonList)? Is there an optimized way?
Finally, I also noticed a long delay (about 1 minute load time, a couple of timeouts) when refreshing the page that is not related to data retrival when creating about 200 polygons. Is this expected?

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

Re: How do I optimize the Map series with many polygons?

Post by Yeray » Wed Jul 15, 2009 9:55 am

Hi Andrew,
AndrewP wrote:Yes, your sample project is almost exactly what I am trying to do.

First of all, I am trying to do this on the web, not a desktop application.
It would be easier for us to find an acceptable solution for you if we could debug your test application and see what are you exactly doing. Trying to implement an example from your explanations will always be slower and more difficult. That's why we often ask for a simple example project we can run as-is to reproduce the problem here.
AndrewP wrote:Second, my cursor is actually a ColorLine hooked up to some mouse events (is this something I should change? Can the CursorTool display only a vertical line?)
Yes, the cursor tool can be viewed as a vertical line and it allows some other features such as following the mouse or snapping to the points of a series:

Code: Select all

cursor1.Style = CursorToolStyles.Vertical;
cursor1.FastCursor = true;

cursor1.Series = fast1;
cursor1.Snap = true;
AndrewP wrote:Is this way less efficient when building the objects than the one you outlined in your post (external PolygonList)? Is there an optimized way?
Finally, I also noticed a long delay (about 1 minute load time, a couple of timeouts) when refreshing the page that is not related to data retrival when creating about 200 polygons. Is this expected?
It's normal, as more points to draw, it costs more. But you have different option to try to optimize it.
One could be using a cursor tool with fastcursor to true. This will prevent the chart to be repainted every time the cursor is moved.
Another could be changing the map series to rectangles drawn directly to the canvas. Here you have another simple example:

Code: Select all

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

        FastLine fast1;
        CursorTool cursor1;
        double threshold1, threshold2;

        private void InitializeChart()
        {
            chartController1.Chart = tChart1;

            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;
            tChart1.Dock = DockStyle.Fill;

            fast1 = new FastLine(tChart1.Chart);
            fast1.FillSampleValues(500);
            fast1.Color = Color.Orange;

            threshold1 = fast1.YValues.Minimum + (fast1.YValues.Maximum - fast1.YValues.Minimum) / 3;
            threshold2 = fast1.YValues.Minimum + (fast1.YValues.Maximum - fast1.YValues.Minimum) / 3 * 2;

            tChart1.Draw();

            cursor1 = new CursorTool(tChart1.Chart);
            cursor1.XValue = fast1.Count / 2;
            cursor1.YValue = (fast1.YValues.Maximum - fast1.YValues.Minimum) / 2 + fast1.YValues.Minimum;

            cursor1.Style = CursorToolStyles.Vertical;
            cursor1.FastCursor = true;
            cursor1.FollowMouse = true;

            tChart1.Walls.Back.Visible = false;
            tChart1.BeforeDraw += new Steema.TeeChart.PaintChartEventHandler(tChart1_BeforeDraw);
        }

        void tChart1_BeforeDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
            g.Pen.Visible = false;
            int XLeft = fast1.CalcXPos(0);
            int XRight = fast1.CalcXPos(1);
            double XDiff = (double)(XRight-XLeft)/2;
            for (int i = 0; i < fast1.Count; i++)
            {
                if (fast1.YValues.Value[i] > threshold2) g.Brush.Color = Color.Red;
                else g.Brush.Color =(fast1.YValues.Value[i] > threshold1) ? Color.Blue : Color.Green;

                int a = (int)Math.Ceiling(fast1.CalcXPos(i) - XDiff);
                int b = tChart1.Axes.Left.CalcYPosValue(tChart1.Axes.Left.Maximum);
                int c = (int)Math.Ceiling(fast1.CalcXPos(i) + XDiff);
                int d = tChart1.Axes.Left.CalcYPosValue(tChart1.Axes.Left.Minimum);
                g.Rectangle(a, b, c, d);
            }
        }
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

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Tue Jul 21, 2009 9:29 pm

Thnaks for your help thus far. I have implemented the solution you last suggested using Graphics3D in the BeforeDrawSeries event of the chart. I have a behaviour where I change the date ranges on the XAxis. When I perform this action, I observe the attached video.

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Tue Jul 21, 2009 9:43 pm

I just uploaded the video. If you need the codec to view the video, it is available for download at http://www.techsmith.com/download/codecs.asp.

In the video, clicking the << button effectively adjusts the time range on the XAxis. The visible colored area over the legend is the problem. That area is a direct result of using the BeforeDrawAxes event to draw the rectangles directly, but I do not understand how. Is it possible that changing the dates ranges on the XAxis before the redraw (we recreate the entire chart, and then redraw the series) is causing this issue (adjusting the XAxis while waiting for data to return to rebuild the series). As you can see, once the redraw occurs all is good.

Is it possible to clear / hide the drawing that I have done (via Graphics3D) when adjusting the date range on the XAxis, effectivley wiping the slate clean, and then waiting for the series to redraw?

This operation will be very difficult to put into a sample app, and I cannot send the entire app (too many installation steps and dependencies). I hope the video will suffice.

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Tue Jul 21, 2009 10:22 pm

Not sure if this is related, but the rectangles have a transparency set and every time I click the "<<" and then the ">>" button (effectively moving the time range back, and then forward to the original time range) the transparency gets darker (the drawing seems to overwrite the last drawn items, resulting in what looks like a darker color, or less transparency).

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by Sandra » Wed Jul 22, 2009 8:33 am

Hello AndrewP,

I couldn't reproduce your problem here. Please, you could send us code of button <<, because we can reproduce the problem here. If is not possible to send code, please explain exactly what do the button because we try to solve the problem.

Thanks.
Best Regards,
Sandra Pazos / 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

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Wed Jul 22, 2009 3:06 pm

Is it possible to clear / hide the drawing that I have done (via Graphics3D) when adjusting the date range on the XAxis, effectivley wiping the slate clean, and then waiting for the series to redraw?

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Wed Jul 22, 2009 3:27 pm

Uploading a sample app.

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by Sandra » Thu Jul 23, 2009 8:28 am

Hello Andrew,

I I do not understand your problem because the video leaves a brown rectangle and here we see the applicació you have send and not appears rectangle.
Is this the problem? If the problem isn't it, please you could explain exactly what is your problem?

Thanks,
Best Regards,
Sandra Pazos / 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

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Thu Jul 23, 2009 4:01 pm

Yes, the problem is the color that appears outside of the chart area (white area where data is displayed). It appears brown on the video, and differing color on the sample I uploaded yesterday. I think what I need is a way to clear all the drawing I have done via Graphics3D when I click those buttons. I that possible?

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by Sandra » Fri Jul 24, 2009 8:16 am

Hello Andrew,

I couldn't reproduce your probleme here. In the application that you send: you can see rectangle brown or different color? Please, check sample that you send appears this rectangle. If appears, please you could say what is your version of TeeChartFor .Net ?

Thanks,
Best Regards,
Sandra Pazos / 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

AndrewP
Newbie
Newbie
Posts: 20
Joined: Tue May 12, 2009 12:00 am

Re: How do I optimize the Map series with many polygons?

Post by AndrewP » Fri Jul 24, 2009 3:34 pm

I have uploaded one more video, just now. This one is of the problem in the sample app that I uploaded a few days ago. As you can clearly see as indicated by the mouse movements, there are areas of color outside of the chart axis area (where data is usually displayed) that should not be there. As you can see by the TeeChart dll attached to my sample project, I am using the latest .Net version. You can feel free to continue to troubleshoot this issue, but I am putting this issue on hold for the time being. I have chosen to go with another solution not related to Graphics3D.

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

Re: How do I optimize the Map series with many polygons?

Post by Narcís » Mon Jul 27, 2009 1:31 pm

Hi AndrewP,

Implementing the BeforeDrawAxes event in your project as below solves the problem.

Code: Select all

        private void tChart1_BeforeDrawAxes(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
					g.Pen.Visible = false;
					int XLeft = fast1.CalcXPos(0);
					int XRight = fast1.CalcXPos(1);
					double XDiff = (double)(XRight - XLeft) / 2;
					for (int i = 0; i < fast1.Count; i++)
					{
						if (fast1.YValues.Value[i] > threshold2) g.Brush.Color = Color.Red;
						else g.Brush.Color = (fast1.YValues.Value[i] > threshold1) ? Color.Blue : Color.Green;

						int a = (int)Math.Ceiling(fast1.CalcXPos(i) - XDiff);
						int b = tChart1.Axes.Left.CalcYPosValue(tChart1.Axes.Left.Maximum);
						int c = (int)Math.Ceiling(fast1.CalcXPos(i) + XDiff);
						int d = tChart1.Axes.Left.CalcYPosValue(tChart1.Axes.Left.Minimum);

						Rectangle chartRect = tChart1.Chart.ChartRect;
						Rectangle rect = new Rectangle(a, b, c-a, d-b);
						if (chartRect.IntersectsWith(rect))
						{
							g.Rectangle(a, b, c, d);	
						}						
					}
        }
Hope this helps!
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

Post Reply