colorgrid takes long time to draw and resize

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
johnf
Newbie
Newbie
Posts: 5
Joined: Fri May 09, 2014 12:00 am

colorgrid takes long time to draw and resize

Post by johnf » Mon May 18, 2015 3:00 pm

Hi,

I am using a colorgrid to generate an image where the number of points can be large (i.e. 1000x1000 or 2000x2000). The color grid takes a long time to generate the plot and also every time I resize the plot it also takes a long time. I recall a version back in 2007 that did this faster. See attached example code.

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Steema.TeeChart;
using Steema.TeeChart.Styles;
using Steema.TeeChart.Tools;

namespace ColorGridExample
{

	public partial class Form1 : Form
	{
		TChart _chart;
		private ColorGrid _colorGrid;
		private LegendPalette _legendPalette;
		private Color[] _rainbowLowBlackPalette;

		private double _colorBarMax;
		private double _colorBarMin;
		private double _colorBarStep;

		private double[] _xData;
		private double[] _yData;
		private double[] _zData;

		public Form1()
		{
			InitializeComponent();

			_colorBarMax = 0.0;
			_colorBarMin = -50.0;
			_colorBarStep = 5.0;

			SetupColorGrid();
			GenerateData();

			_colorGrid.Add(_xData, _zData, _yData);

			_colorGrid.IrregularGrid = true;
			_legendPalette.Series = _colorGrid;
			_legendPalette.Gradient.Visible = false;
		}

		public void SetupColorGrid()
		{
			this.SuspendLayout();
			this._chart = new Steema.TeeChart.TChart();
			this._chart.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
			this._chart.Aspect.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
			this._chart.Aspect.View3D = false;
			this._chart.Dock = System.Windows.Forms.DockStyle.Fill;
			this._chart.Location = new System.Drawing.Point(0, 0);
			this._chart.Name = "tChart1";
			this._chart.Size = new System.Drawing.Size(700, 500);
			this._chart.TabIndex = 0;
			this.Controls.Add(this._chart);


			_chart.Header.Visible = false;
			_chart.Legend.Visible = false;
			_chart.Panel.MarginUnits = Steema.TeeChart.PanelMarginUnits.Pixels;
			_chart.Panel.MarginRight = 80;

			_chart.Axes.Bottom.Automatic = false;
			_chart.Axes.Bottom.AutomaticMaximum = false;
			_chart.Axes.Bottom.AutomaticMinimum = false;
			_chart.Axes.Bottom.Increment = 0.2;
			_chart.Axes.Bottom.Maximum = 1.0;
			_chart.Axes.Bottom.Minimum = -1.0;

			_chart.Axes.Left.Automatic = false;
			_chart.Axes.Left.AutomaticMaximum = false;
			_chart.Axes.Left.AutomaticMinimum = false;
			_chart.Axes.Left.Increment = 0.2;
			_chart.Axes.Left.Maximum = 1.0;
			_chart.Axes.Left.Minimum = -1.0;

			this._colorGrid = new ColorGrid();
			this._colorGrid.Pen.Visible = false;
			this._colorGrid.Title = "colorGrid1";
			this._colorGrid.UseColorRange = false;
			this._colorGrid.UsePalette = true;
			this._colorGrid.XStep = 1;

			this._chart.Series.Add(this._colorGrid);

			LoadColorPalette();
			_legendPalette = new LegendPalette(_chart.Chart);

			_legendPalette.Axis = LegendPaletteAxis.laOther;
			_legendPalette.Width = 60;
			_legendPalette.Pen.Visible = false;
			_legendPalette.Series = _colorGrid;

			this.ResumeLayout(false);

			_chart.SizeChanged += new System.EventHandler(this.Chart_SizeChanged);


		}

		private void Chart_SizeChanged(object sender, EventArgs e)
		{
			_chart.AutoRepaint = false;
			_legendPalette.Left = _chart.Width - _legendPalette.Width - 10;
			_legendPalette.Top = (_chart.Height - _legendPalette.Height) / 2;
			_chart.AutoRepaint = true;
			_chart.Refresh();
		}

