tchart for contourplots lazarus / 55-TAChart ---------------------------------------------------------------------- stephanweber · 2019-04-04 09:50 Hi, I am using tchart for 2-dimensional contourplots with good succes so far, but two features I want to implement, and this looks not so easy: 1. Can I place a little arrow to put (overlay) a vector in the existing contourplot? Of course I can use a lineseries, and use adxy for start and end points, but then I have no arrow point to indicate what is the end point! 2. I get a nice colored plot to indicate f(x,y), e.g. white is smallest, black largest f-value, BUT can I also plot line of given f(x,y)=constant, like equi-potential lines in a electric field, out of the box? Bye Stephan ---------------------------------------------------------------------- wp · 2019-04-04 10:25 Quote from: stephanweber on April 04, 2019, 11:50:30 amI get a nice colored plot to indicate f(x,y), e.g. white is smallest, black largest f-value, BUT can I also plot line of given f(x,y)=constant, like equi- potential lines in a electric field, out of the box? Isn't this what a contour plot is doing? Or what do you mean? TChart? Are you talking of Delphi's TChart or Lazarus' TAChart? Quote from: stephanweber on April 04, 2019, 11:50:30 amCan I place a little arrow to put (overlay) a vector in the existing contourplot? Of course I can use a lineseries, and use adxy for start and end points, but then I have no arrow point to indicate what is the end point!Assuming that you talk of TAChart: There is a TFieldSeries which does plot arrows. But I think this is overkill. Use the following DrawArrow procedure in the OnAfterDraw event of the chart - this is called when all the series have been painted: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  TAGeometry, TAChartUtils; procedure DrawArrow(AChart: TChart; APoint1, APoint2: TDoublePoint;  ArrowLength, ArrowWidth: Integer);var  P1, P2: TPoint;  P: Array [0..2] of TPoint;  angle: Double;  id: IChartDrawer;begin  id := AChart.Drawer;  P1 := AChart.GraphToImage(APoint1);  P2 := AChart.GraphToImage(APoint2);  angle := arctan2(P2.Y - P1.Y, P2.X - P1.X);  id.SetPenParams(psSolid, clBlack);  id.Line(P1.X, P1.Y, P2.X, P2.Y);  P[0] := P2;  P[1] := P2 - RotatePoint(Point(ArrowLength, ArrowWidth div 2), angle);  P[2] := P2 - RotatePoint(Point(ArrowLength, -ArrowWidth div 2), angle);  id.SetBrushParams(bsSolid, clBlack);  id.Polygon(P, 0, 3);end; ---------------------------------------------------------------------- stephanweber · 2019-04-05 06:12 Yes, it is purely about Lazarus ! With contourlines I mean thin lines which connect points of the same function values. Currently, I have a nice color gradient representing the function value (e.g. ranging from 0 to 2.543), but I also want to overlay lines for distinct values (like 0.5;1;2). Bye Stephan ---------------------------------------------------------------------- wp · 2019-04-05 07:55 This? https://forum.lazarus.freepascal.org/index.php/topic,19399.msg11 4039.html ---------------------------------------------------------------------- stephanweber · 2019-04-06 11:06 Code: [Select][quote author=wp link=topic=44921.msg316194#msg316194 date=1554373534]... begin   [b]id := AChart.Drawer;[/b]   P1 := AChart.GraphToImage(APoint1);   P2 := AChart.GraphToImage(APoint2);   angle := arctan2(P2.Y - P1.Y, P2.X - P1.X);   id.SetPenParams(psSolid, clBlack);   id.Line(P1.X, P1.Y, P2.X, P2.Y);   P[0] := P2;   P[1] := P2 - RotatePoint(Point(ArrowLength, ArrowWidth div 2), angle);   P[2] := P2 - RotatePoint(Point(ArrowLength, -ArrowWidth div 2), angle);   id.SetBrushParams(bsSolid, clBlack);   id.Polygon(P, 0, 3); end;  [/quote] I tried to use your code, but chart.drawer gives me a compiler error. Is using Lazarus 1.0 or 1.6 not enough, do i need to upgrade? Bye Stephan ---------------------------------------------------------------------- wp · 2019-04-06 12:00 Quote from: stephanweber on April 06, 2019, 01:06:07 pmI tried to use your code, but chart.drawer gives me a compiler error. Is using Lazarus 1.0 or 1.6 not enough, do i need to upgrade? Maybe the unit TADrawUtils is missing from "uses" (as well as "Math" due to "arctan2"). If the arrow does not show up use the same procedure in the OnAfterPaint event. I wonder why so many people are sticking to the ancient Lazarus versions? ---------------------------------------------------------------------- stephanweber · 2019-04-08 13:34 Quote from: wp on April 06, 2019, 02:00:30 pmI wonder why so many people are sticking to the ancient Lazarus versions? .. because even Lazarus 1.0 was so great! The bugs I trapped into are really only a very few. Please: Note that the error is indeed already on the declaration of "id", and the uses is of course included already. Also atan2 is no problem. So do I need to switch to 2.0? Unfortunately, Ubuntu does not support a direct Lazarus install or update, so far (16.04 at least). Bye Stephan ---------------------------------------------------------------------- lucamar · 2019-04-08 13:57 Quote from: stephanweber on April 08, 2019, 03:34:33 pmSo do I need to switch to 2.0? Unfortunately, Ubuntu does not support a direct Lazarus install or update, so far (16.04 at least). You should swicth to, at least, 1.8.4 (though it's better, if you can, to 2.0). Don't install from the Ubuntu repos: they are always hopelessly outdated (who maintains them, I wonder?). Instead, uninstall your current Lazarus, FPC and FPC-source, install GDebi, download the current DEBs from lazarus-ide.org (or sourceforge) and use GDebi to install them. The problem with ancient versions (and yours is really ancient) is not only the bugs but the new language features that you're missing ... and everyone else is using. Read the Release Notes and User Changes and you'll find that there are quite a lot that break backwards-compatibility: those will let you unable to compile updated packages. ---------------------------------------------------------------------- stephanweber · 2019-04-09 20:59 Quote from: wp on April 04, 2019, 12:25:34 pm Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  TAGeometry, TAChartUtils; procedure DrawArrow(AChart: TChart; APoint1, APoint2: TDoublePoint;  ArrowLength, ArrowWidth: Integer);var  P1, P2: TPoint;  P: Array [0..2] of TPoint;  angle: Double;  id: IChartDrawer;begin...end; Thanks a lot!! I found that I need some further units to get  IChartDrawer, and I am now on Lazarus 2.0 and fpc304. The only remaining problem is this: The arrow code is at the end of all drawings, BUT I see the arrow flashing up shortly, then it is Overwritten with the contourplot coloring!! With some tricks I could prevent this for lineseries, But how to avoid this for the arrow? Bye Stephan ---------------------------------------------------------------------- wp · 2019-04-09 21:38 OnAfterDraw occurs after all series are drawn, when you really painted the arrow here it cannot be overwritten. You must be doing something wrong. How do you draw the contourplot? ---------------------------------------------------------------------- stephanweber · 2019-04-11 07:20 Quote from: wp on April 09, 2019, 11:38:51 pmOnAfterDraw ... This makes the job very well!!! I wonder a little bit about object orientation? Could it be, that whenever something becomes more difficult, do not use OO? I like your solution a lot, and it looks the way I made my non-OO charts without any objects (for Turbo Pascal 5). ---------------------------------------------------------------------- wp · 2019-04-11 08:44 It seems that you never looked into the source code of TAChart - it's full of objects... Events have the purpose to provide for the user a "hook" to attach his own code and to modify an existing class easily. Of course, you can override TChart and do it in the pure object-oriented way, but it will be less straightforward. Purism is not always the best solution.