TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
-
Sam F
- Newbie
- Posts: 45
- Joined: Wed Sep 10, 2008 12:00 am
Post
by Sam F » Wed Mar 28, 2012 6:02 am
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?
-
Attachments
-
- Marks problem
- Marks.png (37.63 KiB) Viewed 8637 times
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Wed Mar 28, 2012 3:35 pm
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;
-
Sam F
- Newbie
- Posts: 45
- Joined: Wed Sep 10, 2008 12:00 am
Post
by Sam F » Wed Mar 28, 2012 11:32 pm
Hi Yeray,
Thank you, that works for me. Much faster having the chart refresh not in the loop as well.
Sam.
-
Yeray
- Site Admin
- Posts: 9613
- Joined: Tue Dec 05, 2006 12:00 am
- Location: Girona, Catalonia
-
Contact:
Post
by Yeray » Fri Mar 30, 2012 7:52 am
Hi Sam,
I'm glad to hear it!