jpgraph_gantt.php

来自「eGroupWare is a multi-user, web-based gr」· PHP 代码 · 共 1,445 行 · 第 1/4 页

PHP
1,445
字号
<?php
/*=======================================================================
// File:	JPGRAPH_GANTT.PHP
// Description:	JpGraph Gantt plot extension
// Created: 	2001-11-12
// Author:	Johan Persson (johanp@aditus.nu)
// Ver:		$Id: jpgraph_gantt.php,v 1.6 2004/06/01 10:38:37 lkneschke Exp $
//
// License:	This code is released under GPL 2.0
//
//========================================================================
*/

// Scale Header types
DEFINE("GANTT_HDAY",1);
DEFINE("GANTT_HWEEK",2);
DEFINE("GANTT_HMONTH",4);
DEFINE("GANTT_HYEAR",8);

// Bar patterns
DEFINE("GANTT_RDIAG",BAND_RDIAG);	// Right diagonal lines
DEFINE("GANTT_LDIAG",BAND_LDIAG); // Left diagonal lines
DEFINE("GANTT_SOLID",BAND_SOLID); // Solid one color
DEFINE("GANTT_VLINE",BAND_VLINE); // Vertical lines
DEFINE("GANTT_HLINE",BAND_HLINE);  // Horizontal lines
DEFINE("GANTT_3DPLANE",BAND_3DPLANE);  // "3D" Plane
DEFINE("GANTT_HVCROSS",BAND_HVCROSS);  // Vertical/Hor crosses
DEFINE("GANTT_DIAGCROSS",BAND_DIAGCROSS); // Diagonal crosses

// Conversion constant
DEFINE("SECPERDAY",3600*24);

// Locales
DEFINE("LOCALE_EN",0);
DEFINE("LOCALE_SE",1);
DEFINE("LOCALE_DE",2);

// Layout of bars
DEFINE("GANTT_EVEN",1);
DEFINE("GANTT_FROMTOP",2);

// Styles for week header
DEFINE("WEEKSTYLE_WNBR",0);
DEFINE("WEEKSTYLE_FIRSTDAY",1);
DEFINE("WEEKSTYLE_FIRSTDAY2",1);

// Styles for month header
DEFINE("MONTHSTYLE_SHORTNAME",0);
DEFINE("MONTHSTYLE_LONGNAME",1);
DEFINE("MONTHSTYLE_LONGNAMEYEAR2",2);
DEFINE("MONTHSTYLE_SHORTNAMEYEAR2",3);
DEFINE("MONTHSTYLE_LONGNAMEYEAR4",4);
DEFINE("MONTHSTYLE_SHORTNAMEYEAR4",5);

//===================================================
// CLASS DateLocale
// Description: Hold localized text used in dates
// ToDOo: Rewrite this to use the real local locale
// instead.
//===================================================
class DateLocale {
    var $iLocale=0; 	// Default to english
    var $iDayAbb = array(
	array("M","T","W","T","F","S","S"),			// English locale
	array("M","T","O","T","F","L","S"),			// Swedish locale
	array("M","D","M","D","F","S","S"));			// German locale
    var $iShortDay = array(
	array("Mon","Tue","Wed","Thu","Fri","Sat","Sun"),
	array("M錸","Tis","Ons","Tor","Fre","L鰎","S鰊"),
	array("Mon","Die","Mit","Don","Fre","Sam","Son"));
    var $iShortMonth = array(
	array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"),
	array("Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"),
	array("Jan","Feb","M鋜","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"));
    var $iMonthName = array(
	array("January","February","Mars","April","May","June","July","August","September","October","November","December"),
	array("Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"),
	array("Januar","Februar","M鋜z","April","Mai","Juni","July","August","September","Oktober","November","Dezember"));
	
//---------------
// CONSTRUCTOR	
    function DateLocale() {
	// Empty
    }

//---------------
// PUBLIC METHODS	
    function Set($aLocale) {
	if( $aLocale < LOCALE_EN || $aLocale > LOCALE_DE )
	    JpGraphError::Raise("<b>JpGraph Error:</b> Unsupported locale ($aLocale)");
	$this->iLocale = $aLocale;
    }
	
    function GetDayAbb() {
	return $this->iDayAbb[$this->iLocale];
    }
	
    function GetShortDay() {
	return $this->iShortDay[$this->iLocale];
    }

    function GetShortMonth($aMonth=null) {
	return $this->iShortMonth[$this->iLocale];
    }
	
    function GetShortMonthName($aNbr) {
	return $this->iShortMonth[$this->iLocale][$aNbr];
    }

    function GetLongMonthName($aNbr) {
	return $this->iMonthName[$this->iLocale][$aNbr];
    }

    function GetMonth() {
	return $this->iMonthName[$this->iLocale];
    }
}

//===================================================
// CLASS GanttGraph
// Description: Main class to handle gantt graphs
//===================================================
class GanttGraph extends Graph {
    var $scale;							// Public accessible
    var $iObj=array();				// Gantt objects
    var $iLabelHMarginFactor=0.2;	// 10% margin on each side of the labels
    var $iLabelVMarginFactor=0.4;	// 40% margin on top and bottom of label
    var $iLayout=GANTT_FROMTOP;	// Could also be GANTT_EVEN

//---------------
// CONSTRUCTOR	
    // Create a new gantt graph
    function GanttGraph($aWidth=-1,$aHeight=-1,$aCachedName="",$aTimeOut=0,$aInline=true) {
	Graph::Graph($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline);		
	$this->scale = new GanttScale($this->img);
	$this->img->SetMargin($aWidth/17,$aWidth/17,$aHeight/7,$aHeight/10);
		
	$this->scale->ShowHeaders(GANTT_HWEEK|GANTT_HDAY);
	$this->SetBox();
    }
	
//---------------
// PUBLIC METHODS	
    // Set what headers should be shown
    function ShowHeaders($aFlg) {
	$this->scale->ShowHeaders($aFlg);
    }
	
    // Specify the fraction of the font height that should be added 
    // as vertical margin
    function SetLabelVMarginFactor($aVal) {
	$this->iLabelVMarginFactor = $aVal;
    }
	
    // Add a new Gantt object
    function Add(&$aObject) {
	if( is_array($aObject) ) {
	    for($i=0; $i<count($aObject); ++$i)
		$this->iObj[] = $aObject[$i];
	}
	else
	    $this->iObj[] = $aObject;
    }

    // Override inherit method from Graph and give a warning message
    function SetScale() {
	JpGraphError::Raise("<b>JpGraph Error:</b> SetScale() is not meaningfull with Gantt charts.");
	// Empty
    }

    // Specify the date range for Gantt graphs (if this is not set it will be
    // automtically determined from the input data)
    function SetDateRange($aStart,$aEnd) {
	$this->scale->SetRange($aStart,$aEnd);
    }
	
    // Get the maximum width of the titles for the bars	
    function GetMaxLabelWidth() {
	$m=0;
	if( $this->iObj != null ) {
	    $m = $this->iObj[0]->title->GetWidth($this->img);
	    for($i=1; $i<count($this->iObj); ++$i) {
		if( $this->iObj[$i]->title->HasTabs() ) {
		    list($tot,$w) = $this->iObj[$i]->title->GetWidth($this->img,true);
		    $m=max($m,$tot);
		}
		else 
		    $m=max($m,$this->iObj[$i]->title->GetWidth($this->img));
	    }
	}
	return $m;
    }
	
    // Get the maximum height of the titles for the bars
    function GetMaxLabelHeight() {
	$m=0;
	if( $this->iObj != null ) {
	    $m = $this->iObj[0]->title->GetHeight($this->img);
	    for($i=1; $i<count($this->iObj); ++$i) {
		$m=max($m,$this->iObj[$i]->title->GetHeight($this->img));
	    }
	}
	return $m;
    }

    function GetMaxBarAbsHeight() {
	$m=0;
	if( $this->iObj != null ) {
	    $m = $this->iObj[0]->GetAbsHeight($this->img);
	    for($i=1; $i<count($this->iObj); ++$i) {
		$m=max($m,$this->iObj[$i]->GetAbsHeight($this->img));
	    }
	}
	return $m;		
    }
	
    // Get the maximum used line number (vertical position) for bars
    function GetBarMaxLineNumber() {
	$m=0;
	if( $this->iObj != null ) {
	    $m = $this->iObj[0]->GetLineNbr();
	    for($i=1; $i<count($this->iObj); ++$i) {
		$m=max($m,$this->iObj[$i]->GetLineNbr());
	    }
	}
	return $m;
    }
	
    // Get the minumum and maximum used dates for all bars
    function GetBarMinMax() {
	$max=$this->scale->NormalizeDate($this->iObj[0]->GetMaxDate());
	$min=$this->scale->NormalizeDate($this->iObj[0]->GetMinDate());
	for($i=1; $i<count($this->iObj); ++$i) {
	    $max=Max($max,$this->scale->NormalizeDate($this->iObj[$i]->GetMaxDate()));
	    $min=Min($min,$this->scale->NormalizeDate($this->iObj[$i]->GetMinDate()));
	}
	$minDate = date("Y-m-d",$min);
	$min = strtotime($minDate);
	$maxDate = date("Y-m-d",$max);
	$max = strtotime($maxDate);	
	return array($min,$max);
    }