		private void LoadColorPalette()
		{
			double minValue = _colorBarMin;
			double maxValue = _colorBarMax;
			double delta = _colorBarMax - _colorBarMin;

			_colorGrid.ClearPalette();
			_rainbowLowBlackPalette = new Color[256];
			int redIndex;
			int greenIndex;
			int blueIndex;
			for (int i = 0; i < 256; i++)
			{
				if (i == 0)
				{
					redIndex = 0;
					greenIndex = 0;
					blueIndex = 0;
				}
				else if (i > 0 && i <= 32)
				{
					redIndex = -255 / 32 * i + 255;
					greenIndex = 0;
					blueIndex = 255;
				}
				else if (i > 32 && i <= 85)
				{
					redIndex = 0;
					greenIndex = (255 / (85 - 32)) * (i - 32);
					blueIndex = 255;

				}
				else if (i > 85 && i <= 143)
				{
					redIndex = 0;
					greenIndex = 255;
					blueIndex = (-255 / (143 - 86)) * (i - 143);
				}
				else if (i > 143 && i <= 199)
				{
					redIndex = (255 / (199 - 143)) * (i - 143);
					greenIndex = 255;
					blueIndex = 0;
				}
				else
				{
					redIndex = 255;
					greenIndex = (-255 / (255 - 199)) * (i - 255);
					blueIndex = 0;
				}
				_rainbowLowBlackPalette[i] = Color.FromArgb(redIndex, greenIndex, blueIndex);

				_colorGrid.AddPalette(((delta / 255.0) * (double)i + minValue), _rainbowLowBlackPalette[i]);
			}
		}

		private void GenerateData()
		{
			var Nx = 50;
			var Ny = 25;
			var Nu = 1001;
			var Nv = 1001;

			_xData = new double[Nu*Nv];
			_yData = new double[Nu*Nv];
			_zData = new double[Nu*Nv];

			var du = 2.0 / (Nu - 1);
			var dv = 2.0 / (Nv - 1);

			int k = 0;
			for (int i=0; i<Nu; i++)
			{
				var v = -1.0 + dv * i;
				for (int j=0; j<Nv; j++)
				{
					var u = -1.0 + du * j;
					var argx = 0.5*Nx*u;
					var argy = 0.5*Ny*v;

					_xData[k] = u;
					_yData[k] = v;
					_zData[k] = 20.0 * Math.Log10(Math.Abs(sinc(argx) * sinc(argy)));
					k++;
				}
			}
		}

		private double sinc(double x)
		{
			if (Math.Abs(x) < 1.0e-7)
			{
				return 1.0;
			}
			else
			{
				return (Math.Sin(Math.PI * x) / (Math.PI * x));
			}
		}

	}
}


namespace ColorGridExample
{
	partial class Form1
	{
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#region Windows Form Designer generated code

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			// 
			// Form1
			// 
			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			this.ClientSize = new System.Drawing.Size(600, 500);
			
			this.Name = "Form1";
			this.Text = "Form1";
			this.ResumeLayout(false);
		}

		#endregion

	}
}


Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: colorgrid takes long time to draw and resize

Post by Christopher » Tue May 19, 2015 10:14 am

Hello,

This is what your application looks like using the present source code and VS2013's profiler:
profile.PNG
profile.PNG (131.98 KiB) Viewed 16682 times
As you can see, the assembly taking up the time here is System.Drawing.dll. I ran a test using the Stopwatch class and found that the application on this relatively old machine runs in 12040 milliseconds, whereas using a version of TeeChart.dll from 2009 the application run in 14420 millseconds. While I agree that over 12 seconds for the chart to render is unacceptable, I'm not entirely sure that older versions of TeeChart would have run significantly quicker. What is more, given that it is the drawing of Lines and Polygons which is taking the time, I'm not sure how to better this performance by doing something other than feeding the chart less lines and polygons to draw. I'll have to have a further think about this.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

johnf
Newbie
Newbie
Posts: 5
Joined: Fri May 09, 2014 12:00 am

Re: colorgrid takes long time to draw and resize

Post by johnf » Wed May 20, 2015 2:50 am

I do not get the flat line like you. Also, try resizing the window. I get that the resize takes almost twice as long.
In addition (although it has been a while since I looked at this) I had found that in the past using
this._chart.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;
ran faster. However, it seems that now it is having minimal improvement.

John

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: colorgrid takes long time to draw and resize

Post by Christopher » Wed May 20, 2015 9:40 am

Hello,

I'm using the latest TeeChart.dll, version 4.1.2015.05140.

Using a more modern machine, I get the following results:
TeeChart.dll 4.1.2015.05140 (14/05/2015): draw, 6658ms. resize, 6358ms
TeeChart.dll 3.5.3700.30574 (17/02/2009): draw, 8188ms. resize, 6770ms

