### Author Topic: brush in arbitrary triangle  (Read 1546 times)

#### frederic

• Full Member
• Posts: 221
##### brush in arbitrary triangle
« on: July 02, 2017, 04:13:05 pm »
dear specialists

in a chart i have 3 arbitrary lines crossing eachother.
they form an arbitrary triangle.

i want to brush the enclosed surface with a color

is this possible in TAchart?

frederic

#### wp

• Hero Member
• Posts: 4076
##### Re: brush in arbitrary triangle
« Reply #1 on: July 02, 2017, 04:33:40 pm »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

#### frederic

• Full Member
• Posts: 221
##### Re: brush in arbitrary triangle
« Reply #2 on: July 03, 2017, 05:27:36 pm »
wp

i prepared a small example ,see attachment.

when you press  "showlinesbtn", then the 3 lines, which form the triangle ,will appear.

it is the same as with the shape component but now in TAchart and with arbitrary appearance.( dimensions and slopes can be changed)

frederic

#### wp

• Hero Member
• Posts: 4076
##### Re: brush in arbitrary triangle
« Reply #3 on: July 03, 2017, 06:20:24 pm »
Since you calculate the intersection points you could draw the triangle in the OnAfterDrawBackwall event. This occurs before axes and series are drawn. Since TAChart does all scaling calculations within its Draw method the chart must have been drawn at least once before the background triangle can be activated, but your ShowLinesBtnClick procedure is perfect for this...

Write this procedure and assign it to the OnAfterDrawBackwall event of the chart:
Code: Pascal  [Select]
1. procedure TForm1.Chart1AfterDrawBackWall(ASender: TChart; ACanvas: TCanvas;
2.   const ARect: TRect);
3. var
4.   P: array[0..3] of TPoint;
5. begin
6.   if not TriangleOK then
7.     exit;
8.
9.   P[0] := Chart1.GraphToImage(DoublePoint(xcross[0], ycross[0]));
10.   P[1] := Chart1.GraphToImage(DoublePoint(xcross[1], ycross[1]));
11.   P[2] := Chart1.GraphToImage(DoublePoint(xcross[2], ycross[2]));
12.   P[3] := P[0];
13.   ACanvas.Brush.Style := bsSolid;
14.   ACanvas.Brush.Color := clRed;
15.   ACanvas.Polygon(P);
16. end;

Then...
• Declare a boolean variable TriangleOK. You can see in the code above that the triangle is not painted if TriangleOK is false
• Set TriangleOK to False at the end of FormCreate.
• Set it to false also at the beginning of DeleteLinesClick. The chart will be redrawn after lineA.Clear etc, but since TriangleOK is false, the triangle will not painted any more.
• Set it to TRUE at the end of successful completion of ShowLinesBtnClick and call Chart1.Invalidate afterwards. Before this line is reached the chart has been repainted, i.e. the axis scaling has been done, because you have added datapoints to the lineseries. And ShowLinesBtnClick calculates the intersection points.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

#### frederic

• Full Member
• Posts: 221
##### Re: brush in arbitrary triangle
« Reply #4 on: July 03, 2017, 09:11:04 pm »
wp

thanks a lot
looking at the code i  expect that this approach can be used in a more generic way

-   so 4 or more lines which enclose a surfrace ,as long as you can calculate P0.....Pn
am i right?

- or another mathematical function(for each x only one  y-value,no circles and introduce more P[n] to approach the curve) with a line
or am i streching it now too far?

a last question:because i have to redraw the chart i suppose that this can only be done once for each chart
with a number of these enclosures i have to combine them in the same OnAfterDrawBackwall event

thanks anyway, we start experimenting
frederic

« Last Edit: July 03, 2017, 09:18:06 pm by frederic »

#### wp

• Hero Member
• Posts: 4076
##### Re: brush in arbitrary triangle
« Reply #5 on: July 03, 2017, 10:19:00 pm »
Yes all this extra drawing must be done in the OnAfterDrawBackWall event. So if you have several items to appear subsequently you must add some logic to this procedure - a primitive logic was the TriangleOK variable of my example.

You can draw anything you want. But since you are plotting data in axis units you must make sure that the chart has been drawn at least once before you show these extras - otherwise the conversion from axis coordinates to pixels would not be known.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

#### frederic

• Full Member
• Posts: 221
##### Re: brush in arbitrary triangle
« Reply #6 on: July 04, 2017, 09:37:12 am »
oke,

this offers then also the possibility to use the textout function:

Code: Pascal  [Select]
1.  pospx:=   chart1.XGraphToImage(xcross[0]+ xmarge);
2.  pospy:=   chart1.YGraphToImage(ycross[0]+ymarge);
3.  ACanvas.TextOut( pospx,pospy,'P0');

which would solve the previous  discussion of adding text to a chart

nice

now find out what the implecations are for zooming and panning

frederic
« Last Edit: July 04, 2017, 09:56:14 am by frederic »

#### wp

• Hero Member
• Posts: 4076
##### Re: brush in arbitrary triangle
« Reply #7 on: July 04, 2017, 11:13:24 am »
which would solve the previous  discussion of adding text to a chart
Hmm... The OnAfterDrawBackwall event is called very early, before series are drawn. Therefore, you must expect that series can paint over your text... Maybe you should try the OnAfterDraw event which comes when everything is complete. Please note this event does not expose a Canvas but an IChartDrawer interface for painting. Here's an example:

Code: Pascal  [Select]
1. procedure TForm1.Chart1AfterDraw(ASender: TChart; ADrawer: IChartDrawer);
2. begin
5. end;
6.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

#### frederic

• Full Member
• Posts: 221
##### Re: brush in arbitrary triangle
« Reply #8 on: July 04, 2017, 05:10:27 pm »
thanks,
i experienced a hidden text already for the reason you mentioned

i will try both methods and see what works best in coding the extreme points of the series.
thanks again
frederic