| View previous topic :: View next topic |
| Author |
Message |
cschulz Member
Joined: 17 Mar 2006 Posts: 4
|
Posted: 17/03/06 16:05 Post subject: New version of TSimpleGraph - how does linking work |
|
|
All sample code is implicit example when programming procedural code I'm at a loss.
For example when adding a rectangle in code that would look like ...
MyVirt.X := 100;
MyVirt.Y := 100;
Pt := SimpleGraph.ScreenToClient( MyVirt );
SimpleGraph.DefaultNodeClass := TRectangularNode;
SimpleGraph.CommandMode := cmInsertNode;
NodeRect.TopLeft := SimpleGraph.ClientToGraph(Pt.X, Pt.Y);
NodeRect.Right := NodeRect.Left + NewNodeWidth;
NodeRect.Bottom := NodeRect.Top + NewNodeHeight;
SimpleGraph.InsertNode(NodeRect, TRectangularNode);
This still works in the new component
However
SimpleGraph.LinkNodes( TGraphNode(SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 1]), TGraphNode(SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 2]), nil);
no longer is supported or works in a complete different way
I'm now trying something like this
if ( SimpleGraph.Objects.Items[ AlleGraphNodes - 1].ClassType = TRectangularNode ) and
( SimpleGraph.Objects.Items[ AlleGraphNodes - 2].ClassType = TRectangularNode ) then
begin
FromObject := SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 1];
ToObject := SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 2];
// showmessage ('laatste twee zijn TRectangularNode --> maak een link !!');
SimpleGraph.Objects.Add( TGraphLink.create() );
TGraphLink(SimpleGraph.Objects.Last).Source := FromObject;
TGraphLink(SimpleGraph.Objects.Last).Target := ToObject;
TGraphLink(SimpleGraph.Objects.Last).Text := 'hallo dit is een test';
end;
To create a link between the last two GraphObjects that are rectangulars ...
It does not work ...
any suggestions to put me on the right track are welcome .. An other option for me is to fall back on the previous version ... but hey
|
|
| Back to top |
|
 |
Kambiz Administrator

Joined: 07 Mar 2003 Posts: 1044 Location: Tehran, Iran
|
Posted: 17/03/06 16:32 Post subject: |
|
|
It is because of a bug in InsertLink method.
It's already fixed in v2.1, and this weekend is going to be released.
_________________ Kambiz |
|
| Back to top |
|
 |
cschulz Member
Joined: 17 Mar 2006 Posts: 4
|
Posted: 24/03/06 14:45 Post subject: still does not work |
|
|
I upgraded the component to 2.4 and loaded the new demo programm. Then I added my button to the bar and copied my little piece of test code in place ....
Adding a link between two GraphObjects in a programmatic way still does not work .. how adding a link in de the demo programm works goes way beyond my understanding of Delphi since there is no place in the code I can pinpoint where 'things are actually happening' its all higher implicit coding to me.
If anyone can provide me with a working (code sample in a single procedure where actual methods are called and actual variables are passed) that would be great ... this is what I got ... and it does not work
Any help is much appreciated ...
| Code: |
procedure TMainForm.ToolButton26Click(Sender: TObject);
const
NewNodeWidth = 100;
NewNodeHeight = 75;
var
Pt: TPoint;
NodeRect: TRect;
MyVirt : TPoint;
AlleGraphNodes : Integer;
MyGraphLink : TGraphLink;
begin
MyVirt.X := 100;
MyVirt.Y := 150;
Pt := SimpleGraph.ScreenToClient( MyVirt );
SimpleGraph.DefaultNodeClass := TRectangularNode;
SimpleGraph.CommandMode := cmInsertNode;
NodeRect.TopLeft := SimpleGraph.ClientToGraph(Pt.X, Pt.Y);
NodeRect.Right := NodeRect.Left + NewNodeWidth;
NodeRect.Bottom := NodeRect.Top + NewNodeHeight;
SimpleGraph.InsertNode(NodeRect, TRectangularNode);
if SimpleGraph.ObjectsCount(nil) > 0 then
begin
SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 1].Hint := 'dit is de hint, ik zie em niet geloof ik ...';
SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 1].Text := 'testing testing';
end;
if SimpleGraph.ObjectsCount(nil) > 1 then
begin
AlleGraphNodes := SimpleGraph.ObjectsCount( nil );
if ( SimpleGraph.Objects.Items[ AlleGraphNodes - 1].ClassType = TRectangularNode ) and
( SimpleGraph.Objects.Items[ AlleGraphNodes - 2].ClassType = TRectangularNode ) then
begin
SimpleGraph.CommandMode := cmInsertLink;
// FOLLOWING INSERTLINK DOES NOT WORK !!!! OR AT LEAST NOT AS I INTEND IT TO ;-)
SimpleGraph.InsertLink( TGraphNode(SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 1]), TGraphNode(SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 2]), nil);
end;
end;
SimpleGraph.CommandMode := cmEdit; // cmViewOnly;
end;
|
explanation ... objects of RectangularNode are placed .. all RectangularNode 's except the first one should get a link with the previous one .... they are all created in the same place so should be moved by hand ... it's a small start to a program where I would like to import a file and automatically create boxes and links ... so I need these two basic things ...
|
|
| Back to top |
|
 |
