New version of TSimpleGraph - how does linking work

Please post bug reports, feature requests, or any question regarding the DELPHI AREA products here.

New version of TSimpleGraph - how does linking work

Postby cschulz » March 17th, 2006, 4:05 pm

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
cschulz
Member
Member
 
Posts: 4
Joined: March 17th, 2006, 3:57 pm

Postby Kambiz » March 17th, 2006, 4:32 pm

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
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2405
Joined: March 7th, 2003, 7:10 pm

still does not work

Postby cschulz » March 24th, 2006, 2:45 pm

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: Select all
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 ...
cschulz
Member
Member
 
Posts: 4
Joined: March 17th, 2006, 3:57 pm

ok got it ...

Postby cschulz » March 24th, 2006, 3:36 pm

hmmm ... I should not have relied so much on code completion suggestions ... :?

Code: Select all
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 :lol: :D
cschulz
Member
Member
 
Posts: 4
Joined: March 17th, 2006, 3:57 pm

Postby Kambiz » March 24th, 2006, 3:48 pm

  1. It's more effecient to use Objects.Count instead of ObjectsCount(nil).
  2. You do not need to change CommandMode.
  3. You do not need to set DefaultNodeClass or DefaultLinkClass.
  4. In you code, nodes will overlap on each other.
  5. 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: Select all
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
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2405
Joined: March 7th, 2003, 7:10 pm

Thanks!

Postby cschulz » March 25th, 2006, 8:42 pm

Thanks Kambiz !
cschulz
Member
Member
 
Posts: 4
Joined: March 17th, 2006, 3:57 pm


Return to DELPHI AREA Products

Who is online

Users browsing this forum: No registered users and 2 guests

cron