Page 1 of 1
FInding x0,y0,x1,y1 for ArrowHead Series
Posted: Wed Apr 27, 2005 12:45 pm
by 9236155
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
Posted: Thu Apr 28, 2005 11:50 am
by Marjan
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.
Posted: Thu Apr 28, 2005 3:59 pm
by 9236155
Marjan,
Thanks a lot, will try it out and confirm to you.
Satish
Posted: Fri Apr 29, 2005 2:51 am
by 9236155
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
Posted: Fri Apr 29, 2005 3:27 pm
by Marjan
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.