Вот кусок правда это не совсем дерево но если расширить растояние между узлами получится что нужно...
Код | TOrient=(orRigth,orUp,orNone); TCircleType=(ctFinish,ctRigthTop);
TCell=Record LenLeft:Integer; LenTop:Integer; LenRight:Integer; LenBottom:Integer; X,Y:Integer; Size:Integer; SelectColor:TColor; End;
TPathCell=Record Value:Integer; Orient:TOrient; isOptimal:Boolean; End;
TMap=array of array of TCell;
TMapPath=array of array of TPathCell; TCircle=Class;
TCircleMng=class Private N,M:Integer; Public Path:TMapPath; Canvas:TCanvas; SeverLen:Integer; Map:TMap; Finish:TCircle; Start:TCircle; OptimalColor:TColor;
constructor Create(xN,xM:Integer); Procedure Draw; Procedure CreateOptimalPath; Procedure Recalc(xCircle:TCircle); end;
TCircle=Class private X1,Y1,X2,Y2,Radius:Integer; public OrientArrow:TOrient; Value:Integer; FillColor:TColor; LeftTop:TCircle; RigthButtom:TCircle;
CircleType:TCircleType; Parent:TCircle;
Sum:Integer; LenTop,LenRigth:Integer; LenPreor:Integer; Visible:Boolean; I,J:Integer; Start:Boolean; CircleMng:TCircleMng; constructor Create(xCircleMng:TCircleMng; xI,xJ:Integer;xCircleType:TCircleType;xParent:TCircle;xLenPreor:Integer;xOrientArrow:TOrient);
procedure SaveCost(xOrientArrow:TOrient); Procedure Draw; Procedure DrawArrow; End;
.......
procedure TCircle.Draw; Var OldBrushStyle:TBrushStyle; OldBrushColor:TColor; OldPenColor:TColor; Canvas:TCanvas; begin IF (Visible=True) and (CircleType<>ctFinish) Then Begin Canvas:=CircleMng.Canvas; OldBrushStyle:=Canvas.Brush.Style; OldBrushColor:=Canvas.Brush.Color; OldPenColor:=Canvas.Pen.Color; Canvas.Brush.Style := bsSolid; IF CircleMng.Path[I,J].isOptimal Then FillColor:=CircleMng.OptimalColor Else FillColor:=Defcolor; Canvas.Brush.Color:=FillColor; Canvas.Ellipse(X1,Y1,X2,Y2); DrawArrow; Canvas.TextOut(X1+Round(Radius/2),Y1+Round(Radius/2),IntToStr(CircleMng.Path[I,J].Value)); Canvas.Brush.Style := OldBrushStyle; Canvas.Brush.Color:=OldBrushColor; Canvas.Pen.Color:= OldPenColor; End; IF LeftTop<>Nil Then LeftTop.Draw; IF RigthButtom<>Nil Then RigthButtom.Draw; end;
procedure TCircle.DrawArrow; Var Canvas:TCanvas; OldBrushStyle:TBrushStyle; OldBrushColor:TColor; OldPenColor:TColor; begin IF Visible=True Then Begin Canvas:=CircleMng.Canvas; OldBrushStyle:=Canvas.Brush.Style; OldBrushColor:=Canvas.Brush.Color; OldPenColor:=Canvas.Pen.Color; Canvas.Brush.Style := bsSolid; IF CircleMng.Path[I,J].Orient=orRigth Then Begin Canvas.Pen.Color:=clGray; Canvas.MoveTo(X1+Round(Radius*2)-2,Y1+Round(Radius)-5); Canvas.LineTo(X1+Round(Radius*2)+5,Y1+Round(Radius)); Canvas.LineTo(X1+Round(Radius*2)-2,Y1+Round(Radius)+5); Canvas.LineTo(X1+Round(Radius*2)-2,Y1+Round(Radius)-5); Canvas.Brush.Color:=clBlack; Canvas.FloodFill(X1+Round(Radius*2),Y1+Round(Radius),clGray,fsBorder); Canvas.Brush.Color:=FillColor; Canvas.Pen.Color:=OldPenColor; End; IF CircleMng.Path[I,J].Orient=orUp Then Begin Canvas.Pen.Color:=clGray; Canvas.MoveTo(X1+Radius-5,Y1); Canvas.LineTo(X1+Radius,Y1-5); Canvas.LineTo(X1+Radius+5,Y1); Canvas.LineTo(X1+Radius-5,Y1); Canvas.Brush.Color:=clBlack; Canvas.FloodFill(X1+Radius-2,Y1-2,clGray,fsBorder); Canvas.Brush.Color:=FillColor; Canvas.Pen.Color:=OldPenColor; End; Canvas.Brush.Style := OldBrushStyle; Canvas.Brush.Color:=OldBrushColor; End; end;
|
Вот скрин
|