FInding x0,y0,x1,y1 for ArrowHead Series

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Satish
Newbie
Newbie
Posts: 37
Joined: Fri Mar 04, 2005 5:00 am

FInding x0,y0,x1,y1 for ArrowHead Series

Post by Satish » Wed Apr 27, 2005 12:45 pm

I have Series1 (TCandleSeries) & Series2(TLIneSeries). Series1 is displayed as a High-Low-Close bar. I need to plot arrows at points where the Series2 intersects Series1. Given that I know the series index at which the intersection occurs, how do I compute x0,y0,x1 & y1 coordinates - I believe they are screen coordinates.

I wish to draw the arrow above the high of the high-low-close bar or below the low of the high-low-close bar. Also how do I ensure that arrows for all other non-intersecting points are not visible. Do I make the arrow color same as chart background color ?

Will appreciate help/suggestions.

Regards,

Satish

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Thu Apr 28, 2005 11:50 am

Hi.

If both series share the same x values then if you know Series2 (or Series1) ValueIndex, you also know intersection x and y value. Example:

Code: Select all

var x,y: double;
begin
  x := Series2.XValues[Index];
  y := Series2.YValues[Index];
end;
On the other hand, if you want to transform real x,y coordinates back to screen coordinates, you can use TChartSeries.CalcXPos and TChartSeries.CalcYPos method. Example:

Code: Select all

var x0,y0: Integer;
begin
  x0 := Series2.CalcXPos(Index);
  y0 := Series2.CalcYPos(Index);
end;
This works fine for line, bar and point series. If series has more than two chart value lists (x,high, low, open ... values), a bit more complex code is needed. In the example below arrows will be drawn above every visible candle:

Code: Select all

// using tChart OnAfterDraw event !
procedure TForm1.Chart1AfterDraw(Sender: TObject);
var i: Integer;
  FromPoint,ToPoint: TPoint;
begin
  Chart1.Canvas.ClipRectangle(Chart1.ChartRect);

  With Series1 do // Series1 is TCandleSeries
    for i := FirstValueIndex to LastValueIndex do
    begin
      ToPoint.X := CalcXPos(i);
      ToPoint.Y := CalcYPosValue(HighValues.Value[i]);
      FromPoint.X := ToPoint.X;
      FromPoint.Y := ToPoint.Y - 20;
      ParentChart.Canvas.Arrow(True,FromPoint,ToPoint,7,7,MiddleZ);
    end;

  Chart1.Canvas.UnClipRectangle;
end;
for all other non-intersecting points are not visible
No simple way to do it. Calculate all intersection points and then draw arrow for individual intersection.
Marjan Slatinek,
http://www.steema.com

Satish
Newbie
Newbie
Posts: 37
Joined: Fri Mar 04, 2005 5:00 am

Post by Satish » Thu Apr 28, 2005 3:59 pm

Marjan,

Thanks a lot, will try it out and confirm to you.

Satish

Satish
Newbie
Newbie
Posts: 37
Joined: Fri Mar 04, 2005 5:00 am

Post by Satish » Fri Apr 29, 2005 2:51 am

Marjan,

Using the canvas method how do I color the arrow - I need to color it either red or green ? Also is there a way to fill the Arrow Series with transparent arrows - Actually I would be using 8-10 red/green arrows in a series having over 250 points.


Satish

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Fri Apr 29, 2005 3:27 pm

Hi, Satish.
how do I color the arrow
This can be done by adding the following lines to chart OnAfterDraw event:

Code: Select all

  ...
  ParentChart.Canvas.Brush.Color := clRed;
  ParentChart.Canvas.Brush.Style := bsSolid;
  ParentChart.Canvas.Arrow(True,FromPoint,ToPoint,7,7,MiddleZ); 
  ..
Also is there a way to fill the Arrow Series with transparent arrows
Try setting arrow point color to clNone. But if you plan to use arrow series, there is a lot simpler solution : clear and repopulate arrow series when your data changes. Of course, you don't simply copy all points from original series, you only copy intersection points.
Marjan Slatinek,
http://www.steema.com

Post Reply