CircularGauge iOS vs Android/WP7

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
jjbonastre
Newbie
Newbie
Posts: 4
Joined: Mon Oct 14, 2013 12:00 am

CircularGauge iOS vs Android/WP7

Post by jjbonastre » Thu Oct 17, 2013 7:28 am

Hi!

I'm creating a circular gauge with the following code (iOS):

Code: Select all

		public static void DrawGaugeChart (TChart tChart, ResourceServiceData data, Rectangle chartBounds, int titleTopMargin, Thickness margin, int orientation)
		{
			Console.WriteLine ("DrawGaugeChart");

			if ((data.ServiceData == null) || (data.AccServiceData == null) || (data.CallData == null) || (data.AccCallData == null))
				return;

			tChart.Series.Clear ();
			tChart.Header.Text = data.Resource.Name;
			tChart.Header.Alignment = MonoTouch.CoreText.CTTextAlignment.Center;
			tChart.Header.Font.Size = 16;
			tChart.SubHeader.Visible = false;

			tChart.AfterDraw += tChart_AfterDraw;

			var gauge = new CircularGauge ();
			gauge.Value = data.ServiceData.ServiceData [0].LevelService;
			gauge.LinearGauge.Visible = true;
			gauge.AutoValueLinearGauge = false;
			gauge.LinearGauge.Value = data.AccServiceData.ServiceData [0].LevelService;
			switch (orientation) {
			case 0:
				gauge.CustomBounds = new Rectangle (margin.Left, margin.Top + titleTopMargin, chartBounds.Width / 2 - margin.Left - margin.Right, chartBounds.Height / 2 - margin.Top - margin.Bottom - titleTopMargin);
				break;
			case 1:
				gauge.CustomBounds = new Rectangle (margin.Left, margin.Top + titleTopMargin, chartBounds.Width / 4 - margin.Left - margin.Right, chartBounds.Height - margin.Top - margin.Bottom - titleTopMargin);
				break;
			}
			Console.WriteLine ("ServiceLevel: " + gauge.CustomBounds);

			if (data.IsServiceLevelAlarm) {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Red.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			} else {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Green.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			}


			var limit = data.ServiceLevelLimit;
			if (limit == 0) {
				gauge.GreenLineStartValue = 90;
				gauge.GreenLineEndValue = 100;
				gauge.RedLineStartValue = 0;
				gauge.RedLineEndValue = 90;
			} else {
				if (limit > 0) {
					gauge.GreenLineStartValue = 0;
					gauge.GreenLineEndValue = limit;
					gauge.RedLineStartValue = limit;
					gauge.RedLineEndValue = 100;
				} else {
					gauge.GreenLineStartValue = Math.Abs (limit);
					gauge.GreenLineEndValue = 100;
					gauge.RedLineStartValue = 0;
					gauge.RedLineEndValue = Math.Abs (limit);
				}
			}

			tChart.Series.Add (gauge);

			int attentionLevelAcc = 100;
			int attentionLevelInt = 100;

			if (data.AccCallData.CallsData [0].NumberAnsweredCalls > 0) {
				attentionLevelAcc = (int)(data.AccCallData.CallsData [0].NumberUnderThresholdAnsweredCalls * 100 / data.AccCallData.CallsData [0].NumberAnsweredCalls);
			}
			if (data.CallData.CallsData [0].NumberAnsweredCalls > 0) {
				attentionLevelInt = (int)(data.CallData.CallsData [0].NumberUnderThresholdAnsweredCalls * 100 / data.CallData.CallsData [0].NumberAnsweredCalls);
			}

			gauge = new CircularGauge ();
			gauge.Value = attentionLevelInt;
			gauge.LinearGauge.Visible = true;
			gauge.AutoValueLinearGauge = false;
			gauge.LinearGauge.Value = attentionLevelAcc;

			switch (orientation) {
			case 0:
				gauge.CustomBounds = new Rectangle (margin.Left + chartBounds.Width / 2, margin.Top + titleTopMargin, chartBounds.Width / 2 - margin.Left - margin.Right, chartBounds.Height / 2 - margin.Top - margin.Bottom - titleTopMargin);
				break;
			case 1:
				gauge.CustomBounds = new Rectangle (margin.Left + chartBounds.Width / 4, margin.Top + titleTopMargin, chartBounds.Width / 4 - margin.Left - margin.Right, chartBounds.Height - margin.Top - margin.Bottom - titleTopMargin);
				break;
			}
			Console.WriteLine ("AttentionLevel: " + gauge.CustomBounds);

			if (data.IsAttentionLevelAlarm) {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Red.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			} else {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Green.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			}

			limit = data.AttentionLevelLimit;
			if (limit == 0) {
				gauge.GreenLineStartValue = 90;
				gauge.GreenLineEndValue = 100;
				gauge.RedLineStartValue = 0;
				gauge.RedLineEndValue = 90;
			} else {
				if (limit > 0) {
					gauge.GreenLineStartValue = 0;
					gauge.GreenLineEndValue = limit;
					gauge.RedLineStartValue = limit;
					gauge.RedLineEndValue = 100;
				} else {
					gauge.GreenLineStartValue = Math.Abs (limit);
					gauge.GreenLineEndValue = 100;
					gauge.RedLineStartValue = 0;
					gauge.RedLineEndValue = Math.Abs (limit);
				}
			}

			tChart.Series.Add (gauge);

			gauge = new CircularGauge ();
			gauge.Value = data.ServiceData.ServiceData [0].LevelAbandon;

			gauge.LinearGauge.Visible = true;
			gauge.AutoValueLinearGauge = false;
			gauge.LinearGauge.Value = data.AccServiceData.ServiceData [0].LevelAbandon;

			switch (orientation) {
			case 0:
				gauge.CustomBounds = new Rectangle (margin.Left, margin.Top + titleTopMargin + chartBounds.Height / 2, chartBounds.Width / 2 - margin.Left - margin.Right, chartBounds.Height / 2 - margin.Top - margin.Bottom - titleTopMargin);
				break;
			case 1:
				gauge.CustomBounds = new Rectangle (margin.Left + chartBounds.Width / 2, margin.Top + titleTopMargin, chartBounds.Width / 4 - margin.Left - margin.Right, chartBounds.Height - margin.Top - margin.Bottom - titleTopMargin);
				break;
			}

			Console.WriteLine ("AbandonLevel: " + gauge.CustomBounds);

			if (data.IsAbandonLevelAlarm) {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Red.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			} else {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Green.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			}

			limit = data.AbandonLevelLimit;
			if (limit == 0) {
				gauge.GreenLineStartValue = 0;
				gauge.GreenLineEndValue = 10;
				gauge.RedLineStartValue = 10;
				gauge.RedLineEndValue = 100;
			} else {
				if (limit > 0) {
					gauge.GreenLineStartValue = 0;
					gauge.GreenLineEndValue = limit;
					gauge.RedLineStartValue = limit;
					gauge.RedLineEndValue = 100;
				} else {
					gauge.GreenLineStartValue = Math.Abs (limit);
					gauge.GreenLineEndValue = 100;
					gauge.RedLineStartValue = 0;
					gauge.RedLineEndValue = Math.Abs (limit);
				}
			}
			tChart.Series.Add (gauge);

			gauge = new CircularGauge ();
			gauge.Value = data.ServiceData.ServiceData [0].Speaking;

			gauge.LinearGauge.Visible = true;
			gauge.LinearGauge.Value = data.AccServiceData.ServiceData [0].Speaking;
			gauge.AutoValueLinearGauge = false;

			switch (orientation) {
			case 0:
				gauge.CustomBounds = new Rectangle (margin.Left + chartBounds.Width / 2, margin.Top + titleTopMargin + chartBounds.Height / 2, chartBounds.Width / 2 - margin.Left - margin.Right, chartBounds.Height / 2 - margin.Top - margin.Bottom - titleTopMargin);
				break;
			case 1:
				gauge.CustomBounds = new Rectangle (margin.Left + 3 * chartBounds.Width / 4, margin.Top + titleTopMargin, chartBounds.Width / 4 - margin.Left - margin.Right, chartBounds.Height - margin.Top - margin.Bottom - titleTopMargin);
				break;
			}

			Console.WriteLine ("Speaking: " + gauge.CustomBounds);

			if (data.IsSpeakingLevelAlarm) {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Red.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			} else {
				gauge.FaceBrush.Gradient.Direction = GradientDirection.TopBottom;
				gauge.FaceBrush.Gradient.UseMiddle = false;
				gauge.FaceBrush.Gradient.StartColor = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.FaceBrush.Gradient.EndColor = UIColor.Green.CGColor;
				gauge.LinearGauge.ValueAreaBrush.Solid = true;
				gauge.LinearGauge.ValueAreaBrush.Color = UIColor.FromRGBA (161, 161, 161, 255).CGColor;
				gauge.LinearGauge.ValueAreaBrush.Visible = true;
			}


			limit = data.SpeakingLevelLimit;
			if (limit == 0) {
				gauge.GreenLineStartValue = 90;
				gauge.GreenLineEndValue = 100;
				gauge.RedLineStartValue = 0;
				gauge.RedLineEndValue = 90;
			} else {
				if (limit > 0) {
					gauge.GreenLineStartValue = 0;
					gauge.GreenLineEndValue = limit;
					gauge.RedLineStartValue = limit;
					gauge.RedLineEndValue = 100;
				} else {
					gauge.GreenLineStartValue = Math.Abs (limit);
					gauge.GreenLineEndValue = 100;
					gauge.RedLineStartValue = 0;
					gauge.RedLineEndValue = Math.Abs (limit);
				}
			}


			tChart.Series.Add (gauge);

			tChart.Hidden = false;
		}

		private static void GetSeriesMark (Series series, GetSeriesMarkEventArgs e)
		{
			var value = series.GetMarkValue (e.ValueIndex);
			if (value > 0) {
				e.MarkText = value + "";
			} else {
				e.MarkText = "";
			}
		}
		
		void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
		{
			int fontSize = 12;                              
			int subTitleTopMargin = 0;
			RectangleF chartBounds = ContentView.Bounds;
			string text = NSBundle.MainBundle.LocalizedString ("Service Level","");
			PointF p = new PointF(0, 0);
			UIColor.White.SetColor();
			g.Font.Color = UIColor.White.CGColor;
			g.Font.Size = fontSize;
			g.Pen.Color=UIColor.White.CGColor;

			if ((UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeLeft) || (UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeRight)) {
				subTitleTopMargin = 0;
				p = new PointF (chartBounds.Width / 4 / 2 - (g.TextWidth (text) / 2), titleTopMargin + subTitleTopMargin + (g.TextHeight (text) / 2));
			} else {
				p = new PointF(chartBounds.Width / 2 / 2 - (g.TextWidth(text) / 2), titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			}


			g.TextOut(Convert.ToInt32(p.X), Convert.ToInt32(p.Y), text);

			text = NSBundle.MainBundle.LocalizedString ("Attention Level","");
			if ((UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeLeft) || (UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeRight)) {
				subTitleTopMargin = 0;
				p = new PointF(chartBounds.Width / 4 / 2 - (g.TextWidth(text) / 2) + chartBounds.Width / 4, titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			} else {
				p = new PointF(chartBounds.Width / 2 / 2 - (g.TextWidth(text) / 2) + chartBounds.Width / 2, titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			}

			g.Font.Color = ThemeManager.GraphSubTitleColor.CGColor;
			g.Font.Size = fontSize;
			g.TextOut(Convert.ToInt32(p.X), Convert.ToInt32(p.Y), text);

			text = NSBundle.MainBundle.LocalizedString ("Abandon Level","");
			if ((UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeLeft) || (UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeRight)) {
				subTitleTopMargin = 0;
				p = new PointF(chartBounds.Width / 4 / 2 - (g.TextWidth(text) / 2) + chartBounds.Width / 2, titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			} else {
				p = new PointF(chartBounds.Width / 2 / 2 - (g.TextWidth(text) / 2), chartBounds.Height / 2 + titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			}

			g.Font.Color = ThemeManager.GraphSubTitleColor.CGColor;
			g.Font.Size = fontSize;
			g.TextOut(Convert.ToInt32(p.X), Convert.ToInt32(p.Y), text);

			text = NSBundle.MainBundle.LocalizedString ("Speaking","");
			if ((UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeLeft) || (UIDevice.CurrentDevice.Orientation == UIDeviceOrientation.LandscapeRight)) {
				subTitleTopMargin = 0;
				p = new PointF(3 * chartBounds.Width / 4 + chartBounds.Width / 4 / 2 - (g.TextWidth(text) / 2), titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			} else {
				p = new PointF(chartBounds.Width / 2 / 2 - (g.TextWidth(text) / 2) + chartBounds.Width / 2, chartBounds.Height / 2 + titleTopMargin + subTitleTopMargin + (g.TextHeight(text) / 2));
			}

			g.Font.Color = ThemeManager.GraphSubTitleColor.CGColor;
			g.Font.Size = fontSize;
			g.TextOut(Convert.ToInt32(p.X), Convert.ToInt32(p.Y), text);

			Chart.Hidden = false;
		}
Result:
gauge_iphone.png
gauge_iphone.png (131.27 KiB) Viewed 7752 times
Quite different from the Windows Phone or Android version:
gauge_wm.png
gauge_wm.png (202.57 KiB) Viewed 7746 times
Problem 1: In iphone there's no way I can paint the chart after draw with a white color. Any suggestion?

Problem 2: If I try to use UIColor.Gray an exception is thrown. I solved this using UIColor.FromRGBA (161, 161, 161, 255) instead.

Problem 3: The gauges don't look really pretty in iOS. Is there any way to make them look like the Android/Phone versions?

The code is similar in windows phone, but replacing Color types with the appropriate ones.

Thanks!

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

Re: CircularGauge iOS vs Android/WP7

Post by Sandra » Thu Oct 17, 2013 5:07 pm

Hello jjbonastre,

We have reproduced your problem and we have already fixed it. If you have the source code version, we can give you the code to solution the bug. For this reason, could you tell us if you have the source code of TeeChart Xamarin Ios?

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

jjbonastre
Newbie
Newbie
Posts: 4
Joined: Mon Oct 14, 2013 12:00 am

Re: CircularGauge iOS vs Android/WP7

Post by jjbonastre » Fri Oct 18, 2013 9:00 am

Hi!

We have the license for the source code version. If you can provide the patch that would be great. Thanks!

Pep
Site Admin
Site Admin
Posts: 3295
Joined: Fri Nov 14, 2003 5:00 am
Contact:

Re: CircularGauge iOS vs Android/WP7

Post by Pep » Fri Oct 18, 2013 9:07 am

Hi jjbonastre,

I've just sent a mail directly to you which includes the fixed file, and also the new dll compiled with latest source files.

Please, do not hesitate to contact us in the case you still having problems.

Post Reply