diff --git a/.travis.yml b/.travis.yml
index 5e7030aade6..6743bf93f6a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -79,7 +79,8 @@ before_script:
#script: phpunit -d memory_limit=-1 --configuration test/phpunit/phpunittest.xml test/phpunit/WebservicesOtherTest.php
#script: phpcs -s --report-checkstyle --report-summary --standard=dev/codesniffer/ruleset.xml --tab-width=4 --ignore=/build/html/,/documents/,/includes/,/test/report/ .
script:
- - phpcs -s --report-checkstyle --report-summary --standard=dev/codesniffer/ruleset.xml --tab-width=4 --ignore=/build/html/,/documents/,/includes/,/test/report/ .
+ - phpcs -s --report-checkstyle --report-checkstyle --report-summary --standard=dev/codesniffer/ruleset.xml --tab-width=4 --ignore=/build/html/,/documents/,/includes/,/test/report/ htdocs/core/class/dolgraph.class.php
+# - phpcs -s --report-checkstyle --report-summary --standard=dev/codesniffer/ruleset.xml --tab-width=4 --ignore=/build/html/,/documents/,/includes/,/test/report/ .
- phpunit -d memory_limit=-1 --configuration test/phpunit/phpunittest.xml test/phpunit/AllTests.php
after_script:
diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php
index 8c6eba6e894..ba22ff22c65 100644
--- a/htdocs/core/class/dolgraph.class.php
+++ b/htdocs/core/class/dolgraph.class.php
@@ -23,8 +23,8 @@
*
* Usage:
* $graph_data = array(array('labelxA',yA),array('labelxB',yB));
- * $graph_data = array(array('labelxA',yA1,...,yAn),array('labelxB',yB1,...yBn)); // when there is n value to show for each x
- * $legend = array("Val1",...,"Valn"); // list of n series name
+ * $graph_data = array(array('labelxA',yA1,...,yAn),array('labelxB',yB1,...yBn)); when there is n value to show for each x
+ * $legend = array("Val1",...,"Valn"); list of n series name
* $px = new DolGraph();
* $px->SetData($graph_data);
* $px->SetMaxValue($px->GetCeilMaxValue());
@@ -38,842 +38,845 @@
/**
- * Parent class of graph classes
+ * Parent class of graph classes
*/
class DolGraph
{
- //! Type of graph
- var $type=array(); // Array with type of each series. Example: array('bars', 'lines', ...)
- var $mode='side'; // Mode bars graph: side, depth
- private $_library='jflot'; // Graphic library to use (jflot, artichow)
+ //! Type of graph
+ var $type=array(); // Array with type of each series. Example: array('bars', 'lines', ...)
+ var $mode='side'; // Mode bars graph: side, depth
+ private $_library='jflot'; // Graphic library to use (jflot, artichow)
- //! Array of data
- var $data; // Data of graph: array(array('abs1',valA1,valB1), array('abs2',valA2,valB2), ...)
- var $title; // Title of graph
- var $cssprefix=''; // To add into css styles
- var $width=380;
- var $height=200;
- var $MaxValue=0;
- var $MinValue=0;
- var $SetShading=0;
+ //! Array of data
+ var $data; // Data of graph: array(array('abs1',valA1,valB1), array('abs2',valA2,valB2), ...)
+ var $title; // Title of graph
+ var $cssprefix=''; // To add into css styles
+ var $width=380;
+ var $height=200;
+ var $MaxValue=0;
+ var $MinValue=0;
+ var $SetShading=0;
- var $PrecisionY=-1;
+ var $PrecisionY=-1;
- var $horizTickIncrement=-1;
- var $SetNumXTicks=-1;
- var $labelInterval=-1;
+ var $horizTickIncrement=-1;
+ var $SetNumXTicks=-1;
+ var $labelInterval=-1;
- var $hideXGrid=false;
- var $hideYGrid=false;
+ var $hideXGrid=false;
+ var $hideYGrid=false;
- var $Legend=array();
- var $LegendWidthMin=0;
- var $showlegend=1;
+ var $Legend=array();
+ var $LegendWidthMin=0;
+ var $showlegend=1;
var $showpointvalue=1;
var $showpercent=0;
- var $graph; // Objet Graph (Artichow, Phplot...)
- var $error;
-
- var $bordercolor; // array(R,G,B)
- var $bgcolor; // array(R,G,B)
- var $bgcolorgrid=array(255,255,255); // array(R,G,B)
- var $datacolor; // array(array(R,G,B),...)
-
- private $_stringtoshow; // To store string to output graph into HTML page
-
-
- /**
- * Constructor
- */
- function __construct()
- {
- global $conf;
- global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet;
-
- // To use old feature
- if (isset($conf->global->MAIN_GRAPH_LIBRARY) && $conf->global->MAIN_GRAPH_LIBRARY == 'artichow')
- {
- $this->_library='artichow';
-
- // Test if module GD present
- $modules_list = get_loaded_extensions();
- $isgdinstalled=0;
- foreach ($modules_list as $module)
- {
- if ($module == 'gd') $isgdinstalled=1;
- }
- if (! $isgdinstalled)
- {
- $this->error="Error: PHP GD module is not available. It is required to build graphics.";
- return -1;
- }
- }
-
- $this->bordercolor = array(235,235,224);
- $this->datacolor = array(array(120,130,150), array(160,160,180), array(190,190,220));
- $this->bgcolor = array(235,235,224);
-
- $color_file = DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/graph-color.php';
- if (is_readable($color_file))
- {
- include_once $color_file;
- if (isset($theme_bordercolor)) $this->bordercolor = $theme_bordercolor;
- if (isset($theme_datacolor)) $this->datacolor = $theme_datacolor;
- if (isset($theme_bgcolor)) $this->bgcolor = $theme_bgcolor;
- }
- //print 'bgcolor: '.join(',',$this->bgcolor).'
';
- return 1;
- }
-
-
- /**
- * Set Y precision
- *
- * @param float $which_prec Precision
- * @return string
- */
- function SetPrecisionY($which_prec)
- {
- $this->PrecisionY = $which_prec;
- return true;
- }
-
- /**
- * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
- *
- * @param float $xi Xi
- * @return boolean True
- */
- function SetHorizTickIncrement($xi)
- {
- $this->horizTickIncrement = $xi;
- return true;
- }
-
- /**
- * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
- *
- * @param float $xt Xt
- * @return boolean True
- */
- function SetNumXTicks($xt)
- {
- $this->SetNumXTicks = $xt;
- return true;
- }
-
- /**
- * Set label interval to reduce number of labels
- *
- * @param float $x Label interval
- * @return boolean True
- */
- function SetLabelInterval($x)
- {
- $this->labelInterval = $x;
- return true;
- }
-
- /**
- * Hide X grid
- *
- * @param boolean $bool XGrid or not
- * @return boolean true
- */
- function SetHideXGrid($bool)
- {
- $this->hideXGrid = $bool;
- return true;
- }
-
- /**
- * Hide Y grid
- *
- * @param boolean $bool YGrid or not
- * @return boolean true
- */
- function SetHideYGrid($bool)
- {
- $this->hideYGrid = $bool;
- return true;
- }
-
- /**
- * Set y label
- *
- * @param string $label Y label
- * @return boolean True
- */
- function SetYLabel($label)
- {
- $this->YLabel = $label;
- }
-
- /**
- * Set width
- *
- * @param int $w Width
- * @return boolean True
- */
- function SetWidth($w)
- {
- $this->width = $w;
- }
-
- /**
- * Set title
- *
- * @param string $title Title
- * @return void
- */
- function SetTitle($title)
- {
- $this->title = $title;
- }
-
- /**
- * Set data
- *
- * @param array $data Data
- * @return void
- * @see draw_jflot for syntax of data array
- */
- function SetData($data)
- {
- $this->data = $data;
- }
-
- /**
- * Set data
- *
- * @param array $datacolor Data color array(array(R,G,B),array(R,G,B)...)
- * @return void
- */
- function SetDataColor($datacolor)
- {
- $this->datacolor = $datacolor;
- }
-
- /**
- * Set type
- *
- * @param array $type Array with type for each serie. Example: array('pie'), array('lines',...,'bars')
- * @return void
- */
- function SetType($type)
- {
- $this->type = $type;
- }
-
- /**
- * Set legend
- *
- * @param string $legend Legend
- * @return void
- */
- function SetLegend($legend)
- {
- $this->Legend = $legend;
- }
-
- /**
- * Set min width
- *
- * @param int $legendwidthmin Min width
- * @return void
- */
- function SetLegendWidthMin($legendwidthmin)
- {
- $this->LegendWidthMin = $legendwidthmin;
- }
-
- /**
- * Set max value
- *
- * @param int $max Max value
- * @return void
- */
- function SetMaxValue($max)
- {
- $this->MaxValue = $max;
- }
-
- /**
- * Get max value
- *
- * @return int Max value
- */
- function GetMaxValue()
- {
- return $this->MaxValue;
- }
-
- /**
- * Set min value
- *
- * @param int $min Min value
- * @return void
- */
- function SetMinValue($min)
- {
- $this->MinValue = $min;
- }
-
- /**
- * Get min value
- *
- * @return int Max value
- */
- function GetMinValue()
- {
- return $this->MinValue;
- }
-
- /**
- * Set height
- *
- * @param int $h Height
- * @return void
- */
- function SetHeight($h)
- {
- $this->height = $h;
- }
-
- /**
- * Set shading
- *
- * @param string $s Shading
- * @return void
- */
- function SetShading($s)
- {
- $this->SetShading = $s;
- }
-
- /**
- * Set shading
- *
- * @param string $s Shading
- * @return void
- */
- function SetCssPrefix($s)
- {
- $this->cssprefix = $s;
- }
-
- /**
- * Reset bg color
- *
- * @return void
- */
- function ResetBgColor()
- {
- unset($this->bgcolor);
- }
-
- /**
- * Reset bgcolorgrid
- *
- * @return void
- */
- function ResetBgColorGrid()
- {
- unset($this->bgcolorgrid);
- }
-
- /**
- * Is graph ko
- *
- * @return string Error
- */
- function isGraphKo()
- {
- return $this->error;
- }
-
- /**
- * Show legend or not
- *
- * @param int $showlegend 1=Show legend (default), 0=Hide legend
- * @return void
- */
- function setShowLegend($showlegend)
- {
- $this->showlegend=$showlegend;
- }
-
- /**
- * Show pointvalue or not
- *
- * @param int $showpointvalue 1=Show value for each point, as tooltip or inline (default), 0=Hide value
- * @return void
- */
- function setShowPointValue($showpointvalue)
- {
- $this->showpointvalue=$showpointvalue;
- }
-
- /**
- * Show percent or not
- *
- * @param int $showpercent 1=Show percent for each point, as tooltip or inline, 0=Hide percent (default)
- * @return void
- */
- function setShowPercent($showpercent)
- {
- $this->showpercent=$showpercent;
- }
-
-
-
- /**
- * Define background color of complete image
- *
- * @param array $bg_color array(R,G,B) ou 'onglet' ou 'default'
- * @return void
- */
- function SetBgColor($bg_color = array(255,255,255))
- {
- global $theme_bgcolor,$theme_bgcoloronglet;
-
- if (! is_array($bg_color))
- {
- if ($bg_color == 'onglet')
- {
- //print 'ee'.join(',',$theme_bgcoloronglet);
- $this->bgcolor = $theme_bgcoloronglet;
- }
- else
- {
- $this->bgcolor = $theme_bgcolor;
- }
- }
- else
- {
- $this->bgcolor = $bg_color;
- }
- }
-
- /**
- * Define background color of grid
- *
- * @param array $bg_colorgrid array(R,G,B) ou 'onglet' ou 'default'
- * @return void
- */
- function SetBgColorGrid($bg_colorgrid = array(255,255,255))
- {
- global $theme_bgcolor,$theme_bgcoloronglet;
-
- if (! is_array($bg_colorgrid))
- {
- if ($bg_colorgrid == 'onglet')
- {
- //print 'ee'.join(',',$theme_bgcoloronglet);
- $this->bgcolorgrid = $theme_bgcoloronglet;
- }
- else
- {
- $this->bgcolorgrid = $theme_bgcolor;
- }
- }
- else
- {
- $this->bgcolorgrid = $bg_colorgrid;
- }
- }
-
- /**
- * Reset data color
- *
- * @return void
- */
- function ResetDataColor()
- {
- unset($this->datacolor);
- }
-
- /**
- * Get max value
- *
- * @return int Max value
- */
- function GetMaxValueInData()
- {
- $k = 0;
- $vals = array();
-
- $nblines = count($this->data);
- $nbvalues = count($this->data[0]) - 1;
-
- for ($j = 0 ; $j < $nblines ; $j++)
- {
- for ($i = 0 ; $i < $nbvalues ; $i++)
- {
- $vals[$k] = $this->data[$j][$i+1];
- $k++;
- }
- }
- rsort($vals);
- return $vals[0];
- }
-
- /**
- * Return min value of all data
- *
- * @return int Min value of all data
- */
- function GetMinValueInData()
- {
- $k = 0;
- $vals = array();
-
- $nblines = count($this->data);
- $nbvalues = count($this->data[0]) - 1;
-
- for ($j = 0 ; $j < $nblines ; $j++)
- {
- for ($i = 0 ; $i < $nbvalues ; $i++)
- {
- $vals[$k] = $this->data[$j][$i+1];
- $k++;
- }
- }
- sort($vals);
- return $vals[0];
- }
-
- /**
- * Return max value of all data
- *
- * @return int Max value of all data
- */
- function GetCeilMaxValue()
- {
- $max = $this->GetMaxValueInData();
- if ($max != 0) $max++;
- $size=dol_strlen(abs(ceil($max)));
- $factor=1;
- for ($i=0; $i < ($size-1); $i++)
- {
- $factor*=10;
- }
-
- $res=0;
- if (is_numeric($max)) $res=ceil($max/$factor)*$factor;
-
- //print "max=".$max." res=".$res;
- return $res;
- }
-
- /**
- * Return min value of all data
- *
- * @return int Max value of all data
- */
- function GetFloorMinValue()
- {
- $min = $this->GetMinValueInData();
- if ($min != 0) $min--;
- $size=dol_strlen(abs(floor($min)));
- $factor=1;
- for ($i=0; $i < ($size-1); $i++)
- {
- $factor*=10;
- }
-
- $res=floor($min/$factor)*$factor;
-
- //print "min=".$min." res=".$res;
- return $res;
- }
-
- /**
- * Build a graph onto disk using correct library
- *
- * @param string $file Image file name to use to save onto disk (also used as javascript unique id)
- * @param string $fileurl Url path to show image if saved onto disk
- * @return void
- */
- function draw($file,$fileurl='')
- {
- if (empty($file))
- {
- $this->error="Call to draw method was made with empty value for parameter file.";
- dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR);
- return -2;
- }
- if (! is_array($this->data) || count($this->data) < 1)
- {
- $this->error="Call to draw method was made but SetData was not called or called with an empty dataset for parameters";
- dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR);
- return -1;
- }
- $call = "draw_".$this->_library;
- call_user_func_array(array($this,$call), array($file,$fileurl));
- }
-
-
- /**
- * Build a graph onto disk using Artichow library
- *
- * @param string $file Image file name to use if we save onto disk
- * @param string $fileurl Url path to show image if saved onto disk
- * @return void
- */
- private function draw_artichow($file,$fileurl)
- {
- global $artichow_defaultfont;
-
- dol_syslog(get_class($this)."::draw_artichow this->type=".join(',',$this->type));
-
- if (! defined('SHADOW_RIGHT_TOP')) define('SHADOW_RIGHT_TOP',3);
- if (! defined('LEGEND_BACKGROUND')) define('LEGEND_BACKGROUND',2);
- if (! defined('LEGEND_LINE')) define('LEGEND_LINE',1);
-
- // Create graph
- $classname='';
- if (! isset($this->type[0]) || $this->type[0] == 'bars') $classname='BarPlot'; // Only one type (first one) is supported by artichow
- else if ($this->type[0] == 'lines') $classname='LinePlot';
- else $classname='TypeUnknown';
- include_once ARTICHOW_PATH.$classname.'.class.php';
-
- // Definition de couleurs
- $bgcolor=new Color($this->bgcolor[0],$this->bgcolor[1],$this->bgcolor[2]);
- $bgcolorgrid=new Color($this->bgcolorgrid[0],$this->bgcolorgrid[1],$this->bgcolorgrid[2]);
- $colortrans=new Color(0,0,0,100);
- $colorsemitrans=new Color(255,255,255,60);
- $colorgradient= new LinearGradient(new Color(235, 235, 235),new Color(255, 255, 255),0);
- $colorwhite=new Color(255,255,255);
-
- // Graph
- $graph = new Graph($this->width, $this->height);
- $graph->border->hide();
- $graph->setAntiAliasing(true);
- if (isset($this->title))
- {
- $graph->title->set($this->title);
- //print $artichow_defaultfont;exit;
- $graph->title->setFont(new $artichow_defaultfont(10));
- }
-
- if (is_array($this->bgcolor)) $graph->setBackgroundColor($bgcolor);
- else $graph->setBackgroundGradient($colorgradient);
-
- $group = new PlotGroup;
- //$group->setSpace(5, 5, 0, 0);
-
- $paddleft=50;
- $paddright=10;
- $strl=dol_strlen(max(abs($this->MaxValue),abs($this->MinValue)));
- if ($strl > 6) $paddleft += ($strl * 4);
- $group->setPadding($paddleft, $paddright); // Width on left and right for Y axis values
- $group->legend->setSpace(0);
- $group->legend->setPadding(2,2,2,2);
- $group->legend->setPosition(NULL,0.1);
- $group->legend->setBackgroundColor($colorsemitrans);
-
- if (is_array($this->bgcolorgrid)) $group->grid->setBackgroundColor($bgcolorgrid);
- else $group->grid->setBackgroundColor($colortrans);
-
- if ($this->hideXGrid) $group->grid->hideVertical(true);
- if ($this->hideYGrid) $group->grid->hideHorizontal(true);
-
- // On boucle sur chaque lot de donnees
- $legends=array();
- $i=0;
- $nblot=count($this->data[0])-1;
-
- while ($i < $nblot)
- {
- $x=0;
- $values=array();
- foreach($this->data as $key => $valarray)
- {
- $legends[$x] = $valarray[0];
- $values[$x] = $valarray[$i+1];
- $x++;
- }
-
- // We fix unknown values to null
- $newvalues=array();
- foreach($values as $val)
- {
- $newvalues[]=(is_numeric($val) ? $val : null);
- }
-
-
- if ($this->type[0] == 'bars')
- {
- //print "Lot de donnees $i
";
- //print_r($values);
- //print '
';
-
- $color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
- $colorbis=new Color(min($this->datacolor[$i][0]+50,255),min($this->datacolor[$i][1]+50,255),min($this->datacolor[$i][2]+50,255),50);
-
- $colorgrey=new Color(100,100,100);
- $colorborder=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2]);
-
- if ($this->mode == 'side') $plot = new BarPlot($newvalues, $i+1, $nblot);
- if ($this->mode == 'depth') $plot = new BarPlot($newvalues, 1, 1, ($nblot-$i-1)*5);
-
- $plot->barBorder->setColor($colorgrey);
- //$plot->setBarColor($color);
- $plot->setBarGradient(new LinearGradient($colorbis, $color, 90));
-
- if ($this->mode == 'side') $plot->setBarPadding(0.1, 0.1);
- if ($this->mode == 'depth') $plot->setBarPadding(0.1, 0.4);
- if ($this->mode == 'side') $plot->setBarSpace(5);
- if ($this->mode == 'depth') $plot->setBarSpace(2);
-
- $plot->barShadow->setSize($this->SetShading);
- $plot->barShadow->setPosition(SHADOW_RIGHT_TOP);
- $plot->barShadow->setColor(new Color(160, 160, 160, 50));
- $plot->barShadow->smooth(TRUE);
- //$plot->setSize(1, 0.96);
- //$plot->setCenter(0.5, 0.52);
-
- // Le mode automatique est plus efficace
- $plot->SetYMax($this->MaxValue);
- $plot->SetYMin($this->MinValue);
- }
-
- if ($this->type[0] == 'lines')
- {
- $color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
- $colorbis=new Color(min($this->datacolor[$i][0]+20,255),min($this->datacolor[$i][1]+20,255),min($this->datacolor[$i][2]+20,255),60);
- $colorter=new Color(min($this->datacolor[$i][0]+50,255),min($this->datacolor[$i][1]+50,255),min($this->datacolor[$i][2]+50,255),90);
-
- $plot = new LinePlot($newvalues);
- //$plot->setSize(1, 0.96);
- //$plot->setCenter(0.5, 0.52);
-
- $plot->setColor($color);
- $plot->setThickness(1);
-
- // Set line background gradient
- $plot->setFillGradient(new LinearGradient($colorter, $colorbis, 90));
-
- $plot->xAxis->setLabelText($legends);
-
- // Le mode automatique est plus efficace
- $plot->SetYMax($this->MaxValue);
- $plot->SetYMin($this->MinValue);
- //$plot->setYAxis(0);
- //$plot->hideLine(true);
- }
-
- //$plot->reduce(80); // Evite temps d'affichage trop long et nombre de ticks absisce satures
-
- $group->legend->setTextFont(new $artichow_defaultfont(10)); // This is to force Artichow to use awFileFontDriver to
- // solve a bug in Artichow with UTF8
- if (count($this->Legend))
- {
- if ($this->type[0] == 'bars') $group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND);
- if ($this->type[0] == 'lines') $group->legend->add($plot, $this->Legend[$i], LEGEND_LINE);
- }
- $group->add($plot);
-
- $i++;
- }
-
- $group->axis->bottom->setLabelText($legends);
- $group->axis->bottom->label->setFont(new $artichow_defaultfont(7));
-
- //print $group->axis->bottom->getLabelNumber();
- if ($this->labelInterval > 0) $group->axis->bottom->setLabelInterval($this->labelInterval);
-
- $graph->add($group);
-
- // Generate file
- $graph->draw($file);
-
- $this->_stringtoshow='';
- }
-
-
- /**
- * Build a graph onto disk using JFlot library. Input when calling this method should be:
- * $this->data = array(array( 0=>'labelxA', 1=>yA), array('labelxB',yB)); or
- * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // TODO Syntax not supported. Removed when dol_print_graph_removed
- * $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // when there is n series to show for each x
- * $this->legend= array("Val1",...,"Valn"); // list of n series name
- * $this->type = array('bars',...'lines'); or array('pie')
- * $this->mode = 'depth' ???
- * $this->bgcolorgrid
- * $this->datacolor
- *
- * @param string $file Image file name to use to save onto disk (also used as javascript unique id)
- * @param string $fileurl Url path to show image if saved onto disk
- * @return void
- */
- private function draw_jflot($file,$fileurl)
- {
- global $artichow_defaultfont;
-
- dol_syslog(get_class($this)."::draw_jflot this->type=".join(',',$this->type));
-
- if (empty($this->width) && empty($this->height))
- {
- print 'Error width or height not set';
- return;
- }
-
- $legends=array();
- $nblot=count($this->data[0])-1; // -1 to remove legend
- if ($nblot < 0) dol_print_error('Bad value for property ->data. Must be set by mydolgraph->SetData before callinf mydolgrapgh->draw');
- $firstlot=0;
- // Works with line but not with bars
- //if ($nblot > 2) $firstlot = ($nblot - 2); // We limit nblot to 2 because jflot can't manage more than 2 bars on same x
-
- $i=$firstlot;
- $serie=array();
- while ($i < $nblot) // Loop on each serie
- {
- $values=array(); // Array with horizontal y values (specific values of a serie) for each abscisse x
- $serie[$i]="var d".$i." = [];\n";
-
- // Fill array $values
- $x=0;
- foreach($this->data as $valarray) // Loop on each x
- {
- $legends[$x] = $valarray[0];
- $values[$x] = (is_numeric($valarray[$i+1]) ? $valarray[$i+1] : null);
- $x++;
- }
-
- // TODO Avoid push by adding generated long array...
- if (isset($this->type[$firstlot]) && $this->type[$firstlot] == 'pie')
- {
- foreach($values as $x => $y) { if (isset($y)) $serie[$i].='d'.$i.'.push({"label":"'.dol_escape_js($legends[$x]).'", "data":'.$y.'});'."\n"; }
- }
- else
- {
- foreach($values as $x => $y) { if (isset($y)) $serie[$i].='d'.$i.'.push(['.$x.', '.$y.']);'."\n"; }
- }
+ var $graph; // Objet Graph (Artichow, Phplot...)
+ var $error;
+
+ var $bordercolor; // array(R,G,B)
+ var $bgcolor; // array(R,G,B)
+ var $bgcolorgrid=array(255,255,255); // array(R,G,B)
+ var $datacolor; // array(array(R,G,B),...)
+
+ private $_stringtoshow; // To store string to output graph into HTML page
+
+
+ /**
+ * Constructor
+ */
+ function __construct()
+ {
+ global $conf;
+ global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet;
+
+ // To use old feature
+ if (isset($conf->global->MAIN_GRAPH_LIBRARY) && $conf->global->MAIN_GRAPH_LIBRARY == 'artichow')
+ {
+ $this->_library='artichow';
+
+ // Test if module GD present
+ $modules_list = get_loaded_extensions();
+ $isgdinstalled=0;
+ foreach ($modules_list as $module)
+ {
+ if ($module == 'gd') $isgdinstalled=1;
+ }
+ if (! $isgdinstalled)
+ {
+ $this->error="Error: PHP GD module is not available. It is required to build graphics.";
+ return -1;
+ }
+ }
+
+ $this->bordercolor = array(235,235,224);
+ $this->datacolor = array(array(120,130,150), array(160,160,180), array(190,190,220));
+ $this->bgcolor = array(235,235,224);
+
+ $color_file = DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/graph-color.php';
+ if (is_readable($color_file))
+ {
+ include_once $color_file;
+ if (isset($theme_bordercolor)) $this->bordercolor = $theme_bordercolor;
+ if (isset($theme_datacolor)) $this->datacolor = $theme_datacolor;
+ if (isset($theme_bgcolor)) $this->bgcolor = $theme_bgcolor;
+ }
+ //print 'bgcolor: '.join(',',$this->bgcolor).'
';
+ }
+
+
+ /**
+ * Set Y precision
+ *
+ * @param float $which_prec Precision
+ * @return string
+ */
+ function SetPrecisionY($which_prec)
+ {
+ $this->PrecisionY = $which_prec;
+ return true;
+ }
+
+ /**
+ * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
+ *
+ * @param float $xi Xi
+ * @return boolean True
+ */
+ function SetHorizTickIncrement($xi)
+ {
+ $this->horizTickIncrement = $xi;
+ return true;
+ }
+
+ /**
+ * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
+ *
+ * @param float $xt Xt
+ * @return boolean True
+ */
+ function SetNumXTicks($xt)
+ {
+ $this->SetNumXTicks = $xt;
+ return true;
+ }
+
+ /**
+ * Set label interval to reduce number of labels
+ *
+ * @param float $x Label interval
+ * @return boolean True
+ */
+ function SetLabelInterval($x)
+ {
+ $this->labelInterval = $x;
+ return true;
+ }
+
+ /**
+ * Hide X grid
+ *
+ * @param boolean $bool XGrid or not
+ * @return boolean true
+ */
+ function SetHideXGrid($bool)
+ {
+ $this->hideXGrid = $bool;
+ return true;
+ }
+
+ /**
+ * Hide Y grid
+ *
+ * @param boolean $bool YGrid or not
+ * @return boolean true
+ */
+ function SetHideYGrid($bool)
+ {
+ $this->hideYGrid = $bool;
+ return true;
+ }
+
+ /**
+ * Set y label
+ *
+ * @param string $label Y label
+ * @return boolean True
+ */
+ function SetYLabel($label)
+ {
+ $this->YLabel = $label;
+ }
+
+ /**
+ * Set width
+ *
+ * @param int $w Width
+ * @return boolean True
+ */
+ function SetWidth($w)
+ {
+ $this->width = $w;
+ }
+
+ /**
+ * Set title
+ *
+ * @param string $title Title
+ * @return void
+ */
+ function SetTitle($title)
+ {
+ $this->title = $title;
+ }
+
+ /**
+ * Set data
+ *
+ * @param array $data Data
+ * @return void
+ * @see draw_jflot for syntax of data array
+ */
+ function SetData($data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Set data
+ *
+ * @param array $datacolor Data color array(array(R,G,B),array(R,G,B)...)
+ * @return void
+ */
+ function SetDataColor($datacolor)
+ {
+ $this->datacolor = $datacolor;
+ }
+
+ /**
+ * Set type
+ *
+ * @param array $type Array with type for each serie. Example: array('pie'), array('lines',...,'bars')
+ * @return void
+ */
+ function SetType($type)
+ {
+ $this->type = $type;
+ }
+
+ /**
+ * Set legend
+ *
+ * @param string $legend Legend
+ * @return void
+ */
+ function SetLegend($legend)
+ {
+ $this->Legend = $legend;
+ }
+
+ /**
+ * Set min width
+ *
+ * @param int $legendwidthmin Min width
+ * @return void
+ */
+ function SetLegendWidthMin($legendwidthmin)
+ {
+ $this->LegendWidthMin = $legendwidthmin;
+ }
+
+ /**
+ * Set max value
+ *
+ * @param int $max Max value
+ * @return void
+ */
+ function SetMaxValue($max)
+ {
+ $this->MaxValue = $max;
+ }
+
+ /**
+ * Get max value
+ *
+ * @return int Max value
+ */
+ function GetMaxValue()
+ {
+ return $this->MaxValue;
+ }
+
+ /**
+ * Set min value
+ *
+ * @param int $min Min value
+ * @return void
+ */
+ function SetMinValue($min)
+ {
+ $this->MinValue = $min;
+ }
+
+ /**
+ * Get min value
+ *
+ * @return int Max value
+ */
+ function GetMinValue()
+ {
+ return $this->MinValue;
+ }
+
+ /**
+ * Set height
+ *
+ * @param int $h Height
+ * @return void
+ */
+ function SetHeight($h)
+ {
+ $this->height = $h;
+ }
+
+ /**
+ * Set shading
+ *
+ * @param string $s Shading
+ * @return void
+ */
+ function SetShading($s)
+ {
+ $this->SetShading = $s;
+ }
+
+ /**
+ * Set shading
+ *
+ * @param string $s Shading
+ * @return void
+ */
+ function SetCssPrefix($s)
+ {
+ $this->cssprefix = $s;
+ }
+
+ /**
+ * Reset bg color
+ *
+ * @return void
+ */
+ function ResetBgColor()
+ {
+ unset($this->bgcolor);
+ }
+
+ /**
+ * Reset bgcolorgrid
+ *
+ * @return void
+ */
+ function ResetBgColorGrid()
+ {
+ unset($this->bgcolorgrid);
+ }
+
+ /**
+ * Is graph ko
+ *
+ * @return string Error
+ */
+ function isGraphKo()
+ {
+ return $this->error;
+ }
+
+ /**
+ * Show legend or not
+ *
+ * @param int $showlegend 1=Show legend (default), 0=Hide legend
+ * @return void
+ */
+ function setShowLegend($showlegend)
+ {
+ $this->showlegend=$showlegend;
+ }
+
+ /**
+ * Show pointvalue or not
+ *
+ * @param int $showpointvalue 1=Show value for each point, as tooltip or inline (default), 0=Hide value
+ * @return void
+ */
+ function setShowPointValue($showpointvalue)
+ {
+ $this->showpointvalue=$showpointvalue;
+ }
+
+ /**
+ * Show percent or not
+ *
+ * @param int $showpercent 1=Show percent for each point, as tooltip or inline, 0=Hide percent (default)
+ * @return void
+ */
+ function setShowPercent($showpercent)
+ {
+ $this->showpercent=$showpercent;
+ }
+
+
+
+ /**
+ * Define background color of complete image
+ *
+ * @param array $bg_color array(R,G,B) ou 'onglet' ou 'default'
+ * @return void
+ */
+ function SetBgColor($bg_color = array(255,255,255))
+ {
+ global $theme_bgcolor,$theme_bgcoloronglet;
+
+ if (! is_array($bg_color))
+ {
+ if ($bg_color == 'onglet')
+ {
+ //print 'ee'.join(',',$theme_bgcoloronglet);
+ $this->bgcolor = $theme_bgcoloronglet;
+ }
+ else
+ {
+ $this->bgcolor = $theme_bgcolor;
+ }
+ }
+ else
+ {
+ $this->bgcolor = $bg_color;
+ }
+ }
+
+ /**
+ * Define background color of grid
+ *
+ * @param array $bg_colorgrid array(R,G,B) ou 'onglet' ou 'default'
+ * @return void
+ */
+ function SetBgColorGrid($bg_colorgrid = array(255,255,255))
+ {
+ global $theme_bgcolor,$theme_bgcoloronglet;
+
+ if (! is_array($bg_colorgrid))
+ {
+ if ($bg_colorgrid == 'onglet')
+ {
+ //print 'ee'.join(',',$theme_bgcoloronglet);
+ $this->bgcolorgrid = $theme_bgcoloronglet;
+ }
+ else
+ {
+ $this->bgcolorgrid = $theme_bgcolor;
+ }
+ }
+ else
+ {
+ $this->bgcolorgrid = $bg_colorgrid;
+ }
+ }
+
+ /**
+ * Reset data color
+ *
+ * @return void
+ */
+ function ResetDataColor()
+ {
+ unset($this->datacolor);
+ }
+
+ /**
+ * Get max value
+ *
+ * @return int Max value
+ */
+ function GetMaxValueInData()
+ {
+ $k = 0;
+ $vals = array();
+
+ $nblines = count($this->data);
+ $nbvalues = count($this->data[0]) - 1;
+
+ for ($j = 0 ; $j < $nblines ; $j++)
+ {
+ for ($i = 0 ; $i < $nbvalues ; $i++)
+ {
+ $vals[$k] = $this->data[$j][$i+1];
+ $k++;
+ }
+ }
+ rsort($vals);
+ return $vals[0];
+ }
+
+ /**
+ * Return min value of all data
+ *
+ * @return int Min value of all data
+ */
+ function GetMinValueInData()
+ {
+ $k = 0;
+ $vals = array();
+
+ $nblines = count($this->data);
+ $nbvalues = count($this->data[0]) - 1;
+
+ for ($j = 0 ; $j < $nblines ; $j++)
+ {
+ for ($i = 0 ; $i < $nbvalues ; $i++)
+ {
+ $vals[$k] = $this->data[$j][$i+1];
+ $k++;
+ }
+ }
+ sort($vals);
+ return $vals[0];
+ }
+
+ /**
+ * Return max value of all data
+ *
+ * @return int Max value of all data
+ */
+ function GetCeilMaxValue()
+ {
+ $max = $this->GetMaxValueInData();
+ if ($max != 0) $max++;
+ $size=dol_strlen(abs(ceil($max)));
+ $factor=1;
+ for ($i=0; $i < ($size-1); $i++)
+ {
+ $factor*=10;
+ }
+
+ $res=0;
+ if (is_numeric($max)) $res=ceil($max/$factor)*$factor;
+
+ //print "max=".$max." res=".$res;
+ return $res;
+ }
+
+ /**
+ * Return min value of all data
+ *
+ * @return int Max value of all data
+ */
+ function GetFloorMinValue()
+ {
+ $min = $this->GetMinValueInData();
+ if ($min != 0) $min--;
+ $size=dol_strlen(abs(floor($min)));
+ $factor=1;
+ for ($i=0; $i < ($size-1); $i++)
+ {
+ $factor*=10;
+ }
+
+ $res=floor($min/$factor)*$factor;
+
+ //print "min=".$min." res=".$res;
+ return $res;
+ }
+
+ /**
+ * Build a graph onto disk using correct library
+ *
+ * @param string $file Image file name to use to save onto disk (also used as javascript unique id)
+ * @param string $fileurl Url path to show image if saved onto disk
+ * @return void
+ */
+ function draw($file,$fileurl='')
+ {
+ if (empty($file))
+ {
+ $this->error="Call to draw method was made with empty value for parameter file.";
+ dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR);
+ return -2;
+ }
+ if (! is_array($this->data) || count($this->data) < 1)
+ {
+ $this->error="Call to draw method was made but SetData was not called or called with an empty dataset for parameters";
+ dol_syslog(get_class($this)."::draw ".$this->error, LOG_ERR);
+ return -1;
+ }
+ $call = "draw_".$this->_library;
+ call_user_func_array(array($this,$call), array($file,$fileurl));
+ }
+
+
+ /**
+ * Build a graph onto disk using Artichow library
+ *
+ * @param string $file Image file name to use if we save onto disk
+ * @param string $fileurl Url path to show image if saved onto disk
+ * @return void
+ */
+ private function draw_artichow($file,$fileurl)
+ {
+ global $artichow_defaultfont;
+
+ dol_syslog(get_class($this)."::draw_artichow this->type=".join(',',$this->type));
+
+ if (! defined('SHADOW_RIGHT_TOP')) define('SHADOW_RIGHT_TOP',3);
+ if (! defined('LEGEND_BACKGROUND')) define('LEGEND_BACKGROUND',2);
+ if (! defined('LEGEND_LINE')) define('LEGEND_LINE',1);
+
+ // Create graph
+ $classname='';
+ if (! isset($this->type[0]) || $this->type[0] == 'bars') $classname='BarPlot'; // Only one type (first one) is supported by artichow
+ else if ($this->type[0] == 'lines') $classname='LinePlot';
+ else $classname='TypeUnknown';
+ include_once ARTICHOW_PATH.$classname.'.class.php';
+
+ // Definition de couleurs
+ $bgcolor=new Color($this->bgcolor[0],$this->bgcolor[1],$this->bgcolor[2]);
+ $bgcolorgrid=new Color($this->bgcolorgrid[0],$this->bgcolorgrid[1],$this->bgcolorgrid[2]);
+ $colortrans=new Color(0,0,0,100);
+ $colorsemitrans=new Color(255,255,255,60);
+ $colorgradient= new LinearGradient(new Color(235, 235, 235),new Color(255, 255, 255),0);
+ $colorwhite=new Color(255,255,255);
+
+ // Graph
+ $graph = new Graph($this->width, $this->height);
+ $graph->border->hide();
+ $graph->setAntiAliasing(true);
+ if (isset($this->title))
+ {
+ $graph->title->set($this->title);
+ //print $artichow_defaultfont;exit;
+ $graph->title->setFont(new $artichow_defaultfont(10));
+ }
+
+ if (is_array($this->bgcolor)) $graph->setBackgroundColor($bgcolor);
+ else $graph->setBackgroundGradient($colorgradient);
+
+ $group = new PlotGroup;
+ //$group->setSpace(5, 5, 0, 0);
+
+ $paddleft=50;
+ $paddright=10;
+ $strl=dol_strlen(max(abs($this->MaxValue),abs($this->MinValue)));
+ if ($strl > 6) $paddleft += ($strl * 4);
+ $group->setPadding($paddleft, $paddright); // Width on left and right for Y axis values
+ $group->legend->setSpace(0);
+ $group->legend->setPadding(2,2,2,2);
+ $group->legend->setPosition(NULL,0.1);
+ $group->legend->setBackgroundColor($colorsemitrans);
+
+ if (is_array($this->bgcolorgrid)) $group->grid->setBackgroundColor($bgcolorgrid);
+ else $group->grid->setBackgroundColor($colortrans);
+
+ if ($this->hideXGrid) $group->grid->hideVertical(true);
+ if ($this->hideYGrid) $group->grid->hideHorizontal(true);
+
+ // On boucle sur chaque lot de donnees
+ $legends=array();
+ $i=0;
+ $nblot=count($this->data[0])-1;
+
+ while ($i < $nblot)
+ {
+ $x=0;
+ $values=array();
+ foreach($this->data as $key => $valarray)
+ {
+ $legends[$x] = $valarray[0];
+ $values[$x] = $valarray[$i+1];
+ $x++;
+ }
+
+ // We fix unknown values to null
+ $newvalues=array();
+ foreach($values as $val)
+ {
+ $newvalues[]=(is_numeric($val) ? $val : null);
+ }
+
+
+ if ($this->type[0] == 'bars')
+ {
+ //print "Lot de donnees $i
";
+ //print_r($values);
+ //print '
';
+
+ $color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
+ $colorbis=new Color(min($this->datacolor[$i][0]+50,255),min($this->datacolor[$i][1]+50,255),min($this->datacolor[$i][2]+50,255),50);
+
+ $colorgrey=new Color(100,100,100);
+ $colorborder=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2]);
+
+ if ($this->mode == 'side') $plot = new BarPlot($newvalues, $i+1, $nblot);
+ if ($this->mode == 'depth') $plot = new BarPlot($newvalues, 1, 1, ($nblot-$i-1)*5);
+
+ $plot->barBorder->setColor($colorgrey);
+ //$plot->setBarColor($color);
+ $plot->setBarGradient(new LinearGradient($colorbis, $color, 90));
+
+ if ($this->mode == 'side') $plot->setBarPadding(0.1, 0.1);
+ if ($this->mode == 'depth') $plot->setBarPadding(0.1, 0.4);
+ if ($this->mode == 'side') $plot->setBarSpace(5);
+ if ($this->mode == 'depth') $plot->setBarSpace(2);
+
+ $plot->barShadow->setSize($this->SetShading);
+ $plot->barShadow->setPosition(SHADOW_RIGHT_TOP);
+ $plot->barShadow->setColor(new Color(160, 160, 160, 50));
+ $plot->barShadow->smooth(TRUE);
+ //$plot->setSize(1, 0.96);
+ //$plot->setCenter(0.5, 0.52);
+
+ // Le mode automatique est plus efficace
+ $plot->SetYMax($this->MaxValue);
+ $plot->SetYMin($this->MinValue);
+ }
+
+ if ($this->type[0] == 'lines')
+ {
+ $color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
+ $colorbis=new Color(min($this->datacolor[$i][0]+20,255),min($this->datacolor[$i][1]+20,255),min($this->datacolor[$i][2]+20,255),60);
+ $colorter=new Color(min($this->datacolor[$i][0]+50,255),min($this->datacolor[$i][1]+50,255),min($this->datacolor[$i][2]+50,255),90);
+
+ $plot = new LinePlot($newvalues);
+ //$plot->setSize(1, 0.96);
+ //$plot->setCenter(0.5, 0.52);
+
+ $plot->setColor($color);
+ $plot->setThickness(1);
+
+ // Set line background gradient
+ $plot->setFillGradient(new LinearGradient($colorter, $colorbis, 90));
+
+ $plot->xAxis->setLabelText($legends);
+
+ // Le mode automatique est plus efficace
+ $plot->SetYMax($this->MaxValue);
+ $plot->SetYMin($this->MinValue);
+ //$plot->setYAxis(0);
+ //$plot->hideLine(true);
+ }
+
+ //$plot->reduce(80); // Evite temps d'affichage trop long et nombre de ticks absisce satures
+
+ $group->legend->setTextFont(new $artichow_defaultfont(10)); // This is to force Artichow to use awFileFontDriver to
+ // solve a bug in Artichow with UTF8
+ if (count($this->Legend))
+ {
+ if ($this->type[0] == 'bars') $group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND);
+ if ($this->type[0] == 'lines') $group->legend->add($plot, $this->Legend[$i], LEGEND_LINE);
+ }
+ $group->add($plot);
+
+ $i++;
+ }
+
+ $group->axis->bottom->setLabelText($legends);
+ $group->axis->bottom->label->setFont(new $artichow_defaultfont(7));
+
+ //print $group->axis->bottom->getLabelNumber();
+ if ($this->labelInterval > 0) $group->axis->bottom->setLabelInterval($this->labelInterval);
+
+ $graph->add($group);
+
+ // Generate file
+ $graph->draw($file);
+
+ $this->_stringtoshow='';
+ }
+
+
+ /**
+ * Build a graph onto disk using JFlot library. Input when calling this method should be:
+ * $this->data = array(array( 0=>'labelxA', 1=>yA), array('labelxB',yB)); or
+ * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // TODO Syntax not supported. Removed when dol_print_graph_removed
+ * $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // when there is n series to show for each x
+ * $this->legend= array("Val1",...,"Valn"); // list of n series name
+ * $this->type = array('bars',...'lines'); or array('pie')
+ * $this->mode = 'depth' ???
+ * $this->bgcolorgrid
+ * $this->datacolor
+ *
+ * @param string $file Image file name to use to save onto disk (also used as javascript unique id)
+ * @param string $fileurl Url path to show image if saved onto disk
+ * @return void
+ */
+ private function draw_jflot($file,$fileurl)
+ {
+ global $artichow_defaultfont;
+
+ dol_syslog(get_class($this)."::draw_jflot this->type=".join(',',$this->type));
+
+ if (empty($this->width) && empty($this->height))
+ {
+ print 'Error width or height not set';
+ return;
+ }
+
+ $legends=array();
+ $nblot=count($this->data[0])-1; // -1 to remove legend
+ if ($nblot < 0) dol_print_error('Bad value for property ->data. Must be set by mydolgraph->SetData before callinf mydolgrapgh->draw');
+ $firstlot=0;
+ // Works with line but not with bars
+ //if ($nblot > 2) $firstlot = ($nblot - 2); // We limit nblot to 2 because jflot can't manage more than 2 bars on same x
+
+ $i=$firstlot;
+ $serie=array();
+ while ($i < $nblot) // Loop on each serie
+ {
+ $values=array(); // Array with horizontal y values (specific values of a serie) for each abscisse x
+ $serie[$i]="var d".$i." = [];\n";
+
+ // Fill array $values
+ $x=0;
+ foreach($this->data as $valarray) // Loop on each x
+ {
+ $legends[$x] = $valarray[0];
+ $values[$x] = (is_numeric($valarray[$i+1]) ? $valarray[$i+1] : null);
+ $x++;
+ }
+
+ // TODO Avoid push by adding generated long array...
+ if (isset($this->type[$firstlot]) && $this->type[$firstlot] == 'pie')
+ {
+ foreach($values as $x => $y) {
+ if (isset($y)) $serie[$i].='d'.$i.'.push({"label":"'.dol_escape_js($legends[$x]).'", "data":'.$y.'});'."\n";
+ }
+ }
+ else
+ {
+ foreach($values as $x => $y) {
+ if (isset($y)) $serie[$i].='d'.$i.'.push(['.$x.', '.$y.']);'."\n";
+ }
+ }
unset($values);
- $i++;
- }
- $tag=dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file),'_',array('-','.'))));
+ $i++;
+ }
+ $tag=dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file),'_',array('-','.'))));
- $this->_stringtoshow =''."\n";
- if (! empty($this->title)) $this->_stringtoshow.='