Page 1 of 1

Annotations do not render. Steema.TeeChart.NET.Xamarin.Forms v4.2021.2.25

Posted: Mon Mar 22, 2021 2:59 am
by 18286055
Annotation Tool Popup doesn't respect placements. Width and Height are both zero, but the bounds show correct sizing. It always renders off the screen, no matter what placement ( left ( x ), top ( y ) ) I set it to.

What is displayed:
0dc96b97-fb87-4518-939d-6a7524443b85.png
0dc96b97-fb87-4518-939d-6a7524443b85.png (18.46 KiB) Viewed 29957 times
Current settings with the above view:
annotations.PNG
annotations.PNG (57.27 KiB) Viewed 29957 times
Previous possible related issue

Re: Annotation Tool Popup doesn't respect placements.

Posted: Mon Mar 22, 2021 2:52 pm
by 18286055
This occurs on both android and iOS.

Re: Annotation Tool Popup doesn't respect placements.

Posted: Mon Mar 22, 2021 4:28 pm
by 18286055
private void Setup()

Code: Select all

	private void Setup()
	{
		// ...
		
		AnnotationTool = new Annotation(Chart1)
						 {
							 Active = true,
							 Position = AnnotationPositions.Custom,
							 Text = ViewModel.SelectedItemDescription,
							 AutoSize = true,
							 TextAlign = TextAlignment.Start,
							 AllowEdit = false
						 };
						 
		// ...
	}		
	
	// AnnotationTool.CoerceVisibleAnnotation(Chart1.ChartBounds, Chart1.Title.ShapeBounds, ViewModel.AnnotationHeightOffset);
	public static void CoerceVisibleAnnotation( this Annotation tool, in Rectangle chart, in Rectangle title, in double offset )
	{
		Rectangle startBounds = tool.Bounds;
		double width = tool.Width;
		double height = tool.Height;

		if ( tool.Bounds.Right > chart.Right ) { tool.Left = chart.Right - width - offset; }

		if ( tool.Left <= chart.Left ) { tool.Left = offset; }

		if ( tool.Top <= title.Bottom ) { tool.Top = title.Bottom + offset; }

		if ( tool.Bounds.Bottom >= chart.Bottom ) { tool.Top = chart.Bottom - height - offset; }
	}

Re: Annotation Tool Popup doesn't respect placements.

Posted: Tue Mar 23, 2021 6:10 am
by Pep
Hello,
please, take a look at this post, because most likely the problem is caused by the object positioning over the Chart, and here you will find how position must be calculated.

Re: Annotation Tool Popup doesn't respect placements.

Posted: Tue Mar 23, 2021 6:17 pm
by 18286055
Yes, I do that to find the target point. If you notice, the arrow points to the selected point. The issue is the annotation; It is not being rendered at all. I tried to center it regardless of what point is chosen.

Code: Select all


public static class ChartExtensions
{
	
	public static double GetLocalMaximum( this Line line, bool isVertical )
	{
		var max = double.MinValue;

		//for (int i = 0; i < line.Count; i++)
		for ( int i = line.FirstVisibleIndex; i <= line.LastVisibleIndex; i++ )
		{
			double v = isVertical
						   ? line.CalcYPos(i)
						   : line.CalcXPos(i);

			max = Math.Max(max, v);
		}

		return max;
	}
	public static double GetLocalMinimum( this Line line, bool isVertical )
	{
		var min = double.MaxValue;

		//for (int i = 0; i < line.Count; i++)
		for ( int i = line.FirstVisibleIndex; i <= line.LastVisibleIndex; i++ )
		{
			double v = isVertical
						   ? line.CalcYPos(i)
						   : line.CalcXPos(i);

			min = Math.Min(min, v);
		}

		return min;
	}
	public static double LocalAveragePos( this Line line, out double min, out double max, bool vertical )
	{
		min = line.GetLocalMinimum(vertical);
		max = line.GetLocalMaximum(vertical);

		return Average(min, max);
	}

	public static void ConfigureAnnotations( this Annotation tool, bool floating, string text )
	{
		tool.Shape.TextFormat = TextFormat.Html;
		tool.Shape.Font.Size = 15;

		tool.Position = floating
							? AnnotationPositions.Custom
							: AnnotationPositions.RightTop;

		tool.Text = text;
		tool.AutoSize = true;
		tool.Active = !string.IsNullOrWhiteSpace(text);
		tool.Invalidate();
	}

	public static double AverageWidth( this Rectangle bounds ) => Average(bounds.Left, bounds.Right);
	public static double AverageHeight( this Rectangle bounds ) => Average(bounds.Top, bounds.Bottom);
	public static double Average( params double[] values ) => values.Sum() / values.Length;
}

// then the methods to set the targets

