DeepGantt智慧项目管理工作进度计划软件是一款DeepSeek AI驱动的新一代智慧项目管理工作进度计划软件,既可以用于工程企业的大型项目进度管理,也适用于个人的工作时间管理。该软件采用付费开源的方式与客户共享源代码,DeepGantt使用最新版的Delphi 12社区版开发,源代码同时兼容即将发布的Delphi 13 佛罗伦萨 版本。
DeepGantt可以通过可视化方式绘制甘特图(横道图),也可以生成双代号网络图,其中双代号网络图中会用到绘制折线虚线的功能,如下如所示:
现将DeepGantt中绘制折线虚线的Delphi源码共享出来以回馈Delphi社区,源码如下:
procedure DrawDashedLineAllPoint(Canvas: TCanvas; const Points: array of TPoint; DashLength: Integer = 5; GapLength: Integer = 5);
var
I: Integer;
StartPoint, EndPoint: TPoint;
IsVertical, IsHorizontal: Boolean;
// 专用垂直虚线绘制
procedure DrawVerticalDashed(X, Y1, Y2: Integer);
var
CurrentY: Integer;
IsDash: Boolean;
begin
CurrentY := Y1;
IsDash := True;
while CurrentY < Y2 do
begin
if IsDash then
begin
Canvas.MoveTo(X, CurrentY);
Canvas.LineTo(X, Min(CurrentY + DashLength, Y2));
end;
Inc(CurrentY, IfThen(IsDash, DashLength, GapLength));
IsDash := not IsDash;
end;
end;
// 专用水平虚线绘制
procedure DrawHorizontalDashed(Y, X1, X2: Integer);
var
CurrentX: Integer;
IsDash: Boolean;
begin
CurrentX := X1;
IsDash := True;
while CurrentX < X2 do
begin
if IsDash then
begin
Canvas.MoveTo(CurrentX, Y);
Canvas.LineTo(Min(CurrentX + DashLength, X2), Y);
end;
Inc(CurrentX, IfThen(IsDash, DashLength, GapLength));
IsDash := not IsDash;
end;
end;
// 通用斜线绘制
procedure DrawDiagonalDashed;
var
Distance, Remaining: Double;
DeltaX, DeltaY: Double;
CurrentX, CurrentY: Integer;
IsDash: Boolean;
begin
Distance := Sqrt(Sqr(EndPoint.X - StartPoint.X) + Sqr(EndPoint.Y - StartPoint.Y));
if Distance = 0 then Exit;
DeltaX := (EndPoint.X - StartPoint.X) / Distance;
DeltaY := (EndPoint.Y - StartPoint.Y) / Distance;
CurrentX := StartPoint.X;
CurrentY := StartPoint.Y;
IsDash := True;
Remaining := Distance;
while Remaining > 0 do
begin
if IsDash then
begin
Canvas.MoveTo(CurrentX, CurrentY);
Canvas.LineTo(
CurrentX + Round(DashLength * DeltaX),
CurrentY + Round(DashLength * DeltaY)
);
end;
// 整数步长更新
if IsDash then
begin
Inc(CurrentX, Round(DashLength * DeltaX));
Inc(CurrentY, Round(DashLength * DeltaY));
Remaining := Remaining - DashLength;
end
else
begin
Inc(CurrentX, Round(GapLength * DeltaX));
Inc(CurrentY, Round(GapLength * DeltaY));
Remaining := Remaining - GapLength;
end;
IsDash := not IsDash;
end;
end;
begin
for I := 0 to High(Points) - 1 do
begin
StartPoint := Points[I];
EndPoint := Points[I + 1];
// 确定线型类别
IsVertical := (StartPoint.X = EndPoint.X);
IsHorizontal := (StartPoint.Y = EndPoint.Y);
// 分类处理
if IsVertical then
begin
if StartPoint.Y < EndPoint.Y then
DrawVerticalDashed(StartPoint.X, StartPoint.Y, EndPoint.Y)
else
DrawVerticalDashed(StartPoint.X, EndPoint.Y, StartPoint.Y);
end
else if IsHorizontal then
begin
if StartPoint.X < EndPoint.X then
DrawHorizontalDashed(StartPoint.Y, StartPoint.X, EndPoint.X)
else
DrawHorizontalDashed(StartPoint.Y, EndPoint.X, StartPoint.X);
end
else
begin
DrawDiagonalDashed;
end;
end;
end;