forked from ghunti/HighchartsPHP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHighchart.php
310 lines (272 loc) · 9.43 KB
/
Highchart.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
<?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 Ghunti\HighchartsPHP;
use Ghunti\HighchartsPHP\HighchartOption;
use Ghunti\HighchartsPHP\HighchartOptionRenderer;
class Highchart implements \ArrayAccess
{
//The chart type.
//A regullar higchart
const HIGHCHART = 0;
//A highstock chart
const HIGHSTOCK = 1;
// A Highchart map
const HIGHMAPS = 2;
//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(';
} elseif ($this->_chartType === self::HIGHMAPS) {
$result .= 'Map(';
} 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;
case self::HIGHMAPS:
$scripts[] = $this->_confs['highmaps']['path'] . $this->_confs['highmaps']['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];
}
}