📄 chart.pas
字号:
for t:=0 to Axes.Count-1 do
with {$IFNDEF CLR}TAxisAccess{$ENDIF}(Axes[t]) do
if not IsDepthAxis then
begin
Automatic:=Saved[t].Auto;
AutomaticMinimum:=Saved[t].AutoMin;
AutomaticMaximum:=Saved[t].AutoMax;
{$IFDEF LCL} // Lazarus FPC bug?
SetMinMax(Saved[t].Min,Saved[t].Max);
{$ELSE}
{$IFDEF CLR}TAxisAccess(Axes[t]).{$ENDIF}InternalSetMinimum(Saved[t].Min);
{$IFDEF CLR}TAxisAccess(Axes[t]).{$ENDIF}InternalSetMaximum(Saved[t].Max);
{$ENDIF}
// if not Automatic then SetMinMax(Saved[t].Min,Saved[t].Max); // 7.0 Removed
end;
Saved:=nil;
end;
procedure TCustomChart.SetBackWall(Value:TChartBackWall);
begin
Walls.Back:=Value;
end;
function TCustomChart.GetBackWall: TChartBackWall;
begin
result:=Walls.Back;
end;
function TCustomChart.GetBottomWall: TChartWall;
begin
result:=Walls.Bottom;
end;
function TCustomChart.GetLeftWall: TChartWall;
begin
result:=Walls.Left;
end;
function TCustomChart.GetRightWall: TChartRightWall;
begin
result:=Walls.Right;
end;
Function TCustomChart.GetFrame:TChartPen;
begin
if Assigned(Walls.Back) then result:=Walls.Back.Pen
else result:=nil;
end;
Procedure TCustomChart.SetFrame(Value:TChartPen);
begin
BackWall.Pen.Assign(Value);
end;
Function TCustomChart.GetBackColor:TColor;
begin
if BackWall.Transparent then result:=Color
else result:=BackWall.Color;
end;
Procedure TCustomChart.SetBackColor(Value:TColor);
begin
BackWall.Color:=Value;
{ fix 4.01: do not set backwall solid when loading dfms... }
if Assigned(Parent) and (not (csLoading in ComponentState)) then
BackWall.Brush.Style:=bsSolid;
end;
Function TCustomChart.IsFreeSeriesColor(AColor:TColor; CheckBackground:Boolean;
ASeries:TChartSeries=nil):Boolean;
var t : Integer;
Begin
for t:=0 to SeriesCount-1 do
if ((Series[t]<>ASeries) and (Series[t].SeriesColor=AColor)) or // 6.02
(CheckBackground and
( (AColor=Color) or (AColor=BackWall.Color) )) then
begin
result:=False;
exit;
end;
result:=(not CheckBackground) or ( (AColor<>Color) and (AColor<>BackWall.Color) );
end;
procedure TCustomChart.SetLeftWall(Value:TChartWall);
begin
Walls.Left:=Value;
end;
procedure TCustomChart.SetBottomWall(Value:TChartWall);
begin
Walls.Bottom:=Value;
end;
procedure TCustomChart.SetRightWall(Value:TChartRightWall);
begin
Walls.Right:=Value;
end;
Procedure TCustomChart.DrawRightWall;
var tmpB : Integer;
tmp : Integer;
tmpBlend : TTeeBlend;
begin
if RightWall.Visible and ActiveSeriesUseAxis and View3D and View3DWalls then
begin
PrepareWallCanvas(RightWall);
tmpB:=ChartRect.Bottom+CalcWallSize(BottomAxis);
tmpBlend:=RightWall.TryDrawWall(ChartRect.Right,tmpB);
With RightWall,ChartRect do
if Size>0 then
begin
if BackWall.Visible then tmp:=BackWall.Size
else tmp:=0;
Canvas.Cube(Right,Right+Size,Top,tmpB,0,Width3D+tmp,ApplyDark3D)
end
else
Canvas.RectangleZ(Right,Top,tmpB,0,Succ(Width3D));
if (not RightWall.Transparent) and
(RightWall.Transparency>0) then Canvas.EndBlending(tmpBlend);
end;
end;
Function TCustomChart.DrawWallFirst(APos:Integer):Boolean;
var P : TFourPoints;
tmpBottom : Integer;
begin
With ChartRect do
begin
P[0]:=Canvas.Calculate3DPosition(APos,Top,0);
tmpBottom:=Bottom+CalcWallSize(BottomAxis);
P[1]:=Canvas.Calculate3DPosition(APos,tmpBottom,0);
P[2]:=Canvas.Calculate3DPosition(APos,tmpBottom,Width3D+BackWall.Size);
end;
result:=TeeCull(P);
end;
Function TCustomChart.DrawRightWallAfter:Boolean;
begin
result:=not DrawWallFirst(ChartRect.Right);
end;
Function TCustomChart.DrawLeftWallFirst:Boolean;
begin
result:=DrawWallFirst(ChartRect.Left);
end;
type TChartAxisAccess=class(TChartAxis);
procedure TCustomChart.DrawTitlesAndLegend(BeforeSeries:Boolean);
Procedure DrawAxisAfter(Axis:TChartAxis);
begin
if IsAxisVisible(Axis) then
begin
TChartAxisAccess(Axis).IHideBackGrid:=True;
Axis.Draw(False);
TChartAxisAccess(Axis).IHideBackGrid:=False;
end;
end;
Procedure DrawAxisGridAfter(Axis:TChartAxis);
begin
if IsAxisVisible(Axis) then
begin
TChartAxisAccess(Axis).IHideSideGrid:=True;
TChartAxisAccess(Axis).DrawGrids(Length(Axis.Tick));
TChartAxisAccess(Axis).IHideSideGrid:=False;
end;
end;
Procedure DrawTitleFoot(CustomOnly:Boolean);
Procedure DoDrawTitle(ATitle:TChartTitle);
begin
if ATitle.CustomPosition=CustomOnly then ATitle.DrawTitle; { 5.02 }
end;
Begin
DoDrawTitle(FTitle);
DoDrawTitle(FSubTitle);
DoDrawTitle(FFoot);
DoDrawTitle(FSubFoot);
end;
{ draw title and foot, or draw foot and title, depending
if legend is at left/right or at top/bottom. }
{ top/bottom legends need to leave space for the title and foot
before they get displayed. }
{ If the Legend.CustomPosition is True, then draw the Legend AFTER
all Series and Axes (on top of chart) }
begin
Canvas.FrontPlaneBegin;
if BeforeSeries then
begin { draw titles and legend before series }
if (not Legend.CustomPosition) and Legend.ShouldDraw then
begin
if Legend.Vertical then
begin
Legend.DrawLegend;
DrawTitleFoot(False);
end
else
begin
DrawTitleFoot(False);
Legend.DrawLegend;
end;
end
else DrawTitleFoot(False);
end
else
begin { after series }
if Legend.CustomPosition and Legend.ShouldDraw then
Legend.DrawLegend;
DrawTitleFoot(True);
end;
Canvas.FrontPlaneEnd;
if not BeforeSeries then
if ActiveSeriesUseAxis then
begin
if View3D then
begin
if DrawRightWallAfter then
begin
if Walls.Right.ShouldDraw then
DrawRightWall;
DrawAxisAfter(RightAxis);
end;
if DrawLeftWallFirst then
begin
if Walls.Left.ShouldDraw then
DrawLeftWall;
DrawAxisAfter(LeftAxis);
end;
if DrawBackWallAfter(Width3D) then
begin
DrawAxisGridAfter(TopAxis);
DrawAxisGridAfter(BottomAxis);
if Walls.Back.ShouldDraw then
DrawBackWall;
end;
end;
end;
end;
// Returns wall size in pixels corresponding to Axis parameter.
// For example: Left axis corresponds to Left wall.
Function TCustomChart.CalcWallSize(Axis:TChartAxis):Integer;
var tmpW : TCustomChartWall;
begin
result:=0;
if View3D and View3DWalls then
begin
if Axis=LeftAxis then tmpW:=Walls.Left else
if Axis=BottomAxis then tmpW:=Walls.Bottom else
if Axis=RightAxis then tmpW:=Walls.Right else tmpW:=Walls.Back;
if tmpW.Visible then result:=tmpW.Size;
end;
end;
Function TCustomChart.ActiveSeriesUseAxis:Boolean;
var t : Integer;
begin
result:=True;
for t:=0 to SeriesCount-1 do
With Series[t] do
if Active then
if UseAxis then
begin
result:=True;
Exit;
end
else result:=False;
end;
Procedure TCustomChart.PrepareWallCanvas(AWall:TChartWall);
begin
With AWall do
begin
Canvas.AssignVisiblePen(Frame);
if Transparent then Canvas.Brush.Style:=bsClear
else SetBrushCanvas(Color,Brush,Brush.Color)
end;
end;
Procedure TCustomChart.DrawLeftWall; { Left wall only }
var tmpB : Integer;
tmpBlend : TTeeBlend;
begin
if View3D and View3DWalls then
begin
PrepareWallCanvas(LeftWall);
tmpB:=ChartRect.Bottom+CalcWallSize(BottomAxis);
tmpBlend:=LeftWall.TryDrawWall(ChartRect.Left,tmpB);
With LeftWall,ChartRect do
if Size>0 then
Canvas.Cube(Left-Size,Left,Top,tmpB,0,Width3D,ApplyDark3D)
else
Canvas.RectangleZ(Left,Top,tmpB,0,Width3D);
if (not LeftWall.Transparent) and (LeftWall.Transparency>0) then
Canvas.EndBlending(tmpBlend);
end;
end;
type
TCanvasAccess=class(TCanvas3D);
Procedure TCustomChart.DrawBackWall;
var tmpRect : TRect;
Procedure DrawBackWallGradient;
var P : TFourPoints;
begin
if (not BackWall.Transparent) and BackWall.HasGradient then
begin
if View3DOptions.Orthogonal then
BackWall.Gradient.Draw(Canvas,Canvas.CalcRect3D(tmpRect,Width3D))
else
begin
if Canvas.SupportsFullRotation then
begin
TCanvasAccess(Canvas).GradientZ:=Width3D;
BackWall.Gradient.Draw(Canvas,tmpRect);
TCanvasAccess(Canvas).GradientZ:=0;
end
else
begin
P:=Canvas.FourPointsFromRect(tmpRect,Width3D);
BackWall.Gradient.Draw(Canvas,P);
end;
end;
if not Canvas.SupportsFullRotation then
Canvas.Brush.Style:=bsClear;
end;
end;
var tmpBlend : TTeeBlend;
Procedure CreateBlender;
begin
with BackWall do
if Transparency>0 then
tmpBlend:=Canvas.BeginBlending(Canvas.RectFromRectZ(tmpRect,Width3D),Transparency);
end;
var tmp : Integer;
tmpSize : Integer;
begin
With BackWall do
begin
PrepareWallCanvas(BackWall);
if View3D then
begin
if View3DWalls then
begin
if Width3D<0 then tmp:=-Size else tmp:=Size;
if Size>0 then
begin
tmpSize:=CalcWallSize(LeftAxis);
with ChartRect do
tmpRect:=TeeRect( Left-tmpSize,Top,
Right,Bottom+CalcWallSize(BottomAxis))
end
else
tmpRect:=ChartRect;
CreateBlender;
DrawBackWallGradient;
if Size>0 then
Canvas.Cube(tmpRect,Width3D,Width3D+tmp,ApplyDark3D)
else
Canvas.RectangleWithZ(tmpRect,Width3D);
end;
end
else
begin
With ChartRect do
tmpRect:=TeeRect(Left,Top,Succ(Right),Succ(Bottom));
CreateBlender;
if Gradient.Visible and (not Transparent) then
begin
Gradient.Draw(Canvas,tmpRect);
Canvas.Brush.Style:=bsClear;
end;
Canvas.Rectangle(tmpRect);
end;
if HasBackImage and BackImage.Inside then
begin
tmpRect:=ChartRect;
if Pen.Visible then
begin
Inc(tmpRect.Top);
Inc(tmpRect.Left);
end;
DrawBitmap(tmpRect,Width3D);
end;
if Transparency>0 then Canvas.EndBlending(tmpBlend);
end;
end;
Procedure TCustomChart.DrawWalls; { Left and Bottom wall only }
Procedure DrawBottomWall;
var P : TFourPoints;
tmpB : Integer;
tmpLeft : Integer;
Procedure CalcBottomWallPoints;
begin
tmpB:=ChartRect.Bottom;
P[0]:=Canvas.Calculate3DPosition(tmpLeft, tmpB,0);
P[1]:=Canvas.Calculate3DPosition(tmpLeft, tmpB,Width3D);
P[2]:=Canvas.Calculate3DPosition(ChartRect.Right, tmpB,Width3D);
P[3]:=Canvas.Calculate3DPosition(ChartRect.Right, tmpB,0);
end;
var tmpBlend : TTeeBlend;
tmpRight : Integer;
begin
PrepareWallCanvas(BottomWall);
tmpB:=ChartRect.Bottom;
if Canvas.SupportsFullRotation then Inc(tmpB);
tmpLeft:=ChartRect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -