forked from ghunti/HighchartsPHP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHighchart.php
249 lines (218 loc) · 7.47 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
<?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 <[email protected]>
*/
include_once "HighchartOption.php";
include_once "HighchartJsExpr.php";
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
*/
private $_options = array();
/**
* The chart type.
* Either self::HIGHCHART or self::HIGHSTOCK
*
* @var int
*/
private $_chartType;
/**
* The javascript library to use.
* One of ENGINE_JQUERY, ENGINE_MOOTOOLS or ENGINE_PROTOTYPE
*
* @var int
*/
private $_jsEngine;
/**
* 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;
}
/**
* Render the chart options and returns the javascript that
* represents them
*
* @return string The javascript code
*/
public function renderOptions()
{
$jsExpressions = array();
//Replace any js expression with random strings so we can switch
//them back after json_encode the options
$options = self::_replaceJsExpr($this->_options, $jsExpressions);
//TODO: Check for encoding errors
$result = json_encode($options);
//Replace any js expression on the json_encoded string
foreach ($jsExpressions as $key => $expr) {
$result = str_replace('"' . $key . '"', $expr, $result);
}
return $result;
}
/**
* 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
*
* @return string The javascript code
*/
public function render($varName = null, $callback = null)
{
$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 .= ');';
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()
{
include_once "conf.php";
$scripts = array();
switch ($this->_jsEngine) {
case self::ENGINE_JQUERY:
$scripts[] = $jsFiles['jQuery']['path'] . $jsFiles['jQuery']['name'];
break;
case self::ENGINE_MOOTOOLS:
$scripts[] = $jsFiles['mootools']['path'] . $jsFiles['mootools']['name'];
if ($this->_chartType === self::HIGHCHART) {
$scripts[] = $jsFiles['highchartsMootoolsAdapter']['path'] . $jsFiles['highchartsMootoolsAdapter']['name'];
} else {
$scripts[] = $jsFiles['highstockMootoolsAdapter']['path'] . $jsFiles['highstockMootoolsAdapter']['name'];
}
break;
case self::ENGINE_PROTOTYPE:
$scripts[] = $jsFiles['prototype']['path'] . $jsFiles['prototype']['name'];
if ($this->_chartType === self::HIGHCHART) {
$scripts[] = $jsFiles['highchartsPrototypeAdapter']['path'] . $jsFiles['highchartsPrototypeAdapter']['name'];
} else {
$scripts[] = $jsFiles['highstockPrototypeAdapter']['path'] . $jsFiles['highstockPrototypeAdapter']['name'];
}
break;
}
switch ($this->_chartType) {
case self::HIGHCHART:
$scripts[] = $jsFiles['highcharts']['path'] . $jsFiles['highcharts']['name'];
break;
case self::HIGHSTOCK:
$scripts[] = $jsFiles['highstock']['path'] . $jsFiles['highstock']['name'];
break;
}
return $scripts;
}
/**
* 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 og 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)
{
$this->_options[$offset] = new HighchartOption($value);
}
public function offsetExists($offset)
{
return isset($this->_options[$offset]);
}
public function offsetUnset($offset)
{
unset($this->_options[$offset]);
}
public function offsetGet($offset)
{
if (!isset($this->_options[$offset])) {
$this->_options[$offset] = new HighchartOption();
}
return $this->_options[$offset];
}
/**
* Replaces any HighchartJsExpr for an id, and save the
* js expression on the jsExpressions array
* Based on Zend_Json
*
* @param mixed $data The data to analyze
* @param array &$jsExpressions The array that will hold
* information about the replaced
* js expressions
*/
private static function _replaceJsExpr($data, &$jsExpressions)
{
if (!is_array($data) &&
!is_object($data)) {
return $data;
}
if (is_object($data) &&
!$data instanceof HighchartJsExpr) {
$data = $data->getValue();
}
if ($data instanceof HighchartJsExpr) {
$magicKey = "____" . count($jsExpressions) . "_" . count($jsExpressions);
$jsExpressions[$magicKey] = $data->getExpression();
return $magicKey;
}
foreach ($data as $key => $value) {
$data[$key] = self::_replaceJsExpr($value, $jsExpressions);
}
return $data;
}
}