303 lines
9.1 KiB
PHP
303 lines
9.1 KiB
PHP
<?php
|
|
/**
|
|
*
|
|
* Copyright 2012-2012 Portugalmail Comunicações S.A (http://www.portugalmail.net/)
|
|
*
|
|
* See the enclosed file LICENCE for license information (GPLv3). If you
|
|
* did not receive this file, see http://www.gnu.org/licenses/gpl-3.0.html.
|
|
*
|
|
* @author Gonçalo Queirós <mail@goncaloqueiros.net>
|
|
*/
|
|
|
|
namespace highcharts;
|
|
|
|
use highcharts\HighchartOption;
|
|
use highcharts\HighchartOptionRenderer;
|
|
|
|
class Highchart implements \ArrayAccess
|
|
{
|
|
//The chart type.
|
|
//A regullar higchart
|
|
const HIGHCHART = 0;
|
|
//A highstock chart
|
|
const HIGHSTOCK = 1;
|
|
|
|
//The js engine to use
|
|
const ENGINE_JQUERY = 10;
|
|
const ENGINE_MOOTOOLS = 11;
|
|
const ENGINE_PROTOTYPE = 12;
|
|
|
|
/**
|
|
* The chart options
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $_options = array();
|
|
|
|
/**
|
|
* The chart type.
|
|
* Either self::HIGHCHART or self::HIGHSTOCK
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $_chartType;
|
|
|
|
/**
|
|
* The javascript library to use.
|
|
* One of ENGINE_JQUERY, ENGINE_MOOTOOLS or ENGINE_PROTOTYPE
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $_jsEngine;
|
|
|
|
/**
|
|
* Array with keys from extra scripts to be included
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $_extraScripts = array();
|
|
|
|
/**
|
|
* Any configurations to use instead of the default ones
|
|
*
|
|
* @var array An array with same structure as the config.php file
|
|
*/
|
|
protected $_confs = array();
|
|
|
|
/**
|
|
* Clone Highchart object
|
|
*/
|
|
public function __clone()
|
|
{
|
|
foreach ($this->_options as $key => $value)
|
|
{
|
|
$this->_options[$key] = clone $value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The Highchart constructor
|
|
*
|
|
* @param int $chartType The chart type (Either self::HIGHCHART or self::HIGHSTOCK)
|
|
* @param int $jsEngine The javascript library to use
|
|
* (One of ENGINE_JQUERY, ENGINE_MOOTOOLS or ENGINE_PROTOTYPE)
|
|
*/
|
|
public function __construct($chartType = self::HIGHCHART, $jsEngine = self::ENGINE_JQUERY)
|
|
{
|
|
$this->_chartType = is_null($chartType) ? self::HIGHCHART : $chartType;
|
|
$this->_jsEngine = is_null($jsEngine) ? self::ENGINE_JQUERY : $jsEngine;
|
|
//Load default configurations
|
|
$this->setConfigurations();
|
|
}
|
|
|
|
/**
|
|
* Override default configuration values with the ones provided.
|
|
* The provided array should have the same structure as the config.php file.
|
|
* If you wish to override a single value you would pass something like:
|
|
* $chart = new Highchart();
|
|
* $chart->setConfigurations(array('jQuery' => array('name' => 'newFile')));
|
|
*
|
|
* @param array $configurations The new configuration values
|
|
*/
|
|
public function setConfigurations($configurations = array())
|
|
{
|
|
include __DIR__ . DIRECTORY_SEPARATOR . "config.php";
|
|
$this->_confs = array_replace_recursive($jsFiles, $configurations);
|
|
}
|
|
|
|
/**
|
|
* Render the chart options and returns the javascript that
|
|
* represents them
|
|
*
|
|
* @return string The javascript code
|
|
*/
|
|
public function renderOptions()
|
|
{
|
|
return HighchartOptionRenderer::render($this->_options);
|
|
}
|
|
|
|
/**
|
|
* Render the chart and returns the javascript that
|
|
* must be printed to the page to create the chart
|
|
*
|
|
* @param string $varName The javascript chart variable name
|
|
* @param string $callback The function callback to pass
|
|
* to the Highcharts.Chart method
|
|
* @param boolean $withScriptTag It renders the javascript wrapped
|
|
* in html script tags
|
|
*
|
|
* @return string The javascript code
|
|
*/
|
|
public function render($varName = null, $callback = null, $withScriptTag = false)
|
|
{
|
|
$result = '';
|
|
if (!is_null($varName)) {
|
|
$result = "$varName = ";
|
|
}
|
|
|
|
$result .= 'new Highcharts.';
|
|
if ($this->_chartType === self::HIGHCHART) {
|
|
$result .= 'Chart(';
|
|
} else {
|
|
$result .= 'StockChart(';
|
|
}
|
|
|
|
$result .= $this->renderOptions();
|
|
$result .= is_null($callback) ? '' : ", $callback";
|
|
$result .= ');';
|
|
|
|
if ($withScriptTag) {
|
|
$result = '<script type="text/javascript">' . $result . '</script>';
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Finds the javascript files that need to be included on the page, based
|
|
* on the chart type and js engine.
|
|
* Uses the conf.php file to build the files path
|
|
*
|
|
* @return array The javascript files path
|
|
*/
|
|
public function getScripts()
|
|
{
|
|
$scripts = array();
|
|
switch ($this->_jsEngine) {
|
|
case self::ENGINE_JQUERY:
|
|
$scripts[] = $this->_confs['jQuery']['path'] . $this->_confs['jQuery']['name'];
|
|
break;
|
|
|
|
case self::ENGINE_MOOTOOLS:
|
|
$scripts[] = $this->_confs['mootools']['path'] . $this->_confs['mootools']['name'];
|
|
if ($this->_chartType === self::HIGHCHART) {
|
|
$scripts[] = $this->_confs['highchartsMootoolsAdapter']['path'] . $this->_confs['highchartsMootoolsAdapter']['name'];
|
|
} else {
|
|
$scripts[] = $this->_confs['highstockMootoolsAdapter']['path'] . $this->_confs['highstockMootoolsAdapter']['name'];
|
|
}
|
|
break;
|
|
|
|
case self::ENGINE_PROTOTYPE:
|
|
$scripts[] = $this->_confs['prototype']['path'] . $this->_confs['prototype']['name'];
|
|
if ($this->_chartType === self::HIGHCHART) {
|
|
$scripts[] = $this->_confs['highchartsPrototypeAdapter']['path'] . $this->_confs['highchartsPrototypeAdapter']['name'];
|
|
} else {
|
|
$scripts[] = $this->_confs['highstockPrototypeAdapter']['path'] . $this->_confs['highstockPrototypeAdapter']['name'];
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
switch ($this->_chartType) {
|
|
case self::HIGHCHART:
|
|
$scripts[] = $this->_confs['highcharts']['path'] . $this->_confs['highcharts']['name'];
|
|
break;
|
|
|
|
case self::HIGHSTOCK:
|
|
$scripts[] = $this->_confs['highstock']['path'] . $this->_confs['highstock']['name'];
|
|
break;
|
|
}
|
|
|
|
//Include scripts with keys given to be included via includeExtraScripts
|
|
if (!empty($this->_extraScripts)) {
|
|
foreach ($this->_extraScripts as $key) {
|
|
$scripts[] = $this->_confs['extra'][$key]['path'] . $this->_confs['extra'][$key]['name'];
|
|
}
|
|
}
|
|
|
|
return $scripts;
|
|
}
|
|
|
|
/**
|
|
* Prints javascript script tags for all scripts that need to be included on page
|
|
*
|
|
* @param boolean $return if true it returns the scripts rather then echoing them
|
|
*/
|
|
public function printScripts($return = false)
|
|
{
|
|
$scripts = '';
|
|
foreach ($this->getScripts() as $script) {
|
|
$scripts .= '<script type="text/javascript" src="' . $script . '"></script>';
|
|
}
|
|
|
|
if ($return) {
|
|
return $scripts;
|
|
}
|
|
else {
|
|
echo $scripts;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Manually adds an extra script to the extras
|
|
*
|
|
* @param string $key key for the script in extra array
|
|
* @param string $filepath path for the script file
|
|
* @param string $filename filename for the script
|
|
*/
|
|
public function addExtraScript($key, $filepath, $filename)
|
|
{
|
|
$this->_confs['extra'][$key] = array('name' => $filename, 'path' => $filepath);
|
|
}
|
|
|
|
/**
|
|
* Signals which extra scripts are to be included given its keys
|
|
*
|
|
* @param array $keys extra scripts keys to be included
|
|
*/
|
|
public function includeExtraScripts(array $keys = array())
|
|
{
|
|
$this->_extraScripts = empty($keys) ? array_keys($this->_confs['extra']) : $keys;
|
|
}
|
|
|
|
/**
|
|
* Global options that don't apply to each chart like lang and global
|
|
* must be set using the Highcharts.setOptions javascript method.
|
|
* This method receives a set of HighchartOption and returns the
|
|
* javascript string needed to set those options globally
|
|
*
|
|
* @param HighchartOption The options to create
|
|
*
|
|
* @return string The javascript needed to set the global options
|
|
*/
|
|
public static function setOptions($options)
|
|
{
|
|
//TODO: Check encoding errors
|
|
$option = json_encode($options->getValue());
|
|
return "Highcharts.setOptions($option);";
|
|
}
|
|
|
|
public function __set($offset, $value)
|
|
{
|
|
$this->offsetSet($offset, $value);
|
|
}
|
|
|
|
public function __get($offset)
|
|
{
|
|
return $this->offsetGet($offset);
|
|
}
|
|
|
|
public function offsetSet($offset, $value): void
|
|
{
|
|
$this->_options[$offset] = new HighchartOption($value);
|
|
}
|
|
|
|
public function offsetExists($offset): bool
|
|
{
|
|
return isset($this->_options[$offset]);
|
|
}
|
|
|
|
public function offsetUnset($offset): void
|
|
{
|
|
unset($this->_options[$offset]);
|
|
}
|
|
|
|
public function offsetGet($offset): mixed
|
|
{
|
|
if (!isset($this->_options[$offset])) {
|
|
$this->_options[$offset] = new HighchartOption();
|
|
}
|
|
return $this->_options[$offset];
|
|
}
|
|
}
|