11066 : So far it looks great, but I have not been able to change the row height?

Question

We are evaluating your phGantX component for use in visualizing info from a time & attendance app.  So far it looks great, but I have not been able to change the row height.  We need to make them taller since we need to draw a time bar and several markers underneath.  However, using the SetRowHeightGrid does nothing, and the GetRowHeightGrid always return zero.  Please advice.

 

Answer

Make sure you set IphGantX3.UseGrid=true, “Set this to true to use the grid instead of the tree. You must do this before adding any rows since all rows added are owned by the component (grid or tree) that is active when the row is created.”

 

If IphGantX3.UseGrid=false the comctrl treeview is used, and this cannot handle rowheights, columns etc

 

The Grid is fully hierarcical and can do everything the old tree can.

10782 : How can I print a Gant with the Rave Reports? I my reports using code, not the visual rave environment.

Question

I’m starting to use your software in VCL for Delphi 2006. How can I print a Gant with the Rave Reports? I create my reports using code, not the visual rave environment.

I use the TRvSystem, and all other renders.

Thanks

Answer

We have no specific information on Rave reports but either it will allow you to get a Canvas to draw to and then you use the PrintToHdc sending in the Canvas.Handle, or you can render to an EMF image (vector based) and send that image to the report generator.

10793 : I would like to move all linked items in one click and drag motion.

Question

I would like to move all linked items in one click and drag motion. I have not been able to figure out how to do this. I started by creating a list of all TphDataEntity_GantTime items in the link list and setting each items selected value to true in the gant mouse down event however this only works if I click a second time to initiate the move. Any suggestions?

Answer

If you do the exact same thing but in the IphGantX3.OnSelectionChangedGantTime event instead it will work better I am sure.

The problem is that when you get the mouse down the Gantt has already decidid what will be in the drag or not.

10742 : How do I change the font color (forecolor) of a time item?

Question

Hi, I allow customers to color code schedules. How do I change the font color (forecolor) of a time item?

Answer

There are properties on the IphGantX interface that controls font things:

TimeItemTextFont1 
TimeItemTextFont1Color 
TimeItemTextFont2 
TimeItemTextFont2Color 
TimeItemTextFont3 
TimeItemTextFont3Color 

There are three different fonts to choose from. You choose which one to use when you set ithe values on the TimeItemText IphDataEntity_GantTime2.TimeItemsTextSet.

  Set gr = de.GantRow
  gr.TimeItems_CanChangeRow = False
  gr.TimeItems_CanMove = True

  Set gt = phGantX1.AddGantTime(de, 0)
  gt.Style = tsNormal
  gt.Start = Date
  gt.Stop = Date + 5

  gt.TimeItemsTextAdd
  gt.TimeItemsTextSet 0, de.Text, 2, 2, 0 <- index zero -> font1

10730 : Is there a way to multi- timeitems so I can move them all together in the Gantt?

Question

Is there a way to multi-select timeitems so I can move them all together in the Gantt?

Answer

Yes. When the user holds the ctrl key, the selected property of clicked time items will be toggled. When the user drag time items all with the Selected=true is moved the same distance.

 

10812 : Is there a basic example on how to use OnVirtualLoad_GantTime?

Question

Question:Is there a basic example on how to use OnVirtualLoad_GantTime. I found one for the Grid, but not the GantTimes. I am using the phGantTimePackage for VCL v3.2.1.

Thanks in Advance,

Answer

Actually there is no specific virtual load solution for the Time items. Partly because the time axis is easier to handle with normal events than the Grid-Y axis. The grid Y axis suffers from all kinds of problems when wanting to make it appear to have more information that it really has; like the scroll bar for example.

The time axis is easier in that respect. You can implement the phGant.OnScalerChange () event and simple check what visual span you have. Based in that you can delete data (Gantt time items) no longer needed and fetch new ones.

This could be packaged as a Virtual Load mechanism for time items, but it is currently not.

10888 : I would like to apply a vertical stripe to a specific day (or days)

Question

I would like to apply a ‘vertical stripe’ to a specific day (or days), I want to use this to show non working (or holidays) using the same technique you use for painting your vertical stripes. How can I achieve this please.

Answer

In order to do this you must know when a day starts and stops in pixels, this is easily found by sending in a datetime to the Gantt.DateScaler.TimeToPixel method.

So in pseudo code I would go like this:

In the implementation of the OnTimeItemAreaPaintBackground event

int numberOfDaysOnScreen=Round(Gantt.StopTime-Gantt.StartTime)
for i=0 to numberOfDaysOnScreen-1 do
begin
  DateTime oneDay=Gantt.StartTime+i
  Color c=GetColorForThisDay(oneDay)
  int PixelForStartOfDay=Gantt.DateScaler.TimeToPixel(Trunc(oneDay))
  int PixelForEndOfDay=Gantt.DateScaler.TimeToPixel(Trunc(oneDay)+1)
  DrawColoredRectangle(PixelForStartOfDay,0,PixelForEndOfDay,Gantt.Height)
end

 

10886 : I would like to color columns for certain days in a different color with the phGantTimePackage.

Question

Hi, I’d like to color columns for certain days in a different color with the phGantTimePackage. Could you pleace provide an example on how to achieve this with the OnGantAreaDrawBackground handler?

Thanks!

Answer

In order to do this you must know when a day starts and stops in pixels, this is easily found by sending in a datetime to the IphGantX3.DateToPixel method.

So in pseudo code I would go like this:

