Page 1 of 1

Remove the time gap from the last datapoint in the chart til

Posted: Tue Apr 16, 2013 8:31 pm
by 9047488
I need a bottom axis that is dateTime and which can do the following : Remove the time gap from the last datapoint in the chart till midnight and from midnight till the first datapoint. This would remove all "dead" spaces in the chart.

Re: Remove the time gap from the last datapoint in the chart til

Posted: Wed Apr 17, 2013 1:13 pm
by yeray
Hello,

You have two alternatives:
- Add the points consecutively, at XValues 0, 1, 2, 3,... and set their labels so the gaps aren't in the XValues but just in the labels.
- Use the AxisBreaks tool, adding a break for each gap you want to have in the axis.

Re: Remove the time gap from the last datapoint in the chart til

Posted: Wed Apr 17, 2013 8:29 pm
by 9047488
Hello Yeray. :D

Basically I am wanting to remove Saturday and Sunday and all out of work hours from a Gantt chart. So it will only show the Working hours in a 5 day working week. ie. ONLY Monday to Friday Example from 7:00 hrs to 17:00 hrs or some variant of this.

I haven't tried it yet, the breakaxis seems to remove DateTime groups from the graph for each weekend or each out of work hours event. Is this the only solution? Do you have a coded example of this Yeray? I couldn't find one. :(

Thank you Yeray. Doug Johnson

Re: Remove the time gap from the last datapoint in the chart til

Posted: Thu Apr 18, 2013 8:55 am
by yeray
Hi Doug,

It seems you'd have many Breaks in your axis. It would probably be easier and more efficient to use the first approach.
Find below an example:

Code: Select all

uses Series, DateUtils;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
    tmpDate: TDateTime;
begin
  Chart1.View3D:=false;
  Chart1.Legend.Visible:=false;

  tmpDate:=StrToDateTime('18/4/2013 7:00');
  with Chart1.AddSeries(TPointSeries) as TPointSeries do
  begin
    Pointer.HorizSize:=2;
    Pointer.VertSize:=2;

    for i:=0 to 100 do
    begin
      if HourOf(tmpDate) > 17 then
      begin
        tmpDate:=IncDay(tmpDate);
        ReplaceTime(tmpDate, EncodeTime(7, 0, 0, 0));
      end;
      if DayOfWeek(tmpDate) = 7 then //Saturday
        tmpDate:=IncDay(tmpDate, 2);
      if DayOfWeek(tmpDate) = 1 then //Sunday
        tmpDate:=IncDay(tmpDate);

      Add(HourOf(tmpDate), FormatDateTime('c', tmpDate));

      tmpDate:=IncHour(tmpDate);
    end;
  end;
end;
Also note you may want to combine the above with the OnGetAxisLabels event to format the bottom axis labels in different ways depending on the level of zoom. There is an example of this in the features demo at "All features\Welcome !\Chart styles\Financial\Candle (OHLC)\Axis Labels no Weekends\".

Alternatively, if you still think the AxisBreak tool would be better for you, find an example at "All features\Welcome !\Tools\Axis Breaks", also in the features demo program included with the installation.

Re: Remove the time gap from the last datapoint in the chart til

Posted: Thu Apr 18, 2013 9:12 pm
by 9047488
Hello Yeray.

That was a great solution to my problem. Thank you. I think that I was over complicating the issue.

I am using Delphi XE3 FMX and the Gantt series.

Can you provide a snippet of code for Delphi that will.....

a) Switch off the auto sizing of the bottom axis to paging? I cannot seem to use the Pages function. I intended to use this and provide a page for each day from eg. 7:00 to 17:00 but the scale of the graph seems to switch to auto size.

b)Display the label on the Item? On the page I need to label the Day for the page only. eg. Monday.

c) Display the label on the item not the axis? The label of the item displayed is always on the axis. It is unique to the item and will overwrite the last label. Can I place it on the item?

Regards Doug

Re: Remove the time gap from the last datapoint in the chart til

Posted: Fri Apr 19, 2013 3:04 pm
by yeray
Hi Doug,

The easier would probably be to use buttons to manually navigate through the pages.
I've made an example for you:
GanttTest.zip
(2.27 KiB) Downloaded 1125 times
In this example I used an slightly different approach than before. If we keep using the real DateTimes as Start and End dates for the gantt points, we can take advantage of this to check if the a date is in a weekend to avoid showing it, and we can also use the datetimes to show the day currently being displayed.

Re: Remove the time gap from the last datapoint in the chart til

