📄 chart.pas
字号:
if IOnTop or FCustomPosition then
ShapeBounds.Bottom:=ShapeBounds.Top+Text.Count*FontH
else
ShapeBounds.Top :=ShapeBounds.Bottom-Text.Count*FontH;
{ apply margins to bottom and right sides }
if not FCustomPosition then
InflateRect(ShapeBounds,tmpFrameWidth,tmpFrameWidth);
tmpMargin:=ParentChart.Canvas.TextWidth('W');
{ resize Title to maximum Chart width }
if AdjustFrame then
begin
tmpMaxWidth:=0;
for t:=0 to Text.Count-1 do
Begin
tmp:=ParentChart.Canvas.TextWidth(Text[t]);
if tmp>tmpMaxWidth then tmpMaxWidth:=tmp;
end;
Inc(tmpMaxWidth,tmpMargin+tmpFrameWidth);
With ShapeBounds do
Case Alignment of
taLeftJustify : Right:=Left +tmpMaxWidth;
taRightJustify : Left :=Right-tmpMaxWidth;
taCenter : begin
if FCustomPosition then Right:=Left+tmpMaxWidth;
tmp:=(Left+Right) div 2;
Left :=tmp-(tmpMaxWidth div 2);
Right:=tmp+(tmpMaxWidth div 2);
end;
end;
end;
{ draw title shape }
Draw;
if Alignment=taLeftJustify then tmpXPosTitle:=ShapeBounds.Left+(tmpMargin div 2);
{ draw all Title text lines }
ParentChart.Canvas.BackMode:=cbmTransparent;
for t:=0 to Text.Count-1 do DrawTitleLine(t);
{ calculate Chart positions after drawing the titles / footers }
if not FCustomPosition then
begin
tmp:=TeeTitleFootDistance+tmpFrameWidth;
if not Transparent then
Inc(tmp,Shadow.VertSize);
{$IFDEF CLR}
tmpR:=ParentChart.ChartRect;
if IOnTop then
tmpR.Top:=ShapeBounds.Bottom+tmp
else
tmpR.Bottom:=ShapeBounds.Bottom-tmp-Text.Count*FontH;
ParentChart.ChartRect:=tmpR;
{$ELSE}
if IOnTop then
ParentChart.ChartRect.Top:=ShapeBounds.Bottom+tmp
else
ParentChart.ChartRect.Bottom:=ShapeBounds.Bottom-tmp-Text.Count*FontH;
{$ENDIF}
ParentChart.RecalcWidthHeight;
end;
end;
end;
Function TChartTitle.GetShapeBounds:TRect;
begin
result:=ShapeBounds;
end;
Procedure TChartTitle.SetAdjustFrame(Value:Boolean);
begin
TTeePanelAccess(ParentChart).SetBooleanProperty(FAdjustFrame,Value);
end;
Procedure TChartTitle.SetAlignment(Value:TAlignment);
Begin
if FAlignment<>Value then
begin
FAlignment:=Value;
Repaint;
end;
end;
Procedure TChartTitle.SetText(Value:TStrings);
begin
FText.Assign(Value);
Repaint;
end;
{ TChartFootTitle }
Constructor TChartFootTitle.Create(AOwner: TCustomTeePanel);
Begin
inherited {$IFDEF CLR}Create(AOwner){$ENDIF};
IOnTop:=False;
With Font do
Begin
Color:=clRed;
Style:=[fsItalic];
end;
//TODO: DCCIL problem prevents using "with" here...
TTeeFontAccess(Font).IDefColor:=clRed;
TTeeFontAccess(Font).IDefStyle:=[fsItalic];
end;
{ TChartWalls }
constructor TChartWalls.Create(Chart: TCustomChart);
begin
inherited Create;
FChart:=Chart;
FBack:=TChartBackWall.Create(FChart);
FLeft:=TChartWall.Create(FChart);
FLeft.InitColor($80FFFF); { ChartMarkColor }
FBottom:=TChartWall.Create(FChart);
FBottom.InitColor(clWhite);
FRight:=TChartRightWall.Create(FChart);
With FRight do
begin
Visible:=False;
InitColor(clSilver);
end;
end;
procedure TChartWalls.Assign(Source: TPersistent);
begin
if Source is TChartWalls then
with TChartWalls(Source) do
begin
Self.Back :=Back;
Self.Bottom :=Bottom;
Self.Left :=Left;
Self.Right :=Right;
end
else inherited;
end;
destructor TChartWalls.Destroy;
begin
FBack.Free;
FBottom.Free;
FLeft.Free;
FRight.Free;
inherited;
end;
procedure TChartWalls.SetBack(const Value: TChartBackWall);
begin
Back.Assign(Value);
end;
procedure TChartWalls.SetBottom(const Value: TChartWall);
begin
Bottom.Assign(Value);
end;
procedure TChartWalls.SetLeft(const Value: TChartWall);
begin
Left.Assign(Value);
end;
procedure TChartWalls.SetRight(const Value: TChartRightWall);
begin
Right.Assign(Value);
end;
function TChartWalls.GetVisible: Boolean;
begin
result:=FChart.View3DWalls;
end;
procedure TChartWalls.SetVisible(const Value: Boolean);
begin
FChart.View3DWalls:=Value;
end;
procedure TChartWalls.SetSize(const Value: Integer);
begin
Left.Size:=Value;
Right.Size:=Value;
Back.Size:=Value;
Bottom.Size:=Value;
end;
{ TCustomChart }
Constructor TCustomChart.Create(AOwner: TComponent);
Begin
inherited;
AutoRepaint:=False;
FTitle:=TChartTitle.Create(Self);
if csDesigning in ComponentState then FTitle.FText.Add(ClassName);
FScrollMouse:=mbRight;
FSubTitle:=TChartTitle.Create(Self);
FFoot :=TChartFootTitle.Create(Self);
FSubFoot :=TChartFootTitle.Create(Self);
FWalls:=TChartWalls.Create(Self);
FLegend:=TChartLegend.Create(Self);
RestoredAxisScales:=True;
AutoRepaint :=True;
if Assigned(TeeNewChartHook) then
if (csDesigning in ComponentState) and
Assigned(Owner) and
(not (csLoading in Owner.ComponentState)) then
TeeNewChartHook(Self);
end;
Destructor TCustomChart.Destroy;
Begin
FSavedScales:=nil;
AutoRepaint:=False; { 5.01 }
FSubTitle.Free;
FTitle.Free;
FSubFoot.Free;
FFoot.Free;
FWalls.Free;
FLegend.Free;
inherited;
end;
type
TSeriesAccess=class(TChartSeries);
Function TCustomChart.FormattedValueLegend(ASeries:TChartSeries; ValueIndex:Integer):String;
var tmp : TCustomChartLegend;
Begin
if Assigned(ASeries) then
begin
tmp:=TCustomChartLegend(TSeriesAccess(ASeries).ILegend);
if not Assigned(tmp) then tmp:=Legend;
result:=tmp.FormattedValue(ASeries,ValueIndex);
end
else
result:='';
end;
Function TCustomChart.InternalFormattedLegend( ALegend:TCustomChartLegend;
SeriesOrValueIndex:Integer):String;
begin
result:=ALegend.FormattedLegend(SeriesOrValueIndex);
if Assigned(FOnGetLegendText) then
FOnGetLegendText(Self,ALegend.InternalLegendStyle,SeriesOrValueIndex,result);
end;
Function TCustomChart.FormattedLegend(SeriesOrValueIndex:Integer):String;
Begin
result:=InternalFormattedLegend(Legend,SeriesOrValueIndex);
end;
procedure TCustomChart.SetLegend(Value:TChartLegend);
begin
FLegend.Assign(Value);
end;
// "remember" the axis scales when zooming, to restore when unzooming
Function TCustomChart.SaveScales:TAllAxisSavedScales;
var t : Integer;
begin
SetLength(result,Axes.Count);
for t:=0 to Axes.Count-1 do
with Axes[t] do
if not IsDepthAxis then
begin
result[t].Auto:=Automatic;
result[t].AutoMin:=AutomaticMinimum;
result[t].AutoMax:=AutomaticMaximum;
result[t].Min:=Minimum;
result[t].Max:=Maximum;
end;
end;
type
TAxisAccess=class(TChartAxis);
// restore the "remembered" axis scales when unzooming
Procedure TCustomChart.RestoreScales(var Saved:TAllAxisSavedScales);
var t : Integer;
begin
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 CLR}TAxisAccess(Axes[t]).{$ENDIF}InternalSetMinimum(Saved[t].Min);
{$IFDEF CLR}TAxisAccess(Axes[t]).{$ENDIF}InternalSetMaximum(Saved[t].Max);
// 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -