Recent

Author Topic: TChart start position  (Read 3207 times)

flori

  • Full Member
  • ***
  • Posts: 196
TChart start position
« on: February 27, 2021, 09:15:13 am »
Does anyone know where is the EndPosition, StartPosition on my TChart? I have just position.
https://wiki.lazarus.freepascal.org/Comparing_TAChart_with_Delphi's_TeeChart_Standard
( it doesn't look like that to me)

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: TChart start position
« Reply #1 on: February 27, 2021, 01:26:53 pm »
I don't understand what you want to say.

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #2 on: February 27, 2021, 02:39:07 pm »
I found it.
Extend: Ymax, Ymin /Xmax Xmin -start y/start x
WP> I create a small demo which use dbf. ->ID, FARM_Name, YIELD. I want to display these TChart BarSeries. As a result I get different column size(I do not understand why!) Small demo project with different behavior of TChart.
When I change Id: 1,2,3.. then I get good results.
I attached small demo.
Thanks for watching

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #3 on: February 27, 2021, 03:07:02 pm »
I think my Lazarus Chart is not working good.
I try listChartsource : as a results: different column width
X   y
1   25
2   26
4   27

When I modified: as a results: same column width
x   y
1   25
2   26
3   27


it's OK
« Last Edit: February 27, 2021, 03:33:23 pm by flori »

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #4 on: February 27, 2021, 03:32:14 pm »
I create small demo2 with TChartListSource. The TChart column is different width.
I do not understand

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: TChart start position
« Reply #5 on: February 27, 2021, 04:38:03 pm »
I could not run your demo because I do not use your report engine. (Please try to keep demos as simple as possible).

But I could see in the lfm file that the x values of the bar series are not equidistant: 2001, 2002, 2003, 2006. In its default settings, the BarSeries calculates the bar widths on the basis of BarWidthPercent in which the "percent" refers to the distance to the next (or previous?) data point. So, when the x values do not have the same distance the bars will vary in width. To adjust the bars to equal widths you must set the BarWidthStyle to bwPercentMin which looks for the smallest x value distance and calculates the widths of all bars based on this value.

Alternatively to changing the BarWidthStyle you can also add "empty" values at the missing years, 2004 and 2005:
Code: Pascal  [Select][+][-]
  1.   ListChartSourc1.Add(2001, 2, 'Farm1');
  2.   ListChartSource1.Add(2002, 50, 'Farm2');
  3.   ListChartSource1.Add(2003, 9, 'Farm4');
  4.   ListChartSource1.Add(2004, NaN);   // <--------- This is a "missing" value
  5.   ListChartSource1.Add(2005, NaN);
  6.   ListChartSource1.Add(2006, 50, 'Farm3');
You must add unit math to the uses clauses to get access to NaN ("not a number").


flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #6 on: February 27, 2021, 06:34:27 pm »
WP> Thank you very much for your help!
 I create a small demo again. I just set ListChartSource.
Unfortunately, users (farmers) change the years many times. Never contain such as: 2012,2013, 2014. Usually the years is unsettled. (2008, 1988, 1999, etc) they are not sorted by year.
I set BarWidthStyle to bwPercentMin and x values of the bar series are equal. The column width is ok , but unfortunately the distance between columns are not equal. (not user friendly and does not looks good).
Thanks

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #7 on: February 28, 2021, 08:26:15 am »
WP> Thank you very much for your help!
 I create a small demo again. I just set ListChartSource.
Unfortunately, users (farmers) change the years many times. Never contain such as: 2012,2013, 2014. Usually the years is unsettled. (2008, 1988, 1999, etc) they are not sorted by year.
I set BarWidthStyle to bwPercentMin and x values of the bar series are equal. The column width is ok , but unfortunately the distance between columns are not equal. (not user friendly and does not looks good).
Thanks

Does anyone know how to solve this problem?
Many thank u!!

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #8 on: February 28, 2021, 09:00:31 am »
I could not run your demo because I do not use your report engine. (Please try to keep demos as simple as possible).

But I could see in the lfm file that the x values of the bar series are not equidistant: 2001, 2002, 2003, 2006. In its default settings, the BarSeries calculates the bar widths on the basis of BarWidthPercent in which the "percent" refers to the distance to the next (or previous?) data point. So, when the x values do not have the same distance the bars will vary in width. To adjust the bars to equal widths you must set the BarWidthStyle to bwPercentMin which looks for the smallest x value distance and calculates the widths of all bars based on this value.

Alternatively to changing the BarWidthStyle you can also add "empty" values at the missing years, 2004 and 2005:
Code: Pascal  [Select][+][-]
  1.   ListChartSourc1.Add(2001, 2, 'Farm1');
  2.   ListChartSource1.Add(2002, 50, 'Farm2');
  3.   ListChartSource1.Add(2003, 9, 'Farm4');
  4.   ListChartSource1.Add(2004, NaN);   // <--------- This is a "missing" value
  5.   ListChartSource1.Add(2005, NaN);
  6.   ListChartSource1.Add(2006, 50, 'Farm3');
You must add unit math to the uses clauses to get access to NaN ("not a number").


I try different years: The column width is ok , but unfortunately the distance between columns are not equal.
Code: Pascal  [Select][+][-]
  1.  ListChartSource1.Add(2001, 2, 'Farm1');
  2.   ListChartSource1.Add(2002, 50, 'Farm2');
  3.   ListChartSource1.Add(2003, 9, 'Farm4');
  4.  // ListChartSource1.Add(2004, 0);   // <--------- This is a "missing" value
  5.   //ListChartSource1.Add(2005, 0);
  6.   ListChartSource1.Add(2006, 50, 'Farm3');

bpranoto

  • Full Member
  • ***
  • Posts: 134
Re: TChart start position
« Reply #9 on: February 28, 2021, 09:21:31 am »
I would make the labels plain consecutive integer value: 0,1,2,3...etc

Then I create an array to map those values to the year:
Code: Pascal  [Select][+][-]
  1. type
  2.   TDynIntArray = array of Integer;
  3.  
  4. constructor TForm1.Create(AOwner: TComponent);
  5.  
  6.   procedure AAdd( var AArray: TDynIntArray ; Value:Integer );
  7.   var
  8.     i : Integer;
  9.   begin
  10.     SetLength(  AArray,Length(AArray) + 1 );
  11.     i := Length(AArray);
  12.     AArray[i-1] := Value;
  13.   end;
  14.  
  15. begin
  16.   inherited Create(AOwner);
  17.   AAdd(Self.FMapXYear,2012);
  18.   AAdd(Self.FMapXYear,2013);
  19.   AAdd(Self.FMapXYear,2019);
  20.   AAdd(Self.FMapXYear,2021);
  21. end;
  22.  

After that, I set the bottom TChartAxis onMarkToText event to print the year instead of the x value:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Chart1AxisList1MarkToText(var AText: String; AMark: Double);
  2. var
  3.   i : Integer;
  4. begin
  5.   i := StrToInt( AText);
  6.   if i >= 0 then begin
  7.     AText := IntToStr(Self.FMapXYear[i]);
  8.   end;
  9. end;
  10.  

Attached is the screenshot

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #10 on: February 28, 2021, 09:53:04 am »
I would make the labels plain consecutive integer value: 0,1,2,3...etc

Then I create an array to map those values to the year:
Code: Pascal  [Select][+][-]
  1. type
  2.   TDynIntArray = array of Integer;
  3.  
  4. constructor TForm1.Create(AOwner: TComponent);
  5.  
  6.   procedure AAdd( var AArray: TDynIntArray ; Value:Integer );
  7.   var
  8.     i : Integer;
  9.   begin
  10.     SetLength(  AArray,Length(AArray) + 1 );
  11.     i := Length(AArray);
  12.     AArray[i-1] := Value;
  13.   end;
  14.  
  15. begin
  16.   inherited Create(AOwner);
  17.   AAdd(Self.FMapXYear,2012);
  18.   AAdd(Self.FMapXYear,2013);
  19.   AAdd(Self.FMapXYear,2019);
  20.   AAdd(Self.FMapXYear,2021);
  21. end;
  22.  

After that, I set the bottom TChartAxis onMarkToText event to print the year instead of the x value:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Chart1AxisList1MarkToText(var AText: String; AMark: Double);
  2. var
  3.   i : Integer;
  4. begin
  5.   i := StrToInt( AText);
  6.   if i >= 0 then begin
  7.     AText := IntToStr(Self.FMapXYear[i]);
  8.   end;
  9. end;
  10.  

Attached is the screenshot

Thanks. But How can I solve this problem when I use dbf? I attached small demo. Because the years change often. (1999, 2005, 2009, etc)

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #11 on: February 28, 2021, 10:03:46 am »
unfortunately it doesn't work with DBF or other DB (ZQUery, etc)

bpranoto

  • Full Member
  • ***
  • Posts: 134
Re: TChart start position
« Reply #12 on: February 28, 2021, 11:05:51 am »
Thanks. But How can I solve this problem when I use dbf? I attached small demo. Because the years change often. (1999, 2005, 2009, etc)

Unfortunately, I can't load your project because I don't have the report component that you used.

The idea is what you put into the data is a simple continous integer, then you control what is to be shown in onMarkToText event.

bpranoto

  • Full Member
  • ***
  • Posts: 134
Re: TChart start position
« Reply #13 on: February 28, 2021, 11:42:19 am »
I succesfully managed to compile your sample project.

Here what I modified:
1. Add a field XLABEL to farm.dbf, fill the record with 1,2
2. Change the property FieldX of DBChartSource1 to XLabel
3. Create onMarkText event:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Chart2AxisList1MarkToText(var AText: String; AMark: Double);
  2. var
  3.   XVal:Integer;
  4. begin
  5.   XVal := StrToInt(AText);
  6.   Dbf1.Locate('XLABEL',XvAL,[]);
  7.   AText := Dbf1.FieldByName('ID').AsString;
  8. end;
  9.  

The modified project is attached

flori

  • Full Member
  • ***
  • Posts: 196
Re: TChart start position
« Reply #14 on: February 28, 2021, 12:10:43 pm »
I succesfully managed to compile your sample project.

Here what I modified:
1. Add a field XLABEL to farm.dbf, fill the record with 1,2
2. Change the property FieldX of DBChartSource1 to XLabel
3. Create onMarkText event:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Chart2AxisList1MarkToText(var AText: String; AMark: Double);
  2. var
  3.   XVal:Integer;
  4. begin
  5.   XVal := StrToInt(AText);
  6.   Dbf1.Locate('XLABEL',XvAL,[]);
  7.   AText := Dbf1.FieldByName('ID').AsString;
  8. end;
  9.  

The modified project is attached

Thank you. It works with just 2 rows. While I add to 3 rows doesn't work.  (ID(2012)...+ID (i))

 

TinyPortal © 2005-2018