private void NearestPointToolOnChange( object sender, NearestPointEventArgs e )
{
	try
	{
		ViewModel.CurrentPointIndex = e.Point;

		// ... always are valid values at this point.
		ViewModel.SelectedItemDescription = $"<b>  {newDate}: {result}</b>{Utils.NewLine}  {SourceItem?.Description}: {result}";
	}
	catch ( IndexOutOfRangeException )
	{
		ViewModel.CurrentPointIndex = -1;
		ViewModel.SelectedItemDescription = string.Empty;
	}
	catch ( Exception ex )
	{
		Api.Debug.HandleException(ex);

		ViewModel.CurrentPointIndex = -1;
		ViewModel.SelectedItemDescription = string.Empty;
	}
	finally { AnnotationTool.Active = false; }
}
private void Chart1_BeforeDrawSeries( object sender, Graphics3D g )
{
	// ...
	// DataLine is a Steema.TeeChart.Styles.Line
	double pointPosX = DataLine.CalcXPos(ViewModel.CurrentPointIndex);
	double pointPosY = DataLine.CalcYPos(ViewModel.CurrentPointIndex);

	SetPoints(pointPosX, pointPosY);
}
private void SetPoints( in double x, in double y )
{
	// AnnotationTool is a Steema.TeeChart.Tools.Annotation
	AnnotationTool.ConfigureAnnotations(ViewModel.FloatingAnnotations, ViewModel.SelectedItemDescription);
	if ( !AnnotationTool.Active ) { return; }

	Chart1.Title.Visible = ViewModel.FloatingAnnotations;

	if ( !ViewModel.FloatingAnnotations )
	{
		TargetPoint = new Point(x, y - GraphViewModel.ANNOTATION_OFFSET);
		SourcePoint = new Point(AnnotationTool.Left, AnnotationTool.Bounds.Bottom);

		return;
	}


	bool leftBound = x <= Chart1.ChartBounds.AverageWidth();
	bool topBound = y <= DataLine.LocalAveragePos(out double minVerticalValueHeight, out double maxVerticalValueHeight, true);

	double targetY = topBound
						 ? y + GraphViewModel.ANNOTATION_OFFSET
						 : y - GraphViewModel.ANNOTATION_OFFSET;

	TargetPoint = new Point(x, targetY);

	AnnotationTool.Left = Chart1.ChartBounds.AverageWidth();
	AnnotationTool.Top = Chart1.ChartBounds.AverageHeight();
	SourcePoint = new Point(AnnotationTool.Left, AnnotationTool.Top);
	// SourcePoint = IsPhone
	// 				  ? AnnotationTool.GetFloatingSourcePoint(Chart1, ViewModel.AnnotationHeightOffset, minVerticalValueHeight, maxVerticalValueHeight, leftBound, topBound)
	// 				  : AnnotationTool.GetTackingSourcePoint(Chart1, ViewModel.AnnotationHeightOffset, x, y, leftBound, topBound);

	// AnnotationTool.CoerceVisibleAnnotation(Chart1.ChartBounds, Chart1.Title.ShapeBounds, ViewModel.AnnotationHeightOffset);
}
private void TChart1_Annotations_AfterDraw( object sender, Graphics3D g )
{
	if ( ViewModel.CurrentPointIndex < 0 || !AnnotationTool.Active ) return;
	
	g.Brush.Color = Color.LightSkyBlue;

	if ( Device.RuntimePlatform == Device.Android )
	{
		g.Pen.Width = 2;
		g.Arrow(true, SourcePoint, TargetPoint, 15, 15, 0);
	}
	else
	{
		g.Pen.Width = 1;
		g.Arrow(true, SourcePoint, TargetPoint, 10, 10, 0);
	}
}

centerPNG.PNG
centerPNG.PNG (65.08 KiB) Viewed 29910 times
8bcfab4b-809c-4cff-943a-159fca5f0e98.png
8bcfab4b-809c-4cff-943a-159fca5f0e98.png (115.17 KiB) Viewed 29910 times

Re: Annotation Tool Popup doesn't respect placements.

Posted: Wed Mar 24, 2021 3:28 pm
by 18286055
I got it to render, albeit incorrectly, by subclassing it and invoking the draw call to it. The DrawText method is NOT being called otherwise, for whatever reason.

Edit: AutoSize was being changed for some reason, somewhere. The sizing is ok.

This is a workaround:

Code: Select all


	public class AnnotationTool : Annotation
	{
		public AnnotationTool( Chart chart, string text ) : this(chart) => Text = text;
		public AnnotationTool( Chart chart ) : base(chart)
		{
			Active = true;
			Position = AnnotationPositions.Custom;
			TextAlign = TextAlignment.Start;
			AutoSize = true;
			AllowEdit = false;
		}

		public Rectangle GetBounds()
		{
			 // forces a refresh.
			AutoSize = true;
			return Bounds;
		}


		public void Draw( Graphics3D g ) { DrawText(g); }
	}
	
	
	// In the graphing page, attach to the AfterDraw event
	private void TChart1_Annotations_AfterDraw( object sender, Graphics3D g )
	{
		/// ...
		AnnotationTool.Draw(g);
		/// ...
	}
And this is the result:
8d51b943-0031-4223-bb6f-954cd25e2a08.png
8d51b943-0031-4223-bb6f-954cd25e2a08.png (139.61 KiB) Viewed 29892 times

Re: Annotations do not render. Steema.TeeChart.NET.Xamarin.Forms v4.2021.2.25

Posted: Thu Mar 25, 2021 9:22 am
by Pep
Hello,
ok great.
Looking at your code, as you have created your custom annotation class , I do not see incorrectly to way that draw method has to be called.
Let me look more carefully, but it looks good to me.

Re: Annotations do not render. Steema.TeeChart.NET.Xamarin.Forms v4.2021.2.25

Posted: Thu Mar 25, 2021 3:18 pm
by 18286055
Pep wrote:
Thu Mar 25, 2021 9:22 am
Hello,
ok great.
Looking at your code, as you have created your custom annotation class , I do not see incorrectly to way that draw method has to be called.
Let me look more carefully, but it looks good to me.
This is a workaround until it is fixed. NOT THE FIX. It should render without having to do that.

https://github.com/Jakar510/DebugSteemaTeeChart

(un)comment Line 203 of GraphPage to see the results.

Re: Annotations do not render. Steema.TeeChart.NET.Xamarin.Forms v4.2021.2.25

Posted: Mon Mar 29, 2021 9:45 am
by Pep
Hello,

sure, I've added it on our bug/wish list so it can be reviewed for further releases.
Thanks.