內容 |
函數類型 (1) 函數特點 (2) 添加一個函數 (3) 定義一個數據源 (4) 函數週期 (5) 函數週期對齊 (6) 派生自定義函數(僅VCL) |
7.1 函數類型
7.1.1 函數特點
一個TeeChart Pro函數是一個序列,它幾乎可以是任何序列類型,它可以應用一個代數函數,而數據源是另一個圖表序列。
所有函數都源自於TteeFunction組件,並且繼承了TeeFunction的Period(期間)屬性。
TeeChart Pro包括下面的預定義函數列表。爲了得到所有函數類型的完整列表,請查看TeeChart編輯器庫Gallery(畫廊)和Helpfile(幫助文件):
函數類型 | 輸入的數量 | 描述 |
Add(添加) | 無限制 | Plots sum of inputs |
Average(平均) | 無限制 | 平均函數,將計算每一組期間點的平均值 |
Bollinger(布林線) | 1 | 布林函數,使用簡單或指數移動平均值來構造Bollinger Trading Bands(布林交易帶_布林線)。 |
Copy(複製) | 1 | 輸入序列的直接拷貝 |
Curve Fitting (曲線擬合) | 1 | 通過使用TypeFitting公式的數據輸入來繪製擬合多項式 |
Divide(除) | 無限制 | The Divide Function plots inputs divided in descending order of inclusion |
Exponential Average(指數平均數) (指數平均數) | 1 | 指數平均數基於Weight(權重) |
Exponential Moving Average (指數移動平均數) | 1 | 指數移動平均數基於Weight(權重) |
Exponential Trend (指數趨勢) | 1 | 通過輸入序列中的點畫出最佳的指數趨勢線 |
High(高) | 無限制 | 高函數,繪製輸入的最高點 |
Low(低) | 無限制 | 高函數,繪製輸入的最低點 |
MACD | 1 | 平滑異同移動平均線 |
Momentum(動量) | 1 | 動量指標MTM,每一個Y值都是當前點的Y值而不是上一個週期點的Y值。M=(Y/Y’) |
Momentum Division (動量除) | 1 | 每一個Y值都是當前點的Y值除以最後一個週期點的Y值,以百分比表示 |
Moving Average (移動平均數) | 1 | 移動平均函數,將計算每一組週期點的簡單或加權平均 |
Multiply(乘) | 無限制 | 乘函數,畫輸入值的乘 |
Root Mean Square (均方根) | 無限制 | 根均方根函數,畫輸入值的RMS(均方根值) |
Relative Strength Index (相對強弱指數) | 1 | RSI函數根據財務數據計算一個百分比值。根據TRSISyle類型不同的公式將被用來計算RSI值 |
Standard Deviation (標準差) | 1 | 繪製每一組週期點的標準偏差(或完全標準差) |
Stochastic(隨機指標) | 1 |
|
Subtract(差集) | 無限制 | 畫出按降序排列減去輸入的值。 |
Trend(趨勢) | 1 | Draws best trend line through points of input Series通過輸入序列點繪製最佳趨勢線 |
一些函數類型只支持一個輸入序列。然而,可以鏈連函數是可能的,例如,在您的圖表中使用幾個序列的平均值來創建一個平均的函數序列,然後通過使用Average(平均)函數作爲Trend(趨勢)函數的輸入來確定平均值的趨勢。
7.1.2 添加一個函數
使用圖表編輯器,在第一個圖表頁面中,選擇Add(添加)按鈕,就好像在圖表中添加一個新序列。在TeeChart的Gallery(畫廊)中,選擇Function(函數)選項卡來選擇您需要的函數。每個函數都被作爲一個LineSeries(線序列)呈現,您可以通過在第一個圖表頁面上選擇change(改變)按鈕來更改與該函數相關聯的序列類型。函數定義在FunctionSeries(函數序列)的Datasource頁面上很容易更改。在這裏,同樣容易地,您可以將您添加到圖表的普通序列的定義更改爲函數的定義(函數實際上是一個datasource的定義,而不是一個序列類型的定義)。
下圖顯示了在編輯函數時的Datasource(數據源)頁面。定義了Line Series(線序列)(名爲“Series2”、標題“Average(平均值)”)。Datasource頁面底部的左邊列表框顯示了可用於輸入的圖表中的其他序列(這裏是“Series1”)。
假設我們從一個完全空白的圖表開始,這是構建一個簡單的Series-Function(序列-函數)相關圖表的代碼步驟。
procedure TForm1.BitBtn5Click(Sender: TObject);
var tmpBarSeries1,
tmpBarSeries2 : TBarSeries;
tmpLineSeries : TLineSeries;
begin
//添加2數據序列
tmpBarSeries1:=TBarSeries.Create(Self);
tmpBarSeries2:=TBarSeries.Create(Self);
AddSeries(tmpBarSeries1);
AddSeries(tmpBarSeries2);
//用數據填充它們(這裏是隨機的)
tmpBarSeries1.FillSampleValues(10);
tmpBarSeries2.FillSampleValues(10);
//添加一個用於Average(平均)函數的序列
tmpLineSeries:=TLineSeries.Create(Self);
AddSeries(tmpLineSeries);
//定義新序列的函數類型
tmpLineSeries.SetFunction(TAverageTeeFunction.Create(Self));
//定義新函數序列的Datasource
//接受了其他兩個序列的序列標題
tmpLineSeries.DataSources.Clear;
tmpLineSeries.DataSources.Add( tmpBarSeries1 );
tmpLineSeries.DataSources.Add( tmpBarSeries2 );
// *注意--當手動填充輸入序列時,需要使用Checkdatasource方法
//—參見題爲“Defining a Datasource(定義數據源)”的部分。
//改變函數的週期使其平均每2個點爲一組
tmpLineSeries.FunctionType.Period := 2;
end;
我們可以添加另一個函數來告訴我們有關前一個的函數的一些事情。
procedure TForm1.BitBtn6Click(Sender: TObject);
var tmpHighLine : TLineSeries;
begin
//添加另一個用於第二個函數的序列
tmpHighLine:=TLineSeries.Create(Self);
AddSeries(tmpHighLine);
//定義新序列的函數類型
tmpHighLine.SetFunction(THighTeeFunction.Create(self));
//定義新函數序列的Datasource ,用現有的函數(tmpLineSeries)作爲輸入。
//如果你想在程序之間使用它,您應該向模塊全局地聲明tmpLineSeries
tmpHighLine.DataSource := tmpLineSeries;
//在默認值0(沒有Period(週期)設置)的情況下,在平均函數的所有點的最高處繪製一條線
end;
7.1.3 定義一個數據源
上一節中的例子強調了使用Datasource來通過代碼來進行函數的使用。序列使用Datasource定義一個函數的輸入,或者定義一個序列TDataset數據源(參見關於訪問數據庫的教程)。
使用圖表編輯器,在添加一個函數之後,函數序列的“Datasource頁面”將顯示一個包含在函數定義中的可用序列的列表。在這裏,你可以改變你想要應用到這個序列的函數類型,並從左邊的列表框“Available(可用)”中選擇序列,並將它們添加到右邊的列表框“Selected(已選擇)”中。
通過代碼使用Series.Datasource屬性的數據源。示例
假設我們在一個圖表中有兩個數據序列。我們使用圖表編輯器來添加一個由2個序列的平均值組成的函數;
我們在這兩個系列中添加了一些點:var t : Integer;
For t := 0 To 10 do
begin
Series1.Add(2 * t);
Series2.Add(3 * t);
end;
注意,這個函數沒有顯示。你需要使用這個Series.CheckDatasource方法來讀取函數的值。
Series3.CheckDataSource; //讀取函數中的數據
函數定義可以在運行時被改變,使用Setfunction方法將一個新函數分配給序列。
Series3.Setfunction(TMovingAverageFunction.Create(self));
使用上面的代碼行,Setfunction將Series3的函數更改爲Moving Average(移動平均值)。
7.1.4 函數週期
Period(週期)是處理函數的一個重要屬性,因爲週期定義了一個函數在週期性的應用中的點的範圍。
示例
我們有6個有值的數據點(例如,BarSeries(條棒序列)的條棒): 3、8、 6、 2、9 、 12
我們定義了一個週期爲0(默認)的函數序列,平均值畫的是:6.667
當週期爲2時,我們得到了3個平均值作爲函數的輸出值: 5.5、 4 、 10.5
這些值將在它們的週期範圍內的中心繪製。第一個值在輸入序列的1和2之間,第2個值在3和4之間,等等。
您可以通過在圖表編輯器中選擇函數來定義週期,也可以使用函數類型在運行時修改週期。
例如,第2序列是函數序列:
Series2.FunctionType.Period:=2;
下面是兩個圖表,突出了應用了週期的效果
7.1.5 函數週期對齊
當函數“Period(週期)”大於0時(因此它由一組點來計算),函數結果在函數週期的“中心”位置被默認添加到序列中。在整個週期空間內,PeriodAlign屬性控制“哪裏”來放置函數計算後的位置。
TeeFunction1.PeriodAlign := paCenter ; { <--默認情況下它是居中的}
“paFirst”和“paLast”常數將在每個“週期”的開始和結束的“X”座標中進行標繪計算。每一個藍色的點都顯示了在每個月的第一天到最後一天之間的所有點的“average(平均數)”。
PeriodAlign= paLast //正如你從下圖所看到的,“average(平均數)”是在月末繪製的。
PeriodAlign =paFirst //在這種情況下,“average(平均數)”是在月初繪製的。
7.1.6 派生自定義函數(僅VCL)
創建一個新的函數組件僅僅是創建一個從TTeeFunction派生的新組件(它也可以從一個現有的函數派生出來)。在TTeeFunction中有兩個重要的虛擬方法可以被覆寫來創建一個新的函數類型。
1) Function TTeeFunction.Calculate(SourceSeries:TChartSeries;First,Last:Longint):Double;
2) FunctionTTeeFunction.CalculateMany(SourceSeriesList:TList; ValueIndex:Longint):Double;
如果只有一個序列是數據源,那麼Calculate方法是用來計算函數結果的。如果多個序列可以是數據源,則用CalculateMany來計算函數結果。
示例:創建新的TMyFunction
讓我們決定需要TMyFunction來返回“平方和”。type
TMyFunction = class( TTeeFunction )
end;
這個函數有一個數據源或多個數據源,因此我們將重寫Calculate和CalculateMany方法。
首先,我們將重寫TMyFunction“Calculate”方法來做一個非常簡單的事情。“Calculate”方法看起來是這樣的:
Function TMyFunction.Calculate(SourceSeries:TChartSeries; First,Last:Integer):Double;
Var StartPoint, EndPoint, t : Integer;
begin
StartPoint:=0;
EndPoint:=SourceSeries.Count-1;
if First <> -1 then StartPoint:=First;
if Last <> -1 then EndPoint:=Last;
Result:=0;
for t:=StartPoint to EndPoint do
Result:= Result + Sqr(SourceSeries.MandatoryValueList[t]);
end;
StartPoint和EndPoint變量用於“循環”所有的SourceSeries點來計算平方和。
“MandatoryValueList”屬性被用來代替“YValues”屬性,只是爲了讓這個函數與諸如HorizBarSeries之類的序列類型一起工作,在這裏“XValues”保持點值而不是“YValues”。
當這個序列只有一個序列作爲數據源時,就會使用“Calculate”方法。當序列有多個序列作爲數據源時,就會調用“CalculateMany”方法。
以允許TMyFunction與具有多個序列作爲數據源的序列一起工作。通過編程的方式,可以將序列添加爲其他序列的數據源。Function TMyFunction.CalculateMany(SourceSeriesList:TList; ValueIndex: Integer):Double;
var t : Integer;
begin
Result:=0 ;
for t:= 0 to SourceSeriesList.Count -1 do
Result := Result + sqr(TChartSeries(SourceSeriesList[t]).MandatoryValueList[ValueIndex]);
end;
“CalculateMany”將會在源序列的每一個點上被調用一次,從零開始,最後以所有數據源的最小點計數結束。
理解Calculate和CalculateMany之間的區別是非常重要的。“Calculate”在只有一個數據源時被調用,它只被調用一次。當有多個序列作爲數據源時,“CalculateMany”被調用多次(每個點的一個)。
第七章 完