    // Stroke the gantt chart
    function Stroke($aStrokeFileName="") {	

	// Should we autoscale dates?
	if( !$this->scale->IsRangeSet() ) {
	    list($min,$max) = $this->GetBarMinMax();
	    $this->scale->SetRange($min,$max);
	}
		
	if( $this->img->img == null ) {
	    // The predefined left, right, top, bottom margins.
	    // Note that the top margin might incease depending on
	    // the title.
	    $lm=30;$rm=30;$tm=20;$bm=30;			
	    if( BRAND_TIMING ) $bm += 10;
			
	    // First find out the height			
	    $n=$this->GetBarMaxLineNumber()+1;
	    $m=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight());
	    $height=$n*((1+$this->iLabelVMarginFactor)*$m);			
			
	    // Add the height of the scale titles			
	    $h=$this->scale->GetHeaderHeight();
	    $height += $h;

	    // Calculate the top margin needed for title and subtitle
	    if( $this->title->t != "" ) {
		$tm += $this->title->GetFontHeight($this->img);
	    }
	    if( $this->subtitle->t != "" ) {
		$tm += $this->subtitle->GetFontHeight($this->img);
	    }

	    // ...and then take the bottom and top plot margins into account
	    $height += $tm + $bm + $this->scale->iTopPlotMargin + $this->scale->iBottomPlotMargin;
			
	    // Now find the minimum width for the chart required
	    $fw=$this->scale->day->GetFontWidth($this->img)+4;
	    $nd=$this->scale->GetNumberOfDays();
	    if( !$this->scale->IsDisplayDay() ) {
				// If we don't display the individual days we can shrink the
				// scale a little bit. This is a little bit pragmatic at the 
				// moment and should be re-written to take into account
				// a) What scales exactly are shown and 
				// b) what format do they use so we know how wide we need to
				// make each scale text space at minimum.
		$fw /= 2;
		if( !$this->scale->IsDisplayWeek() ) {
		    $fw /= 1.8;
		}
	    }
			
	    // Now determine the width for the activity titles column
	    // This is complicated by the fact that the titles may have
	    // tabs. In that case we also need to calculate the individual
	    // tab positions based on the width of the individual columns
			
	    $titlewidth = $this->GetMaxLabelWidth();
						
	    // Now get the total width taking 
	    // titlewidth, left and rigt margin, dayfont size 
	    // into account
	    $width = $titlewidth + $nd*$fw + $lm+$rm;
						
	    $this->img->CreateImgCanvas($width,$height);			
	    $this->img->SetMargin($lm,$rm,$tm,$bm);
	}
		
	// Should we start from the top or just spread the bars out even over the
	// available height
	$this->scale->SetVertLayout($this->iLayout);			
	if( $this->iLayout == GANTT_FROMTOP ) {
	    $maxheight=max($this->GetMaxLabelHeight(),$this->GetMaxBarAbsHeight());
	    $this->scale->SetVertSpacing($maxheight*(1+$this->iLabelVMarginFactor));
	}
	// If it hasn't been set find out the maximum line number
	if( $this->scale->iVertLines == -1 ) 
	    $this->scale->iVertLines = $this->GetBarMaxLineNumber()+1; 	
		
	$maxwidth=max($this->GetMaxLabelWidth(),$this->scale->tableTitle->GetWidth($this->img));
	$this->scale->SetLabelWidth($maxwidth*(1+$this->iLabelHMarginFactor));
	$this->StrokePlotArea();
	$this->scale->Stroke();
	$this->StrokePlotBox();
		
	for($i=0; $i<count($this->iObj); ++$i) {
	    $this->iObj[$i]->SetLabelLeftMargin(round($maxwidth*$this->iLabelHMarginFactor/2));
	    $this->iObj[$i]->Stroke($this->img,$this->scale);
	}
		
	$this->StrokeTitles();
	$this->cache->PutAndStream($this->img,$this->cache_name,$this->inline,$aStrokeFileName);				
    }
}

//===================================================
// CLASS TextProperty
// Description: Holds properties for a text
//===================================================
class TextProperty {
    var $iFFamily=FF_FONT1,$iFStyle=FS_NORMAL,$iFSize=10;
    var $iColor="black";
    var $iShow=true;
    var $iText="";
    var $iHAlign="left",$iVAlign="bottom";
	
//---------------
// CONSTRUCTOR	
    function TextProperty($aTxt="") {
	$this->iText = $aTxt;
    }		
	
//---------------
// PUBLIC METHODS	
    function Set($aTxt) {
	$this->iText = $aTxt;
    }
	
    // Set text color

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?