cschulz Member
Joined: 17 Mar 2006 Posts: 4
|
Posted: 24/03/06 15:36 Post subject: ok got it ... |
|
|
hmmm ... I should not have relied so much on code completion suggestions ...
| Code: |
SourceGraphObject := TGraphObject(SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 1]);
TargetGraphObject := TGraphObject(SimpleGraph.Objects [SimpleGraph.ObjectsCount(nil) - 2]);
// SimpleGraph.InsertLink(Pt, TargetGraphObject);
SimpleGraph.InsertLink(SourceGraphObject, TargetGraphObject);
TGraphLink(SimpleGraph.Objects.Last).Text := 'hallo dit is een test';
TGraphLink(SimpleGraph.Objects.Last).Hint := 'dit is de hint';
|
not that I now understand the subtleties of InsertLink but hey it;s working ! ... I can now continue with my little project ... I feel much better now
|
|
| Back to top |
|
 |
Kambiz Administrator

Joined: 07 Mar 2003 Posts: 1044 Location: Tehran, Iran
|
Posted: 24/03/06 15:48 Post subject: |
|
|
- It's more effecient to use Objects.Count instead of ObjectsCount(nil).
- You do not need to change CommandMode.
- You do not need to set DefaultNodeClass or DefaultLinkClass.
- In you code, nodes will overlap on each other.
- According to the algorithm, objects in the Objects array are the form: TRecatngularNode, TRectangularNode, TGraphLink, TRectangularNode, TRectangularNode, TGraphLink, and so on.
You considered previous object is a node. But as you can see, after two clicks on the button, the previous object is a link. Therefore your code doesn't make a link between all nodes.
| Code: | var
Ofs: Integer = 0; // To prevent overlapped nodes.
procedure TMainForm.Button1Click(Sender: TObject);
const
NewNodeWidth = 100;
NewNodeHeight = 75;
var
I: Integer;
MyVirt : TPoint;
NodeRect: TRect;
NewNode: TGraphNode;
NewLink: TGraphLink;
begin
MyVirt.X := 100 + Ofs;
MyVirt.Y := 150 + Ofs;
Inc(Ofs, 100);
NodeRect.TopLeft := SimpleGraph.ScreenToGraph(MyVirt.X, MyVirt.Y);
NodeRect.Right := NodeRect.Left + NewNodeWidth;
NodeRect.Bottom := NodeRect.Top + NewNodeHeight;
NewNode := SimpleGraph.InsertNode(NodeRect, TRectangularNode);
NewNode.Hint := 'dit is de hint, ik zie em niet geloof ik ...';
NewNode.Text := 'testing testing';
for I := SimpleGraph.Objects.Count - 2 downto 0 do
if SimpleGraph.Objects[I] is TRectangularNode then
begin
NewLink := SimpleGraph.InsertLink(SimpleGraph.Objects[I], NewNode, TGraphLink);
NewLink.Hint := 'hallo dit is een test';
NewLink.Text := 'dit is de hint';
Break;
end;
end; |
P.S. Be aware of using TGraphObjectList.Last method. It initiates backward enumeration, which may affact other part of your code.
_________________ Kambiz |
|
| Back to top |
|
 |
cschulz Member
Joined: 17 Mar 2006 Posts: 4
|
Posted: 25/03/06 20:42 Post subject: Thanks! |
|
|
| Thanks Kambiz !
|
|
| Back to top |
|
 |
|