/
HighchartsWidget.php
143 lines (131 loc) · 4.94 KB
/
HighchartsWidget.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
<?php
/**
* HighchartsWidget class file.
*
* @author Milo Schuman <miloschuman@gmail.com>
* @link https://github.com/miloschuman/yii-highcharts/
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* HighchartsWidget encapsulates the {@link http://www.highcharts.com/ Highcharts}
* charting library's Chart object.
*
* To use this widget, you may insert the following code in a view:
* <pre>
* $this->Widget('ext.highcharts.HighchartsWidget', array(
* 'options'=>array(
* 'title' => array('text' => 'Fruit Consumption'),
* 'xAxis' => array(
* 'categories' => array('Apples', 'Bananas', 'Oranges')
* ),
* 'yAxis' => array(
* 'title' => array('text' => 'Fruit eaten')
* ),
* 'series' => array(
* array('name' => 'Jane', 'data' => array(1, 0, 4)),
* array('name' => 'John', 'data' => array(5, 7, 3))
* )
* )
* ));
* </pre>
*
* By configuring the {@link $options} property, you may specify the options
* that need to be passed to the Highcharts JavaScript object. Please refer to
* the demo gallery and documentation on the {@link http://www.highcharts.com/
* Highcharts website} for possible options.
*
* Alternatively, you can use a valid JSON string in place of an associative
* array to specify options:
*
* <pre>
* $this->Widget('ext.highcharts.HighchartsWidget', array(
* 'options'=>'{
* "title": { "text": "Fruit Consumption" },
* "xAxis": {
* "categories": ["Apples", "Bananas", "Oranges"]
* },
* "yAxis": {
* "title": { "text": "Fruit eaten" }
* },
* "series": [
* { "name": "Jane", "data": [1, 0, 4] },
* { "name": "John", "data": [5, 7,3] }
* ]
* }'
* ));
* </pre>
*
* Note: You must provide a valid JSON string (e.g. double quotes) when using
* the second option. You can quickly validate your JSON string online using
* {@link http://jsonlint.com/ JSONLint}.
*
* Note: You do not need to specify the <code>chart->renderTo</code> option as
* is shown in many of the examples on the Highcharts website. This value is
* automatically populated with the id of the widget's container element. If you
* wish to use a different container, feel free to specify a custom value.
*/
class HighchartsWidget extends CWidget
{
protected $_constr = 'Chart';
protected $_baseScript = 'highcharts';
public $options = array();
public $htmlOptions = array();
public $setupOptions = array();
public $scripts = array();
public $callback = false;
public $scriptPosition = null;
/**
* Renders the widget.
*/
public function run()
{
if (isset($this->htmlOptions['id'])) {
$this->id = $this->htmlOptions['id'];
} else {
$this->htmlOptions['id'] = $this->getId();
}
echo CHtml::openTag('div', $this->htmlOptions);
echo CHtml::closeTag('div');
// check if options parameter is a json string
if (is_string($this->options)) {
if (!$this->options = CJSON::decode($this->options)) {
throw new CException('The options parameter is not valid JSON.');
}
}
// merge options with default values
$defaultOptions = array('chart' => array('renderTo' => $this->id));
$this->options = CMap::mergeArray($defaultOptions, $this->options);
array_unshift($this->scripts, $this->_baseScript);
$this->registerAssets();
}
/**
* Publishes and registers the necessary script files.
*/
protected function registerAssets()
{
$basePath = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'assets' . DIRECTORY_SEPARATOR;
$baseUrl = Yii::app()->getAssetManager()->publish($basePath, false, 1, YII_DEBUG);
$cs = Yii::app()->clientScript;
$cs->registerCoreScript('jquery');
// register additional scripts
$extension = YII_DEBUG ? '.src.js' : '.js';
foreach ($this->scripts as $script) {
$cs->registerScriptFile("{$baseUrl}/{$script}{$extension}", $this->scriptPosition);
}
// highcharts and highstock can't live on the same page
if ($this->_baseScript === 'highstock') {
$cs->scriptMap["highcharts{$extension}"] = "{$baseUrl}/highstock{$extension}";
}
// prepare and register JavaScript code block
$jsOptions = CJavaScript::encode($this->options);
$setupOptions = CJavaScript::encode($this->setupOptions);
$js = "Highcharts.setOptions($setupOptions); var chart = new Highcharts.{$this->_constr}($jsOptions);";
$key = __CLASS__ . '#' . $this->id;
if (is_string($this->callback)) {
$callbackScript = "function {$this->callback}(data) {{$js}}";
$cs->registerScript($key, $callbackScript, CClientScript::POS_END);
} else {
$cs->registerScript($key, $js, CClientScript::POS_LOAD);
}
}
}