In both versions of TeeChart the most called TeeChart function is the same:

TeeChart.dll 4.1.2015.05140:
v2015.PNG
v2015.PNG (15.73 KiB) Viewed 16663 times
TeeChart.dll 3.5.3700.30574:
v3.PNG
v3.PNG (14.3 KiB) Viewed 16648 times
what is more, the Steema.TeeChart.Styles.Custom3DGrid.SearchValue function is identical in both versions. I have added a further improvement to ColorGrid performance to our database with id=1215 so that further attention can be given to this area.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

johnf
Newbie
Newbie
Posts: 5
Joined: Fri May 09, 2014 12:00 am

Re: colorgrid takes long time to draw and resize

Post by johnf » Wed May 20, 2015 1:18 pm

When I drag the corner of the window to resize it, the redraw takes almost twice as long than the initial rendering.
Do you notice this on your computer?

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: colorgrid takes long time to draw and resize

Post by Christopher » Wed May 20, 2015 1:41 pm

johnf wrote:When I drag the corner of the window to resize it, the redraw takes almost twice as long than the initial rendering.
Do you notice this on your computer?
The code I used to produce the figures I mentioned in my last post is in the ticket id=1215. Using that code, are your results different in magnitude?
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

johnf
Newbie
Newbie
Posts: 5
Joined: Fri May 09, 2014 12:00 am

Re: colorgrid takes long time to draw and resize

Post by johnf » Thu May 21, 2015 2:51 am

Hi Christopher,

Thanks for the reply. How are you getting the times to draw and resize?
Where in the profiling report are you looking?
Picture1.png
Picture1.png (303.21 KiB) Viewed 16651 times
John

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: colorgrid takes long time to draw and resize

Post by Christopher » Thu May 21, 2015 10:49 am

Hi John,

No, I couldn't find a global timer for the TeeChart painting operation either within the profiler, so in the code I used to reproduce the issue, present in the ticket id=1215 I mentioned, I had to use .NET framework Stopwatch.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

johnf
Newbie
Newbie
Posts: 5
Joined: Fri May 09, 2014 12:00 am

Re: colorgrid takes long time to draw and resize

Post by johnf » Fri May 22, 2015 1:31 pm

Hi Christopher,

Where did you place the calls to the stopwatch?

John

Christopher
Guru
Posts: 1603
Joined: Fri Nov 15, 2002 12:00 am

Re: colorgrid takes long time to draw and resize

Post by Christopher » Fri May 22, 2015 2:44 pm

Hello John,

Here's the code I used:

