77
83
procedure GetLegendItems(AItems: TChartLegendItems); override;
78
84
function GetSeriesColor: TColor; override;
87
AX, AYLoWhisker, AYLoBox, AY, AYHiBox, AYHiWhisker: Double;
88
AXLabel: String = ''; AColor: TColor = clTAColor): Integer; overload;
89
procedure Assign(ASource: TPersistent); override;
80
90
constructor Create(AOwner: TComponent); override;
81
91
destructor Destroy; override;
83
procedure Draw(ACanvas: TCanvas); override;
93
procedure Draw(ADrawer: IChartDrawer); override;
84
94
function Extent: TDoubleRect; override;
86
96
property BoxBrush: TBrush read FBoxBrush write SetBoxBrush;
110
{ TOpenHighLowCloseSeries }
112
TOpenHighLowCloseSeries = class(TBasicPointSeries)
115
FTickWidth: Cardinal;
116
FYIndexClose: Cardinal;
117
FYIndexHigh: Cardinal;
118
FYIndexLow: Cardinal;
119
FYIndexOpen: Cardinal;
120
procedure SetLinePen(AValue: TPen);
121
procedure SetTickWidth(AValue: Cardinal);
122
procedure SetYIndexClose(AValue: Cardinal);
123
procedure SetYIndexHigh(AValue: Cardinal);
124
procedure SetYIndexLow(AValue: Cardinal);
125
procedure SetYIndexOpen(AValue: Cardinal);
127
procedure GetLegendItems(AItems: TChartLegendItems); override;
128
function GetSeriesColor: TColor; override;
130
procedure Assign(ASource: TPersistent); override;
131
constructor Create(AOwner: TComponent); override;
132
destructor Destroy; override;
134
procedure Draw(ADrawer: IChartDrawer); override;
135
function Extent: TDoubleRect; override;
137
property LinePen: TPen read FLinePen write SetLinePen;
138
property TickWidth: Cardinal
139
read FTickWidth write SetTickWidth default DEF_OHLC_TICK_WIDTH;
140
property YIndexClose: Cardinal
141
read FYIndexClose write SetYIndexClose default DEF_YINDEX_CLOSE;
142
property YIndexHigh: Cardinal
143
read FYIndexHigh write SetYIndexHigh default DEF_YINDEX_HIGH;
144
property YIndexLow: Cardinal
145
read FYIndexLow write SetYIndexLow default DEF_YINDEX_LOW;
146
property YIndexOpen: Cardinal
147
read FYIndexOpen write SetYIndexOpen default DEF_YINDEX_OPEN;
103
Math, SysUtils, TAGraph;
157
Math, SysUtils, TAGeometry, TAGraph, TAMath;
161
{ TLegendItemOHLCLine }
163
TLegendItemOHLCLine = class(TLegendItemLine)
165
procedure Draw(ADrawer: IChartDrawer; const ARect: TRect); override;
168
{ TLegendItemOHLCLine }
170
procedure TLegendItemOHLCLine.Draw(ADrawer: IChartDrawer; const ARect: TRect);
174
inherited Draw(ADrawer, ARect);
175
y := (ARect.Top + ARect.Bottom) div 2;
176
dx := (ARect.Right - ARect.Left) div 3;
177
x := ARect.Left + dx;
178
ADrawer.Line(x, y, x, y + 2);
180
ADrawer.Line(x, y, x, y - 2);
105
183
{ TBubbleSeries }
185
procedure TBubbleSeries.Assign(ASource: TPersistent);
187
if ASource is TBubbleSeries then
188
with TBubbleSeries(ASource) do begin
189
Self.BubbleBrush := FBubbleBrush;
190
Self.BubblePen := FBubblePen;
192
inherited Assign(ASource);
107
195
constructor TBubbleSeries.Create(AOwner: TComponent);
109
197
inherited Create(AOwner);
132
220
r := Max(Source[i]^.YList[0], r);
133
221
with ParentChart.CurrentExtent do
134
222
PrepareGraphPoints(DoubleRect(a.X - r, a.Y - r, b.X + r, b.Y + r), true);
135
ACanvas.Pen.Assign(BubblePen);
136
ACanvas.Brush.Assign(BubbleBrush);
223
ADrawer.Pen := BubblePen;
224
ADrawer.Brush := BubbleBrush;
137
225
for i := 0 to High(FGraphPoints) do begin
138
226
pt := ParentChart.GraphToImage(FGraphPoints[i]);
139
227
r := Source[i + FLoBound]^.YList[0];
140
228
d.X := ParentChart.XGraphToImage(r) - ParentChart.XGraphToImage(0);
141
229
d.Y := ParentChart.YGraphToImage(r) - ParentChart.YGraphToImage(0);
142
ACanvas.EllipseC(pt.X, pt.Y, d.X, d.Y);
230
ADrawer.Ellipse(pt.X - d.X, pt.Y - d.Y, pt.X + d.X, pt.Y + d.Y);
147
235
function TBubbleSeries.Extent: TDoubleRect;
188
276
{ TBoxAndWhiskerSeries }
278
function TBoxAndWhiskerSeries.AddXY(
279
AX, AYLoWhisker, AYLoBox, AY, AYHiBox, AYHiWhisker: Double; AXLabel: String;
280
AColor: TColor): Integer;
283
AX, AYLoWhisker, [AYLoBox, AY, AYHiBox, AYHiWhisker], AXLabel, AColor);
286
procedure TBoxAndWhiskerSeries.Assign(ASource: TPersistent);
288
if ASource is TBoxAndWhiskerSeries then
289
with TBoxAndWhiskerSeries(ASource) do begin
290
Self.BoxBrush.Assign(FBoxBrush);
291
Self.BoxPen.Assign(FBoxPen);
292
Self.FBoxWidth := FBoxWidth;
293
Self.MedianPen.Assign(FMedianPen);
294
Self.WhiskersPen.Assign(FWhiskersPen);
295
Self.FWhiskersWidth := FWhiskersWidth;
297
inherited Assign(ASource);
190
300
constructor TBoxAndWhiskerSeries.Create(AOwner: TComponent);
192
302
inherited Create(AOwner);
262
372
wb := w * BoxWidth;
263
373
ww := w * WhiskersWidth;
265
ACanvas.Pen := WhiskersPen;
266
ACanvas.Brush.Style := bsClear;
375
ADrawer.Pen := WhiskersPen;
376
ADrawer.SetBrushParams(bsClear, clTAColor);
267
377
DoLine(x - ww, ymin, x + ww, ymin);
268
378
DoLine(x, ymin, x, yqmin);
269
379
DoLine(x - ww, ymax, x + ww, ymax);
270
380
DoLine(x, ymax, x, yqmax);
271
ACanvas.Pen := BoxPen;
272
ACanvas.Brush:= BoxBrush;
381
ADrawer.Pen := BoxPen;
382
ADrawer.Brush:= BoxBrush;
273
383
DoRect(x - wb, yqmin, x + wb, yqmax);
274
ACanvas.Pen := MedianPen;
275
ACanvas.Brush.Style := bsClear;
384
ADrawer.Pen := MedianPen;
385
ADrawer.SetBrushParams(bsClear, clTAColor);
276
386
DoLine(x - wb, ymed, x + wb, ymed);
348
458
UpdateParentChart;
461
{ TOpenHighLowCloseSeries }
463
procedure TOpenHighLowCloseSeries.Assign(ASource: TPersistent);
465
if ASource is TOpenHighLowCloseSeries then
466
with TOpenHighLowCloseSeries(ASource) do begin
467
Self.LinePen := FLinePen;
468
Self.FTickWidth := FTickWidth;
469
Self.FYIndexClose := FYIndexClose;
470
Self.FYIndexHigh := FYIndexHigh;
471
Self.FYIndexLow := FYIndexLow;
472
Self.FYIndexOpen := FYIndexOpen;
474
inherited Assign(ASource);
477
constructor TOpenHighLowCloseSeries.Create(AOwner: TComponent);
479
inherited Create(AOwner);
480
FLinePen := TPen.Create;
481
FLinePen.OnChange := @StyleChanged;
482
FTickWidth := DEF_OHLC_TICK_WIDTH;
483
FYIndexOpen := DEF_YINDEX_OPEN;
484
FYIndexLow := DEF_YINDEX_LOW;
485
FYIndexHigh := DEF_YINDEX_HIGH;
486
FYIndexClose := DEF_YINDEX_CLOSE;
489
destructor TOpenHighLowCloseSeries.Destroy;
491
FreeAndNil(FLinePen);
495
procedure TOpenHighLowCloseSeries.Draw(ADrawer: IChartDrawer);
497
function MaybeRotate(AX, AY: Double): TPoint;
501
Result := ParentChart.GraphToImage(DoublePoint(AX, AY));
504
procedure DoLine(AX1, AY1, AX2, AY2: Double);
506
ADrawer.Line(MaybeRotate(AX1, AY1), MaybeRotate(AX2, AY2));
509
function GetGraphPointYIndex(AIndex, AYIndex: Integer): Double;
512
Result := GetGraphPointY(AIndex)
514
Result := AxisToGraphY(Source[AIndex]^.YList[AYIndex - 1]);
521
x, tw, yopen, yhigh, ylow, yclose: Double;
523
my := MaxIntValue([YIndexOpen, YIndexHigh, YIndexLow, YIndexClose]);
524
if IsEmpty or (my >= Source.YCount) then exit;
526
ext2 := ParentChart.CurrentExtent;
527
ExpandRange(ext2.a.X, ext2.b.X, 1.0);
528
ExpandRange(ext2.a.Y, ext2.b.Y, 1.0);
530
PrepareGraphPoints(ext2, true);
532
for i := FLoBound to FUpBound do begin
533
x := GetGraphPointX(i);
534
yopen := GetGraphPointYIndex(i, YIndexOpen);
535
yhigh := GetGraphPointYIndex(i, YIndexHigh);
536
ylow := GetGraphPointYIndex(i, YIndexLow);
537
yclose := GetGraphPointYIndex(i, YIndexClose);
538
tw := GetXRange(x, i) * PERCENT * TickWidth;
540
ADrawer.Pen := LinePen;
541
DoLine(x, yhigh, x, ylow);
542
DoLine(x - tw, yopen, x, yopen);
543
DoLine(x, yclose, x + tw, yclose);
547
function TOpenHighLowCloseSeries.Extent: TDoubleRect;
549
Result := Source.ExtentList;
552
procedure TOpenHighLowCloseSeries.GetLegendItems(AItems: TChartLegendItems);
554
AItems.Add(TLegendItemOHLCLine.Create(LinePen, LegendTextSingle));
557
function TOpenHighLowCloseSeries.GetSeriesColor: TColor;
559
Result := LinePen.Color;
562
procedure TOpenHighLowCloseSeries.SetLinePen(AValue: TPen);
564
if FLinePen = AValue then exit;
569
procedure TOpenHighLowCloseSeries.SetTickWidth(AValue: Cardinal);
571
if FTickWidth = AValue then exit;
572
FTickWidth := AValue;
576
procedure TOpenHighLowCloseSeries.SetYIndexClose(AValue: Cardinal);
578
if FYIndexClose = AValue then exit;
579
FYIndexClose := AValue;
583
procedure TOpenHighLowCloseSeries.SetYIndexHigh(AValue: Cardinal);
585
if FYIndexHigh = AValue then exit;
586
FYIndexHigh := AValue;
590
procedure TOpenHighLowCloseSeries.SetYIndexLow(AValue: Cardinal);
592
if FYIndexLow = AValue then exit;
593
FYIndexLow := AValue;
597
procedure TOpenHighLowCloseSeries.SetYIndexOpen(AValue: Cardinal);
599
if FYIndexOpen = AValue then exit;
600
FYIndexOpen := AValue;
352
605
RegisterSeriesClass(TBubbleSeries, 'Bubble series');
353
606
RegisterSeriesClass(TBoxAndWhiskerSeries, 'Box-and-whiskers series');
607
RegisterSeriesClass(TOpenHighLowCloseSeries, 'Open-high-low-close series');