Recent

Author Topic: Y-axis with whole numbers and non-white pie slices  (Read 3107 times)

JD

  • Hero Member
  • *****
  • Posts: 1848
Y-axis with whole numbers and non-white pie slices
« on: September 09, 2017, 05:26:00 pm »
Hi there,

Sorry if I'm stating the obvious or asking a question that has already been answered but how can I stop the Y axis from displaying decimals. I only want whole numbers. In the attached image, I'm trying to display a count of licenses so it has to be whole numbers.

In addition, I want to know if it is possible to prevent pie charts from having pie slices in white. My form background is white so I would prefer non-white pie slices.

Thanks,

JD
Windows - Lazarus 2.1/FPC 3.2 (built using fpcupdeluxe),
Linux Mint - Lazarus 2.1/FPC 3.2 (built using fpcupdeluxe)

mORMot; Zeos 8; SQLite, PostgreSQL & MariaDB; VirtualTreeView

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Y-axis with whole numbers and non-white pie slices
« Reply #1 on: September 09, 2017, 06:10:16 pm »
I'm guessing you have seen this ?http://wiki.freepascal.org/TAChart_documentation#Axis_intervals
From what I gathered you have two choises 1 create an axistransformation that will return only integers or something along those lines. 2) set the interval.maxlength to 100.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

wp

  • Hero Member
  • *****
  • Posts: 11858
Re: Y-axis with whole numbers and non-white pie slices
« Reply #2 on: September 10, 2017, 01:09:48 am »
The axis labelling algorithm of TAChart is highly automatic and sometimes hard to understand, in particular if you have particular requirements of the axis labels. There is some control by modifiying the Intervals subproperties of the axis. But all these modifications will not work in general, only under certain condtions: taazz suggested that increasing the Intervals.MaxLength avoids the fractional labels. This is true, but if you increase the chart, or if you zoom into the chart, the decimals places will be back.

In my experience the automatic label finding routine does not work if you have special requirments in mind. In these cases I would provide a TListChartsource which contains only the values at which labels will be drawn. Then you can put the logics of how you want the labels to be placed into the code populating the ListChartsource.

This ChartSource must be linked to the Marks.Source of the axis.

You say you count some quantities, and you want the labels to be at integers only. Then you could populate the ListChartSource (named "LabelsSource") like this:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.PopulateAxisLabels;
  2. var
  3.   ex: TDoubleRect;
  4.   y, y1, dy: Integer;
  5. begin
  6.   // Erase old labels
  7.   LabelsSource.Clear;
  8.  
  9.   // Get axis range
  10.   ex := Chart1.LogicalExtent;
  11.  
  12.   // "small" axis range  --> Place labels at every integer
  13.   if (ex.b.y - ex.a.y < 20) then   // the value 20 is just a guess
  14.     dy := 1                // label distance = 1
  15.   else
  16.   if (ex.b.y - ex.a.y < 40) then
  17.     dy := 2                            // label every other integer
  18.   else
  19.   if (ex.b.y - ex.a.y < 100) then
  20.     dy := 5                           // label every 5th integer
  21.   else
  22.     dy := 10;
  23.  
  24.   // Calculate first label to "fit" to the label distance, i.e. if label increment
  25.   // dy is 5 then the first label should be a multiple of 5 to avoid labels such
  26.   // as 1, 6, 11, 16...
  27.   y1 := (trunc(ex.a.y) div dy) * dy;
  28.  
  29.   // Now create the labels:
  30.  
  31.   // Begin at the first label
  32.   y := y1;
  33.   while y < ex.b.y + dy do begin   // ex.b.y is the axis maximum
  34.     // Add label to ListChartSource
  35.     LabelsSource.Add(y,y);
  36.     // Add labels increment the current label position to find the next label
  37.     y := y + dy;
  38.   end;
  39. end;
  40.  

This procedure takes care of the axis range and selects a small label increment at a small axis range and increases it when the axis extent increases. Call this in the Chart's OnExtentChange or OnExtentChanging event.

In the attachment there's a worked-out example of this idea.

 

TinyPortal © 2005-2018