Recent

Author Topic: BarSeries with DateTimeChartSource  (Read 3735 times)

kapibara

  • Hero Member
  • *****
  • Posts: 516
BarSeries with DateTimeChartSource
« on: August 31, 2013, 04:24:59 pm »
I want to display five workdays per week in a BarSeries.

Problem: Non-working days seem to be inserted between the bars containing workday data.

I use ListChartSource and DateTimeChartSource and tried different settings.

How to change this behaviour so only workdays are shown? Small test app attached.
Lazarus trunk / fpc 3.0.4 / Debian 10 - 64 bit

wp

  • Hero Member
  • *****
  • Posts: 6351
Re: BarSeries with DateTimeChartSource
« Reply #1 on: August 31, 2013, 08:03:42 pm »
I never really understood the DateTimeChartSource...

Maybe you get better results if you add labels to the ListChartSource and use the ListChartSource for labelling the axis as I had suggested in the other thread.

Populate the ListChartSource in this way
Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
var
  dt: TDateTime;
begin
  with ListChartSource1 do
  begin
    dt := StrToDate('20.08.2013');
    Add(dt, 1, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('21.08.2013');
    Add(dt, 2, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('22.08.2013');
    Add(dt, 3, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('23.08.2013');
    Add(dt, 4, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('26.08.2013');
    Add(dt, 5, FormatDateTime('MMM-DD (DDD)', dt));
    {
    Add(StrToDate('20.08.2013'),1, '20.8.2013');  //This is a Tuesday
    Add(StrToDate('21.08.2013'),2, '21.8.2013');
    Add(StrToDate('22.08.2013'),3, '22.8.2013');
    Add(StrToDate('23.08.2013'),4, '23.8.2013');
    Add(StrToDate('26.08.2013'),5, '26.8.2013');  //This is a Monday
    }
  end;
end;               

Assign the ListChartSource to the Marks.Source of the BottomAxis. Set BottomAxis.Marks.Style = smsLabel. If you don't want the marks above the bars set Chart1BarSeries1.Marks.Visible = false.

This gets you axis labels only at the bar positions. If you want labels also at missing days use another ListChartSource and populate it by code for each date where you want an axis label.

Of course, manually populated chart source are not ideal for zooming...

To get a constant bar width, set Chart1BarSeries1.BarWidthStyle = bwPercentMin. The width, then, is determined from the closest bar distance and the BarWidthPercent parameter.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

kapibara

  • Hero Member
  • *****
  • Posts: 516
Re: BarSeries with DateTimeChartSource
« Reply #2 on: August 31, 2013, 10:27:16 pm »
Looking better! Thank you. BarWidthStyle = bwPercentMin sized down the last bar. Now only the gap in the chart between workdays has to be removed. Saturday and Sunday should not show up anywhere, neither as points nor marks or labels. Hope there is a way to remove such gaps?

I noticed the call to StrToDate requires a string that matches the computers regional settings.
(Control Panel -> Clock, Language and Region for Windows)
« Last Edit: August 31, 2013, 10:34:25 pm by kapibara »
Lazarus trunk / fpc 3.0.4 / Debian 10 - 64 bit

wp

  • Hero Member
  • *****
  • Posts: 6351
Re: BarSeries with DateTimeChartSource
« Reply #3 on: August 31, 2013, 10:34:33 pm »
So you don't want any gaps? Then don't use the date as x coordinate but the data point index. With this, you have equally spaced bars, and using the label in the ChartSource you get the dates for the axis marks.

Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
var
  dt: TDateTime;
begin
  with ListChartSource1 do
  begin
    dt := StrToDate('2013-08-20');
    Add(0, 1, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('2013-08-21');
    Add(1, 2, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('2013-08-22');
    Add(2, 3, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('2013-08-23');
    Add(3, 4, FormatDateTime('MMM-DD (DDD)', dt));

    dt := StrToDate('2013-08-26');
    Add(4, 5, FormatDateTime('MMM-DD (DDD)', dt));
  end;
end;               

Quote
I noticed the call to StrToDate requires a string that matches the computers regional settings.
No need to go to the Control Panel. Just modify the DefaultFormatSettings and apply the modified copy as an additional parameter to the conversion procedure - unfortunately there is no overloaded StrToDate, but you can use StrToDateTime instead:

Code: [Select]
var
  dt: TDateTime;
  fs: TFormatSettings;
begin
  fs := DefaultFormatSettings;
  fs.ShortDateFormat := 'DD-MM-YYYY';
  fs.DateSeparator := '.';
  dt := StrToDateTime('20.08.2013', fs);
« Last Edit: August 31, 2013, 10:44:19 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

kapibara

  • Hero Member
  • *****
  • Posts: 516
Re: BarSeries with DateTimeChartSource
« Reply #4 on: August 31, 2013, 11:07:17 pm »
There it is! I'm very very happy right now.  :D Thanks again.


So you don't want any gaps? Then don't use the date as x coordinate but the data point index. With this, you have equally spaced bars, and using the label in the ChartSource you get the dates for the axis marks.

Lazarus trunk / fpc 3.0.4 / Debian 10 - 64 bit

wp

  • Hero Member
  • *****
  • Posts: 6351
Re: BarSeries with DateTimeChartSource
« Reply #5 on: September 02, 2013, 09:14:58 am »
Quote
unfortunately there is no overloaded StrToDate
The missing overload of StrToDate has been fixed for fpc trunk (v2.7.1). (http://mantis.freepascal.org/view.php?id=24929)
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10