Code: Select all

                private Stopwatch watch = new Stopwatch();
		private ColorGrid _colorGrid;
		private LegendPalette _legendPalette;
		private Color[] _rainbowLowBlackPalette;

		private double _colorBarMax;
		private double _colorBarMin;
		private double _colorBarStep;

		private double[] _xData;
		private double[] _yData;
		private double[] _zData;


		private void InitializeChart()
		{
			_colorBarMax = 0.0;
			_colorBarMin = -50.0;
			_colorBarStep = 5.0;

			watch.Reset();
			watch.Start();

			tChart1.AfterDraw += TChart1_AfterDraw;

			SetupColorGrid();
			GenerateData();

			_colorGrid.Add(_xData, _zData, _yData);

      _colorGrid.IrregularGrid = true;
			_legendPalette.Series = _colorGrid;
			_legendPalette.Gradient.Visible = false;
		}

		private void TChart1_AfterDraw(object sender, Graphics3D g)
		{
			watch.Stop();
			label1.Text = watch.ElapsedMilliseconds.ToString();
		}

		public void SetupColorGrid()
		{
			this.SuspendLayout();
			this.tChart1.Aspect.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
			this.tChart1.Aspect.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
			this.tChart1.Aspect.View3D = false;


			tChart1.Header.Visible = false;
			tChart1.Legend.Visible = false;
			tChart1.Panel.MarginUnits = Steema.TeeChart.PanelMarginUnits.Pixels;
			tChart1.Panel.MarginRight = 80;

			tChart1.Axes.Bottom.Automatic = false;
			tChart1.Axes.Bottom.AutomaticMaximum = false;
			tChart1.Axes.Bottom.AutomaticMinimum = false;
			tChart1.Axes.Bottom.Increment = 0.2;
			tChart1.Axes.Bottom.Maximum = 1.0;
			tChart1.Axes.Bottom.Minimum = -1.0;

			tChart1.Axes.Left.Automatic = false;
			tChart1.Axes.Left.AutomaticMaximum = false;
			tChart1.Axes.Left.AutomaticMinimum = false;
			tChart1.Axes.Left.Increment = 0.2;
			tChart1.Axes.Left.Maximum = 1.0;
			tChart1.Axes.Left.Minimum = -1.0;

			this._colorGrid = new ColorGrid();
			this._colorGrid.Pen.Visible = false;
			this._colorGrid.Title = "colorGrid1";
			this._colorGrid.UseColorRange = false;
			this._colorGrid.UsePalette = true;
			this._colorGrid.XStep = 1;

			this.tChart1.Series.Add(this._colorGrid);

			LoadColorPalette();
			_legendPalette = new LegendPalette(tChart1.Chart);

			_legendPalette.Axis = LegendPaletteAxis.laOther;
			_legendPalette.Width = 60;
			_legendPalette.Pen.Visible = false;
			_legendPalette.Series = _colorGrid;

			this.ResumeLayout(false);

			tChart1.SizeChanged += new System.EventHandler(this.Chart_SizeChanged);


		}

		private void Chart_SizeChanged(object sender, EventArgs e)
		{
			watch.Reset();
			watch.Start();
			tChart1.AutoRepaint = false;
			_legendPalette.Left = tChart1.Width - _legendPalette.Width - 10;
			_legendPalette.Top = (tChart1.Height - _legendPalette.Height) / 2;
			tChart1.AutoRepaint = true;
			tChart1.Refresh();
		}

		private void LoadColorPalette()
		{
			double minValue = _colorBarMin;
			double maxValue = _colorBarMax;
			double delta = _colorBarMax - _colorBarMin;

			_colorGrid.ClearPalette();
			_rainbowLowBlackPalette = new Color[256];
			int redIndex;
			int greenIndex;
			int blueIndex;
			for (int i = 0; i < 256; i++)
			{
				if (i == 0)
				{
					redIndex = 0;
					greenIndex = 0;
					blueIndex = 0;
				}
				else if (i > 0 && i <= 32)
				{
					redIndex = -255 / 32 * i + 255;
					greenIndex = 0;
					blueIndex = 255;
				}
				else if (i > 32 && i <= 85)
				{
					redIndex = 0;
					greenIndex = (255 / (85 - 32)) * (i - 32);
					blueIndex = 255;

				}
				else if (i > 85 && i <= 143)
				{
					redIndex = 0;
					greenIndex = 255;
					blueIndex = (-255 / (143 - 86)) * (i - 143);
				}
				else if (i > 143 && i <= 199)
				{
					redIndex = (255 / (199 - 143)) * (i - 143);
					greenIndex = 255;
					blueIndex = 0;
				}
				else
				{
					redIndex = 255;
					greenIndex = (-255 / (255 - 199)) * (i - 255);
					blueIndex = 0;
				}
				_rainbowLowBlackPalette[i] = Color.FromArgb(redIndex, greenIndex, blueIndex);

				_colorGrid.AddPalette(((delta / 255.0) * (double)i + minValue), _rainbowLowBlackPalette[i]);
			}
		}

		private void GenerateData()
		{
			var Nx = 50;
			var Ny = 25;
			var Nu = 1001;
			var Nv = 1001;

			_xData = new double[Nu * Nv];
			_yData = new double[Nu * Nv];
			_zData = new double[Nu * Nv];

			var du = 2.0 / (Nu - 1);
			var dv = 2.0 / (Nv - 1);

			int k = 0;
			for (int i = 0; i < Nu; i++)
			{
				var v = -1.0 + dv * i;
				for (int j = 0; j < Nv; j++)
				{
					var u = -1.0 + du * j;
					var argx = 0.5 * Nx * u;
					var argy = 0.5 * Ny * v;

					_xData[k] = u;
					_yData[k] = v;
					_zData[k] = 20.0 * Math.Log10(Math.Abs(sinc(argx) * sinc(argy)));
					k++;
				}
			}
		}

		private double sinc(double x)
		{
			if (Math.Abs(x) < 1.0e-7)
			{
				return 1.0;
			}
			else
			{
				return (Math.Sin(Math.PI * x) / (Math.PI * x));
			}
		}
The calls to the instance of Stopwatch "watch" are on lines 21, 22, 38, 39, 95 and 96.
Best Regards,
Christopher Ireland / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Instructions - How to post in this forum

Post Reply