Page 1 of 1

Marks Overlapping

Posted: Thu Sep 08, 2016 8:25 am
by 17879005
Hi Guys,

I have a chart with 3 bar groups:

Image

My problem is that the marks on top of the bars are overlapping. Making some of them unreadable.

I have tried applying this solution:
http://www.teechart.net/support/viewtopic.php?t=5160

Similarly I created my own method to reposition the marks which I triggered AfterDraw:
(Not optimised, simple implementation just to serve its purpose)

Code: Select all

private void repositionMarks ()
		{
			Rectangle zero = new Rectangle();

			for (int k = 0; k < bar1.Marks.Positions.Count
			      && k < bar2.Marks.Positions.Count
			      && k < bar3.Marks.Positions.Count; k++)
			{
				SeriesMarks.Position pos1 = bar1.Marks.Positions[k];
				SeriesMarks.Position pos2 = bar2.Marks.Positions[k];
				SeriesMarks.Position pos3 = bar3.Marks.Positions[k];

				Rectangle rect1 = pos1.Bounds;
				Rectangle rect2 = pos2.Bounds;
				Rectangle rect3 = pos3.Bounds;

				while (Rectangle.Intersect(rect1, rect2) != zero)
				{
					pos2.Custom = true;
					pos2.LeftTop.Y = pos2.LeftTop.Y + 2;
					pos2.LeftTop.X = pos2.LeftTop.X;
					rect2 = pos2.Bounds;
				}

				while (Rectangle.Intersect(rect1, rect3) != zero 
				       || Rectangle.Intersect(rect2, rect3) != zero)
				{
					pos3.Custom = true;
					pos3.LeftTop.Y = pos3.LeftTop.Y + 2;
					rect3 = pos3.Bounds;
				}
			}
		}
Initially it looked like it was working:

Image

However if you scroll it horizontally, the repositioned marks stays stuck on the right bound of the chart. Please see image below:

Image

I have tried to trigger the mark reposition method also on Scroll Event but still the same issue persists.

I'm setting AutoPosition property but doesn't seem to have any effect.

Code: Select all

_bar1.Marks.AutoPosition = true;
Thanks in advance!

Re: Marks Overlapping

Posted: Mon Sep 12, 2016 9:41 am
by Pep
Hello,

have you tried to refresh the Chart just after the "for" inside the repositionMarks method ?

Code: Select all

            Chart1.Chart.Invalidate();

This should make to repaint the Marks.

Re: Marks Overlapping

Posted: Mon Sep 12, 2016 2:14 pm
by Pep
Hello,
I've been checking more exhaustively the problem, and just want to give you a better solution to the problem. In order to correctly draw marks at a custom position you should call the RepositionMarks methid at the OnAfterDraw event, but the method has to update the marks and arrow positions to correctly canvas relative position. You should use code similar to the following one (here you should introduce the intersect code and also call the method for each Series) :

Code: Select all

        private void RepositionMarks(Steema.TeeChart.Styles.Series series)
        {
            Steema.TeeChart.Styles.SeriesMarks.Position pos;
            series.Chart.AutoRepaint = false;
            for (int i = 0; i < series.Count; i++)
            {
                pos = series.Marks.Positions[i];
                pos.Custom = true;
                pos.LeftTop.Y = series.CalcYPosValue(series.YValues[i] / 2);

                pos.ArrowTo.Y = pos.LeftTop.Y;
                pos.ArrowFrom.Y = pos.LeftTop.Y;

                pos.LeftTop.X = series.CalcXPosValue(series.XValues[i] );
                pos.ArrowTo.X = pos.LeftTop.X;
                pos.ArrowFrom.X = pos.LeftTop.X;

            }
            series.Chart.AutoRepaint = true;
            series.Chart.Invalidate();
        }

Re: Marks Overlapping

Posted: Tue Sep 13, 2016 3:57 am
by 17879005
Hi Pep,

Firstly thank you for spending time on this. I really appreciate it.

Ok so I have incorporated the codes you have given me but the problem still persists. The mark is positioning well on Y axis however when I call CalcXPosValue it is giving me an x coordinate that is almost out of screen. I am not sure if this has something to do with screen scale or zoom. Bigger problem is that, as I scroll left right, the CalcXPosValue is always giving me the same value (until the particular bar is out of screen) hence the mark is not moving with the bar. I'm thinking maybe because the bar is still rendering, however the method is called on AfterDraw.

Please look at this video to understand what I mean:
https://www.dropbox.com/s/ky7lga58il4uy ... s.mov?dl=0

Re: Marks Overlapping

Posted: Tue Sep 13, 2016 11:58 am
by Pep
Hello,

ok, I think the problem could be related on when calcxposvalue and calcyposvalue is done (inside the AfterDraw event). Using the following code all the marks seem to be correctly displayed if these overlap, and also scrolling. Please check the code and if the problem persists let me know so I can send to you a small example with all the files :

Code: Select all

        private void repositionMarks()
        {
            bar1.Chart.AutoRepaint = false;
            bar2.Chart.AutoRepaint = false;
            bar3.Chart.AutoRepaint = false;

            Rectangle zero = new Rectangle();

            for (int k = 0; k < bar1.Marks.Positions.Count
                  && k < bar2.Marks.Positions.Count
                  && k < bar3.Marks.Positions.Count; k++)
            {
                SeriesMarks.Position pos1 = bar1.Marks.Positions[k];
                SeriesMarks.Position pos2 = bar2.Marks.Positions[k];
                SeriesMarks.Position pos3 = bar3.Marks.Positions[k];
                
                pos2.LeftTop.Y = bar2.CalcYPosValue(bar2.YValues[k]);
                pos2.LeftTop.X = bar2.CalcXPosValue(bar2.XValues[k]);

                Rectangle rect1 = pos1.Bounds;
                Rectangle rect2 = pos2.Bounds;

                pos2 = bar2.Marks.Positions[k];
                pos2.Custom = true;

                pos2.ArrowTo.Y = pos2.LeftTop.Y;
                pos2.ArrowFrom.Y = pos2.LeftTop.Y;

                pos2.ArrowTo.X = pos2.LeftTop.X;
                pos2.ArrowFrom.X = pos2.LeftTop.X;


                while (Rectangle.Intersect(rect1, rect2) != zero)
                {
                    pos2.LeftTop.Y += 20;
                    pos2.ArrowTo.Y += 20;
                    pos2.ArrowFrom.Y += 20;

                    rect2 = pos2.Bounds;
                }

                bar2.Chart.AutoRepaint = true;
                bar2.Chart.Invalidate();

                pos3.LeftTop.Y = bar3.CalcYPosValue(bar3.YValues[k]);
                pos3.LeftTop.X = bar3.CalcXPosValue(bar3.XValues[k]);

                Rectangle rect3 = pos3.Bounds;

                pos3 = bar3.Marks.Positions[k];
                pos3.Custom = true;

                pos3.ArrowTo.Y = pos3.LeftTop.Y;
                pos3.ArrowFrom.Y = pos3.LeftTop.Y;

                pos3.ArrowTo.X = pos3.LeftTop.X;
                pos3.ArrowFrom.X = pos3.LeftTop.X;

                Chart.Header.Text = "No Entra";
                while (Rectangle.Intersect(rect1, rect3) != zero
                       || Rectangle.Intersect(rect2, rect3) != zero)
                {
                    Chart.Header.Text = "Entra";
                    pos3.LeftTop.Y += 20;
                    pos3.ArrowTo.Y += 20;
                    pos3.ArrowFrom.Y += 20;
                    pos3.ArrowTo.X = pos3.LeftTop.X;
                    pos3.ArrowFrom.X = pos3.LeftTop.X;

                    rect3 = pos3.Bounds;
                }

                pos3.ArrowTo.X = pos3.LeftTop.X;
                pos3.ArrowFrom.X = pos3.LeftTop.X;

                bar3.Chart.AutoRepaint = true;
                bar3.Chart.Invalidate();
            }
        }

        private void Chart_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
        {
            repositionMarks();  
        }