1 unit DependencyGraphOptions;
2 
3 {$mode objfpc}{$H+}
4 {off $DEFINE WITH_RANDOM_SEED} // ONLY applies, after "apply" or "ok" when the graph is redrawn
5 
6 interface
7 
8 uses
9   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ButtonPanel, StdCtrls,
10   ExtCtrls, Spin, LvlGraphCtrl, Laz_XMLCfg, math, LazarusIDEStrConsts,
11   EnvironmentOpts;
12 
13 type
14 
15   { TLvlGraphOptions }
16 
17   TLvlGraphOptions = class(TIDESubOptions)
18   private
19     FCaptionPos: TLvlGraphNodeCaptionPosition;
20     FEdgeShape: TLvlGraphEdgeShape;
21     FEdgeSplit: TLvlGraphEdgeSplitMode;
22     FExtraSpacingHoriz: integer;
23     FExtraSpacingVert: integer;
24     FHighLevels: Boolean;
25     FLimitLvlHeighAbs: integer;
26     FLimitLvlHeighRel: Single;
27     FMinimizeEdges: Boolean;
28     FOnLoaded: TNotifyEvent;
29     FReduceBackEdges: Boolean;
30     FStraightenGraph: Boolean;
31     {$IFDEF WITH_RANDOM_SEED}
32     FTestRandomSeed: integer;
33     {$ENDIF}
34   public
35     constructor Create;
36     procedure ReadFromXml(AnXmlConf: TRttiXMLConfig; APath: String); override;
37     procedure WriteToXml(AnXmlConf: TRttiXMLConfig; APath: String); override;
38     procedure Assign(ASrc: TPersistent); override;
39     procedure WriteToGraph(AValue: TLvlGraphControl);
40     procedure ReadFromGraph(AValue: TLvlGraphControl);
41   published
42     property MinimizeEdges: Boolean read FMinimizeEdges write FMinimizeEdges;
43     property HighLevels: Boolean read FHighLevels write FHighLevels;
44     property ReduceBackEdges: Boolean read FReduceBackEdges write FReduceBackEdges;
45     property ExtraSpacingHoriz: integer read FExtraSpacingHoriz write FExtraSpacingHoriz;
46     property ExtraSpacingVert: integer read FExtraSpacingVert write FExtraSpacingVert;
47     property CaptionPos: TLvlGraphNodeCaptionPosition read FCaptionPos write FCaptionPos;
48     property EdgeShape: TLvlGraphEdgeShape read FEdgeShape write FEdgeShape;
49     property EdgeSplit: TLvlGraphEdgeSplitMode read FEdgeSplit write FEdgeSplit;
50     property StraightenGraph: Boolean read FStraightenGraph write FStraightenGraph;
51     property LimitLvlHeighAbs: integer read FLimitLvlHeighAbs write FLimitLvlHeighAbs;
52     property LimitLvlHeighRel: Single read FLimitLvlHeighRel write FLimitLvlHeighRel;
53     {$IFDEF WITH_RANDOM_SEED}
54     property TestRandomSeed: integer read FTestRandomSeed write FTestRandomSeed;
55     {$ENDIF}
56 
57     property OnLoaded: TNotifyEvent read FOnLoaded write FOnLoaded;
58   end;
59 
60   TApplyOptionsProc = procedure(AnOpts: TLvlGraphOptions; AGraph: TLvlGraph) of object;
61   TLvlGraphEdgeSplitModes = set of TLvlGraphEdgeSplitMode;
62 
63   { TDependencyGraphOptDialog }
64 
65   TDependencyGraphOptDialog = class(TForm)
66     ApplyButton: TPanelBitBtn;
67     ButtonPanel1: TButtonPanel;
68     chkReduceBackEdges: TCheckBox;
69     chkStraigtenGraph: TCheckBox;
70     chkMinimizeEdges: TCheckBox;
71     chkHighEdges: TCheckBox;
72     chkCaptionOnTop: TCheckBox;
73     dropEdgeShape: TComboBox;
74     dropEdgeSplit: TComboBox;
75     DummySpaceHolder: TLabel;
76     lblExtraSpacing: TLabel;
77     Panel11: TPanel;
78     Panel12: TPanel;
79     spinVertSpacing: TSpinEdit;
80     spinHorizSpacing: TSpinEdit;
81     spinLvlLimitRel: TFloatSpinEdit;
82     lblMaxLevelHeight: TLabel;
83     lblEdgeShape: TLabel;
84     lblEdgeSplit: TLabel;
85     lblSplitCount: TLabel;
86     Panel1: TPanel;
87     Panel10: TPanel;
88     Panel2: TPanel;
89     Panel3: TPanel;
90     Panel4: TPanel;
91     Panel5: TPanel;
92     Panel6: TPanel;
93     Panel7: TPanel;
94     Panel8: TPanel;
95     Panel9: TPanel;
96     spinLvlLimitAbs: TSpinEdit;
97     valSplitCnt: TLabel;
98     valLevelCnt: TLabel;
99     valCrossCnt: TLabel;
100     LblCrossCount: TLabel;
101     lblNodeCnt: TLabel;
102     valNodeCnt: TLabel;
103     lblEdgeCount: TLabel;
104     valEdgeCnt: TLabel;
105     lblEdgeLen: TLabel;
106     valEdgeLen: TLabel;
107     LblLevelCount: TLabel;
108     OptionsGroup: TGroupBox;
109     InfoGroup: TGroupBox;
110     ScrollBox1: TScrollBox;
111     procedure ApplyButtonClick(Sender: TObject);
112     procedure CancelButtonClick(Sender: TObject);
113     procedure FormCreate(Sender: TObject);
114     procedure OKButtonClick(Sender: TObject);
115   private
116     {$IFDEF WITH_RANDOM_SEED}
117     spinTestRandomSeed: TSpinEdit;
118     {$ENDIF}
119     FApplyCallback: TApplyOptionsProc;
120     FGraph: TLvlGraph;
121     FOptions: TLvlGraphOptions;
122     FShowInfo: Boolean;
123     FShowSplitModes: TLvlGraphEdgeSplitModes;
124     FEdgeSplitMap: array[0..ord(high(TLvlGraphEdgeSplitMode))] of TLvlGraphEdgeSplitMode;
125     FEdgeRevSplitMap: array[low(TLvlGraphEdgeSplitMode)..high(TLvlGraphEdgeSplitMode)] of integer;
126     procedure SetApplyCallback(AValue: TApplyOptionsProc);
127     procedure SetGraph(AValue: TLvlGraph);
128     procedure SetOptions(AValue: TLvlGraphOptions);
129     procedure SetShowInfo(AValue: Boolean);
130     procedure SetShowSplitModes(AValue: TLvlGraphEdgeSplitModes);
131     procedure PopulateEdgeSplit;
132     procedure PopulateEdgeShape;
133     procedure WriteToOpts;
134     procedure ReadFromOpts;
135     procedure UpdateInfo;
136   public
137     property Options: TLvlGraphOptions read FOptions write SetOptions;
138     property Graph: TLvlGraph read FGraph write SetGraph;
139     property ApplyCallback: TApplyOptionsProc read FApplyCallback write SetApplyCallback;
140     property ShowInfo: Boolean read FShowInfo write SetShowInfo;
141     property ShowSplitModes: TLvlGraphEdgeSplitModes read FShowSplitModes write SetShowSplitModes;
142   end;
143 
ShowDependencyGraphOptionsnull144 function ShowDependencyGraphOptions(AnOpts: TLvlGraphOptions; AGraph: TLvlGraph; ACaption: String;
145   AnApplyCallback: TApplyOptionsProc = nil): TModalResult;
146 
147 implementation
148 
ShowDependencyGraphOptionsnull149 function ShowDependencyGraphOptions(AnOpts: TLvlGraphOptions; AGraph: TLvlGraph; ACaption: String;
150   AnApplyCallback: TApplyOptionsProc = nil): TModalResult;
151 var
152   Dlg: TDependencyGraphOptDialog;
153 begin
154   Dlg := TDependencyGraphOptDialog.Create(Application);
155   Dlg.Caption := ACaption;
156   Dlg.Graph := AGraph;
157   Dlg.Options := AnOpts;
158   Dlg.ApplyCallback := AnApplyCallback;
159   Result := Dlg.ShowModal;
160   Dlg.Free;
161 end;
162 
163 {$R *.lfm}
164 
165 { TDependencyGraphOptDialog }
166 
167 procedure TDependencyGraphOptDialog.CancelButtonClick(Sender: TObject);
168 begin
169   ModalResult := mrCancel;
170 end;
171 
172 procedure TDependencyGraphOptDialog.FormCreate(Sender: TObject);
173 begin
174   FShowInfo := True;
175   FShowSplitModes := [lgesSeparate, lgesMergeSource, lgesMergeTarget, lgesMergeHighest];
176 
177   chkMinimizeEdges.Caption := LvlGraphShapeMinimizeEdge;
178   chkHighEdges.Caption := LvlGraphShapeCalculateLay;
179   chkReduceBackEdges.Caption := LvlGraphReduceBackedges;
180   chkStraigtenGraph.Caption := LvlGraphStraightenGraph;
181   chkCaptionOnTop.Caption := LvlGraphNamesAboveNode;
182 
183   lblEdgeSplit.Caption := LvlGraphShapeEdgesSplitMo;
184   lblEdgeShape.Caption := LvlGraphShapeEdgesShape;
185   dropEdgeSplit.Constraints.MinWidth := Max(dropEdgeSplit.Constraints.MinWidth,
186     lblEdgeSplit.Width);
187   dropEdgeShape.Constraints.MinWidth := Max(dropEdgeShape.Constraints.MinWidth,
188     lblEdgeShape.Width);
189 
190   OptionsGroup.Caption      := lisOptions;
191   InfoGroup.Caption         := LvlGraphOptInfo;
192   lblNodeCnt.Caption        := LvlGraphShapeNodes;
193   lblEdgeCount.Caption      := LvlGraphOptEdges;
194   lblEdgeLen.Caption        := LvlGraphOptEdgeLen;
195   LblLevelCount.Caption     := LvlGraphOptLevels;
196   LblCrossCount.Caption     := LvlGraphOptCrossings;
197   lblSplitCount.Caption     := LvlGraphOptSplitpoints;
198   lblMaxLevelHeight.Caption := LvlGraphOptLimitHeightOfLvl;
199   lblExtraSpacing.Caption   := LvlGraphExtraSpacing;
200   spinLvlLimitAbs.Hint      := Format(LvlGraphOptAbsoluteLimi, [LineEnding]);
201   spinLvlLimitRel.Hint      := Format(LvlGraphOptLimitRelativ, [LineEnding]);
202   spinHorizSpacing.Hint     := Format(LvlGraphAddHorizontalSpacing, [LineEnding]);
203   spinVertSpacing.Hint      := Format(LvlGraphAddVerticalSpacingAr, [LineEnding]);
204 
205   {$IFDEF WITH_RANDOM_SEED}
206   spinTestRandomSeed := TSpinEdit.Create(Self);
207   spinTestRandomSeed.Parent := OptionsGroup;
208   spinTestRandomSeed.Hint := 'Random seed for testing. Set to none zero to activate';
209   spinTestRandomSeed.ShowHint := True;
210   {$ENDIF}
211 
212 
213   PopulateEdgeSplit;
214   PopulateEdgeShape;
215 end;
216 
217 procedure TDependencyGraphOptDialog.OKButtonClick(Sender: TObject);
218 begin
219   WriteToOpts;
220   ModalResult := mrOK;
221 end;
222 
223 procedure TDependencyGraphOptDialog.ApplyButtonClick(Sender: TObject);
224 begin
225   if ApplyCallback <> nil then begin
226     WriteToOpts;
227     ApplyCallback(Options, Graph);
228     ModalResult := mrNone;
229     UpdateInfo;
230   end;
231 end;
232 
233 procedure TDependencyGraphOptDialog.SetApplyCallback(AValue: TApplyOptionsProc);
234 begin
235   if FApplyCallback = AValue then Exit;
236   FApplyCallback := AValue;
237   if FApplyCallback <> nil then
238     ButtonPanel1.ShowButtons := ButtonPanel1.ShowButtons + [pbClose]
239   else
240     ButtonPanel1.ShowButtons := ButtonPanel1.ShowButtons - [pbClose];
241 end;
242 
243 procedure TDependencyGraphOptDialog.SetGraph(AValue: TLvlGraph);
244 begin
245   if FGraph = AValue then Exit;
246   FGraph := AValue;
247   UpdateInfo;
248 end;
249 
250 procedure TDependencyGraphOptDialog.SetOptions(AValue: TLvlGraphOptions);
251 begin
252   if FOptions = AValue then Exit;
253   FOptions := AValue;
254   ReadFromOpts;
255 end;
256 
257 procedure TDependencyGraphOptDialog.SetShowInfo(AValue: Boolean);
258 begin
259   if FShowInfo = AValue then Exit;
260   FShowInfo := AValue;
261   UpdateInfo;
262 end;
263 
264 procedure TDependencyGraphOptDialog.SetShowSplitModes(
265   AValue: TLvlGraphEdgeSplitModes);
266 begin
267   if FShowSplitModes = AValue then Exit;
268   FShowSplitModes := AValue;
269   PopulateEdgeSplit;
270 end;
271 
272 procedure TDependencyGraphOptDialog.PopulateEdgeSplit;
273 var
274   i: TLvlGraphEdgeSplitMode;
275   j: Integer;
276 begin
277   dropEdgeSplit.Items.Clear;
278   j := 0;
279   for i := low(TLvlGraphEdgeSplitMode) to high(TLvlGraphEdgeSplitMode) do begin
280     if not (i in FShowSplitModes) then
281       continue;
282     FEdgeSplitMap[j] := i;
283     FEdgeRevSplitMap[i] := j;
284     case i of
285       lgesNone:         dropEdgeSplit.Items.Add(LvlGraphSplitNone);
286       lgesSeparate:     dropEdgeSplit.Items.Add(LvlGraphSplitSeparate);
287       lgesMergeSource:  dropEdgeSplit.Items.Add(LvlGraphSplitMergeAtSourc);
288       lgesMergeTarget:  dropEdgeSplit.Items.Add(LvlGraphSplitMergeAtTarge);
289       lgesMergeHighest: dropEdgeSplit.Items.Add(LvlGraphSplitMergeAtHighe);
290       else dropEdgeSplit.Items.Add('?');
291     end;
292     inc(j);
293   end;
294 end;
295 
296 procedure TDependencyGraphOptDialog.PopulateEdgeShape;
297 var
298   i: TLvlGraphEdgeShape;
299 begin
300   dropEdgeShape.Items.Clear;
301   for i := low(TLvlGraphEdgeShape) to high(TLvlGraphEdgeShape) do begin
302     case i of
303       lgesStraight: dropEdgeShape.Items.Add(LvlGraphShapeStraight);
304       lgesCurved:   dropEdgeShape.Items.Add(LvlGraphShapeCurved);
305       else dropEdgeShape.Items.Add('?');
306     end;
307   end;
308 end;
309 
310 procedure TDependencyGraphOptDialog.WriteToOpts;
311 begin
312   Options.MinimizeEdges := chkMinimizeEdges.Checked;
313   Options.HighLevels := chkHighEdges.Checked;
314   Options.ReduceBackEdges := chkReduceBackEdges.Checked;
315   Options.StraightenGraph := chkStraigtenGraph.Checked;
316   Options.EdgeSplit := FEdgeSplitMap[max(0, dropEdgeSplit.ItemIndex)];
317   Options.EdgeShape := TLvlGraphEdgeShape(max(0, dropEdgeShape.ItemIndex));
318   if chkCaptionOnTop.Checked then
319     Options.CaptionPos := lgncTop
320   else
321     Options.CaptionPos := lgncBottom;
322   Options.ExtraSpacingHoriz := spinHorizSpacing.Value;
323   Options.ExtraSpacingVert := spinVertSpacing.Value;
324   Options.LimitLvlHeighAbs := spinLvlLimitAbs.Value;
325   Options.LimitLvlHeighRel := spinLvlLimitRel.Value;
326   {$IFDEF WITH_RANDOM_SEED}
327   Options.TestRandomSeed := spinTestRandomSeed.Value;
328   {$ENDIF}
329 end;
330 
331 procedure TDependencyGraphOptDialog.ReadFromOpts;
332 begin
333   chkMinimizeEdges.Checked := Options.MinimizeEdges;
334   chkHighEdges.Checked := Options.HighLevels;
335   chkReduceBackEdges.Checked := Options.ReduceBackEdges;
336   chkStraigtenGraph.Checked := Options.StraightenGraph;
337   dropEdgeSplit.ItemIndex := FEdgeRevSplitMap[Options.EdgeSplit];
338   dropEdgeShape.ItemIndex := ord(Options.EdgeShape);
339   chkCaptionOnTop.Checked := Options.CaptionPos = lgncTop;
340   spinHorizSpacing.Value := Options.ExtraSpacingHoriz;
341   spinVertSpacing.Value := Options.ExtraSpacingVert;
342   spinLvlLimitAbs.Value := Options.LimitLvlHeighAbs;
343   spinLvlLimitRel.Value := Options.LimitLvlHeighRel;
344   {$IFDEF WITH_RANDOM_SEED}
345   spinTestRandomSeed.Value := Options.TestRandomSeed;
346   {$ENDIF}
347 end;
348 
349 procedure TDependencyGraphOptDialog.UpdateInfo;
ComputeCrossCountnull350   function ComputeCrossCount: integer;
351   var
352     l,i,j,e1,e2: Integer;
353     Level: TLvlGraphLevel;
354     Node1, Node2, Target1, Target2: TLvlGraphNode;
355   begin
356     Result:=0;
357     for l:=0 to Graph.LevelCount-2 do begin
358       Level:=Graph.Levels[l];
359       for i:=0 to Level.Count-2 do begin
360         Node1:=Level.Nodes[i];
361         for j:=i+1 to Level.Count-1 do begin
362           Node2:=Level.Nodes[j];
363           for e1:=0 to Node1.OutEdgeCount-1 do begin
364             Target1:=Node1.OutEdges[e1].Target;
365             for e2:=0 to Node2.OutEdgeCount-1 do begin
366               Target2:=Node2.OutEdges[e2].Target;
367               if Target1.IndexInLevel>Target2.IndexInLevel then
368                 Result+=1;
369             end;
370           end;
371         end;
372       end;
373     end;
374   end;
375 var
376   InfoNodeCnt, InfoEdgeCnt, InfoEdgeLen, InfoSplitCnt: Integer;
377   i, j: Integer;
378   Node: TLvlGraphNode;
379   Targets: TLvlGraphNodeArray;
380 begin
381   InfoGroup.Visible := FGraph <> nil;
382   if FGraph = nil then
383     exit;
384   InfoNodeCnt := 0;
385   InfoEdgeCnt := 0;
386   InfoEdgeLen := 0;
387   InfoSplitCnt := 0;
388   for i := 0 to Graph.NodeCount - 1 do begin
389     Node := Graph.Nodes[i];
390     if not Node.Visible then begin
391       if (Node.OutEdgeCount > 1) or (Node.InEdgeCount > 1) then
392         InfoSplitCnt := InfoSplitCnt + 1;
393       continue;
394     end;
395     InfoNodeCnt := InfoNodeCnt + 1;
396     Targets := Node.GetVisibleTargetNodes;
397     InfoEdgeCnt := InfoEdgeCnt + length(Targets);
398     for j := 0 to high(Targets) do
399       InfoEdgeLen := InfoEdgeLen + abs(Targets[j].Level.Index - Node.Level.Index);
400   end;
401   valNodeCnt.Caption  := IntToStr(InfoNodeCnt);
402   valEdgeCnt.Caption  := IntToStr(InfoEdgeCnt);
403   valEdgeLen.Caption  := IntToStr(InfoEdgeLen);
404   valLevelCnt.Caption := IntToStr(Graph.LevelCount);
405   valCrossCnt.Caption := IntToStr(ComputeCrossCount);
406   valSplitCnt.Caption := IntToStr(InfoSplitCnt);
407 end;
408 
409 { TLvlGraphOptions }
410 
411 constructor TLvlGraphOptions.Create;
412 begin
413   inherited;
414   FMinimizeEdges := True;
415   FHighLevels := False;
416   ReduceBackEdges := True;
417   FExtraSpacingVert := 0;
418   FExtraSpacingHoriz := 0;
419   FCaptionPos := lgncTop;
420   FEdgeShape := lgesCurved;
421   FEdgeSplit := lgesMergeHighest;
422   FStraightenGraph := True;
423   FLimitLvlHeighAbs := 0;
424   FLimitLvlHeighRel := 1.5;
425 end;
426 
427 procedure TLvlGraphOptions.ReadFromXml(AnXmlConf: TRttiXMLConfig; APath: String);
428 var
429   Def: TLvlGraphOptions;
430 begin
431   Def := TLvlGraphOptions.Create;
432   AnXmlConf.ReadObject(APath, Self, Def);
433   Def.Free;
434   if OnLoaded <> nil then
435     OnLoaded(Self);
436 end;
437 
438 procedure TLvlGraphOptions.WriteToXml(AnXmlConf: TRttiXMLConfig; APath: String);
439 var
440   Def: TLvlGraphOptions;
441 begin
442   Def := TLvlGraphOptions.Create;
443   AnXmlConf.WriteObject(APath, Self, Def);
444   Def.Free;
445 end;
446 
447 procedure TLvlGraphOptions.Assign(ASrc: TPersistent);
448 begin
449   FMinimizeEdges := TLvlGraphOptions(ASrc).FMinimizeEdges;
450   FHighLevels := TLvlGraphOptions(ASrc).FHighLevels;
451   FReduceBackEdges := TLvlGraphOptions(ASrc).FReduceBackEdges;
452   FExtraSpacingVert := TLvlGraphOptions(ASrc).FExtraSpacingVert;
453   FExtraSpacingHoriz := TLvlGraphOptions(ASrc).FExtraSpacingHoriz;
454   FCaptionPos := TLvlGraphOptions(ASrc).FCaptionPos;
455   FEdgeShape := TLvlGraphOptions(ASrc).FEdgeShape;
456   FEdgeSplit := TLvlGraphOptions(ASrc).FEdgeSplit;
457   FStraightenGraph := TLvlGraphOptions(ASrc).FStraightenGraph;
458   FLimitLvlHeighAbs := TLvlGraphOptions(ASrc).FLimitLvlHeighAbs;
459   FLimitLvlHeighRel := TLvlGraphOptions(ASrc).FLimitLvlHeighRel;
460 end;
461 
462 procedure TLvlGraphOptions.WriteToGraph(AValue: TLvlGraphControl);
463 var
464   i: Integer;
465 begin
466   if MinimizeEdges then
467     AValue.Options := AValue.Options + [lgoMinimizeEdgeLens]
468   else
469     AValue.Options := AValue.Options - [lgoMinimizeEdgeLens];
470   if HighLevels then
471     AValue.Options := AValue.Options + [lgoHighLevels]
472   else
473     AValue.Options := AValue.Options - [lgoHighLevels];
474   if ReduceBackEdges then
475     AValue.Options := AValue.Options + [lgoReduceBackEdges]
476   else
477     AValue.Options := AValue.Options - [lgoReduceBackEdges];
478   i := ExtraSpacingVert div 2;
479   AValue.NodeStyle.GapTop    := DefaultLvlGraphNodeGapTop + i;
480   AValue.NodeStyle.GapBottom := DefaultLvlGraphNodeGapBottom + ExtraSpacingVert - i;
481   AValue.NodeStyle.GapRight := DefaultLvlGraphNodeGapRight + ExtraSpacingHoriz;
482   AValue.NodeStyle.CaptionPosition := FCaptionPos;
483   AValue.EdgeStyle.SplitMode := EdgeSplit;
484   AValue.EdgeStyle.Shape  := EdgeShape;
485   if StraightenGraph then
486     AValue.Options := AValue.Options + [lgoStraightenGraph]
487   else
488     AValue.Options := AValue.Options - [lgoStraightenGraph];
489   AValue.Limits.MaxLevelHeightAbs := LimitLvlHeighAbs;
490   AValue.Limits.MaxLevelHeightRel := LimitLvlHeighRel;
491   {$IFDEF WITH_RANDOM_SEED}
492   if TestRandomSeed <> 0 then
493     RandSeed := TestRandomSeed; // graph autolayout should be triggered before anything else uses random
494   {$ENDIF}
495 end;
496 
497 procedure TLvlGraphOptions.ReadFromGraph(AValue: TLvlGraphControl);
498 begin
499   MinimizeEdges := lgoMinimizeEdgeLens in AValue.Options;
500   HighLevels := lgoHighLevels in AValue.Options;
501   ReduceBackEdges := lgoReduceBackEdges in AValue.Options;
502   ExtraSpacingVert := AValue.NodeStyle.GapTop - DefaultLvlGraphNodeGapTop
503     + AValue.NodeStyle.GapBottom - DefaultLvlGraphNodeGapBottom;
504   ExtraSpacingHoriz := AValue.NodeStyle.GapRight - DefaultLvlGraphNodeGapRight;
505   FCaptionPos := AValue.NodeStyle.CaptionPosition;
506   EdgeSplit := AValue.EdgeStyle.SplitMode;
507   EdgeShape := AValue.EdgeStyle.Shape;
508   StraightenGraph := lgoStraightenGraph in AValue.Options;
509   LimitLvlHeighAbs := AValue.Limits.MaxLevelHeightAbs;
510   LimitLvlHeighRel := AValue.Limits.MaxLevelHeightRel;
511 end;
512 
513 end.
514 
515