Page 1 of 1

Overlapping of Marks on Bar Charts

Posted: Wed Mar 17, 2004 10:38 pm
by 8120653
I have noticed several posts here before on overlapping of marks and a reference to the sample code in the Tutorial that comes with TeeCharts, but I am not having any luck getting it to work. Isaw where Josep had talked about posting some sample code on this, but I can not find it anywhere. I have a barchart graph that has a bar for each shift (1,2,3) for each month in the year the total number of downtime minutes that occurred for that shift for that month. Depending on the values associated with each shift the marks sometimes overlap to the point you can not even read the values. Does anyone have any suggestions on how to fix this? Any help would be appreciated.

Posted: Fri Mar 19, 2004 11:34 am
by Pep
Hi,

one way around this it to use something like the following code to check if there're marks which intersect with other, and if so, move them to a custom position.

Code: Select all

Rectangle R1,R2;			
System.Drawing.Rectangle DummyRect = new System.Drawing.Rectangle();
for (int i=0; i<pie1.Marks.Positions.Count-1; i++) 
{
	for (int j=0; j<pie1.Marks.Positions.Count-1; j++) 
	{
		if (j!=i)
		{				
		Steema.TeeChart.Styles.SeriesMarks.Position mp1 = pie1.Marks.Positions[i]; 
		Steema.TeeChart.Styles.SeriesMarks.Position mp2 = pie1.Marks.Positions[j]; 						R1 = mp1.Bounds;
		R2 = mp2.Bounds;
		while (Rectangle.Intersect(R1,R2)!=DummyRect )
		{
		  mp1.Custom=true;
		  mp1.LeftTop.X = mp1.LeftTop.X +2;
	  	  mp1.LeftTop.Y = mp1.LeftTop.Y +2;
		  mp1.ArrowTo.X = mp1.LeftTop.X +2;
		  mp1.ArrowTo.Y = mp1.LeftTop.Y +2;
		  R1 = mp1.Bounds;
		  R2 = mp2.Bounds;                                  
		}
		tChart1.Refresh();
	               }
            }
}

Problem when angle=90

Posted: Fri May 19, 2006 4:20 am
by 8120845
This is a very nice piece of code but it has two problems when I use it in V1:

pie1.Marks.Positions.Count is zero when there are actually marks drawn. Sometime later when I execute the code the value is the correct value. So what event sets the count to the right value?

The code doesn't work when the marks are drawn at an angle of 90. This is because the bounds rectangles are for the unrotated marks. How can I fix this?

A third related problem is that when the Angle is 90 degrees drag marks uses the unrotated rectangles for its boundary - this makes it somewhat confusing to use.

Posted: Mon May 22, 2006 1:37 pm
by narcis
Hi TeeNee,
pie1.Marks.Positions.Count is zero when there are actually marks drawn. Sometime later when I execute the code the value is the correct value. So what event sets the count to the right value?
This is because when the code is executed the chart hasn't been drawn yet. You should call this code in TeeChart's AfterDraw event.
The code doesn't work when the marks are drawn at an angle of 90. This is because the bounds rectangles are for the unrotated marks. How can I fix this?

A third related problem is that when the Angle is 90 degrees drag marks uses the unrotated rectangles for its boundary - this makes it somewhat confusing to use.
This seems to be the same problem. I've added it to our defect list (TF02011426) to be fixed for future releases.

Posted: Sat May 27, 2006 4:44 am
by 8120845
There are probably a few more bugs in this area - I have not searched for them all systematically. You might like to have a look :wink: . For example, once you have dragged marks to new positions they no longer zoom properly when you zoom the chart.

[/quote]

Posted: Mon May 29, 2006 9:10 am
by narcis
Hi TeeNee,

This is because those marks have been assigned a custom position. To be properly drawn when zooming they should have a chart relative position (i.e.: the axes, ChartRect, etc.) and this position should be updated every time the chart is zoomed or scrolled.

Posted: Wed Feb 04, 2009 3:46 pm
by 9044601
I have the same issue but i'm developing in C++ Builder. Could you help me?

Posted: Tue Feb 10, 2009 12:32 pm
by narcis
Hi aballesteros,

You can try using something like this:

Code: Select all

void __fastcall TForm4::FormCreate(TObject *Sender)
{
	Series1->FillSampleValues(20);

	Chart1->Draw();

	TRect R1,R2,DummyRect;

	for (int i=0; i<Series1->Marks->Positions->Count-1; i++)
	{
	   for (int j=0; j<Series1->Marks->Positions->Count-1; j++)
	   {
		  if (j!=i)
		  {
			TSeriesMarkPosition *mp1 = new TSeriesMarkPosition;
			TSeriesMarkPosition *mp2 = new TSeriesMarkPosition;
			mp1=Series1->Marks->Positions->Position[i];
			mp2=Series1->Marks->Positions->Position[j];

			R1=mp1->Bounds();
			R2=mp2->Bounds();

			while (IntersectRect(DummyRect, R1, R2))
			{
				mp1->Custom=true;
				mp1->LeftTop.x=mp1->LeftTop.x+2;
				mp1->LeftTop.y=mp1->LeftTop.y+2;
				mp1->ArrowTo.x=mp1->LeftTop.x+2;
				mp1->ArrowTo.y=mp1->LeftTop.y+2;
				R1=mp1->Bounds();
				R2=mp2->Bounds();
			}

			Chart1->Refresh();
		  }
	   }
	}
}

Posted: Tue Feb 10, 2009 3:42 pm
by 14045174
The problem with this solution:
  • I had only 50 points and execution of this code took forever, and even after it was done - some of the marks were still overlapping. Only after I have resized the chart (and wait a while) they finally did not overlap, but the positions for many of them were outside of the chart area (and chart did not adjust left axis max value, like it does for non-custom positioned marks.
  • bigger problem for me - I do not actually display the chart in most cases. I do everything in memory and then grab the image... The drawing code is not running the same way and AfterDraw even does not fire, I did try BeforeDraw - it throws exeptions randomly...
Any suggestions?

Posted: Tue Feb 10, 2009 3:50 pm
by narcis
Hi UserLS,

Running this code in AfterDraw event can lead to several calls of the same method and therefore be a very ineficient application. You could try running it in chart's initialization code and calling tChart1.Draw before so that the chart is internally painted and therefore marks positions have valid values.