📄 statchar.pas
字号:
FLinesPen.Free;
inherited;
end;
Procedure THistogramSeries.CalcFirstLastVisibleIndex; // 7.0
begin
inherited;
if FirstValueIndex>0 then Dec(FFirstVisibleIndex);
if LastValueIndex<(Count-1) then Inc(FLastVisibleIndex);
end;
procedure THistogramSeries.SetLinesPen(const Value: TChartHiddenPen);
begin
FLinesPen.Assign(Value);
end;
class Function THistogramSeries.GetEditorClass:String;
begin
result:='THistogramSeriesEditor';
end;
Function THistogramSeries.VisiblePoints:Integer;
begin
result:=ParentChart.MaxPointsPerPage;
if result=0 then result:=Count;
end;
Procedure THistogramSeries.CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
begin
inherited;
if YMandatory then
begin
if Pen.Visible then Inc(TopMargin,Pen.Width);
end
else InternalCalcHoriz(GetVertAxis,TopMargin,BottomMargin)
end;
Procedure THistogramSeries.InternalCalcHoriz(Axis:TChartAxis; Var Min,Max:Integer);
var tmp : Integer;
begin
tmp:=VisiblePoints;
if tmp>0 then tmp:=(Axis.IAxisSize div VisiblePoints) div 2;
Inc(Min,tmp);
Inc(Max,tmp);
if Pen.Visible then Inc(Max,Pen.Width);
end;
Procedure THistogramSeries.CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
begin
inherited;
if YMandatory then InternalCalcHoriz(GetHorizAxis,LeftMargin,RightMargin)
else if Pen.Visible then Inc(RightMargin,Pen.Width);
end;
Procedure THistogramSeries.Assign(Source:TPersistent);
begin
if Source is THistogramSeries then
With THistogramSeries(Source) do
begin
Self.Pen:=Pen;
Self.LinesPen:=LinesPen;
Self.Brush:=Brush;
Self.FTransparency:=Transparency;
end;
inherited;
end;
function THistogramSeries.CalcRect(ValueIndex:Integer):TRect;
var tmp : Integer;
begin
tmp:=(GetHorizAxis.IAxisSize div VisiblePoints) div 2;
With result do
begin
if ValueIndex=FirstDisplayedIndex then
begin
Left:=CalcXPos(ValueIndex)-tmp+1;
Right:=Left+2*tmp;
if not DrawValuesForward then
SwapInteger(Left,Right);
end
else
begin
Left:=IPrevious;
if DrawValuesForward then
Right:=CalcXPos(ValueIndex)+tmp+1
else
Right:=CalcXPos(ValueIndex)-tmp-1
end;
IPrevious:=Right-1;
Top:=CalcYPos(ValueIndex);
With GetVertAxis do
if Inverted then Bottom:=IStartPos
else Bottom:=IEndPos;
end;
end;
procedure THistogramSeries.DrawValue(ValueIndex:Integer);
Function LastDisplayedIndex:Integer;
begin
if DrawValuesForward then result:=LastValueIndex
else result:=FirstValueIndex;
end;
Procedure VerticalLine(X,Y0,Y1:Integer);
begin
if ParentChart.View3D then
ParentChart.Canvas.VertLine3D(X,Y0,Y1,MiddleZ)
else
ParentChart.Canvas.DoVertLine(X,Y0,Y1);
end;
Procedure HorizLine(X0,X1,Y:Integer);
begin
if ParentChart.View3D then
ParentChart.Canvas.HorizLine3D(X0,X1,Y,MiddleZ)
else
ParentChart.Canvas.DoHorizLine(X0,X1,Y);
end;
var R : TRect;
tmp : Integer;
tmpR : TRect;
tmpBlend : TTeeBlend;
begin
R:=CalcRect(ValueIndex);
With ParentChart.Canvas do
begin
Pen.Style:=psClear;
// rectangle
if Self.Brush.Style<>bsClear then
begin
AssignBrush(Self.Brush,ValueColor[ValueIndex]);
if GetVertAxis.Inverted then Inc(R.Top);
if Transparency>0 then
begin
if ParentChart.View3D then tmpR:=CalcRect3D(R,MiddleZ)
else tmpR:=R;
tmpBlend:=BeginBlending(tmpR,Transparency);
end
else tmpBlend:=nil;
if ParentChart.View3D then
RectangleWithZ(TeeRect(R.Left,R.Top,R.Right-1,R.Bottom),MiddleZ)
else
Rectangle(R);
if Transparency>0 then EndBlending(tmpBlend);
if GetVertAxis.Inverted then Dec(R.Top);
end;
// border
if Self.Pen.Visible then
begin
AssignVisiblePen(Self.Pen);
With R do
if YMandatory then
begin
if ValueIndex=FirstDisplayedIndex then
VerticalLine(Left,Bottom,Top)
else
VerticalLine(Left,Top,CalcYPos(ValueIndex-1));
HorizLine(Left,Right,Top);
if ValueIndex=LastDisplayedIndex then
VerticalLine(Right-1,Top,Bottom);
end
else
begin
if ValueIndex=FirstDisplayedIndex then
HorizLine(Left,Right,Bottom-1)
else
HorizLine(CalcXPos(ValueIndex-1),Right,Bottom-1);
VerticalLine(Right-Self.Pen.Width,Top,Bottom);
if ValueIndex=LastDisplayedIndex then
HorizLine(Left,Right,Top);
end
end;
// dividing line
if (ValueIndex<>FirstDisplayedIndex) and LinesPen.Visible then
begin
if YMandatory then
begin
tmp:=CalcYPos(ValueIndex-1);
if GetVertAxis.Inverted then
tmp:=Math.Min(R.Top,tmp)
else
tmp:=Math.Max(R.Top,tmp);
if not Self.Pen.Visible then Dec(tmp);
AssignVisiblePen(LinesPen);
VerticalLine(R.Left,R.Bottom,tmp);
end
else
begin
tmp:=CalcXPos(ValueIndex-1);
if GetHorizAxis.Inverted then
tmp:=Math.Min(R.Right,tmp)
else
tmp:=Math.Max(R.Left,tmp);
if not Self.Pen.Visible then Dec(tmp);
AssignVisiblePen(LinesPen);
HorizLine(R.Left,tmp,R.Bottom-1);
end;
end;
end;
end;
procedure THistogramSeries.SetTransparency(const Value: TTeeTransparency);
begin
if Value<>FTransparency then
begin
FTransparency:=Value;
Repaint;
end;
end;
class procedure THistogramSeries.CreateSubGallery(
AddSubChart: TChartSubGalleryProc);
begin
inherited;
AddSubChart(TeeMsg_Hollow);
AddSubChart(TeeMsg_NoBorder);
AddSubChart(TeeMsg_Lines);
AddSubChart(TeeMsg_Transparency); { 5.02 }
end;
class procedure THistogramSeries.SetSubGallery(ASeries: TChartSeries;
Index: Integer);
begin
with THistogramSeries(ASeries) do
Case Index of
1: Brush.Style:=bsClear;
2: Pen.Hide;
3: LinesPen.Visible:=True;
4: Transparency:=30;
else inherited;
end;
end;
function THistogramSeries.Clicked(x, y: Integer): Integer;
var t : Integer;
R : TRect;
begin
result:=TeeNoPointClicked;
if (FirstValueIndex<>-1) and (LastValueIndex<>-1) then // 7.0
begin
if Assigned(ParentChart) then ParentChart.Canvas.Calculate2DPosition(X,Y,MiddleZ);
for t:=FirstValueIndex to LastValueIndex do
begin
R:=CalcRect(t);
if PointInRect(R,x,y) then
begin
result:=t;
break;
end;
end;
end;
end;
{ THorizHistogramSeries }
Constructor THorizHistogramSeries.Create(AOwner: TComponent);
begin
inherited;
SetHorizontal;
XValues.Order:=loNone;
YValues.Order:=loAscending;
end;
function THorizHistogramSeries.CalcRect(ValueIndex: Integer): TRect;
var tmp : Integer;
begin
tmp:=(GetVertAxis.IAxisSize div VisiblePoints) div 2;
With result do
begin
if ValueIndex=FirstDisplayedIndex then
begin
Top:=CalcYPos(ValueIndex)-tmp+1;
Bottom:=Top+2*tmp;
end
else
begin
Bottom:=IPrevious;
Top:=CalcYPos(ValueIndex)-tmp;
end;
IPrevious:=Top+1;
Right:=CalcXPos(ValueIndex)+1;
With GetHorizAxis do
if Inverted then Left:=IEndPos
else Left:=IStartPos;
end;
end;
{ TStochasticFunction }
constructor TStochasticFunction.Create(AOwner: TComponent);
begin
inherited;
SingleSource:=True;
HideSourceList:=True;
end;
Destructor TStochasticFunction.Destroy;
begin
FNums:=nil;
FDens:=nil;
inherited;
end;
procedure TStochasticFunction.AddPoints(Source: TChartSeries);
begin
FNums:=nil;
FDens:=nil;
SetLength(FNums,Source.Count);
SetLength(FDens,Source.Count);
inherited;
end;
function TStochasticFunction.Calculate(Series: TChartSeries; FirstIndex,
LastIndex: Integer): Double;
var Lows : TChartValueList;
Highs : TChartValueList;
tmpLow : Double;
tmpHigh : Double;
t : Integer;
begin
result:=0;
With Series do
Begin
Lows :=GetYValueList(TeeMsg_ValuesLow);
Highs :=GetYValueList(TeeMsg_ValuesHigh);
tmpLow :=Lows.Value[FirstIndex];
tmpHigh:=Highs.Value[FirstIndex];
for t:=FirstIndex to LastIndex do
begin
if Lows.Value[t] <tmpLow then tmpLow :=Lows.Value[t];
if Highs.Value[t]>tmpHigh then tmpHigh:=Highs.Value[t];
end;
FNums[LastIndex]:=ValueList(Series).Value[LastIndex]-tmpLow;
FDens[LastIndex]:=tmpHigh-tmpLow;
if tmpHigh<>tmpLow then result:=100.0*(FNums[LastIndex]/FDens[LastIndex]);
end;
end;
{ TRMSFunction }
class function TRMSFunction.GetEditorClass: String;
begin
result:='TRMSFuncEditor';
end;
procedure TRMSFunction.Accumulate(const Value: Double);
begin
ISum2:=ISum2+Sqr(Value);
end;
function TRMSFunction.Calculate(SourceSeries: TChartSeries; FirstIndex,
LastIndex: Integer): Double;
var t : Integer;
begin
if FirstIndex=TeeAllValues then
begin
FirstIndex:=0;
INumPoints:=SourceSeries.Count;
LastIndex:=INumPoints-1;
end
else INumPoints:=LastIndex-FirstIndex+1;
if INumPoints>1 then
begin
ISum2:=0;
With ValueList(SourceSeries) do
for t:=FirstIndex to LastIndex do Accumulate(Value[t]);
result:=CalculateRMS;
end
else result:=0;
end;
function TRMSFunction.CalculateMany(SourceSeriesList: TList;
ValueIndex: Integer): Double;
var t:Integer;
begin
if SourceSeriesList.Count>0 then
begin
INumPoints:=0;
ISum2:=0;
for t:=0 to SourceSeriesList.Count-1 do
begin
With ValueList(TChartSeries(SourceSeriesList[t])) do
if Count>ValueIndex then
begin
Accumulate(Value[ValueIndex]);
Inc(INumPoints);
end;
end;
if INumPoints>1 then result:=CalculateRMS
else result:=0;
end
else result:=0;
end;
function TRMSFunction.CalculateRMS: Double;
Var Divisor : Double;
begin
if Complete then Divisor:=INumPoints
else Divisor:=INumPoints-1;
{ safeguard against only one point }
if Divisor=0 then result:=0
else result:=Sqrt(ISum2 / Divisor );
end;
procedure TRMSFunction.SetComplete(const Value: Boolean);
begin
if FComplete<>Value then
begin
FComplete:=Value;
Recalculate;
end;
end;
{ TMACDFunction }
type TChartSeriesAccess=class(TChartSeries);
Constructor TMACDFunction.Create(AOwner: TComponent);
Procedure HideSeries(ASeries:TChartSeries);
begin
ASeries.ShowInLegend:=False;
TChartSeriesAccess(ASeries).InternalUse:=True;
end;
begin
inherited;
SingleSource:=True;
IMoving1:=TExpMovAveFunction.Create(nil);
IMoving1.Period:=12;
ISeries1:=TChartSeries.Create(nil);
ISeries1.SetFunction(IMoving1);
IMoving2:=TExpMovAveFunction.Create(nil);
IMoving2.Period:=26;
ISeries2:=TChartSeries.Create(nil);
ISeries2.SetFunction(IMoving2);
Period:=IMoving2.Period;
IOther:=TFastLineSeries.Create(Self);
HideSeries(IOther);
IOther.SetFunction(TExpMovAveFunction.Create(nil));
IOther.FunctionType.Period:=9;
IOther.SeriesColor:=clGreen;
IHisto:=TVolumeSeries.Create(Self);
HideSeries(IHisto);
IHisto.SeriesColor:=clRed;
IHisto.UseYOrigin:=True;
IHisto.YOrigin:=0;
end;
destructor TMACDFunction.Destroy;
begin
ISeries1.Free;
ISeries2.Free;
inherited;
end;
class function TMACDFunction.GetEditorClass: String;
begin
result:='TMACDFuncEditor';
end;
procedure TMACDFunction.AddPoints(Source: TChartSeries);
Procedure PrepareSeries(ASeries:TChartSeries);
begin { copy properties from "ParentSeries" to ASeries }
With ASeries do
begin
ParentChart :=ParentSeries.ParentChart;
CustomVertAxis :=ParentSeries.CustomVertAxis;
VertAxis :=ParentSeries.VertAxis;
XValues.DateTime:=ParentSeries.XValues.DateTime;
AfterDrawValues :=ParentSeries.AfterDrawValues;
BeforeDrawValues:=ParentSeries.BeforeDrawValues;
end;
end;
var t : Integer;
begin
{ calculate first line... }
ParentSeries.Clear;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -