16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"TeeChart系列コンポ例"
この発言に対し以下のコメントが寄せられています
#01074 STK さん RE:TeeChart系列コンポ例
TeeChartは高機能なグラフ表示コンポですが,独自の表示形式を実現
するためのサンプルが無く,ソース付のバージョンは$400ドル程度と
ちょっと買うには躊躇する金額です.しかし,継承もとのソースが
無くても,原理的には継承したコンポーネントを作成することが可能です.
というわけで,TeeChartの表示データの保持と要素の画面表示機能を
持つコンポである,TChartSeriesを継承した独自の系列コンポを作って
みました.
<チャートのデータ系列を実現するクラス階層>
TComponent
|
TChartSeries
+---TCustomSeries
| +---TLineSeries
| +---TPointSeries
| ....
+---TCustomBarSeries
| +---TBarSeries
.... ....
TChartSeries を継承したコンポを作る「肝」は
procedure DrawValue( ValueIndex: integer ); override;
に尽きます.すべてはこれを実現するためにあると言ってよいでしょう.
こいつが親チャートから随時呼ばれますので,ここで好きに描画すればよい由.
<ローソクチャート>
下記に挙げる例はTCustomSeriesを継承した,相場表示用のローソクチャート
の系列コンポです.パレットに乗せてフォームに貼り付けてもフォームの上では
表示されませんのでご注意.TeeChartのコンポーネントエディタにも無視されま
す.
・表示するチャートを変えるにはParentChart propertyでチャートを選択して
下さい.
・要素を追加するには AddCandle を実行して下さい.
・陽線はAscendingBrush 陰線は DescendingBrush 等,ひげは LinePen で変えら
れます
・CandleWidth は Period に対する百分率で指定します.
・YValues 等ローソクの表示に関係ない Property は無視されます.
・3次元機能は興味ないので(^^;無視.
<継承するときの注意>
ソースがない場合,ヘルプに書いてない virtual メソッドを探したりするには
Delphi の IDEの機能にある 「ブラウザ」を使ってコンパイル済みのクラス階層
を探索しますが,このブラウザはD1のころからまったく変わっておらず,機能
向上していないのにはちょっとまいりました.
インプライズさんにはオブジェクト指向な処理系としてのDelphiの品位向上のため
にも,ブラウザの機能向上をお願いしたいところです.
(D5で良くなってるとか言う話は無いよね?)
TN(CQJ01721)
--------------------------------------------------------------------------
unit CandleSeries;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
TeEngine, TeCanvas, Series;
type
TCandleSeries = class( TCustomSeries )
protected
FOpenValues: TChartValueList;
FHighValues: TChartValueList;
FLowValues: TChartValueList;
FCloseValues: TChartValueList;
FAscendingBrush, FDescendingBrush: TBrush;
FLinePen, FRectPen: TPen;
FCandleWidth: Double;
FPeriod: TDateTime;
procedure DrawValue( ValueIndex: integer ); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure AddCandle( Time: TDateTime; O,H,L,C: Double );
procedure Clear; override;
published
property OpenValues: TChartValueList
read FOpenValues write FOpenValues;
property HighValues: TChartValueList
read FHighValues write FHighValues;
property LowValues: TChartValueList
read FLowValues write FLowValues;
property CloseValues: TChartValueList
read FCloseValues write FCloseValues;
property AscendingBrush: TBrush
read FAscendingBrush write FAscendingBrush;
property DescendingBrush: TBrush
read FDescendingBrush write FDescendingBrush;
property LinePen: TPen
read FLinePen write FLinePen;
property RectPen: TPen
read FRectPen write FRectPen;
property CandleWidth: Double // in %
read FCandleWidth write FCandleWidth;
property Period: TDateTime
read FPeriod write FPeriod;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [TCandleSeries]);
end;
{ TCandleSeries }
procedure TCandleSeries.AddCandle(Time: TDateTime; O, H, L, C: Double);
var
i: integer;
begin
i := XValues.AddChartValue( Time );
FOpenValues.AddChartValue( O );
FHighValues.AddChartValue( H );
FLowValues.AddChartValue( L );
FCloseValues.AddChartValue( C );
NotifyNewValue(Self, i);
end;
procedure TCandleSeries.Clear;
begin
FOpenValues.ClearList;
FHighValues.ClearList;
FLowValues.ClearList;
FCloseValues.ClearList;
XValues.ClearList;
inherited Clear;
end;
constructor TCandleSeries.Create(AOwner: TComponent);
begin
inherited Create( AOwner );
FOpenValues := TChartValueList.Create(Self, 'Open');
FHighValues := TChartValueList.Create(Self, 'High');
FLowValues := TChartValueList.Create(Self, 'Low');
FCloseValues := TChartValueList.Create(Self, 'Close');
FAscendingBrush := TBrush.Create;
FAscendingBrush.Color := clRed;
FDescendingBrush := TBrush.Create;
FDescendingBrush.Color := clBlue;
FLinePen := TPen.Create;
FRectPen := TPen.Create;
FCandleWidth := 100;
FPeriod := 1;
end;
destructor TCandleSeries.Destroy;
begin
FLinePen.Free;
FRectPen.Free;
FAscendingBrush.Free;
FDescendingBrush.Free;
inherited Destroy;
end;
procedure TCandleSeries.DrawValue(ValueIndex: integer);
var
Canvas: TCanvas3D;
X0,Y0,X1,Y1,W: integer;
HAxis,VAxis: TChartAxis;
Width: Extended;
begin
if FOpenValues.Count <= ValueIndex then Exit;
Canvas := ParentChart.Canvas;
with Canvas do begin
if HorizAxis = aTopAxis then
HAxis := ParentChart.TopAxis
else
HAxis := ParentChart.BottomAxis;
if VertAxis = aLeftAxis then
VAxis := ParentChart.LeftAxis
else
VAxis := ParentChart.RightAxis;
// High Low Line
Pen.Assign( FLinePen );
X0 := HAxis.CalcPosValue( XValues[ValueIndex] );
Y0 := VAxis.CalcPosValue( FLowValues[ValueIndex] );
Y1 := VAxis.CalcPosValue( FHighValues[ValueIndex] );
MoveTo( X0, Y1 );
LineTo( X0, Y0 );
// Candle Body
Pen.Assign( FRectPen );
Width := FPeriod * FCandleWidth / 100;
W := HAxis.CalcSizeValue( Width );
X0 := X0 - W div 2;
X1 := X0 + W;
Y0 := VAxis.CalcPosValue( FOpenValues[ValueIndex] );
Y1 := VAxis.CalcPosValue( FCloseValues[ValueIndex] );
if Y0 > Y1 then begin
Brush.Assign( FAscendingBrush );
Rectangle( X0, Y1, X1, Y0 );
end else begin
Brush.Assign( FDescendingBrush );
Rectangle( X0, Y0, X1, Y1 );
end;
end;
end;
end.
Original document by TN 氏 ID:(CQJ01721)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|