├── LICENSE ├── README.md ├── composer.json └── src ├── ECharts.php ├── EChartsAsset.php ├── MapAsset.php └── ThemeAsset.php /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Cosmo 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of yii2-echarts nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yii2-echarts 2 | ============ 3 | [![Latest Stable Version](https://poser.pugx.org/daixianceng/yii2-echarts/v/stable)](https://packagist.org/packages/daixianceng/yii2-echarts) [![Total Downloads](https://poser.pugx.org/daixianceng/yii2-echarts/downloads)](https://packagist.org/packages/daixianceng/yii2-echarts) [![Latest Unstable Version](https://poser.pugx.org/daixianceng/yii2-echarts/v/unstable)](https://packagist.org/packages/daixianceng/yii2-echarts) [![License](https://poser.pugx.org/daixianceng/yii2-echarts/license)](https://packagist.org/packages/daixianceng/yii2-echarts) 4 | 5 | ECharts widget for Yii2. 6 | 7 | See the [echarts project](https://github.com/ecomfe/echarts) for details. 8 | 9 | ## Installation 10 | 11 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 12 | 13 | Either run 14 | 15 | ``` 16 | php composer.phar require --prefer-dist daixianceng/yii2-echarts "*" 17 | ``` 18 | 19 | or add 20 | 21 | ``` 22 | "daixianceng/yii2-echarts": "*" 23 | ``` 24 | 25 | to the require section of your `composer.json` file. 26 | 27 | 28 | ## Usage 29 | 30 | ### Example 31 | 32 | ```php 33 | 37 | 38 | true, 40 | 'options' => [ 41 | 'style' => 'height: 400px;' 42 | ], 43 | 'pluginEvents' => [ 44 | 'click' => [ 45 | new JsExpression('function (params) {console.log(params)}'), 46 | new JsExpression('function (params) {console.log("ok")}') 47 | ], 48 | 'legendselectchanged' => new JsExpression('function (params) {console.log(params.selected)}') 49 | ], 50 | 'pluginOptions' => [ 51 | 'option' => [ 52 | 'title' => [ 53 | 'text' => '折线图堆叠' 54 | ], 55 | 'tooltip' => [ 56 | 'trigger' => 'axis' 57 | ], 58 | 'legend' => [ 59 | 'data' => ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎'] 60 | ], 61 | 'grid' => [ 62 | 'left' => '3%', 63 | 'right' => '4%', 64 | 'bottom' => '3%', 65 | 'containLabel' => true 66 | ], 67 | 'toolbox' => [ 68 | 'feature' => [ 69 | 'saveAsImage' => [] 70 | ] 71 | ], 72 | 'xAxis' => [ 73 | 'name' => '日期', 74 | 'type' => 'category', 75 | 'boundaryGap' => false, 76 | 'data' => ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] 77 | ], 78 | 'yAxis' => [ 79 | 'type' => 'value' 80 | ], 81 | 'series' => [ 82 | [ 83 | 'name' => '邮件营销', 84 | 'type' => 'line', 85 | 'stack' => '总量', 86 | 'data' => [120, 132, 101, 134, 90, 230, 210] 87 | ], 88 | [ 89 | 'name' => '联盟广告', 90 | 'type' => 'line', 91 | 'stack' => '总量', 92 | 'data' => [220, 182, 191, 234, 290, 330, 310] 93 | ], 94 | [ 95 | 'name' => '视频广告', 96 | 'type' => 'line', 97 | 'stack' => '总量', 98 | 'data' => [150, 232, 201, 154, 190, 330, 410] 99 | ], 100 | [ 101 | 'name' => '直接访问', 102 | 'type' => 'line', 103 | 'stack' => '总量', 104 | 'data' => [320, 332, 301, 334, 390, 330, 320] 105 | ], 106 | [ 107 | 'name' => '搜索引擎', 108 | 'type' => 'line', 109 | 'stack' => '总量', 110 | 'data' => [820, 932, 901, 934, 1290, 1330, 1320] 111 | ] 112 | ] 113 | ] 114 | ] 115 | ]); ?> 116 | ``` 117 | 118 | ### Using themes 119 | 120 | ```php 121 | 127 | 128 | 'dark', 130 | 'responsive' => true, 131 | 'options' => [ 132 | 'style' => 'height: 400px;' 133 | ], 134 | 'pluginOptions' => [ 135 | 'option' => [] 136 | ] 137 | ]); ?> 138 | ``` 139 | 140 | ### Using maps 141 | 142 | ```php 143 | 150 | 151 | true, 153 | 'options' => [ 154 | 'style' => 'height: 400px;' 155 | ], 156 | 'pluginOptions' => [ 157 | 'option' => [ 158 | 'series' => [ 159 | [ 160 | 'name' => 'China map', 161 | 'type' => 'map', 162 | 'map' => 'china', 163 | 'data' => [ 164 | ['name' => '广东', 'selected' => true] 165 | ] 166 | ] 167 | ] 168 | ] 169 | ] 170 | ]); ?> 171 | 172 | true, 174 | 'options' => [ 175 | 'style' => 'height: 400px;' 176 | ], 177 | 'pluginOptions' => [ 178 | 'option' => [ 179 | 'geo' => [ 180 | 'map' => '北京' 181 | ] 182 | ] 183 | ] 184 | ]); ?> 185 | ``` 186 | 187 | ### Configure CDN 188 | 189 | ```php 190 | [ 193 | 'assetManager' => [ 194 | 'class' => 'yii\web\AssetManager', 195 | 'bundles' => [ 196 | 'daixianceng\echarts\EChartsAsset' => [ 197 | 'sourcePath' => null, 198 | 'baseUrl' => 'https://cdn.jsdelivr.net/npm/echarts@4.7.0/dist' 199 | ] 200 | ], 201 | ], 202 | ], 203 | ]; 204 | ?> 205 | ``` 206 | 207 | ## License 208 | 209 | **yii2-echarts** is released under the BSD-3-Clause License. See the bundled `LICENSE` for details. 210 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "daixianceng/yii2-echarts", 3 | "description": "Echarts widget for Yii2.", 4 | "keywords": ["yii2", "extension", "chart", "echarts"], 5 | "homepage": "https://github.com/daixianceng/yii2-echarts", 6 | "type": "yii2-extension", 7 | "license": "BSD-3-Clause", 8 | "authors": [ 9 | { 10 | "name": "Cosmo", 11 | "email": "daixianceng@gmail.com", 12 | "role": "Developer" 13 | } 14 | ], 15 | "support": { 16 | "issues": "https://github.com/daixianceng/yii2-echarts/issues", 17 | "source": "https://github.com/daixianceng/yii2-echarts" 18 | }, 19 | "require": { 20 | "yiisoft/yii2": "*", 21 | "npm-asset/echarts": "*" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "daixianceng\\echarts\\": "src/" 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/ECharts.php: -------------------------------------------------------------------------------- 1 | 18 | * @property string $clientId 19 | */ 20 | class ECharts extends Widget 21 | { 22 | const DIST_FULL = 'full'; 23 | const DIST_COMMON = 'common'; 24 | const DIST_SIMPLE = 'simple'; 25 | 26 | /** 27 | * @var string the client ID of the echarts. 28 | * @see getClientId() 29 | */ 30 | private $_clientId; 31 | 32 | /** 33 | * @var array list of the theme JS files. 34 | */ 35 | protected static $_themeJsFiles = []; 36 | 37 | /** 38 | * @var array list of the map JS files. 39 | */ 40 | protected static $_mapJsFiles = []; 41 | 42 | /** 43 | * @var string the dist of echarts to be used. The possible options are: 44 | * - "full" : A full dist of echarts. 45 | * - "common" : A common dist of echarts. 46 | * - "simple" : A simple dist of echarts. 47 | * Defaults to "common", means a common dist of echarts will be used. 48 | * 49 | * Note that if you are using maps in echarts, you must set it a full dist. 50 | */ 51 | public static $dist = self::DIST_COMMON; 52 | 53 | /** 54 | * @var array the extensions of echarts. 55 | */ 56 | public static $extensions = []; 57 | 58 | /** 59 | * @var boolean whether resize the chart when the container size is changed. 60 | */ 61 | public $responsive = false; 62 | 63 | /** 64 | * @var string the theme name to be used for styling the chart. 65 | */ 66 | public $theme; 67 | 68 | /** 69 | * @var array the HTML attributes for the widget container tag. 70 | */ 71 | public $options = []; 72 | 73 | /** 74 | * @var array the options for the echarts plugin. 75 | * See [its documentation](http://echarts.baidu.com/option.html) or [api](http://echarts.baidu.com/api.html) for details. 76 | */ 77 | public $pluginOptions = []; 78 | 79 | /** 80 | * @var array the attached event handlers for the echarts plugin (event name => handlers) 81 | */ 82 | public $pluginEvents = []; 83 | 84 | /** 85 | * Initializes the widget. 86 | */ 87 | public function init() 88 | { 89 | parent::init(); 90 | if (!isset($this->options['id'])) { 91 | $this->options['id'] = $this->getId(); 92 | } 93 | } 94 | 95 | /** 96 | * Renders the widget. 97 | */ 98 | public function run() 99 | { 100 | echo Html::tag('div', '', $this->options); 101 | $this->registerClientScript(); 102 | } 103 | 104 | /** 105 | * Registers the required js files and script to initialize echarts plugin. 106 | */ 107 | protected function registerClientScript() 108 | { 109 | $id = $this->options['id']; 110 | $view = $this->getView(); 111 | $option = !empty($this->pluginOptions['option']) ? Json::encode($this->pluginOptions['option']) : '{}'; 112 | 113 | if ($this->theme) { 114 | $js = "var {$this->clientId} = echarts.init(document.getElementById('{$id}'), " . $this->quote($this->theme) . ");"; 115 | } else { 116 | $js = "var {$this->clientId} = echarts.init(document.getElementById('{$id}'));"; 117 | } 118 | $js .= "{$this->clientId}.setOption({$option});"; 119 | if (isset($this->pluginOptions['group'])) { 120 | $js .= "{$this->clientId}.group = " . $this->quote($this->pluginOptions['group']) . ";"; 121 | } 122 | if ($this->responsive) { 123 | $js .= "$(window).resize(function () {{$this->clientId}.resize()});"; 124 | } 125 | foreach ($this->pluginEvents as $name => $handlers) { 126 | $handlers = (array) $handlers; 127 | foreach ($handlers as $handler) { 128 | $js .= "{$this->clientId}.on(" . $this->quote($name) . ", $handler);"; 129 | } 130 | } 131 | 132 | EChartsAsset::register($view); 133 | $view->registerJs($js); 134 | } 135 | 136 | /** 137 | * Quotes a string for use in JavaScript. 138 | * 139 | * @param string $string 140 | * @return string the quoted string 141 | */ 142 | private function quote($string) 143 | { 144 | return "'" . addcslashes($string, "'") . "'"; 145 | } 146 | 147 | /** 148 | * Returns the client ID of the echarts. 149 | * 150 | * @return string 151 | */ 152 | public function getClientId() 153 | { 154 | if ($this->_clientId === null) { 155 | $id = $this->options['id']; 156 | $this->_clientId = "echarts_{$id}"; 157 | } 158 | 159 | return $this->_clientId; 160 | } 161 | 162 | /** 163 | * Registers the JS files of the given themes. 164 | * 165 | * @param string|array $theme 166 | */ 167 | public static function registerTheme($theme) 168 | { 169 | $themes = (array) $theme; 170 | array_walk($themes, function (&$name) { 171 | $name .= '.js'; 172 | }); 173 | static::$_themeJsFiles = array_unique(array_merge(static::$_themeJsFiles, $themes)); 174 | if (static::$_themeJsFiles) { 175 | ThemeAsset::register(Yii::$app->getView())->js = static::$_themeJsFiles; 176 | } 177 | } 178 | 179 | /** 180 | * Registers the JS files of the given maps. 181 | * 182 | * @param string|array $map 183 | */ 184 | public static function registerMap($map) 185 | { 186 | $maps = (array) $map; 187 | array_walk($maps, function (&$name) { 188 | $name = 'js/' . $name . '.js'; 189 | }); 190 | static::$_mapJsFiles = array_unique(array_merge(static::$_mapJsFiles, $maps)); 191 | if (static::$_mapJsFiles) { 192 | MapAsset::register(Yii::$app->getView())->js = static::$_mapJsFiles; 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/EChartsAsset.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class EChartsAsset extends AssetBundle 18 | { 19 | /** 20 | * @inheritdoc 21 | */ 22 | public $sourcePath = '@npm/echarts/dist'; 23 | 24 | /** 25 | * Initializes the bundle. 26 | */ 27 | public function init() 28 | { 29 | if (empty($this->js)) { 30 | switch (ECharts::$dist) { 31 | case ECharts::DIST_FULL: 32 | $this->js = YII_DEBUG ? ['echarts.js'] : ['echarts.min.js']; 33 | break; 34 | case ECharts::DIST_COMMON: 35 | $this->js = YII_DEBUG ? ['echarts.common.js'] : ['echarts.common.min.js']; 36 | break; 37 | case ECharts::DIST_SIMPLE: 38 | $this->js = YII_DEBUG ? ['echarts.simple.js'] : ['echarts.simple.min.js']; 39 | break; 40 | default: 41 | throw new InvalidConfigException('The "dist" is not valid.'); 42 | } 43 | 44 | // Registers echarts extensions 45 | foreach (ECharts::$extensions as $extension) { 46 | $this->js[] = YII_DEBUG ? "extension/{$extension}.js" : "extension/{$extension}.min.js"; 47 | } 48 | } 49 | 50 | parent::init(); 51 | } 52 | } -------------------------------------------------------------------------------- /src/MapAsset.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class MapAsset extends AssetBundle 17 | { 18 | public $sourcePath = '@npm/echarts/map'; 19 | 20 | public $depends = [ 21 | 'daixianceng\echarts\EChartsAsset', 22 | ]; 23 | } -------------------------------------------------------------------------------- /src/ThemeAsset.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class ThemeAsset extends AssetBundle 17 | { 18 | public $sourcePath = '@npm/echarts/theme'; 19 | 20 | public $depends = [ 21 | 'daixianceng\echarts\EChartsAsset', 22 | ]; 23 | } --------------------------------------------------------------------------------