2013-05-18 09:19:03 +02:00
< ? php
/* Copyright ( c ) 2003 - 2006 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2015-07-05 22:04:30 +02:00
* Copyright ( c ) 2004 - 2015 Laurent Destailleur < eldy @ users . sourceforge . net >
2013-09-10 15:21:56 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2013-09-10 15:21:56 +02:00
*/
2013-05-18 09:19:03 +02:00
/**
* \file htdocs / core / class / dolgraph . class . php
* \ingroup core
* \brief File for class to generate graph
*/
/**
2017-05-31 10:43:01 +02:00
* Class to build graphs .
2017-08-23 21:01:14 +02:00
* Usage is :
2017-05-31 10:43:01 +02:00
* $dolgraph = new DolGraph ();
2017-11-23 20:00:54 +01:00
* $dolgraph -> SetTitle ( $langs -> transnoentities ( 'MyTitle' ) . '<br>' . $langs -> transnoentities ( 'MyTitlePercent' ) . '%' );
2017-05-31 11:51:38 +02:00
* $dolgraph -> SetMaxValue ( 50 );
2017-05-31 10:43:01 +02:00
* $dolgraph -> SetData ( $data );
2020-03-05 17:23:19 +01:00
* $dolgraph -> setShowLegend ( 2 );
2017-05-31 11:51:38 +02:00
* $dolgraph -> setShowPercent ( 1 );
* $dolgraph -> SetType ( array ( 'pie' ));
2020-03-05 17:23:19 +01:00
* $dolgraph -> setHeight ( '200' );
2017-05-31 10:43:01 +02:00
* $dolgraph -> draw ( 'idofgraph' );
2017-11-23 20:00:54 +01:00
* print $dolgraph -> show ( $total ? 0 : 1 );
2013-05-18 09:19:03 +02:00
*/
class DolGraph
{
2020-12-04 22:30:34 +01:00
public $type = array (); // Array with type of each series. Example: array('bars', 'horizontalbars', 'lines', 'pies', 'piesemicircle', 'polar'...)
2019-11-13 19:35:39 +01:00
public $mode = 'side' ; // Mode bars graph: side, depth
2020-12-04 22:12:20 +01:00
private $_library = 'chart' ; // Graphic library to use (jflot, chart, artichow)
2013-09-10 15:45:36 +02:00
//! Array of data
2019-11-13 19:35:39 +01:00
public $data ; // Data of graph: array(array('abs1',valA1,valB1), array('abs2',valA2,valB2), ...)
public $title ; // Title of graph
public $cssprefix = '' ; // To add into css styles
2019-06-21 14:34:04 +02:00
/**
* @ var int | string Width of graph . It can be a numeric for pixels or a string like '100%'
*/
2019-11-13 19:35:39 +01:00
public $width = 380 ;
2019-06-21 14:34:04 +02:00
/**
* @ var int Height of graph
*/
2019-11-13 19:35:39 +01:00
public $height = 200 ;
2019-06-21 14:34:04 +02:00
2019-11-13 19:35:39 +01:00
public $MaxValue = 0 ;
public $MinValue = 0 ;
public $SetShading = 0 ;
2013-09-10 15:45:36 +02:00
2019-11-13 19:35:39 +01:00
public $horizTickIncrement = - 1 ;
public $SetNumXTicks = - 1 ;
public $labelInterval = - 1 ;
2013-09-10 15:45:36 +02:00
2019-11-13 19:35:39 +01:00
public $hideXGrid = false ;
public $hideYGrid = false ;
2013-09-10 15:45:36 +02:00
2019-11-13 19:35:39 +01:00
public $Legend = array ();
public $LegendWidthMin = 0 ;
public $showlegend = 1 ;
public $showpointvalue = 1 ;
public $showpercent = 0 ;
public $combine = 0 ; // 0.05 if you want to combine records < 5% into "other"
public $graph ; // Objet Graph (Artichow, Phplot...)
2018-09-02 23:01:14 +02:00
2018-08-22 10:37:16 +02:00
/**
* @ var string Error code ( or message )
*/
2019-11-13 19:35:39 +01:00
public $error = '' ;
2013-09-10 15:45:36 +02:00
2019-11-13 19:35:39 +01:00
public $bordercolor ; // array(R,G,B)
public $bgcolor ; // array(R,G,B)
public $bgcolorgrid = array ( 255 , 255 , 255 ); // array(R,G,B)
public $datacolor ; // array(array(R,G,B),...)
2013-09-10 15:45:36 +02:00
2019-11-13 19:35:39 +01:00
private $stringtoshow ; // To store string to output graph into HTML page
2013-09-10 15:45:36 +02:00
/**
* Constructor
2017-10-25 22:02:07 +02:00
*
2020-03-04 22:29:21 +01:00
* @ param string $library 'auto' ( default )
2013-09-10 15:45:36 +02:00
*/
2020-03-04 22:29:21 +01:00
public function __construct ( $library = 'auto' )
2013-09-10 15:45:36 +02:00
{
2019-08-07 12:15:55 +02:00
global $conf ;
2019-05-16 14:47:42 +02:00
global $theme_bordercolor , $theme_datacolor , $theme_bgcolor ;
2013-09-10 15:45:36 +02:00
2019-11-13 19:35:39 +01:00
$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 );
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
$color_file = DOL_DOCUMENT_ROOT . '/theme/' . $conf -> theme . '/theme_vars.inc.php' ;
if ( is_readable ( $color_file )) {
2013-09-10 15:45:36 +02:00
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).'<br>';
2020-03-04 22:29:21 +01:00
$this -> _library = $library ;
if ( $this -> _library == 'auto' ) {
2020-12-04 22:12:20 +01:00
$this -> _library = ( empty ( $conf -> global -> MAIN_JS_GRAPH ) ? 'chart' : $conf -> global -> MAIN_JS_GRAPH );
2020-03-04 22:29:21 +01:00
}
2013-09-10 15:45:36 +02:00
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
*
* @ param float $xi Xi
* @ return boolean True
*/
2019-02-27 20:45:07 +01:00
public function SetHorizTickIncrement ( $xi )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> horizTickIncrement = $xi ;
return true ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
*
* @ param float $xt Xt
* @ return boolean True
*/
2019-02-27 20:45:07 +01:00
public function SetNumXTicks ( $xt )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> SetNumXTicks = $xt ;
return true ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set label interval to reduce number of labels
*
* @ param float $x Label interval
* @ return boolean True
*/
2019-02-27 20:45:07 +01:00
public function SetLabelInterval ( $x )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> labelInterval = $x ;
return true ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Hide X grid
*
* @ param boolean $bool XGrid or not
* @ return boolean true
*/
2019-02-27 20:45:07 +01:00
public function SetHideXGrid ( $bool )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> hideXGrid = $bool ;
return true ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Hide Y grid
*
* @ param boolean $bool YGrid or not
* @ return boolean true
*/
2019-02-27 20:45:07 +01:00
public function SetHideYGrid ( $bool )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> hideYGrid = $bool ;
return true ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set y label
*
* @ param string $label Y label
2015-04-06 12:25:30 +02:00
* @ return boolean | null True
2013-09-10 15:45:36 +02:00
*/
2019-02-27 20:45:07 +01:00
public function SetYLabel ( $label )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> YLabel = $label ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set width
*
2019-06-19 12:53:28 +02:00
* @ param int | string $w Width ( Example : 320 or '100%' )
2015-04-06 12:25:30 +02:00
* @ return boolean | null True
2013-09-10 15:45:36 +02:00
*/
2019-02-27 20:45:07 +01:00
public function SetWidth ( $w )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> width = $w ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set title
*
* @ param string $title Title
* @ return void
*/
2019-02-27 20:45:07 +01:00
public function SetTitle ( $title )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> title = $title ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set data
*
* @ param array $data Data
* @ return void
2019-04-04 18:33:12 +02:00
* @ see draw_jflot () for syntax of data array
2013-09-10 15:45:36 +02:00
*/
2019-02-27 20:45:07 +01:00
public function SetData ( $data )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> data = $data ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set data
*
* @ param array $datacolor Data color array ( array ( R , G , B ), array ( R , G , B ) ... )
* @ return void
*/
2019-02-27 20:45:07 +01:00
public function SetDataColor ( $datacolor )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> datacolor = $datacolor ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set type
*
2020-03-05 16:30:55 +01:00
* @ param array $type Array with type for each serie . Example : array ( 'type1' , 'type2' , ... ) where type can be :
2020-12-09 13:31:14 +01:00
* 'pie' , 'piesemicircle' , 'polar' , 'lines' , 'linesnopoint' , 'bars' , 'horizontalbars' ...
2013-09-10 15:45:36 +02:00
* @ return void
*/
2019-02-27 20:45:07 +01:00
public function SetType ( $type )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> type = $type ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set legend
*
2014-12-04 13:20:56 +01:00
* @ param array $legend Legend . Example : array ( 'seriename1' , 'seriname2' , ... )
2013-09-10 15:45:36 +02:00
* @ return void
*/
2019-02-27 20:45:07 +01:00
public function SetLegend ( $legend )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> Legend = $legend ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set min width
*
* @ param int $legendwidthmin Min width
* @ return void
*/
2019-02-27 20:45:07 +01:00
public function SetLegendWidthMin ( $legendwidthmin )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> LegendWidthMin = $legendwidthmin ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set max value
*
* @ param int $max Max value
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetMaxValue ( $max )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> MaxValue = $max ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Get max value
*
* @ return int Max value
*/
2020-10-31 14:32:18 +01:00
public function GetMaxValue ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
return $this -> MaxValue ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set min value
*
* @ param int $min Min value
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetMinValue ( $min )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> MinValue = $min ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Get min value
*
* @ return int Max value
*/
2020-10-31 14:32:18 +01:00
public function GetMinValue ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
return $this -> MinValue ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set height
*
* @ param int $h Height
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetHeight ( $h )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> height = $h ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set shading
*
* @ param string $s Shading
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetShading ( $s )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> SetShading = $s ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Set shading
*
* @ param string $s Shading
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetCssPrefix ( $s )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$this -> cssprefix = $s ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Reset bg color
*
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function ResetBgColor ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
unset ( $this -> bgcolor );
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Reset bgcolorgrid
*
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function ResetBgColorGrid ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
unset ( $this -> bgcolorgrid );
}
/**
* Is graph ko
*
* @ return string Error
*/
2020-10-31 14:32:18 +01:00
public function isGraphKo ()
2013-09-10 15:45:36 +02:00
{
return $this -> error ;
}
/**
* Show legend or not
*
2020-03-05 17:23:19 +01:00
* @ param int $showlegend 1 = Show legend ( default ), 0 = Hide legend , 2 = Show legend on right
2013-09-10 15:45:36 +02:00
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function setShowLegend ( $showlegend )
2013-09-10 15:45:36 +02:00
{
2019-11-13 19:35:39 +01:00
$this -> showlegend = $showlegend ;
2013-09-10 15:45:36 +02:00
}
/**
* Show pointvalue or not
*
* @ param int $showpointvalue 1 = Show value for each point , as tooltip or inline ( default ), 0 = Hide value
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function setShowPointValue ( $showpointvalue )
2013-09-10 15:45:36 +02:00
{
2019-11-13 19:35:39 +01:00
$this -> showpointvalue = $showpointvalue ;
2013-09-10 15:45:36 +02:00
}
/**
* Show percent or not
*
* @ param int $showpercent 1 = Show percent for each point , as tooltip or inline , 0 = Hide percent ( default )
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function setShowPercent ( $showpercent )
2013-09-10 15:45:36 +02:00
{
2019-11-13 19:35:39 +01:00
$this -> showpercent = $showpercent ;
2013-09-10 15:45:36 +02:00
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Define background color of complete image
*
* @ param array $bg_color array ( R , G , B ) ou 'onglet' ou 'default'
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetBgColor ( $bg_color = array ( 255 , 255 , 255 ))
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2019-11-13 19:35:39 +01:00
global $theme_bgcolor , $theme_bgcoloronglet ;
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
if ( ! is_array ( $bg_color )) {
if ( $bg_color == 'onglet' ) {
2013-09-10 15:45:36 +02:00
//print 'ee'.join(',',$theme_bgcoloronglet);
$this -> bgcolor = $theme_bgcoloronglet ;
2020-05-21 15:05:19 +02:00
} else {
2013-09-10 15:45:36 +02:00
$this -> bgcolor = $theme_bgcolor ;
}
2020-05-21 15:05:19 +02:00
} else {
2013-09-10 15:45:36 +02:00
$this -> bgcolor = $bg_color ;
}
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Define background color of grid
*
* @ param array $bg_colorgrid array ( R , G , B ) ou 'onglet' ou 'default'
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function SetBgColorGrid ( $bg_colorgrid = array ( 255 , 255 , 255 ))
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2019-11-13 19:35:39 +01:00
global $theme_bgcolor , $theme_bgcoloronglet ;
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
if ( ! is_array ( $bg_colorgrid )) {
if ( $bg_colorgrid == 'onglet' ) {
2013-09-10 15:45:36 +02:00
//print 'ee'.join(',',$theme_bgcoloronglet);
$this -> bgcolorgrid = $theme_bgcoloronglet ;
2020-05-21 15:05:19 +02:00
} else {
2013-09-10 15:45:36 +02:00
$this -> bgcolorgrid = $theme_bgcolor ;
}
2020-05-21 15:05:19 +02:00
} else {
2013-09-10 15:45:36 +02:00
$this -> bgcolorgrid = $bg_colorgrid ;
}
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Reset data color
*
* @ return void
*/
2020-10-31 14:32:18 +01:00
public function ResetDataColor ()
{
// phpcs:enable
unset ( $this -> datacolor );
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
2013-09-10 15:45:36 +02:00
* Get max value
*
* @ return int Max value
*/
2020-10-31 14:32:18 +01:00
public function GetMaxValueInData ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2020-03-12 12:45:44 +01:00
if ( ! is_array ( $this -> data )) return 0 ;
2020-03-07 16:45:28 +01:00
2013-09-10 15:45:36 +02:00
$k = 0 ;
$vals = array ();
$nblines = count ( $this -> data );
2020-10-09 13:54:47 +02:00
$nbvalues = ( empty ( $this -> data [ 0 ]) ? 0 : count ( $this -> data [ 0 ]) - 1 );
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
for ( $j = 0 ; $j < $nblines ; $j ++ ) {
for ( $i = 0 ; $i < $nbvalues ; $i ++ ) {
2019-11-13 19:35:39 +01:00
$vals [ $k ] = $this -> data [ $j ][ $i + 1 ];
2013-09-10 15:45:36 +02:00
$k ++ ;
}
}
rsort ( $vals );
return $vals [ 0 ];
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Return min value of all data
*
* @ return int Min value of all data
*/
2020-10-31 14:32:18 +01:00
public function GetMinValueInData ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2020-03-12 12:45:44 +01:00
if ( ! is_array ( $this -> data )) return 0 ;
2020-03-07 16:45:28 +01:00
2013-09-10 15:45:36 +02:00
$k = 0 ;
$vals = array ();
$nblines = count ( $this -> data );
2020-10-09 13:54:47 +02:00
$nbvalues = ( empty ( $this -> data [ 0 ]) ? 0 : count ( $this -> data [ 0 ]) - 1 );
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
for ( $j = 0 ; $j < $nblines ; $j ++ ) {
for ( $i = 0 ; $i < $nbvalues ; $i ++ ) {
2019-11-13 19:35:39 +01:00
$vals [ $k ] = $this -> data [ $j ][ $i + 1 ];
2013-09-10 15:45:36 +02:00
$k ++ ;
}
}
sort ( $vals );
return $vals [ 0 ];
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Return max value of all data
*
* @ return int Max value of all data
*/
2020-10-31 14:32:18 +01:00
public function GetCeilMaxValue ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$max = $this -> GetMaxValueInData ();
if ( $max != 0 ) $max ++ ;
2019-11-13 19:35:39 +01:00
$size = dol_strlen ( abs ( ceil ( $max )));
$factor = 1 ;
2020-12-09 13:31:14 +01:00
for ( $i = 0 ; $i < ( $size - 1 ); $i ++ ) {
2019-11-13 19:35:39 +01:00
$factor *= 10 ;
2013-09-10 15:45:36 +02:00
}
2019-11-13 19:35:39 +01:00
$res = 0 ;
if ( is_numeric ( $max )) $res = ceil ( $max / $factor ) * $factor ;
2013-09-10 15:45:36 +02:00
//print "max=".$max." res=".$res;
return $res ;
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
* Return min value of all data
*
2015-04-06 12:25:30 +02:00
* @ return double Max value of all data
2013-09-10 15:45:36 +02:00
*/
2020-10-31 14:32:18 +01:00
public function GetFloorMinValue ()
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2013-09-10 15:45:36 +02:00
$min = $this -> GetMinValueInData ();
2019-11-13 19:35:39 +01:00
if ( $min == '' ) $min = 0 ;
2013-09-10 15:45:36 +02:00
if ( $min != 0 ) $min -- ;
2019-11-13 19:35:39 +01:00
$size = dol_strlen ( abs ( floor ( $min )));
$factor = 1 ;
2020-12-09 13:31:14 +01:00
for ( $i = 0 ; $i < ( $size - 1 ); $i ++ ) {
2019-11-13 19:35:39 +01:00
$factor *= 10 ;
2013-09-10 15:45:36 +02:00
}
2019-11-13 19:35:39 +01:00
$res = floor ( $min / $factor ) * $factor ;
2013-09-10 15:45:36 +02:00
//print "min=".$min." res=".$res;
return $res ;
}
/**
2017-10-25 22:02:07 +02:00
* Build a graph into memory using correct library ( may also be wrote on disk , depending on library used )
2013-09-10 15:45:36 +02:00
*
* @ 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
2015-04-06 12:25:30 +02:00
* @ return integer | null
2013-09-10 15:45:36 +02:00
*/
2020-10-31 14:32:18 +01:00
public function draw ( $file , $fileurl = '' )
2013-09-10 15:45:36 +02:00
{
2020-12-09 13:31:14 +01:00
if ( empty ( $file )) {
2019-11-13 19:35:39 +01:00
$this -> error = " Call to draw method was made with empty value for parameter file. " ;
2020-12-09 13:31:14 +01:00
dol_syslog ( get_class ( $this ) . " ::draw " . $this -> error , LOG_ERR );
2013-09-10 15:45:36 +02:00
return - 2 ;
}
2020-12-09 13:31:14 +01:00
if ( ! is_array ( $this -> data )) {
2019-11-13 19:35:39 +01:00
$this -> error = " Call to draw method was made but SetData was not called or called with an empty dataset for parameters " ;
2020-12-09 13:31:14 +01:00
dol_syslog ( get_class ( $this ) . " ::draw " . $this -> error , LOG_ERR );
2013-09-10 15:45:36 +02:00
return - 1 ;
}
2020-12-09 13:31:14 +01:00
if ( count ( $this -> data ) < 1 ) {
2019-11-13 19:35:39 +01:00
$this -> error = " Call to draw method was made but SetData was is an empty dataset " ;
2020-12-09 13:31:14 +01:00
dol_syslog ( get_class ( $this ) . " ::draw " . $this -> error , LOG_WARNING );
2018-02-04 12:14:39 +01:00
}
2020-12-09 13:31:14 +01:00
$call = " draw_ " . $this -> _library ;
2019-11-13 19:35:39 +01:00
call_user_func_array ( array ( $this , $call ), array ( $file , $fileurl ));
2013-09-10 15:45:36 +02:00
}
2020-10-31 14:32:18 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2013-09-10 15:45:36 +02:00
/**
2016-04-22 12:11:57 +02:00
* Build a graph using JFlot library . Input when calling this method should be :
2017-05-31 10:43:01 +02:00
* $this -> data = array ( array ( 0 => 'labelxA' , 1 => yA ), array ( 'labelxB' , yB ));
* $this -> data = array ( array ( 0 => 'labelxA' , 1 => yA1 , ... , n => yAn ), array ( 'labelxB' , yB1 , ... yBn )); // or when there is n series to show for each x
2017-11-23 20:00:54 +01:00
* $this -> data = array ( array ( 'label' => 'labelxA' , 'data' => yA ), array ( 'labelxB' , yB )); // Syntax deprecated
2013-09-10 15:45:36 +02:00
* $this -> legend = array ( " Val1 " , ... , " Valn " ); // list of n series name
2020-03-04 22:29:21 +01:00
* $this -> type = array ( 'bars' , ... 'lines' , 'linesnopoint' ); or array ( 'pie' ) or array ( 'polar' )
2013-09-10 15:45:36 +02:00
* $this -> mode = 'depth' ? ? ?
* $this -> bgcolorgrid
* $this -> datacolor
2016-04-22 12:11:57 +02:00
* $this -> shownodatagraph
2013-09-10 15:45:36 +02:00
*
* @ param string $file Image file name to use to save onto disk ( also used as javascript unique id )
2016-04-22 12:11:57 +02:00
* @ param string $fileurl Url path to show image if saved onto disk . Never used here .
2013-09-10 15:45:36 +02:00
* @ return void
*/
2018-10-26 17:32:32 +02:00
private function draw_jflot ( $file , $fileurl )
2013-09-10 15:45:36 +02:00
{
2020-10-31 14:32:18 +01:00
// phpcs:enable
2020-03-04 22:29:21 +01:00
global $conf , $langs ;
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
dol_syslog ( get_class ( $this ) . " ::draw_jflot this->type= " . join ( ',' , $this -> type ) . " this->MaxValue= " . $this -> MaxValue );
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
if ( empty ( $this -> width ) && empty ( $this -> height )) {
2013-09-10 15:45:36 +02:00
print 'Error width or height not set' ;
return ;
}
2020-01-16 02:54:00 +01:00
$legends = array ();
$nblot = 0 ;
2020-01-09 16:26:30 +01:00
if ( is_array ( $this -> data ) && is_array ( $this -> data [ 0 ])) {
2020-01-16 02:54:00 +01:00
$nblot = count ( $this -> data [ 0 ]) - 1 ; // -1 to remove legend
2020-01-09 16:26:30 +01:00
}
2018-02-04 12:14:39 +01:00
if ( $nblot < 0 ) dol_syslog ( 'Bad value for property ->data. Must be set by mydolgraph->SetData before calling mydolgrapgh->draw' , LOG_WARNING );
2020-01-16 02:54:00 +01:00
$firstlot = 0 ;
2013-09-10 15:45:36 +02:00
// 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
2020-01-16 02:54:00 +01:00
$i = $firstlot ;
$serie = array ();
2013-09-10 15:45:36 +02:00
while ( $i < $nblot ) // Loop on each serie
{
2020-01-16 02:54:00 +01:00
$values = array (); // Array with horizontal y values (specific values of a serie) for each abscisse x
2020-12-09 13:31:14 +01:00
$serie [ $i ] = " var d " . $i . " = []; \n " ;
2013-09-10 15:45:36 +02:00
// Fill array $values
2020-01-16 02:54:00 +01:00
$x = 0 ;
foreach ( $this -> data as $valarray ) // Loop on each x
2013-09-10 15:45:36 +02:00
{
$legends [ $x ] = $valarray [ 0 ];
2020-01-16 02:54:00 +01:00
$values [ $x ] = ( is_numeric ( $valarray [ $i + 1 ]) ? $valarray [ $i + 1 ] : null );
2013-09-10 15:45:36 +02:00
$x ++ ;
}
2020-12-09 13:31:14 +01:00
if ( isset ( $this -> type [ $firstlot ]) && in_array ( $this -> type [ $firstlot ], array ( 'pie' , 'piesemicircle' , 'polar' ))) {
2020-01-16 02:54:00 +01:00
foreach ( $values as $x => $y ) {
2020-12-09 13:31:14 +01:00
if ( isset ( $y )) $serie [ $i ] .= 'd' . $i . '.push({"label":"' . dol_escape_js ( $legends [ $x ]) . '", "data":' . $y . '});' . " \n " ;
2013-09-10 15:45:36 +02:00
}
2020-05-21 15:05:19 +02:00
} else {
2020-01-16 02:54:00 +01:00
foreach ( $values as $x => $y ) {
2020-12-09 13:31:14 +01:00
if ( isset ( $y )) $serie [ $i ] .= 'd' . $i . '.push([' . $x . ', ' . $y . ']);' . " \n " ;
2013-09-10 15:45:36 +02:00
}
}
2013-09-01 20:55:59 +02:00
2013-08-05 18:30:10 +02:00
unset ( $values );
2013-09-10 15:45:36 +02:00
$i ++ ;
}
2020-01-16 02:54:00 +01:00
$tag = dol_escape_htmltag ( dol_string_unaccent ( dol_string_nospecial ( basename ( $file ), '_' , array ( '-' , '.' ))));
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
$this -> stringtoshow = '<!-- Build using jflot -->' . " \n " ;
if ( ! empty ( $this -> title )) $this -> stringtoshow .= '<div class="center dolgraphtitle' . ( empty ( $this -> cssprefix ) ? '' : ' dolgraphtitle' . $this -> cssprefix ) . '">' . $this -> title . '</div>' ;
if ( ! empty ( $this -> shownographyet )) {
$this -> stringtoshow .= '<div style="width:' . $this -> width . 'px;height:' . $this -> height . 'px;" class="nographyet"></div>' ;
$this -> stringtoshow .= '<div class="nographyettext margintoponly">' . $langs -> trans ( " NotEnoughDataYet " ) . '...</div>' ;
2020-10-31 14:32:18 +01:00
return ;
2016-04-22 12:11:57 +02:00
}
2020-02-29 01:26:24 +01:00
// Start the div that will contains all the graph
2020-03-12 12:45:44 +01:00
$dolxaxisvertical = '' ;
if ( count ( $this -> data ) > 20 ) $dolxaxisvertical = 'dol-xaxis-vertical' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '<div id="placeholder_' . $tag . '" style="width:' . $this -> width . 'px;height:' . $this -> height . 'px;" class="dolgraph' . ( empty ( $dolxaxisvertical ) ? '' : ' ' . $dolxaxisvertical ) . ( empty ( $this -> cssprefix ) ? '' : ' dolgraph' . $this -> cssprefix ) . ' center"></div>' . " \n " ;
2017-08-23 21:01:14 +02:00
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '<script id="' . $tag . '">' . " \n " ;
$this -> stringtoshow .= '$(function () {' . " \n " ;
2020-01-16 02:54:00 +01:00
$i = $firstlot ;
2020-12-09 13:31:14 +01:00
if ( $nblot < 0 ) {
$this -> stringtoshow .= '<!-- No series of data -->' . " \n " ;
2020-05-21 15:05:19 +02:00
} else {
2020-12-09 13:31:14 +01:00
while ( $i < $nblot ) {
$this -> stringtoshow .= '<!-- Serie ' . $i . ' -->' . " \n " ;
$this -> stringtoshow .= $serie [ $i ] . " \n " ;
2018-06-11 14:22:01 +02:00
$i ++ ;
}
2013-09-10 15:45:36 +02:00
}
2020-01-16 02:54:00 +01:00
$this -> stringtoshow .= " \n " ;
2013-09-10 15:45:36 +02:00
// Special case for Graph of type 'pie'
2020-12-09 13:31:14 +01:00
if ( isset ( $this -> type [ $firstlot ]) && in_array ( $this -> type [ $firstlot ], array ( 'pie' , 'piesemicircle' , 'polar' ))) {
2020-01-16 02:54:00 +01:00
$datacolor = array ();
2020-03-05 01:38:41 +01:00
foreach ( $this -> datacolor as $val ) {
2020-12-09 13:31:14 +01:00
if ( is_array ( $val )) $datacolor [] = " # " . sprintf ( " %02x%02x%02x " , $val [ 0 ], $val [ 1 ], $val [ 2 ]); // If datacolor is array(R, G, B)
else $datacolor [] = " # " . str_replace ( array ( '#' , '-' ), '' , $val ); // If $val is '124' or '#124'
2020-03-05 01:38:41 +01:00
}
2013-08-09 19:19:48 +02:00
2020-01-16 02:54:00 +01:00
$urltemp = '' ; // TODO Add support for url link into labels
$showlegend = $this -> showlegend ;
$showpointvalue = $this -> showpointvalue ;
$showpercent = $this -> showpercent ;
2013-09-01 20:55:59 +02:00
2020-01-16 02:54:00 +01:00
$this -> stringtoshow .= '
2020-12-09 13:31:14 +01:00
function plotWithOptions_ ' . $tag . ' () {
$ . plot ( $ ( " #placeholder_' . $tag . ' " ), d0 ,
2013-09-10 15:45:36 +02:00
{
2015-07-05 22:04:30 +02:00
series : {
pie : {
show : true ,
radius : 0.8 ,
2020-12-09 13:31:14 +01:00
' . ($this->combine ? '
2015-07-05 22:04:30 +02:00
combine : {
2020-12-09 13:31:14 +01:00
threshold : ' . $this->combine . '
}, ' : ' ') . '
2015-07-05 22:04:30 +02:00
label : {
show : true ,
radius : 0.9 ,
formatter : function ( label , series ) {
var percent = Math . round ( series . percent );
var number = series . data [ 0 ][ 1 ];
return \ '' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '<span style="font-size:8pt;text-align:center;padding:2px;color:black;">' ;
if ( $urltemp ) $this -> stringtoshow .= '<a style="color: #FFFFFF;" border="0" href="' . $urltemp . '">' ;
$this -> stringtoshow .= '\'+' ;
$this -> stringtoshow .= ( $showlegend ? '' : 'label+\' \'+' ); // Hide label if already shown in legend
$this -> stringtoshow .= ( $showpointvalue ? 'number+' : '' );
$this -> stringtoshow .= ( $showpercent ? '\'<br/>\'+percent+\'%\'+' : '' );
$this -> stringtoshow .= '\'' ;
if ( $urltemp ) $this -> stringtoshow .= '</a>' ;
$this -> stringtoshow .= ' </ span > \ ' ;
2015-07-05 22:04:30 +02:00
},
background : {
opacity : 0.0 ,
color : \ ' #000000\'
}
}
}
2013-09-10 16:12:20 +02:00
},
zoom : {
2015-07-05 22:04:30 +02:00
interactive : true
2013-09-10 16:12:20 +02:00
},
pan : {
2015-07-05 22:04:30 +02:00
interactive : true
2013-09-10 16:12:20 +02:00
}, ' ;
2020-12-09 13:31:14 +01:00
if ( count ( $datacolor )) {
$this -> stringtoshow .= 'colors: ' . ( ! empty ( $data [ 'seriescolor' ]) ? json_encode ( $data [ 'seriescolor' ]) : json_encode ( $datacolor )) . ',' ;
2013-09-10 15:45:36 +02:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'legend: {show: ' . ( $showlegend ? 'true' : 'false' ) . ' , position : \ ' ne\ ' }
2013-09-10 15:45:36 +02:00
});
2020-12-09 13:31:14 +01:00
} ' . " \n " ;
2013-08-05 17:19:49 +02:00
}
// Other cases, graph of type 'bars', 'lines'
2020-05-21 01:41:27 +02:00
else {
2013-08-05 17:19:49 +02:00
// Add code to support tooltips
2020-10-31 14:32:18 +01:00
// TODO: remove js css and use graph-tooltip-inner class instead by adding css in each themes
2019-11-13 19:35:39 +01:00
$this -> stringtoshow .= '
2020-12-09 13:31:14 +01:00
function showTooltip_ ' . $tag . ' ( x , y , contents ) {
$ ( \ '<div class="graph-tooltip-inner" id="tooltip_' . $tag . ' " > \ ' + contents + \ '</div> \ ').css( {
2013-09-10 16:12:20 +02:00
position : \ ' absolute\ ' ,
display : \ ' none\ ' ,
2018-10-24 23:25:40 +02:00
top : y + 10 ,
left : x + 15 ,
border : \ ' 1 px solid #000\',
padding : \ ' 5 px\ ' ,
\ ' background - color\ ' : \ ' #000\',
\ ' color\ ' : \ ' #fff\',
\ ' font - weight\ ' : \ ' bold\ ' ,
2013-09-10 16:12:20 +02:00
width : 200 ,
opacity : 0.80
2018-10-25 00:24:25 +02:00
}) . appendTo ( " body " ) . fadeIn ( 100 );
2013-09-10 16:12:20 +02:00
}
2015-03-11 03:58:57 +01:00
2013-09-10 16:12:20 +02:00
var previousPoint = null ;
2020-12-09 13:31:14 +01:00
$ ( " #placeholder_' . $tag . ' " ) . bind ( " plothover " , function ( event , pos , item ) {
2013-09-10 16:12:20 +02:00
$ ( " #x " ) . text ( pos . x . toFixed ( 2 ));
$ ( " #y " ) . text ( pos . y . toFixed ( 2 ));
2015-03-11 03:58:57 +01:00
2013-09-10 16:12:20 +02:00
if ( item ) {
if ( previousPoint != item . dataIndex ) {
previousPoint = item . dataIndex ;
2015-03-11 03:58:57 +01:00
2013-09-10 16:12:20 +02:00
$ ( " #tooltip " ) . remove ();
/* console.log(item); */
var x = item . datapoint [ 0 ] . toFixed ( 2 );
var y = item . datapoint [ 1 ] . toFixed ( 2 );
var z = item . series . xaxis . ticks [ item . dataIndex ] . label ;
' ;
2020-12-09 13:31:14 +01:00
if ( $this -> showpointvalue > 0 ) $this -> stringtoshow .= '
showTooltip_ ' . $tag . ' ( item . pageX , item . pageY , item . series . label + " <br> " + z + " => " + y );
2013-09-10 16:12:20 +02:00
' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '
2013-09-10 16:12:20 +02:00
}
}
else {
2020-12-09 13:31:14 +01:00
$ ( " #tooltip_' . $tag . ' " ) . remove ();
2013-09-10 16:12:20 +02:00
previousPoint = null ;
}
});
2013-09-10 15:45:36 +02:00
' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'var stack = null, steps = false;' . " \n " ;
2013-09-10 15:45:36 +02:00
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'function plotWithOptions_' . $tag . '() {' . " \n " ;
$this -> stringtoshow .= '$.plot($("#placeholder_' . $tag . '"), [ ' . " \n " ;
2019-11-13 19:35:39 +01:00
$i = $firstlot ;
2020-12-09 13:31:14 +01:00
while ( $i < $nblot ) {
if ( $i > $firstlot ) $this -> stringtoshow .= ', ' . " \n " ;
2019-11-13 19:35:39 +01:00
$color = sprintf ( " %02x%02x%02x " , $this -> datacolor [ $i ][ 0 ], $this -> datacolor [ $i ][ 1 ], $this -> datacolor [ $i ][ 2 ]);
$this -> stringtoshow .= '{ ' ;
2020-10-31 18:51:30 +01:00
if ( ! isset ( $this -> type [ $i ]) || $this -> type [ $i ] == 'bars' ) {
2020-10-31 14:32:18 +01:00
if ( $nblot == 3 ) {
if ( $i == $firstlot ) $align = 'right' ;
elseif ( $i == $firstlot + 1 ) $align = 'center' ;
else $align = 'left' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'bars: { lineWidth: 1, show: true, align: "' . $align . '", barWidth: 0.45 }, ' ;
} else $this -> stringtoshow .= 'bars: { lineWidth: 1, show: true, align: "' . ( $i == $firstlot ? 'center' : 'left' ) . '", barWidth: 0.5 }, ' ;
2020-10-31 14:32:18 +01:00
}
2020-12-09 13:31:14 +01:00
if ( isset ( $this -> type [ $i ]) && ( $this -> type [ $i ] == 'lines' || $this -> type [ $i ] == 'linesnopoint' )) $this -> stringtoshow .= 'lines: { show: true, fill: false }, points: { show: ' . ( $this -> type [ $i ] == 'linesnopoint' ? 'false' : 'true' ) . ' }, ' ;
$this -> stringtoshow .= 'color: "#' . $color . '", label: "' . ( isset ( $this -> Legend [ $i ]) ? dol_escape_js ( $this -> Legend [ $i ]) : '' ) . '", data: d' . $i . ' }' ;
2013-09-10 15:45:36 +02:00
$i ++ ;
}
2018-10-25 00:24:25 +02:00
// shadowSize: 0 -> Drawing is faster without shadows
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= " \n " . ' ], { series: { shadowSize: 0, stack: stack, lines: { fill: false, steps: steps }, bars: { barWidth: 0.6, fillColor: { colors: [{opacity: 0.9 }, {opacity: 0.85}] }} }' . " \n " ;
2013-09-10 15:45:36 +02:00
// Xaxis
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ', xaxis: { ticks: [' . " \n " ;
2019-11-13 19:35:39 +01:00
$x = 0 ;
2020-12-09 13:31:14 +01:00
foreach ( $this -> data as $key => $valarray ) {
if ( $x > 0 ) $this -> stringtoshow .= ', ' . " \n " ;
$this -> stringtoshow .= ' [' . $x . ', "' . $valarray [ 0 ] . '"]' ;
2013-09-10 15:45:36 +02:00
$x ++ ;
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '] }' . " \n " ;
2013-09-10 15:45:36 +02:00
// Yaxis
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ', yaxis: { min: ' . $this -> MinValue . ', max: ' . ( $this -> MaxValue ) . ' }' . " \n " ;
2013-09-10 15:45:36 +02:00
// Background color
2019-11-13 19:35:39 +01:00
$color1 = sprintf ( " %02x%02x%02x " , $this -> bgcolorgrid [ 0 ], $this -> bgcolorgrid [ 0 ], $this -> bgcolorgrid [ 2 ]);
$color2 = sprintf ( " %02x%02x%02x " , $this -> bgcolorgrid [ 0 ], $this -> bgcolorgrid [ 1 ], $this -> bgcolorgrid [ 2 ]);
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ', grid: { hoverable: true, backgroundColor: { colors: ["#' . $color1 . '", "#' . $color2 . '"] }, borderWidth: 1, borderColor: \'#e6e6e6\', tickColor : \'#e6e6e6\' }' . " \n " ;
$this -> stringtoshow .= '});' . " \n " ;
$this -> stringtoshow .= '}' . " \n " ;
2013-08-05 17:19:49 +02:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'plotWithOptions_' . $tag . '();' . " \n " ;
$this -> stringtoshow .= '});' . " \n " ;
$this -> stringtoshow .= '</script>' . " \n " ;
2013-09-10 15:45:36 +02:00
}
2020-03-04 22:29:21 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Build a graph using Chart library . Input when calling this method should be :
* $this -> data = array ( array ( 0 => 'labelxA' , 1 => yA ), array ( 'labelxB' , yB ));
* $this -> data = array ( array ( 0 => 'labelxA' , 1 => yA1 , ... , n => yAn ), array ( 'labelxB' , yB1 , ... yBn )); // or when there is n series to show for each x
* $this -> data = array ( array ( 'label' => 'labelxA' , 'data' => yA ), array ( 'labelxB' , yB )); // Syntax deprecated
* $this -> legend = array ( " Val1 " , ... , " Valn " ); // list of n series name
2020-03-05 16:30:55 +01:00
* $this -> type = array ( 'bars' , ... 'lines' , 'linesnopoint' ); or array ( 'pie' ) or array ( 'polar' ) or array ( 'piesemicircle' );
2020-03-04 22:29:21 +01:00
* $this -> mode = 'depth' ? ? ?
* $this -> bgcolorgrid
* $this -> datacolor
* $this -> shownodatagraph
*
* @ 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 . Never used here .
* @ return void
*/
private function draw_chart ( $file , $fileurl )
{
// phpcs:enable
global $conf , $langs ;
2020-12-09 13:31:14 +01:00
dol_syslog ( get_class ( $this ) . " ::draw_chart this->type= " . join ( ',' , $this -> type ) . " this->MaxValue= " . $this -> MaxValue );
2020-03-04 22:29:21 +01:00
2020-12-09 13:31:14 +01:00
if ( empty ( $this -> width ) && empty ( $this -> height )) {
2020-03-04 22:29:21 +01:00
print 'Error width or height not set' ;
return ;
}
2020-03-05 17:23:19 +01:00
$showlegend = $this -> showlegend ;
2020-03-04 22:29:21 +01:00
$legends = array ();
$nblot = 0 ;
2020-03-09 22:52:30 +01:00
if ( is_array ( $this -> data )) {
foreach ( $this -> data as $valarray ) // Loop on each x
{
$nblot = max ( $nblot , count ( $valarray ) - 1 ); // -1 to remove legend
}
2020-03-04 22:29:21 +01:00
}
2020-03-09 22:52:30 +01:00
//var_dump($nblot);
2020-03-04 22:29:21 +01:00
if ( $nblot < 0 ) dol_syslog ( 'Bad value for property ->data. Must be set by mydolgraph->SetData before calling mydolgrapgh->draw' , LOG_WARNING );
$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
2020-12-09 13:31:14 +01:00
$serie = array ();
$arrayofgroupslegend = array ();
2020-03-06 20:02:05 +01:00
//var_dump($this->data);
$i = $firstlot ;
2020-03-04 22:29:21 +01:00
while ( $i < $nblot ) // Loop on each serie
{
2020-03-06 01:18:35 +01:00
$values = array (); // Array with horizontal y values (specific values of a serie) for each abscisse x (with x=0,1,2,...)
2020-03-04 22:29:21 +01:00
$serie [ $i ] = " " ;
2020-03-06 01:42:42 +01:00
2020-03-04 22:29:21 +01:00
// Fill array $values
$x = 0 ;
foreach ( $this -> data as $valarray ) // Loop on each x
{
2020-03-06 01:18:35 +01:00
$legends [ $x ] = ( array_key_exists ( 'label' , $valarray ) ? $valarray [ 'label' ] : $valarray [ 0 ]);
$array_of_ykeys = array_keys ( $valarray );
$alabelexists = 1 ;
2020-03-12 12:45:44 +01:00
$tmpykey = explode ( '_' , ( $array_of_ykeys [ $i + ( $alabelexists ? 1 : 0 )]), 3 );
if ( ! empty ( $tmpykey [ 2 ]) || $tmpykey [ 2 ] == '0' ) { // This is a 'Group by' array
2020-12-09 13:31:14 +01:00
$tmpvalue = ( array_key_exists ( 'y_' . $tmpykey [ 1 ] . '_' . $tmpykey [ 2 ], $valarray ) ? $valarray [ 'y_' . $tmpykey [ 1 ] . '_' . $tmpykey [ 2 ]] : $valarray [ $i + 1 ]);
2020-03-12 12:45:44 +01:00
$values [ $x ] = ( is_numeric ( $tmpvalue ) ? $tmpvalue : null );
2020-03-06 01:18:35 +01:00
$arrayofgroupslegend [ $i ] = array (
2020-12-09 13:31:14 +01:00
'stacknum' => $tmpykey [ 1 ],
2020-03-06 01:18:35 +01:00
'legend' => $this -> Legend [ $tmpykey [ 1 ]],
2020-12-09 13:31:14 +01:00
'legendwithgroup' => $this -> Legend [ $tmpykey [ 1 ]] . ' - ' . $tmpykey [ 2 ]
2020-03-06 01:18:35 +01:00
);
} else {
2020-12-09 13:31:14 +01:00
$tmpvalue = ( array_key_exists ( 'y_' . $i , $valarray ) ? $valarray [ 'y_' . $i ] : $valarray [ $i + 1 ]);
2020-03-09 22:52:30 +01:00
//var_dump($i.'_'.$x.'_'.$tmpvalue);
2020-03-12 12:45:44 +01:00
$values [ $x ] = ( is_numeric ( $tmpvalue ) ? $tmpvalue : null );
2020-03-06 01:18:35 +01:00
}
2020-03-04 22:29:21 +01:00
$x ++ ;
}
2020-03-09 22:52:30 +01:00
//var_dump($values);
2020-03-05 16:30:55 +01:00
$j = 0 ;
foreach ( $values as $x => $y ) {
if ( isset ( $y )) {
2020-12-09 13:31:14 +01:00
$serie [ $i ] .= ( $j > 0 ? " , " : " " ) . $y ;
2020-03-09 22:52:30 +01:00
} else {
2020-12-09 13:31:14 +01:00
$serie [ $i ] .= ( $j > 0 ? " , " : " " ) . 'null' ;
2020-03-04 22:29:21 +01:00
}
2020-03-09 22:52:30 +01:00
$j ++ ;
2020-03-04 22:29:21 +01:00
}
2020-03-12 12:45:44 +01:00
$values = null ; // Free mem
2020-03-04 22:29:21 +01:00
$i ++ ;
}
2020-03-06 20:02:05 +01:00
//var_dump($serie);
//var_dump($arrayofgroupslegend);
2020-03-04 22:29:21 +01:00
$tag = dol_escape_htmltag ( dol_string_unaccent ( dol_string_nospecial ( basename ( $file ), '_' , array ( '-' , '.' ))));
2020-12-09 13:31:14 +01:00
$this -> stringtoshow = '<!-- Build using chart -->' . " \n " ;
2020-12-11 17:57:57 +01:00
if ( ! empty ( $this -> title )) $this -> stringtoshow .= '<div class="center dolgraphtitle' . ( empty ( $this -> cssprefix ) ? '' : ' dolgraphtitle' . $this -> cssprefix ) . '">' . $this -> title . '</div>' ;
2020-12-09 13:31:14 +01:00
if ( ! empty ( $this -> shownographyet )) {
$this -> stringtoshow .= '<div style="width:' . $this -> width . ( strpos ( $this -> width , '%' ) > 0 ? '' : 'px' ) . '; height:' . $this -> height . 'px;" class="nographyet"></div>' ;
$this -> stringtoshow .= '<div class="nographyettext margintoponly">' . $langs -> trans ( " NotEnoughDataYet " ) . '...</div>' ;
2020-03-04 22:29:21 +01:00
return ;
}
// Start the div that will contains all the graph
2020-04-10 10:59:32 +02:00
$dolxaxisvertical = '' ;
if ( count ( $this -> data ) > 20 ) $dolxaxisvertical = 'dol-xaxis-vertical' ;
2020-03-04 22:29:21 +01:00
// No height for the pie grah
2020-03-05 00:17:16 +01:00
$cssfordiv = 'dolgraphchart' ;
2020-12-09 13:31:14 +01:00
if ( isset ( $this -> type [ $firstlot ])) $cssfordiv .= ' dolgraphchar' . $this -> type [ $firstlot ];
$this -> stringtoshow .= '<div id="placeholder_' . $tag . '" style="min-height: ' . $this -> height . ( strpos ( $this -> height , '%' ) > 0 ? '' : 'px' ) . '; width:' . $this -> width . ( strpos ( $this -> width , '%' ) > 0 ? '' : 'px' ) . ';" class="' . $cssfordiv . ' dolgraph' . ( empty ( $dolxaxisvertical ) ? '' : ' ' . $dolxaxisvertical ) . ( empty ( $this -> cssprefix ) ? '' : ' dolgraph' . $this -> cssprefix ) . ' center"><canvas id="canvas_' . $tag . '"></canvas></div>' . " \n " ;
2020-03-04 22:29:21 +01:00
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '<script id="' . $tag . '">' . " \n " ;
2020-03-04 22:29:21 +01:00
$i = $firstlot ;
2020-12-09 13:31:14 +01:00
if ( $nblot < 0 ) {
2020-03-04 22:29:21 +01:00
$this -> stringtoshow .= '<!-- No series of data -->' ;
2020-05-21 15:05:19 +02:00
} else {
2020-12-09 13:31:14 +01:00
while ( $i < $nblot ) {
2020-03-04 22:29:21 +01:00
//$this->stringtoshow .= '<!-- Series '.$i.' -->'."\n";
//$this->stringtoshow .= $serie[$i]."\n";
$i ++ ;
}
}
$this -> stringtoshow .= " \n " ;
2020-03-05 16:30:55 +01:00
// Special case for Graph of type 'pie', 'piesemicircle', or 'polar'
2020-12-09 13:31:14 +01:00
if ( isset ( $this -> type [ $firstlot ]) && ( in_array ( $this -> type [ $firstlot ], array ( 'pie' , 'polar' , 'piesemicircle' )))) {
2020-03-12 12:45:44 +01:00
$type = $this -> type [ $firstlot ]; // pie or polar
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'var options = {' . " \n " ;
2020-03-12 12:45:44 +01:00
$legendMaxLines = 0 ; // Does not work
2020-03-06 11:52:32 +01:00
if ( empty ( $showlegend )) {
$this -> stringtoshow .= 'legend: { display: false }, ' ;
2020-03-06 12:45:02 +01:00
} else {
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'legend: { position: \'' . ( $showlegend == 2 ? 'right' : 'top' ) . '\'' ;
2020-03-12 12:45:44 +01:00
if ( ! empty ( $legendMaxLines )) {
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ', maxLines: ' . $legendMaxLines . '' ;
2020-03-06 12:45:02 +01:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ' }, ' . " \n " ;
2020-03-06 11:52:32 +01:00
}
2020-03-06 12:45:02 +01:00
2020-03-05 16:30:55 +01:00
if ( $this -> type [ $firstlot ] == 'piesemicircle' ) {
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'circumference: Math.PI,' . " \n " ;
$this -> stringtoshow .= 'rotation: -Math.PI,' . " \n " ;
2020-03-05 16:30:55 +01:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'elements: { arc: {' . " \n " ;
2020-03-05 16:30:55 +01:00
// Color of earch arc
2020-03-05 01:38:41 +01:00
$this -> stringtoshow .= 'backgroundColor: [' ;
2020-12-09 13:31:14 +01:00
$i = 0 ;
$foundnegativecolor = 0 ;
2020-03-12 12:45:44 +01:00
foreach ( $legends as $val ) // Loop on each serie
2020-03-04 22:29:21 +01:00
{
2020-12-09 13:31:14 +01:00
if ( $i > 0 ) $this -> stringtoshow .= ', ' . " \n " ;
if ( is_array ( $this -> datacolor [ $i ])) $color = 'rgb(' . $this -> datacolor [ $i ][ 0 ] . ', ' . $this -> datacolor [ $i ][ 1 ] . ', ' . $this -> datacolor [ $i ][ 2 ] . ')' ; // If datacolor is array(R, G, B)
2020-03-05 01:38:41 +01:00
else {
$tmp = str_replace ( '#' , '' , $this -> datacolor [ $i ]);
if ( strpos ( $tmp , '-' ) !== false ) {
$foundnegativecolor ++ ;
2020-03-12 12:45:44 +01:00
$color = '#FFFFFF' ; // If $val is '-123'
2020-12-09 13:31:14 +01:00
} else $color = " # " . $tmp ; // If $val is '123' or '#123'
2020-03-05 01:38:41 +01:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= " ' " . $color . " ' " ;
2020-03-04 22:29:21 +01:00
$i ++ ;
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '], ' . " \n " ;
2020-03-05 16:30:55 +01:00
// Border color
2020-03-05 01:38:41 +01:00
if ( $foundnegativecolor ) {
$this -> stringtoshow .= 'borderColor: [' ;
$i = 0 ;
2020-03-12 12:45:44 +01:00
foreach ( $legends as $val ) // Loop on each serie
2020-03-05 01:38:41 +01:00
{
2020-12-09 13:31:14 +01:00
if ( $i > 0 ) $this -> stringtoshow .= ', ' . " \n " ;
2020-03-12 12:45:44 +01:00
if ( is_array ( $this -> datacolor [ $i ])) $color = 'null' ; // If datacolor is array(R, G, B)
2020-03-05 01:38:41 +01:00
else {
$tmp = str_replace ( '#' , '' , $this -> datacolor [ $i ]);
2020-12-09 13:31:14 +01:00
if ( strpos ( $tmp , '-' ) !== false ) $color = '#' . str_replace ( '-' , '' , $tmp ); // If $val is '-123'
2020-03-12 12:45:44 +01:00
else $color = 'null' ; // If $val is '123' or '#123'
2020-03-04 22:29:21 +01:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ( $color == 'null' ? " 'rgba(0,0,0,0.2)' " : " ' " . $color . " ' " );
2020-03-05 01:38:41 +01:00
$i ++ ;
2020-03-04 22:29:21 +01:00
}
2020-03-05 01:38:41 +01:00
$this -> stringtoshow .= ']' ;
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '} } };' . " \n " ;
2020-03-04 22:29:21 +01:00
$this -> stringtoshow .= '
2020-12-09 13:31:14 +01:00
var ctx = document . getElementById ( " canvas_' . $tag . ' " ) . getContext ( " 2d " );
2020-03-04 22:29:21 +01:00
var chart = new Chart ( ctx , {
// The type of chart we want to create
2020-12-09 13:31:14 +01:00
type : \ '' . ( in_array ( $type , array ( 'pie' , 'piesemicircle' )) ? 'doughnut' : 'polarArea' ) . ' \ ' ,
2020-03-04 22:29:21 +01:00
// Configuration options go here
options : options ,
data : {
labels : [ ' ;
$i = 0 ;
2020-03-12 12:45:44 +01:00
foreach ( $legends as $val ) // Loop on each serie
2020-03-04 22:29:21 +01:00
{
2020-03-05 00:17:16 +01:00
if ( $i > 0 ) $this -> stringtoshow .= ', ' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= " ' " . dol_escape_js ( dol_trunc ( $val , 32 )) . " ' " ;
2020-03-04 22:29:21 +01:00
$i ++ ;
}
$this -> stringtoshow .= ' ],
datasets : [ ' ;
$i = 0 ;
$i = 0 ;
while ( $i < $nblot ) // Loop on each serie
{
2020-12-09 13:31:14 +01:00
$color = 'rgb(' . $this -> datacolor [ $i ][ 0 ] . ', ' . $this -> datacolor [ $i ][ 1 ] . ', ' . $this -> datacolor [ $i ][ 2 ] . ')' ;
2020-03-04 22:29:21 +01:00
//$color = (!empty($data['seriescolor']) ? json_encode($data['seriescolor']) : json_encode($datacolor));
2020-12-09 13:31:14 +01:00
if ( $i > 0 ) $this -> stringtoshow .= ', ' . " \n " ;
$this -> stringtoshow .= '{' . " \n " ;
2020-03-04 22:29:21 +01:00
//$this->stringtoshow .= 'borderColor: \''.$color.'\', ';
//$this->stringtoshow .= 'backgroundColor: \''.$color.'\', ';
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ' data: [' . $serie [ $i ] . ']' ;
$this -> stringtoshow .= '}' . " \n " ;
2020-03-04 22:29:21 +01:00
$i ++ ;
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ']' . " \n " ;
$this -> stringtoshow .= '}' . " \n " ;
$this -> stringtoshow .= '});' . " \n " ;
2020-03-04 22:29:21 +01:00
}
2020-03-05 00:17:16 +01:00
// Other cases, graph of type 'bars', 'lines', 'linesnopoint'
2020-05-21 01:41:27 +02:00
else {
2020-03-05 00:17:16 +01:00
$type = 'bar' ;
2020-12-11 17:57:57 +01:00
2020-12-09 13:31:14 +01:00
$isfunnel = false ;
2020-12-11 17:57:57 +01:00
if ( $file == 'idgraphleadfunnel' ) $isfunnel = true ;
2020-03-04 22:29:21 +01:00
if ( ! isset ( $this -> type [ $firstlot ]) || $this -> type [ $firstlot ] == 'bars' ) $type = 'bar' ;
2020-12-04 22:30:34 +01:00
if ( isset ( $this -> type [ $firstlot ]) && $this -> type [ $firstlot ] == 'horizontalbars' ) $type = 'horizontalBar' ;
2020-03-05 00:17:16 +01:00
if ( isset ( $this -> type [ $firstlot ]) && ( $this -> type [ $firstlot ] == 'lines' || $this -> type [ $firstlot ] == 'linesnopoint' )) $type = 'line' ;
2020-03-04 22:29:21 +01:00
2020-03-06 02:24:24 +01:00
$this -> stringtoshow .= 'var options = { maintainAspectRatio: false, aspectRatio: 2.5, ' ;
2020-03-06 09:51:30 +01:00
if ( empty ( $showlegend )) {
$this -> stringtoshow .= 'legend: { display: false }, ' ;
}
2020-03-06 02:24:24 +01:00
$this -> stringtoshow .= 'scales: { xAxes: [{ ' ;
2020-12-11 17:57:57 +01:00
if ( $isfunnel ) { // FIXME Remove isfunnel by introducing a method hideXValues() on dolgraph
$this -> stringtoshow .= ' ticks: { display: false }, display: true,' ;
2020-12-09 13:31:14 +01:00
}
2020-03-06 02:24:24 +01:00
//$this->stringtoshow .= 'type: \'time\', '; // Need Moment.js
$this -> stringtoshow .= 'distribution: \'linear\'' ;
2020-03-08 20:22:46 +01:00
if ( $type == 'bar' && count ( $arrayofgroupslegend ) > 0 ) {
2020-03-06 02:24:24 +01:00
$this -> stringtoshow .= ', stacked: true' ;
2020-03-06 01:18:35 +01:00
}
2020-03-06 02:24:24 +01:00
$this -> stringtoshow .= ' }]' ;
2020-12-14 19:57:59 +01:00
$this -> stringtoshow .= ', yAxes: [{ ticks: { beginAtZero: true }' ;
2020-03-08 20:22:46 +01:00
if ( $type == 'bar' && count ( $arrayofgroupslegend ) > 0 ) {
2020-12-14 19:57:59 +01:00
$this -> stringtoshow .= ', stacked: true' ;
2020-03-06 02:24:24 +01:00
}
2020-12-14 19:57:59 +01:00
$this -> stringtoshow .= ' }] }' ;
2020-12-11 17:57:57 +01:00
// Add a callback to change label to show only positive value
2020-12-10 10:58:07 +01:00
if ( $isfunnel ) {
2020-12-11 17:57:57 +01:00
$this -> stringtoshow .= ' , tooltips : { mode : \ ' nearest\ ' ,
2020-12-10 10:58:07 +01:00
callbacks : {
title : function ( tooltipItem , data ) {
return data . datasets [ tooltipItem [ 0 ] . datasetIndex ] . label ;
},
label : function ( tooltipItem , data ) {
return data . datasets [ tooltipItem . datasetIndex ] . data [ 0 ][ 1 ];
}
}
}, ' ;
}
2020-03-06 01:18:35 +01:00
$this -> stringtoshow .= '};' ;
$this -> stringtoshow .= '
2020-12-09 13:31:14 +01:00
var ctx = document . getElementById ( " canvas_' . $tag . ' " ) . getContext ( " 2d " );
2020-03-04 22:29:21 +01:00
var chart = new Chart ( ctx , {
// The type of chart we want to create
2020-12-09 13:31:14 +01:00
type : \ '' . $type . ' \ ' ,
2020-03-04 22:29:21 +01:00
// Configuration options go here
2020-03-05 02:55:06 +01:00
options : options ,
2020-03-04 22:29:21 +01:00
data : {
labels : [ ' ;
$i = 0 ;
2020-12-11 17:57:57 +01:00
if ( ! $isfunnel ) {
foreach ( $legends as $val ) // Loop on each serie
{
if ( $i > 0 ) $this -> stringtoshow .= ', ' ;
$this -> stringtoshow .= " ' " . dol_escape_js ( dol_trunc ( $val , 32 )) . " ' " ;
$i ++ ;
}
2020-03-04 22:29:21 +01:00
}
2020-03-06 01:18:35 +01:00
//var_dump($arrayofgroupslegend);
2020-03-04 22:29:21 +01:00
$this -> stringtoshow .= ' ],
datasets : [ ' ;
2020-03-06 01:18:35 +01:00
2020-03-07 16:45:28 +01:00
global $theme_datacolor ;
//var_dump($arrayofgroupslegend);
2020-03-06 01:18:35 +01:00
$i = 0 ; $iinstack = 0 ;
$oldstacknum = - 1 ;
2020-03-04 22:29:21 +01:00
while ( $i < $nblot ) // Loop on each serie
{
2020-12-09 13:31:14 +01:00
$foundnegativecolor = 0 ;
2020-03-12 12:45:44 +01:00
$usecolorvariantforgroupby = 0 ;
2020-03-07 16:45:28 +01:00
// We used a 'group by' and we have too many colors so we generated color variants per
if ( is_array ( $arrayofgroupslegend [ $i ]) && count ( $arrayofgroupslegend [ $i ]) > 0 ) { // If we used a group by.
$nbofcolorneeds = count ( $arrayofgroupslegend );
$nbofcolorsavailable = count ( $theme_datacolor );
if ( $nbofcolorneeds > $nbofcolorsavailable ) {
2020-03-09 13:56:25 +01:00
$usecolorvariantforgroupby = 1 ;
2020-03-07 16:45:28 +01:00
}
$textoflegend = $arrayofgroupslegend [ $i ][ 'legendwithgroup' ];
} else {
$textoflegend = $this -> Legend [ $i ];
}
2020-12-15 10:49:07 +01:00
2020-03-09 13:56:25 +01:00
if ( $usecolorvariantforgroupby ) {
2020-03-06 01:18:35 +01:00
$newcolor = $this -> datacolor [ $arrayofgroupslegend [ $i ][ 'stacknum' ]];
2020-03-07 16:45:28 +01:00
// If we change the stack
2020-03-06 01:18:35 +01:00
if ( $oldstacknum == - 1 || $arrayofgroupslegend [ $i ][ 'stacknum' ] != $oldstacknum ) {
$iinstack = 0 ;
2020-03-07 16:45:28 +01:00
}
//var_dump($iinstack);
if ( $iinstack ) {
2020-03-06 01:18:35 +01:00
// Change color with offset of $$iinstack
//var_dump($newcolor);
2020-03-07 16:45:28 +01:00
if ( $iinstack % 2 ) { // We increase agressiveness of reference color for color 2, 4, 6, ...
2020-03-12 12:45:44 +01:00
$ratio = min ( 95 , 10 + 10 * $iinstack ); // step of 20
$brightnessratio = min ( 90 , 5 + 5 * $iinstack ); // step of 10
2020-03-07 16:45:28 +01:00
} else { // We decrease agressiveness of reference color for color 3, 5, 7, ..
2020-12-09 13:31:14 +01:00
$ratio = max ( - 100 , - 15 * $iinstack + 10 ); // step of -20
2020-03-12 12:45:44 +01:00
$brightnessratio = min ( 90 , 10 * $iinstack ); // step of 20
2020-03-07 16:45:28 +01:00
}
//var_dump('Color '.($iinstack+1).' : '.$ratio.' '.$brightnessratio);
2020-03-06 01:18:35 +01:00
$newcolor = array_values ( colorHexToRgb ( colorAgressiveness ( colorArrayToHex ( $newcolor ), $ratio , $brightnessratio ), false , true ));
}
$oldstacknum = $arrayofgroupslegend [ $i ][ 'stacknum' ];
2020-03-04 22:29:21 +01:00
2020-12-09 13:31:14 +01:00
$color = 'rgb(' . $newcolor [ 0 ] . ', ' . $newcolor [ 1 ] . ', ' . $newcolor [ 2 ] . ', 0.9)' ;
$bordercolor = 'rgb(' . $newcolor [ 0 ] . ', ' . $newcolor [ 1 ] . ', ' . $newcolor [ 2 ] . ')' ;
} else { // We do not use a 'group by'
2020-12-11 17:57:57 +01:00
if ( $isfunnel ) {
2020-12-15 10:49:07 +01:00
$bordercolor == 'null' ;
2020-12-11 17:57:57 +01:00
if ( is_array ( $this -> datacolor [ $i ])) {
$color = 'rgb(' . $this -> datacolor [ $i ][ 0 ] . ', ' . $this -> datacolor [ $i ][ 1 ] . ', ' . $this -> datacolor [ $i ][ 2 ] . ', 0.9)' ; // If datacolor is array(R, G, B)
2020-12-09 13:31:14 +01:00
} else {
2020-12-11 17:57:57 +01:00
// TODO FIXME This logic must be in the caller that set $this->datacolor
$tmp = str_replace ( '#' , '' , $this -> datacolor [ $i ]);
if ( strpos ( $tmp , '-' ) !== false ) {
$foundnegativecolor ++ ;
$color = '#FFFFFF' ; // If $val is '-123'
} else {
$color = " # " . $tmp ; // If $val is '123' or '#123'
$bordercolor = $color ;
}
if ( $foundnegativecolor ) {
if ( is_array ( $this -> datacolor [ $i ])) $color = 'null' ; // If datacolor is array(R, G, B)
else {
$tmp = str_replace ( '#' , '' , $this -> datacolor [ $i ]);
if ( strpos ( $tmp , '-' ) !== false ) $bordercolor = '#' . str_replace ( '-' , '' , $tmp ); // If $val is '-123'
else $bordercolor = 'null' ; // If $val is '123' or '#123'
}
2020-12-09 13:31:14 +01:00
}
}
2020-12-15 10:49:07 +01:00
$bordercolor == 'null' ? " 'rgba(0,0,0,0.2)' " : " ' " . $bordercolor . " ' " ;
2020-12-11 17:57:57 +01:00
} else {
$color = 'rgb(' . $this -> datacolor [ $i ][ 0 ] . ', ' . $this -> datacolor [ $i ][ 1 ] . ', ' . $this -> datacolor [ $i ][ 2 ] . ', 0.9)' ;
$bordercolor = $color ;
//$color = (!empty($data['seriescolor']) ? json_encode($data['seriescolor']) : json_encode($datacolor));
2020-12-09 13:31:14 +01:00
}
2020-03-06 01:18:35 +01:00
}
if ( $i > 0 ) $this -> stringtoshow .= ', ' ;
$this -> stringtoshow .= " \n " ;
$this -> stringtoshow .= '{' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'dolibarrinfo: \'y_' . $i . '\', ' ;
$this -> stringtoshow .= 'label: \'' . dol_escape_js ( dol_string_nohtmltag ( $textoflegend )) . '\', ' ;
$this -> stringtoshow .= 'pointStyle: \'' . ( $this -> type [ $i ] == 'linesnopoint' ? 'line' : 'circle' ) . '\', ' ;
$this -> stringtoshow .= 'fill: ' . ( $type == 'bar' ? 'true' : 'false' ) . ', ' ;
2020-12-11 17:57:57 +01:00
if ( $isfunnel ) {
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'borderWidth: \'2\', ' ;
2020-12-11 17:57:57 +01:00
} elseif ( $type == 'bar' || $type == 'horizontalBar' ) {
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= 'borderWidth: \'1\', ' ;
}
$this -> stringtoshow .= 'borderColor: \'' . $bordercolor . '\', ' ;
$this -> stringtoshow .= 'backgroundColor: \'' . $color . '\', ' ;
if ( $arrayofgroupslegend [ $i ]) $this -> stringtoshow .= 'stack: \'' . $arrayofgroupslegend [ $i ][ 'stacknum' ] . '\', ' ;
2020-12-10 10:58:07 +01:00
$this -> stringtoshow .= 'data: [' ;
2020-12-11 17:57:57 +01:00
if ( $isfunnel ) {
2020-12-10 10:58:07 +01:00
$this -> stringtoshow .= '[' .- $serie [ $i ] . ',' . $serie [ $i ] . ']' ;
2020-12-11 17:57:57 +01:00
} else {
2020-12-10 10:58:07 +01:00
$this -> stringtoshow .= $serie [ $i ];
}
$this -> stringtoshow .= ']' ;
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '}' . " \n " ;
2020-03-06 01:18:35 +01:00
2020-03-04 22:29:21 +01:00
$i ++ ;
2020-03-06 01:18:35 +01:00
$iinstack ++ ;
2020-03-04 22:29:21 +01:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= ']' . " \n " ;
$this -> stringtoshow .= '}' . " \n " ;
$this -> stringtoshow .= '});' . " \n " ;
2020-03-04 22:29:21 +01:00
}
2020-12-09 13:31:14 +01:00
$this -> stringtoshow .= '</script>' . " \n " ;
2020-03-04 22:29:21 +01:00
}
2019-11-20 12:43:49 +01:00
/**
* Output HTML string to total value
*
* @ return string HTML string to total value
*/
2020-10-31 14:32:18 +01:00
public function total ()
2019-11-20 12:43:49 +01:00
{
2019-11-20 12:45:12 +01:00
$value = 0 ;
2020-01-18 16:17:07 +01:00
foreach ( $this -> data as $valarray ) // Loop on each x
2019-11-20 12:43:49 +01:00
{
2019-11-20 12:45:12 +01:00
$value += $valarray [ 1 ];
}
return $value ;
2019-11-20 12:43:49 +01:00
}
2013-09-10 15:45:36 +02:00
/**
* Output HTML string to show graph
*
2020-01-25 22:43:24 +01:00
* @ param int | string $shownographyet Show graph to say there is not enough data or the message in $shownographyet if it is a string .
* @ return string HTML string to show graph
2013-09-10 15:45:36 +02:00
*/
2020-10-31 14:32:18 +01:00
public function show ( $shownographyet = 0 )
2013-09-10 15:45:36 +02:00
{
2017-11-23 20:00:54 +01:00
global $langs ;
2020-12-09 13:31:14 +01:00
if ( $shownographyet ) {
$s = '<div class="nographyet" style="width:' . ( preg_match ( '/%/' , $this -> width ) ? $this -> width : $this -> width . 'px' ) . '; height:' . ( preg_match ( '/%/' , $this -> height ) ? $this -> height : $this -> height . 'px' ) . ';"></div>' ;
2020-03-12 11:13:50 +01:00
$s .= '<div class="nographyettext margintoponly">' ;
2020-01-25 22:43:24 +01:00
if ( is_numeric ( $shownographyet )) {
2020-12-09 13:31:14 +01:00
$s .= $langs -> trans ( " NotEnoughDataYet " ) . '...' ;
2020-01-25 22:43:24 +01:00
} else {
2020-12-09 13:31:14 +01:00
$s .= $shownographyet . '...' ;
2020-01-25 22:43:24 +01:00
}
$s .= '</div>' ;
2017-11-23 20:00:54 +01:00
return $s ;
}
2015-03-11 03:58:57 +01:00
return $this -> stringtoshow ;
2013-09-10 15:45:36 +02:00
}
2015-03-11 03:58:57 +01:00
2013-09-10 15:45:36 +02:00
/**
* getDefaultGraphSizeForStats
*
* @ param string $direction 'width' or 'height'
* @ param string $defaultsize Value we want as default size
* @ return int Value of width or height to use by default
*/
2019-02-27 20:45:07 +01:00
public static function getDefaultGraphSizeForStats ( $direction , $defaultsize = '' )
2013-09-10 15:45:36 +02:00
{
global $conf ;
2015-03-11 03:58:57 +01:00
2013-09-11 09:40:00 +02:00
if ( $direction == 'width' )
{
if ( empty ( $conf -> dol_optimize_smallscreen )) return ( $defaultsize ? $defaultsize : '500' );
2019-11-13 19:35:39 +01:00
else return ( empty ( $_SESSION [ 'dol_screen_width' ]) ? '280' : ( $_SESSION [ 'dol_screen_width' ] - 40 ));
2013-09-11 09:40:00 +02:00
}
2015-03-11 03:58:57 +01:00
if ( $direction == 'height' )
2013-09-11 09:40:00 +02:00
{
2019-11-13 19:35:39 +01:00
return ( empty ( $conf -> dol_optimize_smallscreen ) ? ( $defaultsize ? $defaultsize : '200' ) : '160' );
2013-09-11 09:40:00 +02:00
}
2013-09-10 15:45:36 +02:00
return 0 ;
}
2013-05-18 09:19:03 +02:00
}