Recent

Author Topic: EvsSimpleGraph (Load / Save Single Graph Objects  (Read 3627 times)

simsee

  • Full Member
  • ***
  • Posts: 184
EvsSimpleGraph (Load / Save Single Graph Objects
« on: February 16, 2017, 12:54:21 pm »
Dear all, I'm using TEVSimpleGraph component and I need to load from/save to disk indivual graph objects. Before to devise form scratch a custom solution (i.e. based on approaches described in http://wiki.freepascal.org/Streaming_components), I'm trying to use some built-in methods of above component, but I have some difficulties. Here is my demo code, that produces run-time errors showed in comments... Someone knows this library and can help me? Thanks!

Code: Pascal  [Select][+][-]
  1. unit prova;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, usimplegraph, Forms, Controls, Graphics, Dialogs,
  9.   StdCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     EvsSimpleGraph: TEvsSimpleGraph;
  19.     procedure Button1Click(Sender: TObject);
  20.     procedure Button2Click(Sender: TObject);
  21.     procedure FormShow(Sender: TObject);
  22.   private
  23.     { private declarations }
  24.   public
  25.     { public declarations }
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.   Rect : TRect;
  31.   Node : TEvsGraphNode;
  32.   FileStream : TFileStream;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.FormShow(Sender: TObject);
  41. begin
  42.   with Rect do
  43.     begin
  44.       Left:=100;
  45.       Right:=150;
  46.       Top:=100;
  47.       Bottom:=150;
  48.     end;
  49.   Node:=EvsSimpleGraph.InsertNode(Rect);
  50. end;
  51.  
  52. procedure TForm1.Button1Click(Sender: TObject); //create rectangle and save it
  53. begin
  54.   FileStream:=TFileStream.Create('prova',fmCreate or fmOpenWrite);
  55.   Node.SaveToStream(FileStream);
  56.   FileStream.Free;
  57.   EvsSimpleGraph.Clear;   //delete rectangle
  58. end;
  59.  
  60. procedure TForm1.Button2Click(Sender: TObject);  //reload rectangle
  61. begin
  62.   FileStream:=TFileStream.Create('prova',fmOpenRead);
  63.   Node.Create(EvsSimpleGraph);    // External: SIGSEGV  !!!
  64.   Node.LoadFromStream(FileStream);  // External: SIGSEGV  !!!
  65.   FileStream.Free;
  66. end;
  67.  
  68. end.  
« Last Edit: February 16, 2017, 02:23:44 pm by simsee »

sky_khan

  • Guest
Re: EvsSimpleGraph (Load / Save Single Graph Objects
« Reply #1 on: February 16, 2017, 02:23:28 pm »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);  //reload rectangle
  2. begin
  3.   FileStream:=TFileStream.Create('prova',fmOpenRead);
  4.   Node.Create(EvsSimpleGraph);    // External: SIGSEGV  !!!
  5.   Node.LoadFromStream(FileStream);  // External: SIGSEGV  !!!
  6.   FileStream.Free;
  7. end;
  8.  

You cant do this.
First, it is not how objects are instantiated. You have to use as "Node:=TTheClassYouWant.Create"
Second, if you dont want to stuck with only one kind of shape, you cant create a node from correct class. Because you dont know which kind of object is in stream.

I downloaded and looked EvsSimpleGraph source and I think you can use it's WriteObjects and ReadObjects methods but they are protected.
Still you can crack it like this:

Code: Pascal  [Select][+][-]
  1. type
  2.   TSimpleGraphCrack = class(TEvsSimpleGraph);  
  3.  
  4. procedure TForm1.Button2Click(Sender: TObject);
  5. var
  6.   fs : TFileStream;
  7. begin
  8.   fs:=TFileStream.Create('prova',fmCreate);
  9.   try
  10.     if fGraph.SelectedObjects.Count>0 then
  11.       TSimpleGraphCrack(fGraph).WriteObjects(fs,fGraph.SelectedObjects);
  12.   finally
  13.     fs.Free;
  14.   end;
  15. end;
  16.  
  17. procedure TForm1.Button3Click(Sender: TObject);
  18. var
  19.   fs : TFileStream;
  20. begin
  21.   fGraph.Clear;
  22.   fs:=TFileStream.Create('prova',fmOpenRead);
  23.   try
  24.     if fs.Size>0 then
  25.       TSimpleGraphCrack(fGraph).ReadObjects(fs);
  26.   finally
  27.     fs.Free;
  28.   end;
  29. end;
  30.  

Button2Click will save only selected objects on graph and Button3Click will load what is saved. If you want choose objects by some other way you may create and fill your own list by

myList:=TEvsGraphObjectList.Create;
myList.Add(NodeYouWantToSave);

simsee

  • Full Member
  • ***
  • Posts: 184
Re: EvsSimpleGraph (Load / Save Single Graph Objects
« Reply #2 on: February 16, 2017, 03:18:35 pm »
I madly used the constructor... I apologize... Thanks also for useful suggestions. Only another question: why I can't use LoadFromStream/SaveToStream methods of TEvsGraphNode class to load/save individual objects? According to documentation from the orginal library for Delphi (available with the package at http://www.delphiarea.com/?dl_id=11), these methods are intended to this purpose. Thanks again.

simsee

  • Full Member
  • ***
  • Posts: 184
Re: EvsSimpleGraph (Load / Save Single Graph Objects
« Reply #3 on: February 16, 2017, 03:56:19 pm »
Now it works. Graph objects can be loaded/saved using LoadFromStream/SaveToStream methods, without subclassing TEVSSimpleGraph class. I thought that they did not work because I forgotten to repaint the control with the Invalidate procedure). Here a sample code (I drop expection handlers for sake of brevity):

Code: Pascal  [Select][+][-]
  1. unit prova;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, usimplegraph, Forms, Controls, Graphics, Dialogs,
  9.   StdCtrls;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     EvsSimpleGraph: TEvsSimpleGraph;
  19.     procedure Button1Click(Sender: TObject);
  20.     procedure Button2Click(Sender: TObject);
  21.     procedure FormShow(Sender: TObject);
  22.   private
  23.     { private declarations }
  24.   public
  25.     { public declarations }
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.   Rect : TRect;
  31.   Node : TEvsGraphNode;
  32.   FileStream : TFileStream;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.FormShow(Sender: TObject);  //create a rectangle
  41. begin  
  42.   with Rect do        
  43.     begin
  44.       Left:=100;
  45.       Right:=150;
  46.       Top:=100;
  47.       Bottom:=150;
  48.     end;
  49.   Node:=EvsSimpleGraph.InsertNode(Rect,TEvsRectangularNode);
  50. end;
  51.  
  52. procedure TForm1.Button1Click(Sender: TObject); // save rectangle
  53. begin
  54.   FileStream:=TFileStream.Create('prova',fmCreate or fmOpenWrite);
  55.   Node.SaveToStream(FileStream);
  56.   FileStream.Free;
  57.   EvsSimpleGraph.Clear;
  58. end;
  59.  
  60. procedure TForm1.Button2Click(Sender: TObject);  //reload rectangle
  61. begin
  62.   Node:=TEvsRectangularNode.Create(EvsSimpleGraph);
  63.   FileStream:=TFileStream.Create('prova',fmOpenRead);
  64.   Node.LoadFromStream(FileStream);
  65.   FileStream.Free;
  66.   EvsSimpleGraph.Invalidate;
  67. end;
  68.  
  69. end.  


sky_khan

  • Guest
Re: EvsSimpleGraph (Load / Save Single Graph Objects
« Reply #4 on: February 16, 2017, 04:04:52 pm »
Well, I assumed you would not want to be stuck with one and only Rectangular shape. If you absolutely know it will be only Rectangular node, not a triangle, not a circle or anything else i guess this will work too.

simsee

  • Full Member
  • ***
  • Posts: 184
Re: EvsSimpleGraph (Load / Save Single Graph Objects
« Reply #5 on: February 16, 2017, 04:33:09 pm »
Thanks again for these additional explanations!

 

TinyPortal © 2005-2018