Posted: Mon Apr 22, 2013 2:02 am
by 9047488
Hi Yeray.

That was fantastic. Thank you. Took me some time convert to FireMonkey though. (LongDayNames)
var
formatSettings : TFormatSettings;
begin
....
....
FormatSettings.Create;
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, formatSettings);
Chart1.SubTitle.Text.Text:= FormatSettings.LongDayNames[DayOfTheWeek(date)+1] + ' ' + DateToStr(date);
......
....
end;

You have done more than your share Yeray, but can I ask two more questions?

a) I need to be able to drag a Gantt bar on the graph. I tried using the Chart dbl clk tool and set these to on. No good. Must the data to be dragged be in the series String Grid as I am using code to build the chart.

b) When I move to the next day I need to change the "Chart1.SubTitle.Text.Text" to represent the current date but it comes up with a strange error. Can this be done. the page forward/back/start/end buttons don't show the date for the page displayed?

Best regards Doug Johnson

Re: Remove the time gap from the last datapoint in the chart til

Posted: Tue Apr 23, 2013 12:58 pm
by yeray
Hi Doug,
Doug wrote:a) I need to be able to drag a Gantt bar on the graph. I tried using the Chart dbl clk tool and set these to on. No good. Must the data to be dragged be in the series String Grid as I am using code to build the chart.
I added a TGanttTool (TeeGanttTool unit) to the testing application above and it seems to work as expected. Is this what you tried?
The code I've added is basically this, at the end of the FormCreate method:

Code: Select all

uses TeeGanttTool;

procedure TForm1.FormCreate(Sender: TObject);
//...
  Chart1.Zoom.Allow:=false;
  Chart1.AllowPanning:=pmNone;
  (Chart1.Tools.Add(TGanttTool) as TGanttTool).Series:=Chart1[0];

  SetAxisDate(Today);
end;
Doug wrote:b) When I move to the next day I need to change the "Chart1.SubTitle.Text.Text" to represent the current date but it comes up with a strange error. Can this be done. the page forward/back/start/end buttons don't show the date for the page displayed?
In the testing application above, I have this:

Code: Select all

procedure TForm1.BFirstClick(Sender: TObject);
begin
  SetAxisDate(Chart1[0].XValues.MinValue);
end;

procedure TForm1.BPredClick(Sender: TObject);
begin
  if (DayOfWeek(Chart1.Axes.Bottom.Minimum-1) = 1) then //Sunday
  begin
    if ((Chart1.Axes.Bottom.Minimum-3) > Chart1[0].XValues.MinValue) then
      SetAxisDate(IncDay(Chart1.Axes.Bottom.Minimum, -3));
  end
  else
    if (Chart1.Axes.Bottom.Minimum-1) > Chart1[0].XValues.MinValue-1 then
      SetAxisDate(IncDay(Chart1.Axes.Bottom.Minimum, -1));
end;

procedure TForm1.BNextClick(Sender: TObject);
begin
  if (DayOfWeek(Chart1.Axes.Bottom.Minimum+1) = 7) then //Saturday
  begin
    if ((Chart1.Axes.Bottom.Minimum+3) > Chart1[0].XValues.MinValue) then
      SetAxisDate(IncDay(Chart1.Axes.Bottom.Minimum, 3));
  end
  else
  if (Chart1.Axes.Bottom.Minimum+1) < Chart1[0].XValues.MaxValue then
    SetAxisDate(IncDay(Chart1.Axes.Bottom.Minimum));
end;

procedure TForm1.BLastClick(Sender: TObject);
begin
  SetAxisDate(Chart1[0].XValues.MaxValue);
end;

procedure TForm1.SetAxisDate(date: TDateTime);
var min, max: TDateTime;
begin
  max:=date;
  ReplaceTime(max, EncodeTime(17,0,0,0));
  min:=date;
  ReplaceTime(min, EncodeTime(7,0,0,0));

  Chart1.Axes.Bottom.SetMinMax(min, max);

  Chart1.Title.Text.Text:=LongDayNames[DayOfTheWeek(date)+1] + ' ' + DateToStr(date);
end;
As you can see, the buttons actually check what date they have to set (basically to skip weekends), and the date is set in both the bottom axis scale and in the chart title in the SetAxisDate method.

PS: Note I modified the code in BPredClick method because I found it wasn't working as expected in the application I posted the last day.
There may be some other bugs/problems/imprecisions in the example posted. note it's just an example to show you the way to go. Of course you have to understand and adapt the idea to your own application.