📄 qixyplotchannel.pas
字号:
{*******************************************************}
{ }
{ TiXYPlotChannel }
{ }
{ Copyright (c) 1997,2003 Iocomp Software }
{ }
{*******************************************************}
{$I iInclude.inc}
{$ifdef iVCL}unit iXYPlotChannel;{$endif}
{$ifdef iCLX}unit QiXYPlotChannel;{$endif}
interface
uses
{$I iIncludeUses.inc}
{$IFDEF iVCL} iTypes, iGPFunctions, iClasses, iPlotObjects, iPlotDataNullList, iPlotChannelCustom, iPlotAxis;{$ENDIF}
{$IFDEF iCLX}QiTypes, QiGPFunctions, QiClasses, QiPlotObjects, QiPlotDataNullList, QiPlotChannelCustom, QiPlotAxis;{$ENDIF}
type
TiXYPlotChannel = class(TiPlotChannelCustom)
private
function GetDataCursorDisplayText(Style: TiPlotDataCursorStyle; XValue, YValue: Double; Status: TiPlotDataPointStatus): String;
protected
procedure DrawSetup(const Canvas: TCanvas); override;
procedure Draw (const Canvas: TCanvas; const BackGroundColor: TColor); override;
procedure CalcStartXIndex; override;
procedure CalcStopXIndex; override;
function GetVisibleMaxX : Double; override;
function GetVisibleMinX : Double; override;
function GetVisibleMaxY : Double; override;
function GetVisibleMinY : Double; override;
procedure DataCursorUpate(Sender: TObject); override;
public
constructor Create(AOwner: TObject; AOnChange, AOnInsert, AOnRemove, AOnRename: TNotifyEvent); override;
function AddNull : Integer;
function AddEmpty : Integer;
end;
implementation
uses
{$ifdef iCLX}
QiPlotDataCursor;
{$else}
iPlotDataCursor;
{$endif}
type
TiPlotDataCursorAccess = class(TiPlotDataCursor) end;
TiPlotAxisAccess = class(TiPlotAxis ) end;
//****************************************************************************************************************************************************
constructor TiXYPlotChannel.Create(AOwner: TObject; AOnChange, AOnInsert, AOnRemove, AOnRename: TNotifyEvent);
begin
inherited;
end;
//****************************************************************************************************************************************************
procedure TiXYPlotChannel.CalcStartXIndex;
begin
StartIndex := 0;
end;
//****************************************************************************************************************************************************
procedure TiXYPlotChannel.CalcStopXIndex;
begin
StopIndex := DataList.Count-1;
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.AddNull: Integer;
begin
Result := DataList.Add(0, 0);
DataList.Null [DataList.Count-1] := True;
DataList.Empty[DataList.Count-1] := False;
TriggerChange(Self);
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.AddEmpty: Integer;
begin
Result := DataList.Add(0, 0);
DataList.Null [DataList.Count-1] := False;
DataList.Empty[DataList.Count-1] := True;
TriggerChange(Self);
end;
//****************************************************************************************************************************************************
procedure TiXYPlotChannel.DrawSetup;
begin
CanDraw := False;
if not Assigned(XAxis) then exit;
if not Assigned(YAxis) then exit;
if not Visible then exit;
if DataList.Count = 0 then exit;
CalcStartXIndex;
CalcStopXIndex;
if StartIndex = - 1 then exit;
if StopIndex = - 1 then exit;
CanDraw := True;
end;
//****************************************************************************************************************************************************
procedure TiXYPlotChannel.Draw(const Canvas: TCanvas; const BackGroundColor: TColor);
begin
DrawConnectPoints(Canvas, XYAxesReversed);
DrawMarkers (Canvas, XYAxesReversed);
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.GetVisibleMaxX: Double;
var
x : Integer;
AValue : Double;
begin
CalcStartXIndex;
CalcStopXIndex;
Result := -1E300;
if not AxesValid then Exit;
if not Visible then Exit;
if StartIndex = -1 then Exit;
if StopIndex = -1 then Exit;
for x := 0 to Count-1 do
begin
if DataEmpty[x] then Continue;
if DataNull [x] then Continue;
AValue := DataXDrawMax[x];
if AValue > Result then Result := AValue;
end;
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.GetVisibleMinX: Double;
var
x : Integer;
AValue : Double;
begin
CalcStartXIndex;
CalcStopXIndex;
Result := 1E300;
if not AxesValid then Exit;
if not Visible then Exit;
if StartIndex = -1 then Exit;
if StopIndex = -1 then Exit;
for x := 0 to Count-1 do
begin
if DataEmpty[x] then Continue;
if DataNull [x] then Continue;
AValue := DataXDrawMin[x];
if AValue < Result then Result := AValue;
end;
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.GetVisibleMaxY: Double;
var
x : Integer;
AValue : Double;
begin
CalcStartXIndex;
CalcStopXIndex;
Result := -1E300;
if not AxesValid then Exit;
if not Visible then Exit;
if StartIndex = -1 then Exit;
if StopIndex = -1 then Exit;
for x := 0 to Count-1 do
begin
if DataEmpty[x] then Continue;
if DataNull [x] then Continue;
AValue := DataYDrawMax[x];
if AValue > Result then Result := AValue;
end;
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.GetVisibleMinY: Double;
var
x : Integer;
AValue : Double;
begin
CalcStartXIndex;
CalcStopXIndex;
Result := 1E300;
if not AxesValid then Exit;
if not Visible then Exit;
if StartIndex = -1 then Exit;
if StopIndex = -1 then Exit;
for x := 0 to Count-1 do
begin
if DataEmpty[x] then Continue;
if DataNull [x] then Continue;
AValue := DataYDrawMin[x];
if AValue < Result then Result := AValue;
end;
end;
//****************************************************************************************************************************************************
procedure TiXYPlotChannel.DataCursorUpate(Sender: TObject);
var
iDataCursor : TiPlotDataCursor;
X1Value : Double;
Y1Value : Double;
X2Value : Double;
Y2Value : Double;
XValue : Double;
YValue : Double;
Status : TiPlotDataPointStatus;
begin
iDataCursor := Sender as TiPlotDataCursor;
Status := ipdpsValid;
XValue := 0;
YValue := 0;
if Assigned(XAxis) and Assigned(YAxis) then
begin
X1Value := TiPlotAxisAccess(XAxis).PixelsToPositionDouble(TiPlotDataCursorAccess(iDataCursor).Pointer1Pixels);
X2Value := TiPlotAxisAccess(XAxis).PixelsToPositionDouble(TiPlotDataCursorAccess(iDataCursor).Pointer2Pixels);
Y1Value := TiPlotAxisAccess(YAxis).PixelsToPositionDouble(TiPlotDataCursorAccess(iDataCursor).Pointer1Pixels);
Y2Value := TiPlotAxisAccess(YAxis).PixelsToPositionDouble(TiPlotDataCursorAccess(iDataCursor).Pointer2Pixels);
case iDataCursor.Style of
ipcsValueXY : begin
XValue := X1Value;
YValue := Y2Value;
end;
ipcsValueX : begin
XValue := X1Value;
YValue := 0;
end;
ipcsValueY : begin
XValue := 0;
YValue := Y2Value;
end;
ipcsDeltaX : begin
XValue := ABS(X1Value - X2Value);
YValue := 0;
end;
ipcsDeltaY : begin
XValue := 0;
YValue := ABS(Y1Value - Y2Value);
end;
ipcsInverseDeltaX : begin
if ((X1Value - X2Value) <> 0) and (XAxis.CursorScaler <> 0) then
XValue := ABS(1/((X1Value - X2Value)*XAxis.CursorScaler))
else
XValue := 1E320;
YValue := 0;
end;
end;
end;
TiPlotDataCursorAccess(iDataCursor).SetData(XValue, YValue, Status);
TiPlotDataCursorAccess(iDataCursor).CursorDisplayText := GetDataCursorDisplayText(iDataCursor.Style, XValue, YValue, Status);
end;
//****************************************************************************************************************************************************
function TiXYPlotChannel.GetDataCursorDisplayText(Style: TiPlotDataCursorStyle; XValue, YValue: Double; Status: TiPlotDataPointStatus): String;
begin
FDataCursorXText := '';
FDataCursorYText := '';
FDataCursorXValue := XValue;
FDataCursorYValue := YValue;
FDataCursorStatus := Status;
if Assigned(XAxis) then
begin
case Style of
ipcsValueXY : begin
FDataCursorXText := GetXValueText(XValue);
if Assigned(YAxis) then
begin
case Status of
ipdpsValid : FDataCursorYText := GetYValueText(YValue);
ipdpsNull : FDataCursorYText := GetTranslation('Null');
ipdpsEmpty : FDataCursorYText := GetTranslation('Empty');
end;
end
else FDataCursorYText := 'No Y-Axis';
Result := FDataCursorXText + ', ' + FDataCursorYText;
end;
ipcsValueX : begin
FDataCursorXText := GetXValueText(XValue);
Result := FDataCursorXText;
end;
ipcsValueY : begin
if Assigned(YAxis) then
begin
case Status of
ipdpsValid : FDataCursorYText := GetYValueText(YValue);
ipdpsNull : FDataCursorYText := GetTranslation('Null');
ipdpsEmpty : FDataCursorYText := GetTranslation('Empty');
end;
end
else FDataCursorYText := 'No Y-Axis';
Result := FDataCursorYText;
end;
ipcsDeltaX : begin
FDataCursorXText := GetXValueText(XValue);
Result := FDataCursorXText;
end;
ipcsDeltaY : begin
if Assigned(YAxis) then
begin
FDataCursorYText := GetYValueText(YValue);
end
else FDataCursorYText := 'No Y-Axis';
Result := FDataCursorYText;
end;
ipcsInverseDeltaX : begin
if XValue < 1E301 then
FDataCursorXText := GetXValueText(XValue)
else
FDataCursorXText := GetTranslation('Infinite');
Result := FDataCursorXText;
end;
end;
end
else
begin
FDataCursorXText := GetTranslation('No X-Axis');
Result := FDataCursorXText;
end;
end;
//****************************************************************************************************************************************************
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -