primary Questions about TChart lazarus / 55-TAChart ---------------------------------------------------------------------- majid.ebru · 2018-02-09 18:31 Hi i have many primary Questions  about TChart. please help and guide me how can i fix min and max axis ? how can i have mult color line? how can i change value of X axis to Srtinf Text? how can i show value of point? ---------------------------------------------------------------------- majid.ebru · 2018-02-09 18:32 and ---------------------------------------------------------------------- wp · 2018-02-09 19:08 Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i fix min and max axis ? Set the Extent of the chart (can be done by code like below, or directly in the Object Inspector) 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   Chart1.Extent.YMax := 100;  Chart1.Extent.YMin := 0;  Chart1.Extent.UseYMax := true;  Chart1.Extent.UseYMin := true; Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i change value of X axis to Srtinf Text? What you probably need is an event handler for the event OnMarkToText of the axis. Example 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 procedure TForm1.Chart1AxisList1MarkToText(var AText: String; AMark: Double);begin  if AMark = 0.0 then AText := 'zero';end; Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i show value of point? Set the Marks.Style of the series to smsValue. The settings of Marks.Style define the combinations of the data point parameters (x, y, text) which will be shown as datapoint label (http://wiki.lazarus.f reepascal.org/TAChart_documentation#Mark_labels): 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 type  TSeriesMarksStyle = (    smsCustom,         { user-defined }    smsNone,           { no labels }    smsValue,          { 1234 }    smsPercent,        { 12 % }    smsLabel,          { Cars }    smsLabelPercent,   { Cars 12 % }    smsLabelValue,     { Cars 1234 }  smsLegend,         { ? }    smsPercentTotal,   { 12 % of 1234 }    smsLabelPercentTotal, { Cars 12 % of 1234 }    smsXValue);        { 21/6/1996 }    Change the format string in Marks.Format to limit the number of decimal places, e.g. '%.2f' for 2 decimals only. I'll have to think about the other questions. - What does the last image (06.png) mean? - In image 05.png you have a chart with a line series, and there's a horizontal dividing line. The parts of the line series above the dividing line should be painted in a different color than the parts below the dividing line. Correct? Will be dividing line be fixed, or should it be user-changeable? ---------------------------------------------------------------------- taazz · 2018-02-09 19:16 Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i have mult color line? There is no reason for multi colour lines. lines are not part of the data only points are the data lines are there to sombolize an idea only it is either negative or positive it can't be both. Don't waste your time on a illogical case. Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i show value of point? select the series of the chart and change the marks.style to what ever you need make sure that the marks are visible. ---------------------------------------------------------------------- wp · 2018-02-09 20:48 Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i have mult color line? Drawing the segments of a lineseries in different colors is not supported. But you can use a TUserDrawnSeries instead of the TLineSeries in which you can draw whatever you want - see attached demo. FormCreate defines some dummy data in an array of TDataRec records (record of x and y values) and calculates the range covered by the x and y values (Extent)The Extent has to be passed to the series in its event OnGetBounds.The event OnDraw expects code which paints the entire series. My code simply iterates through the data point array, calculates the image coordinates of each data point (by calling the chart's method GraphToImage) and draws the line segments in the color which is assigned to the current point index in the COLORS array. I should mention that using a Canvas in the OnDraw event is not up to the standard of TAChart which has introduced dedicated drawers. But there's nothing else at the moment, and you hopefully do not want to paint on exotic output devices.This probably is also the way to answer the question related to image 05.png where the series changes color above and below a dividing line. The only code which has to be added is the calculation of the intersection point of the line segment with the dividing line. ---------------------------------------------------------------------- wp · 2018-02-09 21:01 Quote from: taazz on February 09, 2018, 08:16:55 pmQuote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i have mult color line? There is no reason for multi colour lines. lines are not part of the data only points are the data lines are there to sombolize an idea only it is either negative or positive it can't be both. Don't waste your time on a illogical case. I don't quite understand what you mean, but I could imagine several use cases of multi-colored line segments. For example to highlight segments for which the slope exceeds a given limit. Or - if the series displays a road - the color symbolizes the number of accidents on each segment. ---------------------------------------------------------------------- wp · 2018-02-10 20:52 Quote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i have mult color line? The TLineSeries of TAChart in Lazarus trunk, r57277, now has a new property "ColorEach" with which you can colorize the line segments individually. The color is added to the data points (4th parameter of the series method AddXY) and can be applied to data points symbol and/or the line segments before or after each data point (TColorEachMode = (ceNone, cePoint, ceLineBefore, ceLineAfter, cePointAndLineBefore, cePointAndLineAfter). See the demo in the TAChart demo folder (lazarus/components/tachart/demo/line) ---------------------------------------------------------------------- wp · 2018-02-10 23:18 In the attachment there is a solution to the "color-split" chart. It is based on the user-drawn series as described above. Drag the horizontal dividing line up and down to move the color boundary. There's a little glitch, when data point symbols are shown and the dividing line goes right through the symbol because the symbol is always drawn as a full circle - to get over this a clipping approach should be used. ---------------------------------------------------------------------- majid.ebru · 2018-02-11 06:29 Quote from: wp on February 11, 2018, 12:18:42 amIn the attachment there is a solution to the "color-split" chart. It is based on the user-drawn series as described above. Drag the horizontal dividing line up and down to move the color boundary. There's a little glitch, when data point symbols are shown and the dividing line goes right through the symbol because the symbol is always drawn as a full circle - to get over this a clipping approach should be used. Thankyou your project is very Goooooooood but i can't compile your project? waht do i do? i should update my TChart element? ---------------------------------------------------------------------- majid.ebru · 2018-02-11 06:31 Quote from: wp on February 10, 2018, 09:52:01 pmQuote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i have mult color line? The TLineSeries of TAChart in Lazarus trunk, r57277, now has a new property "ColorEach" with which you can colorize the line segments individually. The color is added to the data points (4th parameter of the series method AddXY) and can be applied to data points symbol and/or the line segments before or after each data point (TColorEachMode = (ceNone, cePoint, ceLineBefore, ceLineAfter, cePointAndLineBefore, cePointAndLineAfter). See the demo in the TAChart demo folder (lazarus/components/tachart/demo/line) it's perfect how can i do that? ---------------------------------------------------------------------- wp · 2018-02-11 09:49 Quote from: majid.ebru on February 11, 2018, 07:29:39 amQuote from: wp on February 11, 2018, 12:18:42 amIn the attachment there is a solution to the "color-split" chart. It is based on the user-drawn series as described above. Drag the horizontal dividing line up and down to move the color boundary. There's a little glitch, when data point symbols are shown and the dividing line goes right through the symbol because the symbol is always drawn as a full circle - to get over this a clipping approach should be used. Thankyou your project is very Goooooooood but i can't compile your project? waht do i do? i should update my TChart element? It seems that you don't use Laz 1.8. You should upgrade, there are many new features. If you don't want to, just remove the line causing the trouble. ---------------------------------------------------------------------- wp · 2018-02-11 10:48 Quote from: majid.ebru on February 11, 2018, 07:31:07 amQuote from: wp on February 10, 2018, 09:52:01 pmQuote from: majid.ebru on February 09, 2018, 07:31:31 pmhow can i have mult color line? The TLineSeries of TAChart in Lazarus trunk, r57277, now has a new property "ColorEach" with which you can colorize the line segments individually. The color is added to the data points (4th parameter of the series method AddXY) and can be applied to data points symbol and/or the line segments before or after each data point (TColorEachMode = (ceNone, cePoint, ceLineBefore, ceLineAfter, cePointAndLineBefore, cePointAndLineAfter). See the demo in the TAChart demo folder (lazarus/components/tachart/demo/line) it's perfect how can i do that? You must install the trunk version of Lazarus (this is the developer version). The easiest way is using the fpcupdeluxe program (https://github.com/newpascal/fpcupdeluxe/releases/tag/v1.6.0n). ---------------------------------------------------------------------- corpsman · 2022-04-30 16:19 Quote from: wp on February 11, 2018, 12:18:42 amIn the attachment there is a solution to the "color-split" chart. It is based on the user-drawn series as described above. Drag the horizontal dividing line up and down to move the color boundary. There's a little glitch, when data point symbols are shown and the dividing line goes right through the symbol because the symbol is always drawn as a full circle - to get over this a clipping approach should be used. The sample is cool but your intersect routine has some errors here is my version that works better 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 Function Intersect(p1, p2: TPoint; y: Integer): Integer;Begin  If p1.y = p2.y Then // fixed catch of div by zero    Result := (p1.x + p2.x) Div 2  Else    Result := round(((p2.x - p1.x) * (y - p1.y)) / (p2.y - p1.y) + p1.x); // reorder to divide "larger" numbers is more stable.End; And the Routine that does the rending changed to this: 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  Procedure TForm1.Chart1UserDrawnSeries1Draw(ACanvas: TCanvas;  Const ARect: TRect);   Procedure DrawCircle(p: TPoint; AColor: TColor; R: Integer);  Begin    Chart1.Drawer.SetBrushParams(bsSolid, AColor);    Chart1.Drawer.Ellipse(P.x - R, P.y - R, P.x + R, P.y + R);  End;   Function GetColor(y, yref: Integer): TColor;  Begin    If y > yref Then      Result := COLOR_BELOW    Else      Result := COLOR_ABOVE;  End; Var  i: Integer;  gp: TDoublePoint;  p1, p2, p3: TPoint;  yref: Integer;  x: Integer;  showDataPoints: Boolean;Begin  showDataPoints := Checkbox1.Checked;  pen.Width := 4;  Chart1.Drawer.Pen := Pen;  yref := Chart1.YGraphToImage(Chart1ConstantLine1.Position);   i := 0;  gp := DoublePoint(Data[i].X, Data[i].Y);  p1 := Chart1.GraphToImage(gp);  If showDataPoints Then Begin    Chart1.Drawer.SetPenParams(psSolid, GetColor(p1.y, yref));    DrawCircle(p1, GetColor(p1.y, yref), RADIUS); // Fix copy paste index error 2->1  End;  For i := 1 To High(Data) Do Begin // draw from second to last point (index of by one correction)    gp := DoublePoint(Data[i].X, Data[i].Y);    p2 := Chart1.GraphToImage(gp);  If (p2.y - yref) * (p1.y - yref) < 0 Then Begin      p3 := Point(Intersect(p1, p2, yref), yref);      Chart1.Drawer.SetPenParams(psSolid, GetColor(p1.y, yref), 2);      Chart1.Drawer.Line(p1, p3);      Chart1.Drawer.SetPenParams(psSolid, GetColor(p2.y, yref), 2);      Chart1.Drawer.Line(p3, p2);    End    Else Begin      Chart1.Drawer.SetPenParams(psSolid, GetColor(p2.y, yref), 2);      Chart1.Drawer.Line(p1, p2);    End;    If showDataPoints Then      DrawCircle(p2, GetColor(p2.y, yref), RADIUS);    p1 := p2;  End;End; Thanks a lot for publishing your code. ---------------------------------------------------------------------- wp · 2022-04-30 21:07 Thanks for pointing out these bugs. I committed the fix to git-main (except for the reordering of multiplication and division - this really makes no difference with floats). ---------------------------------------------------------------------- Tulurdes · 2024-02-26 17:24 Hi all, I know this topic is a little old but I think it is still very relevant. I haven't updated from 2.2.4 yet, so I'm not sure if they improved the chart possibilities. But I've made some changes on this code and made it more compact in the draw event so I could reuse it in a easier way. I've also added a "fill" option so it could work as both line and area. But I'm struggling with something, I'd like to make this chart independent, but there are some items that seems impossible to replace since the event only passes as parameters ACanvas and ARect This are the calls I can't get rid of Chart1.YGraphToImage (direct access to a chart) Chart1.GraphToImage (direct access to a chart) Data.X, Data.Y (direct access to chart data source) What I want is to be able to create charts at runtime and have this drawing style working on all of them. Any help would be very welcome. ---------------------------------------------------------------------- wp · 2024-02-26 23:35 I think you are wanting the TUserDefinedSeries to do something it was not designed for. Maybe it would be better to create a new series type so that you have access to the series variables. This is not too difficult. When the series descends from TBasicPointSeries it inherits all the data handling, all you have to do is to override the Draw(ADrawer) method. You can use the code from TAreaSeries or TLineSeries as a reference. Add properties for the reference level at which the color changes, as well as the brushes and pens above and below the reference line. Maybe just like in attached demo. ---------------------------------------------------------------------- Tulurdes · 2024-02-27 16:32 Awesome code you've sent, thank you! it gave me some ideas to another problem that I'll be facing in the future I've thought of that, but wanted to see if there was something that I was missing. I was studying TAChart code and seems to me that makes more sense to update the tachart package, at least for the TLineSeries the TAreaSeries is a little more complex, will take a litte more time. I've made TLineSeries work like a charm with minimal changes (wouldn't break any compatibility). Now I'll try to figure out how can I send a suggestion of improvement to the official Dev team, maybe they can include this to the official release so more people can benefit from this functionality. If you know how to do this kind of suggestion, I'd appreciate also. ---------------------------------------------------------------------- wp · 2024-02-27 16:57 Send feature requests or bug reports to the GitLab bug tracker (https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues). Mention "TAChart" in the title of the report - this makes it easier for me to identify it. Carefully describe the issue, add a project to demonstrate the issue, ideally add a patch so that I can see what you want to modify in the code. Quote from: Tulurdes on February 27, 2024, 05:32:47 pmseems to me that makes more sense to update the tachart package, at least for the TLineSeries the TAreaSeries is a little more complex Hmmm... you are talking about the 2-color feature? I think I would not add it to the standard TLineSeries or TAreaSeries because I am rather sure that most users will not need it. One possible option could be to create a "TAChartExtraSeriesPackage" with additional series types, rarely used, but maybe too complex for the average user to write it him/herself. ---------------------------------------------------------------------- Tulurdes · 2024-02-27 18:04 Thanks a Lot! Actually what I've done is add a color each option (ceZeroLevel) Just sent a bug tracker named "TAChart improvement suggestion on the TLineSeries" I think you will like the approach. Didn't knew you where the responsible for TAChart, what an honor. I'm not an average user (I think), been programming for the past 24 years, I'm just dont have experience with git and stuff, been mostly a lone dev. Thanks again for all the help and attention. I really hope you like the suggestion