int numberOfDaysOnScreen=Round(phGant.Stop-phGant.Start)
for i=0 to numberOfDaysOnScreen-1 do
begin
  DateTime oneDay=phGantt.Start+i
  Color c=GetColorForThisDay(oneDay)
  int PixelForStartOfDay=phGantt.DateToPixel(Trunc(oneDay))
  int PixelForEndOfDay=phGantt.DateToPixel(Trunc(oneDay)+1)
  DrawColoredRectangle(PixelForStartOfDay,0,PixelForEndOfDay,Gantt.Height)
end

10702 : I would like more control over the appearance of Links.

Question

I would like more control over the appearance of Links. I have been attempting to use the OnUserDrawLinks with limited success. Are there any examples (Delphi preferred) of how to use OnUserDrawLinks?

Answer

Drawing links so that they look good in all situtions is hard. That is partly why we left a door open for you with the user draw link event.

This is our code to draw links:


procedure TphGant_ComBasic.DrawLink(theStartPoint,theStopPoint:TPoint;
  theCanvas:TCanvas;theLinkStyle:TLinkStyle; theLinkColor:TColor;theLinkPenWidth: Integer;
  aDataEntity_Link:TphDataEntity_Link);
var
  aMiddlePoint, aNewStopPoint:TPoint;
  cLRArr, cUDArr ,cOri,ssFold,ssMinDist, OldPenWidth:Integer;
  aColor : TColor;
begin
  OldPenWidth := theCanvas.Pen.Width;
  try
    theCanvas.Pen.Color := theLinkColor;
    theCanvas.Pen.Width := theLinkPenWidth;
    theCanvas.MoveTo(theStartPoint.X,theStartPoint.Y);
    cLRArr := 3;
    cUDArr := 3;
    cOri:=1;
    ssMinDist:=7;
    if GA.IsPrinting then
    begin
      cLRArr := Round(3*GA.Scalex);
      cUDArr := Round(3*GA.Scaley);
      ssMinDist:=Round(ssMinDist*GA.Scalex);
    end;

    aNewStopPoint := theStopPoint;

    if Assigned(aDataEntity_Link) and (aDataEntity_Link.StartFinishOption=tlsfSS) then
    begin
      // tlsfSS is treated the same way for tlsDefault and tlsMSProject
      if theStartPoint.X>theStopPoint.X then
        ssFold:=theStopPoint.X-ssMinDist
      else
        ssFold:=theStartPoint.X-ssMinDist;

      theCanvas.LineTo(ssFold,theStartPoint.Y);
      theCanvas.LineTo(ssFold,aNewStopPoint.Y);
      theCanvas.LineTo(aNewStopPoint.X,aNewStopPoint.Y);

      theLinkStyle:=tlsDefault;
    end
    else
    begin

      case theLinkStyle of
        tlsDefault:
    begin
      if theStartPoint.X>theStopPoint.X then
              cOri:=-1;
            // Moves horizonatal endpoint one extra pixel to get get nicer looking arrows
            aNewStopPoint.X := theStopPoint.X-cOri;
            // This code draws the line cut in three parts - horizontal - vertical - horizontal
            aMiddlePoint.X:=theStartPoint.X+((aNewStopPoint.X-theStartPoint.X) div 2);
            aMiddlePoint.Y:=theStartPoint.Y+((aNewStopPoint.Y-theStartPoint.Y) div 2);
            theCanvas.LineTo(aMiddlePoint.X,theStartPoint.Y);
            theCanvas.LineTo(aMiddlePoint.X,aNewStopPoint.Y);
            theCanvas.LineTo(aNewStopPoint.X,aNewStopPoint.Y);
          end;
        tlsMSProject:
          begin
            if theStartPoint.Y<theStopPoint.Y then
              cOri:=-1;
            if theStartPoint.X < theStopPoint.X then
              aNewStopPoint.X := theStopPoint.X + cUDArr  // Moves endpoint horizontal get the arrow "inside" the box
            else
              aNewStopPoint.X := theStopPoint.X - cUDArr; // Moves endpoint horizontal get the arrow "inside" the box
            // Moves endpoint one extra pixel up/down to get nicer looking arrows
            aNewStopPoint.Y := theStopPoint.Y+cOri;
            // Draw horizontal line, then downwards to the recieving point
            theCanvas.LineTo(aNewStopPoint.X,theStartPoint.Y);
            theCanvas.LineTo(aNewStopPoint.X,aNewStopPoint.Y+cUDArr*cOri);
          end;
      end;
    end;
    // Don't draw the arrow if we are "out of bounds"
    if PointInRect( aNewStopPoint, theCanvas.ClipRect ) then
    begin
      case theLinkStyle of
        tlsDefault:
          begin
            // This code draws the arrow
            theCanvas.LineTo(aNewStopPoint.X-cLRArr*cOri,aNewStopPoint.Y-cLRArr);
            theCanvas.LineTo(aNewStopPoint.X-cLRArr*cOri,aNewStopPoint.Y+cLRArr);
            theCanvas.LineTo(aNewStopPoint.X,aNewStopPoint.Y);
          end;
        tlsMSProject:
          begin
            // This code draws the arrow downwards or upwards!
            aColor := theCanvas.Brush.Color;
            theCanvas.Brush.Color := theLinkColor;
            theCanvas.Polygon( [
              Point(aNewStopPoint.X,aNewStopPoint.Y),
              Point(aNewStopPoint.X-cUDArr,aNewStopPoint.Y+cUDArr*cOri),
              Point(aNewStopPoint.X+cUDArr,aNewStopPoint.Y+cUDArr*cOri)
              ] );
            theCanvas.Brush.Color := aColor;
          end;
      end;
    end;
  finally
    theCanvas.Pen.Width := OldPenWidth;
  end;
end;