Page 1 of 1

Overlapping marks for a line series

Posted: Wed Mar 28, 2012 6:02 am
by 10550286
This is a recurring issue I see. I have attempted to implement the code as referenced at http://www.teechart.net/support/viewtopic.php?t=560.

So, in my test project, I have this code:

Code: Select all

__fastcall TFormMain::TFormMain(TComponent* Owner)
  : TForm(Owner)
{
  Chart1->AddSeries(new TLineSeries(Chart1));
  Chart1->Series[0]->Marks->Visible = true;

  for(int i(0); i < 50; ++i) {
    Chart1->Series[0]->AddXY(i,i);
  }

   Chart1->Draw();

   TRect R1,R2,DummyRect;

   for (int i=0; i<Chart1->Series[0]->Marks->Positions->Count-1; i++)
   {
      for (int j=0; j<Chart1->Series[0]->Marks->Positions->Count-1; j++)
      {
        if (j!=i)
        {
         TSeriesMarkPosition *mp1 = new TSeriesMarkPosition;
         TSeriesMarkPosition *mp2 = new TSeriesMarkPosition;
         mp1=Chart1->Series[0]->Marks->Positions->Position[i];
         mp2=Chart1->Series[0]->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();
        }
      }
   }

}
However, it seems to make no difference at all. See attached screen capture. The code seems to be getting into the parts editing the Mark position - but it is like the changes are being ignored. Is there a setting I am missing?

Re: Overlapping marks for a line series

Posted: Wed Mar 28, 2012 3:35 pm
by yeray
Hi Sam,

I think the code works fine. It's just it's not as smart as this example needs. Note it checks the marks rectangles with two for loops, but once a mark overlap is detected and a mark is moved to fix that overlapping, the next marks are still going to be checked but not the prior.
Here you have an smarter version:

Code: Select all

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.AddSeries(TLineSeries);
  Chart1[0].Marks.Visible:=true;

  for i:=0 to 49 do
    Chart1[0].AddXY(i,i);
end;

procedure TForm1.Button1Click(Sender: TObject);

  function MarkOverlaps(ValueIndex: Integer): Boolean;
  var i: Integer;
      DummyRect: TRect;
  begin
    result:=false;
    with Chart1[0].Marks.Positions do
    for i:=0 to Count-1 do
      if (i<>ValueIndex) then
        if IntersectRect(DummyRect, Position[i].Bounds, Position[ValueIndex].Bounds) then
        begin
          result:=true;
          break;
        end;
  end;

var i, j: Integer;

begin
  with Chart1[0].Marks.Positions do
  begin
    for i:=0 to Count-1 do
    begin
      while MarkOverlaps(i) do
        with Position[i] do
        begin
          Custom:=true;
          LeftTop.X:=LeftTop.X+2;
          LeftTop.Y:=LeftTop.Y+2;
          ArrowTo.X:=LeftTop.X+2;
          ArrowTo.Y:=LeftTop.Y+2;
        end;
    end;
  end;

  Chart1.Refresh;
end;

Re: Overlapping marks for a line series

Posted: Wed Mar 28, 2012 11:32 pm
by 10550286
Hi Yeray,

Thank you, that works for me. Much faster having the chart refresh not in the loop as well.

Sam.

Re: Overlapping marks for a line series

Posted: Fri Mar 30, 2012 7:52 am
by yeray
Hi Sam,

I'm glad to hear it! :D