Recent

Author Topic: [Solved] tachart format to display marks  (Read 13166 times)

jagnje

  • New Member
  • *
  • Posts: 23
[Solved] tachart format to display marks
« on: March 17, 2015, 01:24:55 pm »
hello.

anyone knows about the syntax of the string to display marks

I would like to display floating point numbers but only with 1 decimal.

thanks!
« Last Edit: March 17, 2015, 08:08:17 pm by jagnje »

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: tachart format to display marks
« Reply #1 on: March 17, 2015, 02:53:22 pm »
Use Series.Marks.DisplayFormat := '%.1f' for 1 decimal (or '%.1g' for AT MOST 1 decimal).

jagnje

  • New Member
  • *
  • Posts: 23
Re: tachart format to display marks
« Reply #2 on: March 17, 2015, 03:54:47 pm »
thanks, much appreciated.

jagnje

  • New Member
  • *
  • Posts: 23
Re: tachart format to display marks
« Reply #3 on: March 17, 2015, 06:42:03 pm »
Use Series.Marks.DisplayFormat := '%.1f' for 1 decimal (or '%.1g' for AT MOST 1 decimal).

ok that was of course helpful but works only if i specify marks.style := smsCustom
if I put marks.style := smspercent, it seems that marks.style does not count as 2 decimal places get displayed every time

but let me tell you where was the problem. on some other chart, where i have more space, I used
a string that I found in some demo
          Marks.Format := '%1:.2f%';
          Marks.Style := smsPercent;

where left axis shows the numerus (which is preferable)

now I changed some charts that are very space restricted with your suggestion

          Marks.Format := '%.1f%%'; // these %% are my addition because I want to show % sign

and now the y-axis shows percentage, as now I add percentages to the chart in order to display marks as I wish

the whole thing works well enough now (though I would prefer y-axis to show numerus, it is just odd that you cannot change the format the string when smsPercent is chosen

thanks!

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: tachart format to display marks
« Reply #4 on: March 17, 2015, 07:28:22 pm »
Quote
it is just odd that you cannot change the format the string when smsPercent is chosen
No - smsPercent etc. are predefined, you cannot change the format string. But you can use these strings as a template - leave everything as it is and change for example the number of decimal places by replacing the "%1:.2%%" with "1:.1%%" (the second number is the number of decimal places; the first number before the colon tells the formatter which parameter passed to the Format() function internally is to be used). Of course, the style then jumps back to smsCustom because it is no longer the predefined string.

I am not sure at the moment, if the numbers are automatically multiplied by 100 to get the percentage.

If this does not work satisfactorily then you can also use the event OnMarkToText of the axis.Marks or series.Marks. Here you have full control over the way the mark text is generated:

Code: [Select]
procedure TForm1.Chart1AxisList0MarkToText(var AText: String; AMark: Double);
begin
  AText := Format('%.1f%%', [AMark*100]);
  // If AMark = 0.5 then AText would become '50.0%'
end;

jagnje

  • New Member
  • *
  • Posts: 23
Re: tachart format to display marks
« Reply #5 on: March 17, 2015, 08:07:59 pm »
oh, thank you, this works perfectly, I wasn't aware about it at all :)

CM630

  • Hero Member
  • *****
  • Posts: 1077
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: [Solved] tachart format to display marks
« Reply #6 on: March 18, 2015, 09:15:08 am »
I have the following problem:
I want to have time on the X axis.
If I use TDateTimeIntervalChartSource date is displayed, 0 corresponds to a year in the 19th century.
I want to use relative time (duration), so I want to start from year 0, month 0, day zero, hour zero, seconds zero....
What is the best way to achieve it?
Shall I use  TDateTimeIntervalChartSource and subtract some 1900 years from my values?
Also, I could not understand to what time interval the value of 1 corresponds. Is it one day, one hour, one year?

Лазар 3,0 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: [Solved] tachart format to display marks
« Reply #7 on: March 18, 2015, 10:32:33 am »
The values plotted which are compatible with TDateTimeIntervalChartSource are TDateTime, TDate, or TTime numbers, i.e. ordinary floating point values which advance in units of days.

You can use the "DateTimeFormat" property to enforce a particular formatting by the chartsource. In fpc trunk, the function FormatDateTime has been extended to accept also square brackets around hour, minute or second format parts which are interpreted as "duration", i.e. the part with the square bracket can become larger than its natural limit. Example: FormatdateTime('[h]:nn:ss], 1.5) = '36:00:00'. (1.5 is one and a half day, i.e. 24+12 hours). Does not work with days, though.

How big are your date/time durations? Maybe you don't need the years and months, and an alternative format string such as 'd"days" hh:nn' would be ok? Please be aware that the length of a year or month is not well-defined: the length of a year may be 365 or 366 days, the length of a month varies between 28 and 31 days.

CM630

  • Hero Member
  • *****
  • Posts: 1077
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: [Solved] tachart format to display marks
« Reply #8 on: March 22, 2015, 07:41:09 pm »
...You can use the "DateTimeFormat" property to enforce a particular formatting by the chartsource. In fpc trunk, the function FormatDateTime has been extended to accept also square brackets around hour, minute or second format parts which are interpreted as "duration", i.e. the part with the square bracket can become larger than its natural limit. Example: FormatdateTime('[h]:nn:ss], 1.5) = '36:00:00'. (1.5 is one and a half day, i.e. 24+12 hours). Does not work with days, though.

Indeed, I would need only hh:mm:ss,z, and nothing greater than a week has a fixed duration.
What do you mean by Does not work with days? I can't think of a natural limit of days, unless you mean that the maximum should be 7? I have tried something, it seems to work quite okay:
Code: [Select]
uses ...  TATextElements, TAChartUtils...
procedure TForm1.Button1Click(Sender: TObject);
var
  MyChart: TChart;
  MyDTI: TDateTimeIntervalChartSource;
begin
  MyDTI:= TDateTimeIntervalChartSource.Create(Self);
  MyChart:=TChart.Create(Self);
  MyChart.Left:=0;
  MyChart.Top:=0;
  MyChart.Width:=400;
  MyChart.BottomAxis.Range.Min:=0;
  MyChart.BottomAxis.Range.UseMin:=True;
  MyChart.BottomAxis.Range.Max:=1/24;
  MyChart.BottomAxis.Range.UseMax:=True;
  MyChart.BottomAxis.Marks.OverlapPolicy:=opHideNeighbour;
  MyChart.Parent:=Self;
  MyChart.BottomAxis.Marks.Style:=smsLabel;
  MyDTI.DateTimeFormat:='hh:nn:ss,z';
  MyChart.BottomAxis.Marks.Source:= MyDTI;
end;
The problem is that due to various legacay, etc. reasons I have to use 1 as a second, not as a day.
So I upon adding data in the series, I will have to divide their X values to 86400.
But if I have to switch the scales view to nontime marks, I will have to multiply all X values of all points in all series.
Could you offer me a better way to handle the situation? Maybe I could use TChartAxisTransformations with LinearAxisTransform and switch the scale property from 1 to (1/86400)?
« Last Edit: March 22, 2015, 07:44:04 pm by CM630 »
Лазар 3,0 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: [Solved] tachart format to display marks
« Reply #9 on: March 22, 2015, 08:46:02 pm »
Quote
What do you mean by Does not work with days?
The syntax with the square backets is implemented only for the hour, minute and second parts of a date/time value.

Quote
Could you offer me a better way to handle the situation?
If I understand you correctly you want to add data to the series in time units of seconds, but use the TDataTimeIntervalChartsource? Yes, I think a LinearAxisTransform could do the job.

However, I would prefer another option because you seem to store the chart data primarily somewhere else, in an array for example. If you call "series.AddXY" you will duplicate the data in memory - that may be acceptable for small charts, but may not for a large amount of data. I'd recommend to pass the data from their primary storage (the array) to the series by means of a TUserDefinedChartSource. It has an event OnGetChartDataItem in which you assign the external data to the series and in which you can do the division by the 86400 for the x data. Have a look at http://wiki.lazarus.freepascal.org/TAChart_Tutorial:_Userdefined_ChartSource, the tutorial gives step-by-step instructions how to set up and use such a ChartSource.

CM630

  • Hero Member
  • *****
  • Posts: 1077
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: [Solved] tachart format to display marks
« Reply #10 on: March 24, 2015, 02:37:26 pm »
Quote
Could you offer me a better way to handle the situation?
If I understand you correctly you want to add data to the series in time units of seconds, but use the TDataTimeIntervalChartsource? Yes, I think a LinearAxisTransform could do the job.
 

I do not insist on  TDataTimeIntervalChartsource. I would anything else but  TDataTimeIntervalChartsource,  provided it can display time as hh:nn:ss,z.



 


However, I would prefer another option because you seem to store the chart data primarily somewhere else, in an array for example. If you call "series.AddXY" you will duplicate the data in memory - that may be acceptable for small charts, but may not for a large amount of data. I'd recommend to pass the data from their primary storage (the array) to the series by means of a TUserDefinedChartSource. It has an event OnGetChartDataItem in which you assign the external data to the series and in which you can do the division by the 86400 for the x data. Have a look at http://wiki.lazarus.freepascal.org/TAChart_Tutorial:_Userdefined_ChartSource, the tutorial gives step-by-step instructions how to set up and use such a ChartSource.
There are two cases. In on of them I have data arrays with fixed timeshift (dt). I.e. I might have an oscillogram with 8 channels, each channel measured at refresh rate 5000 samples per second. Usually all 8 channels have same refresh rate, but it is not obligatory.
In the other case I might have several (tens or hundreds) channels with varying timeshift. In this case each Y has its own X value, like in the case you are talking about. Or maybe all channels might have a common X array. In this case most like I won't have data in the memory. Or I can free the array, after plotting all the data.
I will read about TUserDefinedChartSources, after I find timwe to solve the time display issue.
Лазар 3,0 32 bit (sometimes 64 bit); FPC3,2,2; rev: Lazarus_3_0 on Win10 64bit.

Vittorio

  • New Member
  • *
  • Posts: 32
Re: [Solved] tachart format to display marks
« Reply #11 on: April 20, 2018, 09:59:56 am »
Hi there, please help with syntax of marks.format to display only integer marks.

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: [Solved] tachart format to display marks
« Reply #12 on: April 20, 2018, 11:58:31 am »
Code: Pascal  [Select][+][-]
  1.   Chart.LeftAxis.Marks.Format := '%0:.0f';

But I would not touch this property which is only for formatting, not for marks positioning: if the chart decides to place marks at 0.0 0.2 0.4, 0.6, 0.8 1.0 they will be labeled as '0' '0' '0' '1' '1' '1' - probably not what you want.

You must play with the Intervals settings of the axis to change marks positioning. Increase Intervals.MaxLength to increase the distance between marks.

Vittorio

  • New Member
  • *
  • Posts: 32
Re: [Solved] tachart format to display marks
« Reply #13 on: April 23, 2018, 09:53:30 am »
wp, thanks a lot! That's enough for my puprose, because in my case marks can be only 1, 2, 3, ...

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: [Solved] tachart format to display marks
« Reply #14 on: April 23, 2018, 10:58:21 am »
[...] because in my case marks can be only 1, 2, 3, ...
Please remember my previous post... The chart does not take care of that. If the marks get too far apart then it adds intermediate marks. It does not matter if your data allow only integer marks or not.

 

TinyPortal © 2005-2018