├── .commitlintrc.js ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github └── workflows │ └── build.yml ├── .gitignore ├── .lintmdrc ├── .prettierignore ├── .prettierrc ├── .umirc.js ├── LICENSE ├── README.md ├── __tests__ ├── charts │ └── simple-spec.tsx ├── helper │ ├── is-equal-spec.ts │ ├── is-fucntion-spec.ts │ ├── is-string-spec.ts │ └── pick-spec.ts └── utils │ └── index.ts ├── docs ├── examples │ ├── api.md │ ├── dynamic.md │ ├── event.md │ ├── gl.md │ ├── graph.md │ ├── loading.md │ ├── locale.md │ ├── simple.md │ ├── svg.md │ └── theme.md └── index.md ├── package.json ├── src ├── core.tsx ├── helper │ ├── is-equal.ts │ ├── is-function.ts │ ├── is-string.ts │ └── pick.ts ├── index.ts └── types.ts └── tsconfig.json /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-angular'], 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'wip'], 8 | ], 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [Makefile] 16 | indent_style = tab 17 | indent_size = 1 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist/ 3 | test 4 | build/ -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:@typescript-eslint/recommended", 5 | "plugin:@typescript-eslint/eslint-recommended", 6 | "prettier" 7 | ], 8 | "parser": "@typescript-eslint/parser", 9 | "plugins": ["prettier", "@typescript-eslint", "import"], 10 | "parserOptions": { 11 | "ecmaVersion": 6, 12 | "sourceType": "module", 13 | "impliedStrict": true 14 | }, 15 | "rules": { 16 | "no-sparse-arrays": 0, 17 | "no-self-assign": 0, 18 | "no-unused-vars": 0, // @typescript-eslint/no-unused-vars 19 | "no-inner-declarations": 0, 20 | "prettier/prettier": 2, 21 | "@typescript-eslint/no-unused-vars": 1, 22 | "@typescript-eslint/no-non-null-assertion": 0, 23 | "@typescript-eslint/no-explicit-any": 0, 24 | "@typescript-eslint/no-use-before-define": [2, { "functions": false }], 25 | "@typescript-eslint/ban-ts-ignore": 0, 26 | "@typescript-eslint/interface-name-prefix": 0, 27 | "@typescript-eslint/no-empty-interface": 0, 28 | "@typescript-eslint/camelcase": 0, 29 | "@typescript-eslint/no-inferrable-types": 0, 30 | "@typescript-eslint/explicit-function-return-type": 0, 31 | "@typescript-eslint/type-annotation-spacing": 0, 32 | "@typescript-eslint/no-empty-function": 0, 33 | "@typescript-eslint/explicit-module-boundary-types": "off", 34 | "@typescript-eslint/ban-types": "off", 35 | "no-undef": 0, 36 | "@typescript-eslint/no-var-requires": 0, 37 | "import/order": 0, 38 | "import/no-default-export": 0 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: ["push", "pull_request"] 4 | 5 | jobs: 6 | build: 7 | runs-on: macOS-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2.3.4 11 | - name: Setup Node.js environment 12 | uses: actions/setup-node@v2.1.5 13 | with: 14 | node-version: '20' 15 | - name: npm install 16 | run: | 17 | npm install 18 | - name: build 19 | run: | 20 | npm run build 21 | env: 22 | CI: true 23 | - name: Coveralls 24 | uses: coverallsapp/github-action@master 25 | with: 26 | github-token: ${{ secrets.GITHUB_TOKEN }} 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # lock 9 | package-lock.json 10 | 11 | # Runtime data 12 | pids 13 | *.pid 14 | *.seed 15 | *.pid.lock 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # nyc test coverage 24 | .nyc_output 25 | 26 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 27 | .grunt 28 | 29 | # Bower dependency directory (https://bower.io/) 30 | bower_components 31 | 32 | # node-waf configuration 33 | .lock-wscript 34 | 35 | # Compiled binary addons (http://nodejs.org/api/addons.html) 36 | build/Release 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | yarn.lock 43 | 44 | # Typescript v1 declaration files 45 | typings/ 46 | 47 | # Optional npm cache directory 48 | .npm 49 | 50 | # Optional eslint cache 51 | .eslintcache 52 | 53 | # Optional REPL history 54 | .node_repl_history 55 | 56 | # Output of 'npm pack' 57 | *.tgz 58 | 59 | # Yarn Integrity file 60 | .yarn-integrity 61 | 62 | # dotenv environment variables file 63 | .env 64 | 65 | public 66 | build 67 | dist 68 | temp 69 | .DS_Store 70 | .idea 71 | .cache 72 | demos/assets/screenshots 73 | /lib 74 | /esm 75 | /dist 76 | 77 | *.sw* 78 | *.un~ 79 | 80 | .vscode 81 | /stats.json 82 | .umi 83 | .umi-production 84 | -------------------------------------------------------------------------------- /.lintmdrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-long-code": 1 4 | } 5 | } -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | stats.json 2 | .cache 3 | dist 4 | .umi 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "trailingComma": "es5", 5 | "bracketSpacing": true, 6 | "printWidth": 120, 7 | "arrowParens": "always", 8 | "endOfLine": "auto" 9 | } 10 | -------------------------------------------------------------------------------- /.umirc.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'dumi'; 2 | 3 | export default defineConfig({ 4 | mode: 'site', 5 | title: '\b', 6 | base: '/', 7 | exportStatic: {}, 8 | publicPath: process.env.NODE_ENV === 'production' ? '/echarts-for-react/' : '/', 9 | base: process.env.NODE_ENV === 'production' ? '/echarts-for-react/' : '/', 10 | logo: 'https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/zh/images/logo.png?_v_=20200710_1', 11 | styles: [ 12 | '.__dumi-default-navbar-logo:not([data-plaintext]) { padding-left: 200px!important; }', 13 | '.echarts-for-react.class_1 { height: 400px!important; }', 14 | '.echarts-for-react.class_2 { height: 500px!important; }', 15 | ], 16 | navs: [ 17 | null, 18 | { title: 'G2', path: 'https://github.com/antvis/G2' }, 19 | { title: '在线文档', path: 'https://github.com/hustcc/echarts-for-react' }, 20 | { title: 'GitHub', path: 'https://github.com/hustcc/echarts-for-react' }, 21 | ], 22 | analytics: { 23 | // Google Analytics 代码,配置后会启用 24 | ga: 'G-T1MYFFZ6TL', 25 | baidu: 'df880ba684fa4f42e9e672abeef0e34b', 26 | }, 27 | // more config: https://d.umijs.org/config 28 | }); 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 AntV team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do { so, subject } to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # echarts-for-react 2 | 3 | The simplest, and the best React wrapper for [Apache ECharts](https://github.com/apache/incubator-echarts). 4 | 5 | [![npm](https://img.shields.io/npm/v/echarts-for-react.svg)](https://www.npmjs.com/package/echarts-for-react) 6 | [![build](https://github.com/hustcc/echarts-for-react/actions/workflows/build.yml/badge.svg)](https://github.com/hustcc/echarts-for-react/actions/workflows/build.yml) 7 | [![Coverage](https://img.shields.io/coveralls/hustcc/echarts-for-react/master.svg)](https://coveralls.io/github/hustcc/echarts-for-react) 8 | [![NPM downloads](https://img.shields.io/npm/dm/echarts-for-react.svg)](https://www.npmjs.com/package/echarts-for-react) 9 | [![License](https://img.shields.io/npm/l/echarts-for-react.svg)](https://www.npmjs.com/package/echarts-for-react) 10 | ![ECharts Ver](https://img.shields.io/badge/echarts-%5E3.0.0%20%7C%7C%20%5E4.0.0%20%7C%7C%20%5E5.0.0-blue.svg) 11 | ![React Ver](https://img.shields.io/badge/React-%20%5E15.0.0%20%7C%7C%20%20%5E16.0.0%20%7C%7C%20%20%5E17.0.0-blue.svg) 12 | 13 | 14 | ## Install 15 | 16 | ```bach 17 | $ npm install --save echarts-for-react 18 | 19 | # `echarts` is the peerDependence of `echarts-for-react`, you can install echarts with your own version. 20 | $ npm install --save echarts 21 | ``` 22 | 23 | Then use it. 24 | 25 | ```ts 26 | import ReactECharts from 'echarts-for-react'; 27 | 28 | // render echarts option. 29 | 30 | ``` 31 | 32 | You can run website. 33 | 34 | ```bash 35 | $ git clone git@github.com:hustcc/echarts-for-react.git 36 | 37 | $ npm install 38 | 39 | $ npm start 40 | ``` 41 | 42 | Then open [http://127.0.0.1:8081/](http://127.0.0.1:8081/) in your browser. or see [https://git.hust.cc/echarts-for-react/](https://git.hust.cc/echarts-for-react/) which is deploy on gh-pages. 43 | 44 | 45 | ## Usage 46 | 47 | Code of a simple demo code showed below. For more example can see: [https://git.hust.cc/echarts-for-react/](https://git.hust.cc/echarts-for-react/) 48 | 49 | ```ts 50 | import React from 'react'; 51 | import ReactECharts from 'echarts-for-react'; // or var ReactECharts = require('echarts-for-react'); 52 | 53 | 62 | ``` 63 | 64 | Import ECharts.js modules manually to reduce bundle size 65 | 66 | **With Echarts.js v5:** 67 | 68 | ```ts 69 | import React from 'react'; 70 | // import the core library. 71 | import ReactEChartsCore from 'echarts-for-react/lib/core'; 72 | // Import the echarts core module, which provides the necessary interfaces for using echarts. 73 | import * as echarts from 'echarts/core'; 74 | // Import charts, all with Chart suffix 75 | import { 76 | // LineChart, 77 | BarChart, 78 | // PieChart, 79 | // ScatterChart, 80 | // RadarChart, 81 | // MapChart, 82 | // TreeChart, 83 | // TreemapChart, 84 | // GraphChart, 85 | // GaugeChart, 86 | // FunnelChart, 87 | // ParallelChart, 88 | // SankeyChart, 89 | // BoxplotChart, 90 | // CandlestickChart, 91 | // EffectScatterChart, 92 | // LinesChart, 93 | // HeatmapChart, 94 | // PictorialBarChart, 95 | // ThemeRiverChart, 96 | // SunburstChart, 97 | // CustomChart, 98 | } from 'echarts/charts'; 99 | // import components, all suffixed with Component 100 | import { 101 | // GridSimpleComponent, 102 | GridComponent, 103 | // PolarComponent, 104 | // RadarComponent, 105 | // GeoComponent, 106 | // SingleAxisComponent, 107 | // ParallelComponent, 108 | // CalendarComponent, 109 | // GraphicComponent, 110 | // ToolboxComponent, 111 | TooltipComponent, 112 | // AxisPointerComponent, 113 | // BrushComponent, 114 | TitleComponent, 115 | // TimelineComponent, 116 | // MarkPointComponent, 117 | // MarkLineComponent, 118 | // MarkAreaComponent, 119 | // LegendComponent, 120 | // LegendScrollComponent, 121 | // LegendPlainComponent, 122 | // DataZoomComponent, 123 | // DataZoomInsideComponent, 124 | // DataZoomSliderComponent, 125 | // VisualMapComponent, 126 | // VisualMapContinuousComponent, 127 | // VisualMapPiecewiseComponent, 128 | // AriaComponent, 129 | // TransformComponent, 130 | DatasetComponent, 131 | } from 'echarts/components'; 132 | // Import renderer, note that introducing the CanvasRenderer or SVGRenderer is a required step 133 | import { 134 | CanvasRenderer, 135 | // SVGRenderer, 136 | } from 'echarts/renderers'; 137 | 138 | // Register the required components 139 | echarts.use( 140 | [TitleComponent, TooltipComponent, GridComponent, BarChart, CanvasRenderer] 141 | ); 142 | 143 | // The usage of ReactEChartsCore are same with above. 144 | 154 | ``` 155 | 156 | **With Echarts.js v3 or v4:** 157 | 158 | ```ts 159 | import React from 'react'; 160 | // import the core library. 161 | import ReactEChartsCore from 'echarts-for-react/lib/core'; 162 | 163 | // then import echarts modules those you have used manually. 164 | import echarts from 'echarts/lib/echarts'; 165 | // import 'echarts/lib/chart/line'; 166 | import 'echarts/lib/chart/bar'; 167 | // import 'echarts/lib/chart/pie'; 168 | // import 'echarts/lib/chart/scatter'; 169 | // import 'echarts/lib/chart/radar'; 170 | 171 | // import 'echarts/lib/chart/map'; 172 | // import 'echarts/lib/chart/treemap'; 173 | // import 'echarts/lib/chart/graph'; 174 | // import 'echarts/lib/chart/gauge'; 175 | // import 'echarts/lib/chart/funnel'; 176 | // import 'echarts/lib/chart/parallel'; 177 | // import 'echarts/lib/chart/sankey'; 178 | // import 'echarts/lib/chart/boxplot'; 179 | // import 'echarts/lib/chart/candlestick'; 180 | // import 'echarts/lib/chart/effectScatter'; 181 | // import 'echarts/lib/chart/lines'; 182 | // import 'echarts/lib/chart/heatmap'; 183 | 184 | // import 'echarts/lib/component/graphic'; 185 | // import 'echarts/lib/component/grid'; 186 | // import 'echarts/lib/component/legend'; 187 | import 'echarts/lib/component/tooltip'; 188 | // import 'echarts/lib/component/polar'; 189 | // import 'echarts/lib/component/geo'; 190 | // import 'echarts/lib/component/parallel'; 191 | // import 'echarts/lib/component/singleAxis'; 192 | // import 'echarts/lib/component/brush'; 193 | 194 | import 'echarts/lib/component/title'; 195 | 196 | // import 'echarts/lib/component/dataZoom'; 197 | // import 'echarts/lib/component/visualMap'; 198 | 199 | // import 'echarts/lib/component/markPoint'; 200 | // import 'echarts/lib/component/markLine'; 201 | // import 'echarts/lib/component/markArea'; 202 | 203 | // import 'echarts/lib/component/timeline'; 204 | // import 'echarts/lib/component/toolbox'; 205 | 206 | // import 'zrender/lib/vml/vml'; 207 | 208 | // The usage of ReactEChartsCore are same with above. 209 | 219 | ``` 220 | 221 | For **Next.js** user, code transpilation is needed. For Next.js 13.1 or higher, as all `next-transpile-modules` features are natively built-in and the package has been deprecated, so please add `transpilePackages: ['echarts', 'zrender']` into `nextConfig` object: 222 | 223 | ```js 224 | // next.config.js 225 | /** @type {import('next').NextConfig} */ 226 | 227 | const nextConfig = { 228 | // ...existing properties, 229 | transpilePackages: ['echarts', 'zrender'], 230 | } 231 | 232 | module.exports = nextConfig 233 | ``` 234 | 235 | For Next.js with version < 13.1: 236 | 237 | ```js 238 | // next.config.js 239 | const withTM = require("next-transpile-modules")(["echarts", "zrender"]); 240 | 241 | module.exports = withTM({}) 242 | ``` 243 | 244 | ## Props of Component 245 | 246 | - **`option`** (required, object) 247 | 248 | the echarts option config, can see [https://echarts.apache.org/option.html#title](https://echarts.apache.org/option.html#title). 249 | 250 | - **`notMerge`** (optional, object) 251 | 252 | when `setOption`, not merge the data, default is `false`. See [https://echarts.apache.org/api.html#echartsInstance.setOption](https://echarts.apache.org/api.html#echartsInstance.setOption). 253 | 254 | - **`replaceMerge`** (optional, string | string[]) 255 | 256 | when `setOption`, default is `null`. See [https://echarts.apache.org/api.html#echartsInstance.setOption](https://echarts.apache.org/api.html#echartsInstance.setOption). 257 | 258 | - **`lazyUpdate`** (optional, object) 259 | 260 | when `setOption`, lazy update the data, default is `false`. See [https://echarts.apache.org/api.html#echartsInstance.setOption](https://echarts.apache.org/api.html#echartsInstance.setOption). 261 | 262 | - **`style`** (optional, object) 263 | 264 | the `style` of echarts div. `object`, default is {height: '300px'}. 265 | 266 | - **`className`** (optional, string) 267 | 268 | the `class` of echarts div. you can setting the css style of charts by class name. 269 | 270 | - **`theme`** (optional, string) 271 | 272 | the `theme` of echarts. `string`, should `registerTheme` before use it (theme object format: [https://github.com/ecomfe/echarts/blob/master/theme/dark.js](https://github.com/ecomfe/echarts/blob/master/theme/dark.js)). e.g. 273 | 274 | ```ts 275 | // import echarts 276 | import echarts from 'echarts'; 277 | ... 278 | // register theme object 279 | echarts.registerTheme('my_theme', { 280 | backgroundColor: '#f4cccc' 281 | }); 282 | ... 283 | // render the echarts use option `theme` 284 | 289 | ``` 290 | 291 | - **`onChartReady`** (optional, function) 292 | 293 | when the chart is ready, will callback the function with the `echarts object` as it's paramter. 294 | 295 | - **`loadingOption`** (optional, object) 296 | 297 | the echarts loading option config, can see [https://echarts.apache.org/api.html#echartsInstance.showLoading](https://echarts.apache.org/api.html#echartsInstance.showLoading). 298 | 299 | - **`showLoading`** (optional, bool, default: false) 300 | 301 | `bool`, when the chart is rendering, show the loading mask. 302 | 303 | - **`onEvents`** (optional, array(string=>function) ) 304 | 305 | binding the echarts event, will callback with the `echarts event object`, and `the echart object` as it's paramters. e.g: 306 | 307 | ```ts 308 | const onEvents = { 309 | 'click': this.onChartClick, 310 | 'legendselectchanged': this.onChartLegendselectchanged 311 | } 312 | ... 313 | 318 | ``` 319 | for more event key name, see: [https://echarts.apache.org/api.html#events](https://echarts.apache.org/api.html#events) 320 | 321 | - **`opts`** (optional, object) 322 | 323 | the `opts` of echarts. `object`, will be used when initial echarts instance by `echarts.init`. Document [here](https://echarts.apache.org/api.html#echarts.init). 324 | 325 | ```ts 326 | 331 | ``` 332 | 333 | - **`autoResize`** (optional, boolean) 334 | 335 | decide whether to trigger `this.resize` when window resize. default is `true`. 336 | 337 | 338 | ## Component API & Echarts API 339 | 340 | the Component only has `one API` named `getEchartsInstance`. 341 | 342 | - **`getEchartsInstance()`** : get the echarts instance object, then you can use any `API of echarts`. 343 | 344 | for example: 345 | 346 | ```ts 347 | // render the echarts component below with rel 348 | { this.echartRef = e; }} 350 | option={this.getOption()} 351 | /> 352 | 353 | // then get the `ReactECharts` use this.echarts_react 354 | 355 | const echartInstance = this.echartRef.getEchartsInstance(); 356 | // then you can use any API of echarts. 357 | const base64 = echartInstance.getDataURL(); 358 | ``` 359 | 360 | TypeScript and `useRef()` example: 361 | 362 | ```ts 363 | const getOption = () => {/** */}; 364 | 365 | export default function App() { 366 | const echartsRef = useRef>(null); 367 | 368 | useEffect(() => { 369 | if (echartsRef.current) { 370 | const echartsInstance = echartsRef.current.getEchartsInstance(); 371 | // do something 372 | echartsInstance.resize(); 373 | } 374 | }, []); 375 | return ; 376 | } 377 | ``` 378 | 379 | **About API of echarts, can see** [https://echarts.apache.org/api.html#echartsInstance](https://echarts.apache.org/api.html#echartsInstance). 380 | 381 | You can use the API to do: 382 | 383 | 1. `binding / unbinding` event. 384 | 2. `dynamic charts` with dynamic data. 385 | 3. get the echarts dom / dataURL / base64, save the chart to png. 386 | 4. `release` the charts. 387 | 388 | 389 | ## FAQ 390 | 391 | ### How to render the chart with svg when using echarts 4.x 392 | 393 | Use the props `opts` of component with `renderer = 'svg'`. For example: 394 | 395 | 396 | ```ts 397 | 402 | ``` 403 | 404 | ### How to resolve Error `Component series.scatter3D not exists. Load it first.` 405 | 406 | Install and import [`echarts-gl`](https://www.npmjs.com/package/echarts-gl) module when you want to create a [GL instance](https://www.echartsjs.com/examples/zh/index.html#chart-type-globe) 407 | 408 | ```sh 409 | npm install --save echarts-gl 410 | ``` 411 | 412 | ```ts 413 | import 'echarts-gl' 414 | import ReactECharts from "echarts-for-react"; 415 | 416 | 419 | ``` 420 | 421 | 422 | ## LICENSE 423 | 424 | MIT@[hustcc](https://github.com/hustcc). 425 | -------------------------------------------------------------------------------- /__tests__/charts/simple-spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactECharts from '../../src/'; 3 | import type { EChartsOption } from '../../src/'; 4 | import { render, destroy, createDiv, removeDom } from '../utils'; 5 | 6 | const options: EChartsOption = { 7 | xAxis: { 8 | type: 'category', 9 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 10 | }, 11 | yAxis: { 12 | type: 'value', 13 | }, 14 | series: [ 15 | { 16 | data: [820, 932, 901, 934, 1290, 1330, 1320], 17 | type: 'line', 18 | smooth: true, 19 | }, 20 | ], 21 | }; 22 | 23 | describe('chart', () => { 24 | it('simple', () => { 25 | let instance; 26 | const div = createDiv(); 27 | const Comp = (instance = e)} option={options} />; 28 | render(Comp, div); 29 | 30 | expect(instance).toBeDefined(); 31 | expect(instance.getEchartsInstance()).toBeDefined(); 32 | 33 | destroy(div); 34 | expect(div.querySelector('*')).toBe(null); 35 | 36 | removeDom(div); 37 | }); 38 | 39 | describe('container size', () => { 40 | it('default', () => { 41 | let instance; 42 | const div = createDiv(); 43 | div.style.display = 'block'; 44 | div.style.width = '1200px'; 45 | div.style.height = '720px'; 46 | 47 | const Comp = (instance = e)} option={options} />; 48 | render(Comp, div); 49 | 50 | expect(instance).toBeDefined(); 51 | expect(instance.getEchartsInstance()).toBeDefined(); 52 | expect(instance.getEchartsInstance().getWidth()).toBe(1200); 53 | expect(instance.getEchartsInstance().getHeight()).toBe(300); // default height 54 | 55 | destroy(div); 56 | expect(div.querySelector('*')).toBe(null); 57 | 58 | removeDom(div); 59 | }); 60 | 61 | describe('style', () => { 62 | it('100% width', () => { 63 | let instance; 64 | const div = createDiv(); 65 | div.style.display = 'block'; 66 | div.style.width = '1200px'; 67 | div.style.height = '720px'; 68 | 69 | const style = { 70 | width: '100%', 71 | }; 72 | 73 | const Comp = (instance = e)} option={options} style={style} />; 74 | render(Comp, div); 75 | 76 | expect(instance).toBeDefined(); 77 | expect(instance.getEchartsInstance()).toBeDefined(); 78 | expect(instance.getEchartsInstance().getWidth()).toBe(1200); 79 | expect(instance.getEchartsInstance().getHeight()).toBe(300); // default height 80 | 81 | destroy(div); 82 | expect(div.querySelector('*')).toBe(null); 83 | 84 | removeDom(div); 85 | }); 86 | 87 | it('100% width, 100% height', () => { 88 | let instance; 89 | const div = createDiv(); 90 | div.style.display = 'block'; 91 | div.style.width = '1200px'; 92 | div.style.height = '720px'; 93 | 94 | const style = { 95 | width: '100%', 96 | height: '100%', 97 | }; 98 | 99 | const Comp = (instance = e)} option={options} style={style} />; 100 | render(Comp, div); 101 | 102 | expect(instance).toBeDefined(); 103 | expect(instance.getEchartsInstance()).toBeDefined(); 104 | expect(instance.getEchartsInstance().getWidth()).toBe(1200); 105 | expect(instance.getEchartsInstance().getHeight()).toBe(720); 106 | 107 | destroy(div); 108 | expect(div.querySelector('*')).toBe(null); 109 | 110 | removeDom(div); 111 | }); 112 | 113 | it('custom width, custom height', () => { 114 | let instance; 115 | const div = createDiv(); 116 | div.style.display = 'block'; 117 | div.style.width = '1200px'; 118 | div.style.height = '720px'; 119 | 120 | const style = { 121 | width: '400px', 122 | height: '150px', 123 | }; 124 | 125 | const Comp = (instance = e)} option={options} style={style} />; 126 | render(Comp, div); 127 | 128 | expect(instance).toBeDefined(); 129 | expect(instance.getEchartsInstance()).toBeDefined(); 130 | expect(instance.getEchartsInstance().getWidth()).toBe(400); 131 | expect(instance.getEchartsInstance().getHeight()).toBe(150); 132 | 133 | destroy(div); 134 | expect(div.querySelector('*')).toBe(null); 135 | 136 | removeDom(div); 137 | }); 138 | }); 139 | 140 | describe('opts', () => { 141 | it('default', () => { 142 | let instance; 143 | const div = createDiv(); 144 | div.style.display = 'block'; 145 | div.style.width = '1200px'; 146 | div.style.height = '720px'; 147 | 148 | const opts = { 149 | width: null, 150 | height: null, 151 | }; 152 | 153 | const Comp = (instance = e)} option={options} opts={opts} />; 154 | render(Comp, div); 155 | 156 | expect(instance).toBeDefined(); 157 | expect(instance.getEchartsInstance()).toBeDefined(); 158 | expect(instance.getEchartsInstance().getWidth()).toBe(1200); 159 | expect(instance.getEchartsInstance().getHeight()).toBe(300); // default height 160 | 161 | destroy(div); 162 | expect(div.querySelector('*')).toBe(null); 163 | 164 | removeDom(div); 165 | }); 166 | 167 | it('custom width, custom height', () => { 168 | let instance; 169 | const div = createDiv(); 170 | div.style.display = 'block'; 171 | div.style.width = '1200px'; 172 | div.style.height = '720px'; 173 | 174 | const opts = { 175 | width: 400, 176 | height: 150, 177 | }; 178 | 179 | const Comp = (instance = e)} option={options} opts={opts} />; 180 | render(Comp, div); 181 | 182 | expect(instance).toBeDefined(); 183 | expect(instance.getEchartsInstance()).toBeDefined(); 184 | expect(instance.getEchartsInstance().getWidth()).toBe(400); 185 | expect(instance.getEchartsInstance().getHeight()).toBe(150); 186 | 187 | destroy(div); 188 | expect(div.querySelector('*')).toBe(null); 189 | 190 | removeDom(div); 191 | }); 192 | }); 193 | }); 194 | }); 195 | -------------------------------------------------------------------------------- /__tests__/helper/is-equal-spec.ts: -------------------------------------------------------------------------------- 1 | import { isEqual } from '../../src/helper/is-equal'; 2 | 3 | describe('is-equal', () => { 4 | it('isEqual', () => { 5 | expect(isEqual({}, {})).toBe(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /__tests__/helper/is-fucntion-spec.ts: -------------------------------------------------------------------------------- 1 | import { isFunction } from '../../src/helper/is-function'; 2 | 3 | describe('is-function', () => { 4 | it('isFunction', () => { 5 | expect(isFunction(1)).toBe(false); 6 | expect(isFunction('')).toBe(false); 7 | expect(isFunction(true)).toBe(false); 8 | expect(isFunction(() => {})).toBe(true); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /__tests__/helper/is-string-spec.ts: -------------------------------------------------------------------------------- 1 | import { isString } from '../../src/helper/is-string'; 2 | 3 | describe('is-function', () => { 4 | it('isFunction', () => { 5 | expect(isString(1)).toBe(false); 6 | expect(isString('')).toBe(true); 7 | expect(isString(true)).toBe(false); 8 | expect(isString(() => {})).toBe(false); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /__tests__/helper/pick-spec.ts: -------------------------------------------------------------------------------- 1 | import { pick } from '../../src/helper/pick'; 2 | 3 | describe('pick', () => { 4 | it('pick', () => { 5 | expect(pick({ a: 1 }, [])).toEqual({}); 6 | expect(pick({ a: 1 }, ['b'])).toEqual({}); 7 | expect(pick({ a: 1 }, ['a'])).toEqual({ a: 1 }); 8 | expect(pick({ a: 1 }, ['a', 'b'])).toEqual({ a: 1 }); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /__tests__/utils/index.ts: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom'; 2 | 3 | /** 4 | * 渲染组件 5 | * @param comp 6 | * @param container 7 | */ 8 | export function render(comp: any, container: HTMLElement) { 9 | ReactDOM.render(comp, container); 10 | } 11 | 12 | /** 13 | * 卸载组件 14 | * @param container 15 | */ 16 | export function destroy(container: HTMLElement) { 17 | ReactDOM.unmountComponentAtNode(container); 18 | } 19 | 20 | /** 21 | * 创建一个 div 节点,并放到 container,默认放到 body 上 22 | * @param title 23 | * @param container 24 | * @param id 容器 id 25 | */ 26 | export function createDiv(container: HTMLElement = document.body): HTMLElement { 27 | const div = document.createElement('div'); 28 | 29 | container.appendChild(div); 30 | 31 | return div; 32 | } 33 | 34 | /** 35 | * 移除 dom 元素 36 | * @param dom 37 | */ 38 | export function removeDom(dom: HTMLElement) { 39 | const parent = dom.parentNode; 40 | 41 | if (parent) { 42 | parent.removeChild(dom); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /docs/examples/api.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ECharts API 3 | order: 2 4 | --- 5 | 6 | ## ECharts API 7 | 8 | ```tsx 9 | import React, { useRef } from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | const Page: React.FC = () => { 13 | const option = { 14 | title: { 15 | text: '漏斗图', 16 | subtext: '纯属虚构' 17 | }, 18 | tooltip: { 19 | trigger: 'item', 20 | formatter: "{a}
{b} : {c}%" 21 | }, 22 | toolbox: { 23 | feature: { 24 | dataView: {readOnly: false}, 25 | restore: {}, 26 | saveAsImage: {} 27 | } 28 | }, 29 | legend: { 30 | data: ['展现','点击','访问','咨询','订单'] 31 | }, 32 | series: [ 33 | { 34 | name: '预期', 35 | type: 'funnel', 36 | left: '10%', 37 | width: '80%', 38 | label: { 39 | normal: { 40 | formatter: '{b}预期' 41 | }, 42 | emphasis: { 43 | position:'inside', 44 | formatter: '{b}预期: {c}%' 45 | } 46 | }, 47 | labelLine: { 48 | normal: { 49 | show: false 50 | } 51 | }, 52 | itemStyle: { 53 | normal: { 54 | opacity: 0.7 55 | } 56 | }, 57 | data: [ 58 | {value: 60, name: '访问'}, 59 | {value: 40, name: '咨询'}, 60 | {value: 20, name: '订单'}, 61 | {value: 80, name: '点击'}, 62 | {value: 100, name: '展现'} 63 | ] 64 | }, 65 | { 66 | name: '实际', 67 | type: 'funnel', 68 | left: '10%', 69 | width: '80%', 70 | maxSize: '80%', 71 | label: { 72 | normal: { 73 | position: 'inside', 74 | formatter: '{c}%', 75 | textStyle: { 76 | color: '#fff' 77 | } 78 | }, 79 | emphasis: { 80 | position:'inside', 81 | formatter: '{b}实际: {c}%' 82 | } 83 | }, 84 | itemStyle: { 85 | normal: { 86 | opacity: 0.5, 87 | borderColor: '#fff', 88 | borderWidth: 2 89 | } 90 | }, 91 | data: [ 92 | {value: 30, name: '访问'}, 93 | {value: 10, name: '咨询'}, 94 | {value: 5, name: '订单'}, 95 | {value: 50, name: '点击'}, 96 | {value: 80, name: '展现'} 97 | ] 98 | } 99 | ] 100 | }; 101 | 102 | const instance = useRef(null); 103 | 104 | function clickBtn() { 105 | const base64 = instance.current.getEchartsInstance().getDataURL(); 106 | 107 | const img = new Image(); 108 | img.src = base64; 109 | const newWin = window.open('', '_blank'); 110 | newWin.document.write(img.outerHTML); 111 | } 112 | 113 | return ( 114 | <> 115 | 120 |
121 | 122 |
123 | 124 | ); 125 | }; 126 | 127 | export default Page; 128 | ``` 129 | -------------------------------------------------------------------------------- /docs/examples/dynamic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Dynamic 3 | order: 6 4 | --- 5 | 6 | ## Dynamic 7 | 8 | ```tsx 9 | import React, { useState, useEffect } from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | import cloneDeep from 'lodash.clonedeep'; 12 | 13 | const Page: React.FC = () => { 14 | const DEFAULT_OPTION = { 15 | title: { 16 | text:'Hello Echarts-for-react.', 17 | }, 18 | tooltip: { 19 | trigger: 'axis' 20 | }, 21 | legend: { 22 | data:['最新成交价', '预购队列'] 23 | }, 24 | toolbox: { 25 | show: true, 26 | feature: { 27 | dataView: {readOnly: false}, 28 | restore: {}, 29 | saveAsImage: {} 30 | } 31 | }, 32 | grid: { 33 | top: 60, 34 | left: 30, 35 | right: 60, 36 | bottom:30 37 | }, 38 | dataZoom: { 39 | show: false, 40 | start: 0, 41 | end: 100 42 | }, 43 | visualMap: { 44 | show: false, 45 | min: 0, 46 | max: 1000, 47 | color: ['#BE002F', '#F20C00', '#F00056', '#FF2D51', '#FF2121', '#FF4C00', '#FF7500', 48 | '#FF8936', '#FFA400', '#F0C239', '#FFF143', '#FAFF72', '#C9DD22', '#AFDD22', 49 | '#9ED900', '#00E500', '#0EB83A', '#0AA344', '#0C8918', '#057748', '#177CB0'] 50 | }, 51 | xAxis: [ 52 | { 53 | type: 'category', 54 | boundaryGap: true, 55 | data: (function (){ 56 | let now = new Date(); 57 | let res = []; 58 | let len = 50; 59 | while (len--) { 60 | res.unshift(now.toLocaleTimeString().replace(/^\D*/,'')); 61 | now = new Date(now - 2000); 62 | } 63 | return res; 64 | })() 65 | }, 66 | { 67 | type: 'category', 68 | boundaryGap: true, 69 | data: (function (){ 70 | let res = []; 71 | let len = 50; 72 | while (len--) { 73 | res.push(50 - len + 1); 74 | } 75 | return res; 76 | })() 77 | } 78 | ], 79 | yAxis: [ 80 | { 81 | type: 'value', 82 | scale: true, 83 | name: '价格', 84 | max: 20, 85 | min: 0, 86 | boundaryGap: [0.2, 0.2] 87 | }, 88 | { 89 | type: 'value', 90 | scale: true, 91 | name: '预购量', 92 | max: 1200, 93 | min: 0, 94 | boundaryGap: [0.2, 0.2] 95 | } 96 | ], 97 | series: [ 98 | { 99 | name:'预购队列', 100 | type:'bar', 101 | xAxisIndex: 1, 102 | yAxisIndex: 1, 103 | itemStyle: { 104 | normal: { 105 | barBorderRadius: 4, 106 | } 107 | }, 108 | animationEasing: 'elasticOut', 109 | animationDelay: function (idx) { 110 | return idx * 10; 111 | }, 112 | animationDelayUpdate: function (idx) { 113 | return idx * 10; 114 | }, 115 | data:(function (){ 116 | let res = []; 117 | let len = 50; 118 | while (len--) { 119 | res.push(Math.round(Math.random() * 1000)); 120 | } 121 | return res; 122 | })() 123 | }, 124 | { 125 | name:'最新成交价', 126 | type:'line', 127 | data:(function (){ 128 | let res = []; 129 | let len = 0; 130 | while (len < 50) { 131 | res.push((Math.random()*10 + 5).toFixed(1) - 0); 132 | len++; 133 | } 134 | return res; 135 | })() 136 | } 137 | ] 138 | }; 139 | 140 | let count; 141 | 142 | const [option, setOption] = useState(DEFAULT_OPTION); 143 | 144 | function fetchNewData() { 145 | const axisData = (new Date()).toLocaleTimeString().replace(/^\D*/,''); 146 | const newOption = cloneDeep(option); // immutable 147 | newOption.title.text = 'Hello Echarts-for-react.' + new Date().getSeconds(); 148 | const data0 = newOption.series[0].data; 149 | const data1 = newOption.series[1].data; 150 | data0.shift(); 151 | data0.push(Math.round(Math.random() * 1000)); 152 | data1.shift(); 153 | data1.push((Math.random() * 10 + 5).toFixed(1) - 0); 154 | 155 | newOption.xAxis[0].data.shift(); 156 | newOption.xAxis[0].data.push(axisData); 157 | newOption.xAxis[1].data.shift(); 158 | newOption.xAxis[1].data.push(count++); 159 | 160 | setOption(newOption); 161 | } 162 | 163 | useEffect(() => { 164 | const timer = setInterval(() => { 165 | fetchNewData(); 166 | }, 1000); 167 | 168 | return () => clearInterval(timer); 169 | }); 170 | 171 | return ; 175 | }; 176 | 177 | export default Page; 178 | ``` 179 | -------------------------------------------------------------------------------- /docs/examples/event.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Event 3 | order: 4 4 | --- 5 | 6 | ## Event 7 | 8 | ```tsx 9 | import React, { useState } from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | const Page: React.FC = () => { 13 | const option = { 14 | title : { 15 | text: '某站点用户访问来源', 16 | subtext: '纯属虚构', 17 | x:'center' 18 | }, 19 | tooltip : { 20 | trigger: 'item', 21 | formatter: "{a}
{b} : {c} ({d}%)" 22 | }, 23 | legend: { 24 | orient: 'vertical', 25 | left: 'left', 26 | data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎'] 27 | }, 28 | series : [ 29 | { 30 | name: '访问来源', 31 | type: 'pie', 32 | radius : '55%', 33 | center: ['50%', '60%'], 34 | data:[ 35 | {value:335, name:'直接访问'}, 36 | {value:310, name:'邮件营销'}, 37 | {value:234, name:'联盟广告'}, 38 | {value:135, name:'视频广告'}, 39 | {value:1548, name:'搜索引擎'} 40 | ], 41 | itemStyle: { 42 | emphasis: { 43 | shadowBlur: 10, 44 | shadowOffsetX: 0, 45 | shadowColor: 'rgba(0, 0, 0, 0.5)' 46 | } 47 | } 48 | } 49 | ] 50 | }; 51 | 52 | const [count, setCount] = useState(0); 53 | 54 | function onChartReady(echarts) { 55 | console.log('echarts is ready', echarts); 56 | } 57 | 58 | function onChartClick(param, echarts) { 59 | console.log(param, echarts); 60 | setCount(count + 1); 61 | }; 62 | 63 | function onChartLegendselectchanged(param, echarts) { 64 | console.log(param, echarts); 65 | }; 66 | 67 | return ( 68 | <> 69 | 78 |
Click Count: {count}
79 |
Open console, see the log detail.
80 | 81 | ); 82 | }; 83 | 84 | export default Page; 85 | ``` 86 | -------------------------------------------------------------------------------- /docs/examples/gl.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Web GL 3 | order: 7 4 | --- 5 | 6 | ## Web GL 7 | 8 | ```tsx 9 | import React from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | import 'echarts-gl'; 12 | 13 | const Page: React.FC = () => { 14 | const option = { 15 | grid3D: {}, 16 | xAxis3D: {}, 17 | yAxis3D: {}, 18 | zAxis3D: {}, 19 | series: [{ 20 | type: 'scatter3D', 21 | symbolSize: 50, 22 | data: [[-1, -1, -1], [0, 0, 0], [1, 1, 1]], 23 | itemStyle: { 24 | opacity: 1 25 | } 26 | }] 27 | }; 28 | 29 | return ; 33 | }; 34 | 35 | export default Page; 36 | ``` 37 | -------------------------------------------------------------------------------- /docs/examples/graph.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Graph 3 | order: 9 4 | --- 5 | 6 | ## Graph 7 | 8 | ```tsx 9 | import React from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | const Page: React.FC = () => { 13 | const webkitDep = {"type":"force","categories":[{"name":"HTMLElement","keyword":{},"base":"HTMLElement"},{"name":"WebGL","keyword":{},"base":"WebGLRenderingContext"},{"name":"SVG","keyword":{},"base":"SVGElement"},{"name":"CSS","keyword":{},"base":"CSSRule"},{"name":"Other","keyword":{}}],"nodes":[{"name":"AnalyserNode","value":1,"category":4},{"name":"AudioNode","value":1,"category":4},{"name":"Uint8Array","value":1,"category":4},{"name":"Float32Array","value":1,"category":4},{"name":"ArrayBuffer","value":1,"category":4},{"name":"ArrayBufferView","value":1,"category":4},{"name":"Attr","value":1,"category":4},{"name":"Node","value":1,"category":4},{"name":"Element","value":1,"category":4},{"name":"AudioBuffer","value":1,"category":4},{"name":"AudioBufferCallback","value":1,"category":4},{"name":"AudioBufferSourceNode","value":1,"category":4},{"name":"AudioSourceNode","value":1,"category":4},{"name":"AudioGain","value":1,"category":4},{"name":"AudioParam","value":1,"category":4},{"name":"AudioContext","value":1,"category":4},{"name":"AudioDestinationNode","value":1,"category":4},{"name":"AudioListener","value":1,"category":4},{"name":"BiquadFilterNode","value":1,"category":4},{"name":"ChannelMergerNode","value":1,"category":4},{"name":"ChannelSplitterNode","value":1,"category":4},{"name":"ConvolverNode","value":1,"category":4},{"name":"DelayNode","value":1,"category":4},{"name":"DynamicsCompressorNode","value":1,"category":4},{"name":"GainNode","value":1,"category":4},{"name":"MediaElementAudioSourceNode","value":1,"category":4},{"name":"MediaStreamAudioDestinationNode","value":1,"category":4},{"name":"MediaStreamAudioSourceNode","value":1,"category":4},{"name":"OscillatorNode","value":1,"category":4},{"name":"PannerNode","value":1,"category":4},{"name":"ScriptProcessorNode","value":1,"category":4},{"name":"WaveShaperNode","value":1,"category":4},{"name":"WaveTable","value":1,"category":4},{"name":"CanvasRenderingContext","value":1,"category":4},{"name":"HTMLCanvasElement","value":1,"category":0},{"name":"CanvasRenderingContext2D","value":1,"category":4},{"name":"ImageData","value":1,"category":4},{"name":"CanvasGradient","value":1,"category":4},{"name":"CanvasPattern","value":1,"category":4},{"name":"HTMLImageElement","value":1,"category":0},{"name":"HTMLVideoElement","value":1,"category":0},{"name":"TextMetrics","value":1,"category":4},{"name":"CDATASection","value":1,"category":4},{"name":"Text","value":1,"category":4},{"name":"CharacterData","value":1,"category":4},{"name":"ClientRectList","value":1,"category":4},{"name":"ClientRect","value":1,"category":4},{"name":"Clipboard","value":1,"category":4},{"name":"FileList","value":1,"category":4},{"name":"DataTransferItemList","value":1,"category":4},{"name":"Comment","value":1,"category":4},{"name":"Console","value":1,"category":4},{"name":"MemoryInfo","value":1,"category":4},{"name":"Crypto","value":1,"category":4},{"name":"CSSCharsetRule","value":1,"category":3},{"name":"CSSRule","value":3,"category":3},{"name":"CSSFontFaceRule","value":1,"category":3},{"name":"CSSStyleDeclaration","value":1,"category":3},{"name":"CSSImportRule","value":1,"category":3},{"name":"MediaList","value":1,"category":4},{"name":"CSSStyleSheet","value":1,"category":3},{"name":"CSSMediaRule","value":1,"category":3},{"name":"CSSRuleList","value":1,"category":3},{"name":"CSSPageRule","value":1,"category":3},{"name":"CSSPrimitiveValue","value":1,"category":3},{"name":"CSSValue","value":1,"category":3},{"name":"Counter","value":1,"category":4},{"name":"RGBColor","value":1,"category":4},{"name":"Rect","value":1,"category":4},{"name":"CSSStyleRule","value":1,"category":3},{"name":"StyleSheet","value":1,"category":4},{"name":"CSSUnknownRule","value":1,"category":3},{"name":"CSSValueList","value":1,"category":3},{"name":"Database","value":1,"category":4},{"name":"SQLTransactionCallback","value":1,"category":4},{"name":"DatabaseCallback","value":1,"category":4},{"name":"DatabaseSync","value":1,"category":4},{"name":"SQLTransactionSyncCallback","value":1,"category":4},{"name":"DataTransferItem","value":1,"category":4},{"name":"StringCallback","value":1,"category":4},{"name":"Entry","value":1,"category":4},{"name":"File","value":1,"category":4},{"name":"DataView","value":1,"category":4},{"name":"DedicatedWorkerContext","value":1,"category":4},{"name":"WorkerContext","value":1,"category":4},{"name":"DirectoryEntry","value":1,"category":4},{"name":"DirectoryReader","value":1,"category":4},{"name":"VoidCallback","value":1,"category":4},{"name":"DirectoryEntrySync","value":1,"category":4},{"name":"EntrySync","value":1,"category":4},{"name":"DirectoryReaderSync","value":1,"category":4},{"name":"FileEntrySync","value":1,"category":4},{"name":"EntriesCallback","value":1,"category":4},{"name":"EntryArraySync","value":1,"category":4},{"name":"DocumentFragment","value":1,"category":4},{"name":"NodeList","value":1,"category":4},{"name":"DocumentType","value":1,"category":4},{"name":"NamedNodeMap","value":1,"category":4},{"name":"DOMFileSystem","value":1,"category":4},{"name":"DOMFileSystemSync","value":1,"category":4},{"name":"DOMImplementation","value":1,"category":4},{"name":"HTMLDocument","value":1,"category":0},{"name":"DOMMimeType","value":1,"category":4},{"name":"DOMPlugin","value":1,"category":4},{"name":"DOMMimeTypeArray","value":1,"category":4},{"name":"DOMPluginArray","value":1,"category":4},{"name":"DOMSelection","value":1,"category":4},{"name":"Range","value":1,"category":4},{"name":"DOMSettableTokenList","value":1,"category":4},{"name":"DOMTokenList","value":1,"category":4},{"name":"DOMStringMap","value":1,"category":4},{"name":"ShadowRoot","value":1,"category":4},{"name":"Entity","value":1,"category":4},{"name":"EntityReference","value":1,"category":4},{"name":"EntryArray","value":1,"category":4},{"name":"MetadataCallback","value":1,"category":4},{"name":"EntryCallback","value":1,"category":4},{"name":"Metadata","value":1,"category":4},{"name":"ErrorCallback","value":1,"category":4},{"name":"FileError","value":1,"category":4},{"name":"FileCallback","value":1,"category":4},{"name":"FileEntry","value":1,"category":4},{"name":"FileWriterCallback","value":1,"category":4},{"name":"FileWriterSync","value":1,"category":4},{"name":"FileReader","value":1,"category":4},{"name":"FileReaderSync","value":1,"category":4},{"name":"FileSystemCallback","value":1,"category":4},{"name":"FileWriter","value":1,"category":4},{"name":"Float64Array","value":1,"category":4},{"name":"GamepadList","value":1,"category":4},{"name":"Gamepad","value":1,"category":4},{"name":"Geolocation","value":1,"category":4},{"name":"PositionCallback","value":1,"category":4},{"name":"Geoposition","value":1,"category":4},{"name":"Coordinates","value":1,"category":4},{"name":"HTMLAllCollection","value":1,"category":0},{"name":"HTMLAnchorElement","value":1,"category":0},{"name":"HTMLElement","value":3,"category":0},{"name":"HTMLAppletElement","value":1,"category":0},{"name":"HTMLAreaElement","value":1,"category":0},{"name":"HTMLAudioElement","value":1,"category":0},{"name":"HTMLMediaElement","value":1,"category":0},{"name":"HTMLBaseElement","value":1,"category":0},{"name":"HTMLBaseFontElement","value":1,"category":0},{"name":"HTMLBodyElement","value":1,"category":0},{"name":"HTMLBRElement","value":1,"category":0},{"name":"HTMLButtonElement","value":1,"category":0},{"name":"HTMLFormElement","value":1,"category":0},{"name":"ValidityState","value":1,"category":4},{"name":"HTMLCollection","value":1,"category":0},{"name":"HTMLContentElement","value":1,"category":0},{"name":"HTMLDataListElement","value":1,"category":0},{"name":"HTMLDetailsElement","value":1,"category":0},{"name":"HTMLDirectoryElement","value":1,"category":0},{"name":"HTMLDivElement","value":1,"category":0},{"name":"HTMLDListElement","value":1,"category":0},{"name":"HTMLEmbedElement","value":1,"category":0},{"name":"SVGDocument","value":1,"category":2},{"name":"HTMLFieldSetElement","value":1,"category":0},{"name":"HTMLFontElement","value":1,"category":0},{"name":"HTMLFormControlsCollection","value":1,"category":0},{"name":"HTMLFrameElement","value":1,"category":0},{"name":"HTMLFrameSetElement","value":1,"category":0},{"name":"HTMLHeadElement","value":1,"category":0},{"name":"HTMLHeadingElement","value":1,"category":0},{"name":"HTMLHRElement","value":1,"category":0},{"name":"HTMLHtmlElement","value":1,"category":0},{"name":"HTMLIFrameElement","value":1,"category":0},{"name":"HTMLInputElement","value":1,"category":0},{"name":"HTMLKeygenElement","value":1,"category":0},{"name":"HTMLLabelElement","value":1,"category":0},{"name":"HTMLLegendElement","value":1,"category":0},{"name":"HTMLLIElement","value":1,"category":0},{"name":"HTMLLinkElement","value":1,"category":0},{"name":"HTMLMapElement","value":1,"category":0},{"name":"HTMLMarqueeElement","value":1,"category":0},{"name":"TimeRanges","value":1,"category":4},{"name":"MediaController","value":1,"category":4},{"name":"MediaError","value":1,"category":4},{"name":"TextTrackList","value":1,"category":4},{"name":"TextTrack","value":1,"category":4},{"name":"HTMLMenuElement","value":1,"category":0},{"name":"HTMLMetaElement","value":1,"category":0},{"name":"HTMLMeterElement","value":1,"category":0},{"name":"HTMLModElement","value":1,"category":0},{"name":"HTMLObjectElement","value":1,"category":0},{"name":"HTMLOListElement","value":1,"category":0},{"name":"HTMLOptGroupElement","value":1,"category":0},{"name":"HTMLOptionElement","value":1,"category":0},{"name":"HTMLOptionsCollection","value":1,"category":0},{"name":"HTMLOutputElement","value":1,"category":0},{"name":"HTMLParagraphElement","value":1,"category":0},{"name":"HTMLParamElement","value":1,"category":0},{"name":"HTMLPreElement","value":1,"category":0},{"name":"HTMLProgressElement","value":1,"category":0},{"name":"HTMLQuoteElement","value":1,"category":0},{"name":"HTMLScriptElement","value":1,"category":0},{"name":"HTMLSelectElement","value":1,"category":0},{"name":"HTMLShadowElement","value":1,"category":0},{"name":"HTMLSourceElement","value":1,"category":0},{"name":"HTMLSpanElement","value":1,"category":0},{"name":"HTMLStyleElement","value":1,"category":0},{"name":"HTMLTableCaptionElement","value":1,"category":0},{"name":"HTMLTableCellElement","value":1,"category":0},{"name":"HTMLTableColElement","value":1,"category":0},{"name":"HTMLTableElement","value":1,"category":0},{"name":"HTMLTableSectionElement","value":1,"category":0},{"name":"HTMLTableRowElement","value":1,"category":0},{"name":"HTMLTextAreaElement","value":1,"category":0},{"name":"HTMLTitleElement","value":1,"category":0},{"name":"HTMLTrackElement","value":1,"category":0},{"name":"HTMLUListElement","value":1,"category":0},{"name":"HTMLUnknownElement","value":1,"category":0},{"name":"IDBCursor","value":1,"category":4},{"name":"IDBAny","value":1,"category":4},{"name":"IDBKey","value":1,"category":4},{"name":"IDBRequest","value":1,"category":4},{"name":"IDBCursorWithValue","value":1,"category":4},{"name":"IDBDatabase","value":1,"category":4},{"name":"DOMStringList","value":1,"category":4},{"name":"IDBObjectStore","value":1,"category":4},{"name":"IDBTransaction","value":1,"category":4},{"name":"IDBFactory","value":1,"category":4},{"name":"IDBVersionChangeRequest","value":1,"category":4},{"name":"IDBOpenDBRequest","value":1,"category":4},{"name":"IDBIndex","value":1,"category":4},{"name":"IDBKeyRange","value":1,"category":4},{"name":"DOMError","value":1,"category":4},{"name":"Int16Array","value":1,"category":4},{"name":"Int32Array","value":1,"category":4},{"name":"Int8Array","value":1,"category":4},{"name":"JavaScriptCallFrame","value":1,"category":4},{"name":"LocalMediaStream","value":1,"category":4},{"name":"MediaStream","value":1,"category":4},{"name":"Location","value":1,"category":4},{"name":"MediaQueryList","value":1,"category":4},{"name":"MediaQueryListListener","value":1,"category":4},{"name":"MediaSource","value":1,"category":4},{"name":"SourceBufferList","value":1,"category":4},{"name":"SourceBuffer","value":1,"category":4},{"name":"MediaStreamTrackList","value":1,"category":4},{"name":"MediaStreamList","value":1,"category":4},{"name":"MediaStreamTrack","value":1,"category":4},{"name":"MessageChannel","value":1,"category":4},{"name":"MessagePort","value":1,"category":4},{"name":"MutationObserver","value":1,"category":4},{"name":"MutationRecord","value":1,"category":4},{"name":"Navigator","value":1,"category":4},{"name":"BatteryManager","value":1,"category":4},{"name":"NavigatorUserMediaErrorCallback","value":1,"category":4},{"name":"NavigatorUserMediaError","value":1,"category":4},{"name":"NavigatorUserMediaSuccessCallback","value":1,"category":4},{"name":"NodeFilter","value":1,"category":4},{"name":"NodeIterator","value":1,"category":4},{"name":"Notation","value":1,"category":4},{"name":"Notification","value":1,"category":4},{"name":"NotificationPermissionCallback","value":1,"category":4},{"name":"NotificationCenter","value":1,"category":4},{"name":"OESVertexArrayObject","value":1,"category":4},{"name":"WebGLVertexArrayObjectOES","value":1,"category":1},{"name":"Performance","value":1,"category":4},{"name":"PerformanceNavigation","value":1,"category":4},{"name":"PerformanceTiming","value":1,"category":4},{"name":"PositionErrorCallback","value":1,"category":4},{"name":"PositionError","value":1,"category":4},{"name":"ProcessingInstruction","value":1,"category":4},{"name":"RadioNodeList","value":1,"category":4},{"name":"RTCDataChannel","value":1,"category":4},{"name":"RTCPeerConnection","value":1,"category":4},{"name":"RTCSessionDescription","value":1,"category":4},{"name":"RTCIceCandidate","value":1,"category":4},{"name":"RTCSessionDescriptionCallback","value":1,"category":4},{"name":"RTCStatsCallback","value":1,"category":4},{"name":"RTCStatsResponse","value":1,"category":4},{"name":"RTCStatsReport","value":1,"category":4},{"name":"RTCStatsElement","value":1,"category":4},{"name":"ScriptProfile","value":1,"category":4},{"name":"ScriptProfileNode","value":1,"category":4},{"name":"SharedWorker","value":1,"category":4},{"name":"AbstractWorker","value":1,"category":4},{"name":"SharedWorkerContext","value":1,"category":4},{"name":"SpeechGrammarList","value":1,"category":4},{"name":"SpeechGrammar","value":1,"category":4},{"name":"SpeechInputResultList","value":1,"category":4},{"name":"SpeechInputResult","value":1,"category":4},{"name":"SpeechRecognition","value":1,"category":4},{"name":"SpeechRecognitionResult","value":1,"category":4},{"name":"SpeechRecognitionAlternative","value":1,"category":4},{"name":"SpeechRecognitionResultList","value":1,"category":4},{"name":"SQLResultSet","value":1,"category":4},{"name":"SQLResultSetRowList","value":1,"category":4},{"name":"SQLStatementCallback","value":1,"category":4},{"name":"SQLTransaction","value":1,"category":4},{"name":"SQLStatementErrorCallback","value":1,"category":4},{"name":"SQLTransactionErrorCallback","value":1,"category":4},{"name":"SQLError","value":1,"category":4},{"name":"SQLTransactionSync","value":1,"category":4},{"name":"StorageInfo","value":1,"category":4},{"name":"StorageInfoUsageCallback","value":1,"category":4},{"name":"StorageInfoQuotaCallback","value":1,"category":4},{"name":"StorageInfoErrorCallback","value":1,"category":4},{"name":"DOMCoreException","value":1,"category":4},{"name":"StyleSheetList","value":1,"category":4},{"name":"SVGAElement","value":1,"category":2},{"name":"SVGTransformable","value":1,"category":2},{"name":"SVGAnimatedString","value":1,"category":2},{"name":"SVGAltGlyphDefElement","value":1,"category":2},{"name":"SVGElement","value":3,"category":2},{"name":"SVGAltGlyphElement","value":1,"category":2},{"name":"SVGURIReference","value":1,"category":2},{"name":"SVGAltGlyphItemElement","value":1,"category":2},{"name":"SVGAnimateColorElement","value":1,"category":2},{"name":"SVGAnimationElement","value":1,"category":2},{"name":"SVGAnimatedAngle","value":1,"category":2},{"name":"SVGAngle","value":1,"category":2},{"name":"SVGAnimatedLength","value":1,"category":2},{"name":"SVGLength","value":1,"category":2},{"name":"SVGAnimatedLengthList","value":1,"category":2},{"name":"SVGLengthList","value":1,"category":2},{"name":"SVGAnimatedNumberList","value":1,"category":2},{"name":"SVGNumberList","value":1,"category":2},{"name":"SVGAnimatedPreserveAspectRatio","value":1,"category":2},{"name":"SVGPreserveAspectRatio","value":1,"category":2},{"name":"SVGAnimatedRect","value":1,"category":2},{"name":"SVGRect","value":1,"category":2},{"name":"SVGAnimatedTransformList","value":1,"category":2},{"name":"SVGTransformList","value":1,"category":2},{"name":"SVGAnimateElement","value":1,"category":2},{"name":"SVGAnimateMotionElement","value":1,"category":2},{"name":"SVGAnimateTransformElement","value":1,"category":2},{"name":"ElementTimeControl","value":1,"category":4},{"name":"SVGCircleElement","value":1,"category":2},{"name":"SVGClipPathElement","value":1,"category":2},{"name":"SVGAnimatedEnumeration","value":1,"category":2},{"name":"SVGColor","value":1,"category":2},{"name":"SVGComponentTransferFunctionElement","value":1,"category":2},{"name":"SVGAnimatedNumber","value":1,"category":2},{"name":"SVGCursorElement","value":1,"category":2},{"name":"SVGExternalResourcesRequired","value":1,"category":2},{"name":"SVGDefsElement","value":1,"category":2},{"name":"SVGDescElement","value":1,"category":2},{"name":"SVGStylable","value":1,"category":2},{"name":"SVGSVGElement","value":1,"category":2},{"name":"SVGElementInstance","value":1,"category":2},{"name":"EventTarget","value":1,"category":4},{"name":"SVGElementInstanceList","value":1,"category":2},{"name":"SVGUseElement","value":1,"category":2},{"name":"SVGEllipseElement","value":1,"category":2},{"name":"SVGAnimatedBoolean","value":1,"category":2},{"name":"SVGFEBlendElement","value":1,"category":2},{"name":"SVGFilterPrimitiveStandardAttributes","value":1,"category":2},{"name":"SVGFEColorMatrixElement","value":1,"category":2},{"name":"SVGFEComponentTransferElement","value":1,"category":2},{"name":"SVGFECompositeElement","value":1,"category":2},{"name":"SVGFEConvolveMatrixElement","value":1,"category":2},{"name":"SVGAnimatedInteger","value":1,"category":2},{"name":"SVGFEDiffuseLightingElement","value":1,"category":2},{"name":"SVGFEDisplacementMapElement","value":1,"category":2},{"name":"SVGFEDistantLightElement","value":1,"category":2},{"name":"SVGFEDropShadowElement","value":1,"category":2},{"name":"SVGFEFloodElement","value":1,"category":2},{"name":"SVGFEFuncAElement","value":1,"category":2},{"name":"SVGFEFuncBElement","value":1,"category":2},{"name":"SVGFEFuncGElement","value":1,"category":2},{"name":"SVGFEFuncRElement","value":1,"category":2},{"name":"SVGFEGaussianBlurElement","value":1,"category":2},{"name":"SVGFEImageElement","value":1,"category":2},{"name":"SVGFEMergeElement","value":1,"category":2},{"name":"SVGFEMergeNodeElement","value":1,"category":2},{"name":"SVGFEMorphologyElement","value":1,"category":2},{"name":"SVGFEOffsetElement","value":1,"category":2},{"name":"SVGFEPointLightElement","value":1,"category":2},{"name":"SVGFESpecularLightingElement","value":1,"category":2},{"name":"SVGFESpotLightElement","value":1,"category":2},{"name":"SVGFETileElement","value":1,"category":2},{"name":"SVGFETurbulenceElement","value":1,"category":2},{"name":"SVGFilterElement","value":1,"category":2},{"name":"SVGFitToViewBox","value":1,"category":2},{"name":"SVGFontElement","value":1,"category":2},{"name":"SVGFontFaceElement","value":1,"category":2},{"name":"SVGFontFaceFormatElement","value":1,"category":2},{"name":"SVGFontFaceNameElement","value":1,"category":2},{"name":"SVGFontFaceSrcElement","value":1,"category":2},{"name":"SVGFontFaceUriElement","value":1,"category":2},{"name":"SVGForeignObjectElement","value":1,"category":2},{"name":"SVGGElement","value":1,"category":2},{"name":"SVGGlyphElement","value":1,"category":2},{"name":"SVGGlyphRefElement","value":1,"category":2},{"name":"SVGGradientElement","value":1,"category":2},{"name":"SVGHKernElement","value":1,"category":2},{"name":"SVGImageElement","value":1,"category":2},{"name":"SVGLinearGradientElement","value":1,"category":2},{"name":"SVGLineElement","value":1,"category":2},{"name":"SVGLocatable","value":1,"category":2},{"name":"SVGMatrix","value":1,"category":2},{"name":"SVGMarkerElement","value":1,"category":2},{"name":"SVGMaskElement","value":1,"category":2},{"name":"SVGMetadataElement","value":1,"category":2},{"name":"SVGMissingGlyphElement","value":1,"category":2},{"name":"SVGMPathElement","value":1,"category":2},{"name":"SVGNumber","value":1,"category":2},{"name":"SVGPaint","value":1,"category":2},{"name":"SVGPathElement","value":1,"category":2},{"name":"SVGPathSegList","value":1,"category":2},{"name":"SVGPathSegArcAbs","value":1,"category":2},{"name":"SVGPathSegArcRel","value":1,"category":2},{"name":"SVGPathSegClosePath","value":1,"category":2},{"name":"SVGPathSegCurvetoCubicAbs","value":1,"category":2},{"name":"SVGPathSegCurvetoCubicRel","value":1,"category":2},{"name":"SVGPathSegCurvetoCubicSmoothAbs","value":1,"category":2},{"name":"SVGPathSegCurvetoCubicSmoothRel","value":1,"category":2},{"name":"SVGPathSegCurvetoQuadraticAbs","value":1,"category":2},{"name":"SVGPathSegCurvetoQuadraticRel","value":1,"category":2},{"name":"SVGPathSegCurvetoQuadraticSmoothAbs","value":1,"category":2},{"name":"SVGPathSegCurvetoQuadraticSmoothRel","value":1,"category":2},{"name":"SVGPathSegLinetoAbs","value":1,"category":2},{"name":"SVGPathSegLinetoHorizontalAbs","value":1,"category":2},{"name":"SVGPathSegLinetoHorizontalRel","value":1,"category":2},{"name":"SVGPathSegLinetoRel","value":1,"category":2},{"name":"SVGPathSegLinetoVerticalAbs","value":1,"category":2},{"name":"SVGPathSegLinetoVerticalRel","value":1,"category":2},{"name":"SVGPathSegMovetoAbs","value":1,"category":2},{"name":"SVGPathSegMovetoRel","value":1,"category":2},{"name":"SVGPoint","value":1,"category":2},{"name":"SVGPathSeg","value":1,"category":2},{"name":"SVGPatternElement","value":1,"category":2},{"name":"SVGPointList","value":1,"category":2},{"name":"SVGPolygonElement","value":1,"category":2},{"name":"SVGPolylineElement","value":1,"category":2},{"name":"SVGRadialGradientElement","value":1,"category":2},{"name":"SVGRectElement","value":1,"category":2},{"name":"SVGScriptElement","value":1,"category":2},{"name":"SVGSetElement","value":1,"category":2},{"name":"SVGStopElement","value":1,"category":2},{"name":"SVGStyleElement","value":1,"category":2},{"name":"SVGLangSpace","value":1,"category":2},{"name":"SVGZoomAndPan","value":1,"category":2},{"name":"SVGViewSpec","value":1,"category":2},{"name":"SVGTransform","value":1,"category":2},{"name":"SVGSwitchElement","value":1,"category":2},{"name":"SVGSymbolElement","value":1,"category":2},{"name":"SVGTests","value":1,"category":2},{"name":"SVGStringList","value":1,"category":2},{"name":"SVGTextContentElement","value":1,"category":2},{"name":"SVGTextElement","value":1,"category":2},{"name":"SVGTextPathElement","value":1,"category":2},{"name":"SVGTextPositioningElement","value":1,"category":2},{"name":"SVGTitleElement","value":1,"category":2},{"name":"SVGTRefElement","value":1,"category":2},{"name":"SVGTSpanElement","value":1,"category":2},{"name":"SVGViewElement","value":1,"category":2},{"name":"SVGVKernElement","value":1,"category":2},{"name":"TextTrackCueList","value":1,"category":4},{"name":"TextTrackCue","value":1,"category":4},{"name":"Touch","value":1,"category":4},{"name":"TouchList","value":1,"category":4},{"name":"TreeWalker","value":1,"category":4},{"name":"Uint16Array","value":1,"category":4},{"name":"Uint32Array","value":1,"category":4},{"name":"Uint8ClampedArray","value":1,"category":4},{"name":"WebGLRenderingContext","value":3,"category":1},{"name":"WebGLProgram","value":1,"category":1},{"name":"WebGLBuffer","value":1,"category":1},{"name":"WebGLFramebuffer","value":1,"category":1},{"name":"WebGLRenderbuffer","value":1,"category":1},{"name":"WebGLTexture","value":1,"category":1},{"name":"WebGLShader","value":1,"category":1},{"name":"WebGLActiveInfo","value":1,"category":1},{"name":"WebGLContextAttributes","value":1,"category":1},{"name":"WebGLShaderPrecisionFormat","value":1,"category":1},{"name":"WebGLUniformLocation","value":1,"category":1},{"name":"WebKitAnimationList","value":1,"category":4},{"name":"WebKitAnimation","value":1,"category":4},{"name":"WebKitCSSFilterValue","value":1,"category":4},{"name":"WebKitCSSKeyframeRule","value":1,"category":4},{"name":"WebKitCSSKeyframesRule","value":1,"category":4},{"name":"WebKitCSSMatrix","value":1,"category":4},{"name":"WebKitCSSMixFunctionValue","value":1,"category":4},{"name":"WebKitCSSTransformValue","value":1,"category":4},{"name":"WebKitNamedFlow","value":1,"category":4},{"name":"WebSocket","value":1,"category":4},{"name":"Worker","value":1,"category":4},{"name":"WorkerLocation","value":1,"category":4},{"name":"WorkerNavigator","value":1,"category":4},{"name":"XMLHttpRequest","value":1,"category":4},{"name":"XMLHttpRequestUpload","value":1,"category":4},{"name":"DOMFormData","value":1,"category":4},{"name":"XPathEvaluator","value":1,"category":4},{"name":"XPathExpression","value":1,"category":4},{"name":"XPathNSResolver","value":1,"category":4},{"name":"XPathResult","value":1,"category":4},{"name":"XSLTProcessor","value":1,"category":4}],"links":[{"source":0,"target":1},{"source":0,"target":2},{"source":0,"target":3},{"source":4,"target":4},{"source":5,"target":4},{"source":6,"target":7},{"source":6,"target":8},{"source":9,"target":3},{"source":10,"target":9},{"source":11,"target":12},{"source":11,"target":9},{"source":11,"target":13},{"source":11,"target":14},{"source":15,"target":16},{"source":15,"target":17},{"source":15,"target":0},{"source":15,"target":18},{"source":15,"target":9},{"source":15,"target":11},{"source":15,"target":19},{"source":15,"target":20},{"source":15,"target":21},{"source":15,"target":22},{"source":15,"target":23},{"source":15,"target":24},{"source":15,"target":25},{"source":15,"target":26},{"source":15,"target":27},{"source":15,"target":28},{"source":15,"target":29},{"source":15,"target":30},{"source":15,"target":31},{"source":15,"target":32},{"source":15,"target":4},{"source":16,"target":1},{"source":13,"target":14},{"source":1,"target":15},{"source":1,"target":1},{"source":1,"target":14},{"source":14,"target":3},{"source":12,"target":1},{"source":18,"target":1},{"source":18,"target":14},{"source":18,"target":3},{"source":33,"target":34},{"source":35,"target":33},{"source":35,"target":36},{"source":35,"target":37},{"source":35,"target":38},{"source":35,"target":39},{"source":35,"target":34},{"source":35,"target":40},{"source":35,"target":41},{"source":42,"target":43},{"source":19,"target":1},{"source":20,"target":1},{"source":44,"target":7},{"source":45,"target":46},{"source":47,"target":48},{"source":47,"target":49},{"source":47,"target":39},{"source":50,"target":44},{"source":51,"target":52},{"source":21,"target":1},{"source":21,"target":9},{"source":53,"target":5},{"source":54,"target":55},{"source":56,"target":55},{"source":56,"target":57},{"source":58,"target":55},{"source":58,"target":59},{"source":58,"target":60},{"source":61,"target":55},{"source":61,"target":62},{"source":61,"target":59},{"source":63,"target":55},{"source":63,"target":57},{"source":64,"target":65},{"source":64,"target":66},{"source":64,"target":67},{"source":64,"target":68},{"source":55,"target":55},{"source":55,"target":60},{"source":62,"target":55},{"source":57,"target":55},{"source":57,"target":65},{"source":69,"target":55},{"source":69,"target":57},{"source":60,"target":70},{"source":60,"target":62},{"source":60,"target":55},{"source":71,"target":55},{"source":72,"target":65},{"source":73,"target":74},{"source":75,"target":73},{"source":75,"target":76},{"source":76,"target":77},{"source":78,"target":79},{"source":78,"target":80},{"source":49,"target":81},{"source":49,"target":78},{"source":82,"target":5},{"source":83,"target":84},{"source":22,"target":1},{"source":22,"target":14},{"source":85,"target":80},{"source":85,"target":86},{"source":85,"target":87},{"source":88,"target":89},{"source":88,"target":90},{"source":88,"target":88},{"source":88,"target":91},{"source":86,"target":92},{"source":90,"target":93},{"source":94,"target":7},{"source":94,"target":8},{"source":94,"target":95},{"source":96,"target":7},{"source":96,"target":97},{"source":98,"target":85},{"source":99,"target":88},{"source":100,"target":60},{"source":100,"target":96},{"source":100,"target":101},{"source":102,"target":103},{"source":104,"target":102},{"source":103,"target":102},{"source":105,"target":103},{"source":106,"target":7},{"source":106,"target":107},{"source":108,"target":109},{"source":23,"target":1},{"source":23,"target":14},{"source":8,"target":7},{"source":8,"target":109},{"source":8,"target":110},{"source":8,"target":8},{"source":8,"target":57},{"source":8,"target":6},{"source":8,"target":46},{"source":8,"target":45},{"source":8,"target":95},{"source":8,"target":111},{"source":112,"target":7},{"source":113,"target":7},{"source":92,"target":114},{"source":80,"target":98},{"source":80,"target":85},{"source":80,"target":115},{"source":80,"target":116},{"source":80,"target":87},{"source":114,"target":80},{"source":93,"target":89},{"source":116,"target":80},{"source":89,"target":99},{"source":89,"target":89},{"source":89,"target":117},{"source":89,"target":88},{"source":118,"target":119},{"source":120,"target":81},{"source":121,"target":80},{"source":121,"target":122},{"source":121,"target":120},{"source":91,"target":89},{"source":91,"target":123},{"source":91,"target":81},{"source":48,"target":81},{"source":124,"target":119},{"source":125,"target":4},{"source":126,"target":98},{"source":127,"target":119},{"source":122,"target":127},{"source":3,"target":5},{"source":3,"target":3},{"source":128,"target":5},{"source":128,"target":128},{"source":24,"target":1},{"source":24,"target":13},{"source":129,"target":130},{"source":131,"target":132},{"source":133,"target":134},{"source":135,"target":7},{"source":135,"target":95},{"source":136,"target":137},{"source":138,"target":137},{"source":139,"target":137},{"source":140,"target":141},{"source":142,"target":137},{"source":143,"target":137},{"source":144,"target":137},{"source":145,"target":137},{"source":146,"target":137},{"source":146,"target":147},{"source":146,"target":95},{"source":146,"target":148},{"source":34,"target":137},{"source":149,"target":7},{"source":150,"target":137},{"source":150,"target":95},{"source":151,"target":137},{"source":151,"target":149},{"source":152,"target":137},{"source":153,"target":137},{"source":154,"target":137},{"source":155,"target":137},{"source":101,"target":8},{"source":101,"target":135},{"source":101,"target":149},{"source":137,"target":8},{"source":137,"target":149},{"source":156,"target":137},{"source":156,"target":157},{"source":158,"target":137},{"source":158,"target":149},{"source":158,"target":147},{"source":158,"target":148},{"source":159,"target":137},{"source":160,"target":149},{"source":160,"target":7},{"source":147,"target":137},{"source":147,"target":149},{"source":161,"target":137},{"source":161,"target":157},{"source":162,"target":137},{"source":163,"target":137},{"source":164,"target":137},{"source":165,"target":137},{"source":166,"target":137},{"source":167,"target":137},{"source":167,"target":157},{"source":39,"target":137},{"source":168,"target":137},{"source":168,"target":48},{"source":168,"target":147},{"source":168,"target":95},{"source":168,"target":148},{"source":168,"target":114},{"source":169,"target":137},{"source":169,"target":147},{"source":169,"target":95},{"source":169,"target":148},{"source":170,"target":137},{"source":170,"target":147},{"source":171,"target":137},{"source":171,"target":147},{"source":172,"target":137},{"source":173,"target":137},{"source":173,"target":70},{"source":173,"target":108},{"source":174,"target":137},{"source":174,"target":149},{"source":175,"target":137},{"source":141,"target":137},{"source":141,"target":176},{"source":141,"target":177},{"source":141,"target":178},{"source":141,"target":179},{"source":141,"target":180},{"source":181,"target":137},{"source":182,"target":137},{"source":183,"target":137},{"source":183,"target":95},{"source":184,"target":137},{"source":185,"target":137},{"source":185,"target":147},{"source":185,"target":148},{"source":185,"target":157},{"source":186,"target":137},{"source":187,"target":137},{"source":188,"target":137},{"source":188,"target":147},{"source":189,"target":149},{"source":189,"target":188},{"source":189,"target":7},{"source":190,"target":137},{"source":190,"target":147},{"source":190,"target":108},{"source":190,"target":95},{"source":190,"target":148},{"source":191,"target":137},{"source":192,"target":137},{"source":193,"target":137},{"source":194,"target":137},{"source":194,"target":95},{"source":195,"target":137},{"source":196,"target":137},{"source":197,"target":137},{"source":197,"target":147},{"source":197,"target":95},{"source":197,"target":189},{"source":197,"target":149},{"source":197,"target":148},{"source":197,"target":7},{"source":198,"target":137},{"source":199,"target":137},{"source":200,"target":137},{"source":201,"target":137},{"source":201,"target":70},{"source":202,"target":137},{"source":203,"target":137},{"source":204,"target":137},{"source":205,"target":137},{"source":205,"target":202},{"source":205,"target":149},{"source":205,"target":206},{"source":207,"target":137},{"source":207,"target":149},{"source":206,"target":137},{"source":206,"target":149},{"source":208,"target":137},{"source":208,"target":147},{"source":208,"target":95},{"source":208,"target":148},{"source":209,"target":137},{"source":210,"target":137},{"source":210,"target":180},{"source":211,"target":137},{"source":212,"target":137},{"source":40,"target":141},{"source":213,"target":214},{"source":213,"target":215},{"source":213,"target":216},{"source":217,"target":213},{"source":218,"target":219},{"source":218,"target":214},{"source":218,"target":220},{"source":218,"target":221},{"source":222,"target":215},{"source":222,"target":223},{"source":222,"target":224},{"source":222,"target":216},{"source":225,"target":214},{"source":225,"target":220},{"source":225,"target":216},{"source":226,"target":215},{"source":226,"target":226},{"source":220,"target":219},{"source":220,"target":214},{"source":220,"target":221},{"source":220,"target":216},{"source":220,"target":225},{"source":224,"target":216},{"source":216,"target":227},{"source":216,"target":214},{"source":216,"target":221},{"source":221,"target":218},{"source":221,"target":227},{"source":221,"target":220},{"source":223,"target":216},{"source":228,"target":5},{"source":228,"target":228},{"source":229,"target":5},{"source":229,"target":229},{"source":230,"target":5},{"source":230,"target":230},{"source":231,"target":231},{"source":232,"target":233},{"source":234,"target":219},{"source":177,"target":176},{"source":25,"target":12},{"source":25,"target":141},{"source":235,"target":236},{"source":236,"target":235},{"source":237,"target":238},{"source":237,"target":239},{"source":233,"target":240},{"source":26,"target":12},{"source":26,"target":233},{"source":27,"target":12},{"source":27,"target":233},{"source":241,"target":233},{"source":240,"target":242},{"source":243,"target":244},{"source":115,"target":117},{"source":245,"target":7},{"source":246,"target":95},{"source":246,"target":7},{"source":97,"target":7},{"source":247,"target":131},{"source":247,"target":104},{"source":247,"target":105},{"source":247,"target":248},{"source":247,"target":129},{"source":249,"target":250},{"source":251,"target":232},{"source":7,"target":97},{"source":7,"target":95},{"source":7,"target":7},{"source":7,"target":8},{"source":252,"target":7},{"source":253,"target":252},{"source":253,"target":7},{"source":95,"target":7},{"source":254,"target":7},{"source":255,"target":256},{"source":257,"target":255},{"source":257,"target":87},{"source":258,"target":259},{"source":28,"target":12},{"source":28,"target":14},{"source":28,"target":32},{"source":29,"target":1},{"source":260,"target":52},{"source":260,"target":261},{"source":260,"target":262},{"source":132,"target":133},{"source":263,"target":264},{"source":265,"target":7},{"source":265,"target":70},{"source":266,"target":95},{"source":107,"target":7},{"source":107,"target":94},{"source":107,"target":107},{"source":107,"target":46},{"source":107,"target":45},{"source":68,"target":64},{"source":67,"target":64},{"source":267,"target":4},{"source":267,"target":5},{"source":268,"target":269},{"source":268,"target":241},{"source":268,"target":270},{"source":268,"target":233},{"source":268,"target":271},{"source":268,"target":267},{"source":268,"target":272},{"source":271,"target":269},{"source":272,"target":273},{"source":274,"target":275},{"source":30,"target":1},{"source":276,"target":277},{"source":111,"target":94},{"source":111,"target":8},{"source":111,"target":7},{"source":111,"target":95},{"source":111,"target":106},{"source":278,"target":279},{"source":278,"target":244},{"source":280,"target":84},{"source":239,"target":176},{"source":239,"target":2},{"source":238,"target":239},{"source":281,"target":282},{"source":283,"target":284},{"source":285,"target":281},{"source":286,"target":287},{"source":288,"target":286},{"source":289,"target":290},{"source":291,"target":292},{"source":293,"target":292},{"source":74,"target":292},{"source":294,"target":295},{"source":296,"target":289},{"source":77,"target":296},{"source":297,"target":298},{"source":297,"target":299},{"source":300,"target":301},{"source":70,"target":59},{"source":70,"target":7},{"source":70,"target":70},{"source":302,"target":70},{"source":303,"target":304},{"source":303,"target":305},{"source":306,"target":307},{"source":308,"target":309},{"source":310,"target":307},{"source":311,"target":312},{"source":313,"target":314},{"source":315,"target":316},{"source":317,"target":318},{"source":319,"target":320},{"source":321,"target":322},{"source":323,"target":324},{"source":325,"target":326},{"source":327,"target":312},{"source":328,"target":312},{"source":329,"target":312},{"source":312,"target":330},{"source":312,"target":307},{"source":331,"target":304},{"source":331,"target":315},{"source":332,"target":304},{"source":332,"target":333},{"source":334,"target":65},{"source":334,"target":67},{"source":335,"target":307},{"source":335,"target":336},{"source":335,"target":319},{"source":335,"target":333},{"source":337,"target":338},{"source":337,"target":315},{"source":339,"target":304},{"source":340,"target":341},{"source":157,"target":342},{"source":307,"target":8},{"source":307,"target":342},{"source":307,"target":307},{"source":343,"target":344},{"source":343,"target":345},{"source":343,"target":307},{"source":343,"target":346},{"source":343,"target":343},{"source":345,"target":343},{"source":347,"target":304},{"source":347,"target":315},{"source":338,"target":348},{"source":349,"target":350},{"source":349,"target":305},{"source":349,"target":333},{"source":351,"target":350},{"source":351,"target":305},{"source":351,"target":333},{"source":351,"target":319},{"source":352,"target":350},{"source":352,"target":305},{"source":353,"target":350},{"source":353,"target":305},{"source":353,"target":336},{"source":353,"target":333},{"source":354,"target":350},{"source":354,"target":336},{"source":354,"target":333},{"source":354,"target":305},{"source":354,"target":319},{"source":354,"target":355},{"source":354,"target":348},{"source":356,"target":350},{"source":356,"target":336},{"source":356,"target":305},{"source":357,"target":350},{"source":357,"target":305},{"source":357,"target":336},{"source":357,"target":333},{"source":358,"target":307},{"source":358,"target":336},{"source":359,"target":350},{"source":359,"target":336},{"source":359,"target":305},{"source":360,"target":350},{"source":361,"target":335},{"source":362,"target":335},{"source":363,"target":335},{"source":364,"target":335},{"source":365,"target":350},{"source":365,"target":305},{"source":365,"target":336},{"source":366,"target":350},{"source":366,"target":321},{"source":367,"target":350},{"source":368,"target":307},{"source":368,"target":305},{"source":369,"target":350},{"source":369,"target":305},{"source":369,"target":333},{"source":369,"target":336},{"source":370,"target":350},{"source":370,"target":336},{"source":370,"target":305},{"source":371,"target":307},{"source":371,"target":336},{"source":372,"target":350},{"source":372,"target":305},{"source":372,"target":336},{"source":373,"target":307},{"source":373,"target":336},{"source":374,"target":350},{"source":374,"target":305},{"source":375,"target":350},{"source":375,"target":336},{"source":375,"target":355},{"source":375,"target":333},{"source":376,"target":341},{"source":376,"target":355},{"source":376,"target":333},{"source":376,"target":315},{"source":350,"target":341},{"source":350,"target":315},{"source":350,"target":305},{"source":377,"target":321},{"source":377,"target":323},{"source":378,"target":307},{"source":379,"target":307},{"source":380,"target":307},{"source":381,"target":307},{"source":382,"target":307},{"source":383,"target":307},{"source":384,"target":304},{"source":384,"target":315},{"source":385,"target":304},{"source":386,"target":307},{"source":387,"target":341},{"source":388,"target":341},{"source":388,"target":325},{"source":388,"target":333},{"source":389,"target":307},{"source":390,"target":304},{"source":390,"target":315},{"source":390,"target":321},{"source":318,"target":316},{"source":391,"target":388},{"source":391,"target":315},{"source":392,"target":304},{"source":392,"target":315},{"source":393,"target":307},{"source":393,"target":324},{"source":393,"target":394},{"source":395,"target":377},{"source":395,"target":315},{"source":395,"target":333},{"source":395,"target":313},{"source":395,"target":314},{"source":396,"target":341},{"source":396,"target":315},{"source":396,"target":333},{"source":394,"target":394},{"source":397,"target":307},{"source":398,"target":307},{"source":399,"target":338},{"source":320,"target":400},{"source":401,"target":334},{"source":402,"target":304},{"source":402,"target":403},{"source":402,"target":336},{"source":402,"target":404},{"source":402,"target":405},{"source":402,"target":406},{"source":402,"target":407},{"source":402,"target":408},{"source":402,"target":409},{"source":402,"target":410},{"source":402,"target":411},{"source":402,"target":412},{"source":402,"target":413},{"source":402,"target":414},{"source":402,"target":415},{"source":402,"target":416},{"source":402,"target":417},{"source":402,"target":418},{"source":402,"target":419},{"source":402,"target":420},{"source":402,"target":421},{"source":402,"target":422},{"source":402,"target":423},{"source":404,"target":424},{"source":405,"target":424},{"source":406,"target":424},{"source":407,"target":424},{"source":408,"target":424},{"source":409,"target":424},{"source":410,"target":424},{"source":411,"target":424},{"source":412,"target":424},{"source":413,"target":424},{"source":414,"target":424},{"source":415,"target":424},{"source":416,"target":424},{"source":417,"target":424},{"source":418,"target":424},{"source":419,"target":424},{"source":420,"target":424},{"source":403,"target":424},{"source":421,"target":424},{"source":422,"target":424},{"source":425,"target":377},{"source":425,"target":315},{"source":425,"target":333},{"source":425,"target":325},{"source":423,"target":423},{"source":426,"target":423},{"source":427,"target":304},{"source":427,"target":426},{"source":428,"target":304},{"source":428,"target":426},{"source":429,"target":388},{"source":429,"target":315},{"source":430,"target":304},{"source":430,"target":315},{"source":431,"target":338},{"source":432,"target":312},{"source":433,"target":341},{"source":433,"target":336},{"source":341,"target":305},{"source":341,"target":57},{"source":341,"target":65},{"source":434,"target":435},{"source":342,"target":436},{"source":342,"target":423},{"source":342,"target":437},{"source":342,"target":315},{"source":342,"target":324},{"source":342,"target":307},{"source":342,"target":314},{"source":342,"target":316},{"source":342,"target":394},{"source":342,"target":400},{"source":342,"target":438},{"source":342,"target":8},{"source":342,"target":95},{"source":439,"target":304},{"source":440,"target":377},{"source":441,"target":442},{"source":443,"target":341},{"source":443,"target":333},{"source":443,"target":315},{"source":443,"target":423},{"source":443,"target":324},{"source":444,"target":304},{"source":445,"target":309},{"source":445,"target":333},{"source":445,"target":315},{"source":446,"target":443},{"source":446,"target":317},{"source":446,"target":319},{"source":447,"target":341},{"source":438,"target":394},{"source":304,"target":393},{"source":304,"target":325},{"source":326,"target":438},{"source":448,"target":309},{"source":449,"target":446},{"source":309,"target":305},{"source":346,"target":304},{"source":346,"target":343},{"source":346,"target":315},{"source":450,"target":436},{"source":450,"target":442},{"source":437,"target":321},{"source":437,"target":326},{"source":437,"target":323},{"source":437,"target":307},{"source":451,"target":307},{"source":43,"target":44},{"source":43,"target":43},{"source":180,"target":452},{"source":180,"target":453},{"source":453,"target":180},{"source":453,"target":94},{"source":452,"target":453},{"source":179,"target":180},{"source":454,"target":344},{"source":455,"target":454},{"source":456,"target":7},{"source":456,"target":252},{"source":457,"target":5},{"source":457,"target":457},{"source":458,"target":5},{"source":458,"target":458},{"source":2,"target":5},{"source":2,"target":2},{"source":459,"target":2},{"source":459,"target":459},{"source":31,"target":1},{"source":31,"target":3},{"source":460,"target":33},{"source":460,"target":461},{"source":460,"target":462},{"source":460,"target":463},{"source":460,"target":464},{"source":460,"target":465},{"source":460,"target":4},{"source":460,"target":5},{"source":460,"target":466},{"source":460,"target":467},{"source":460,"target":468},{"source":460,"target":469},{"source":460,"target":470},{"source":460,"target":36},{"source":460,"target":39},{"source":460,"target":34},{"source":460,"target":40},{"source":460,"target":3},{"source":471,"target":472},{"source":473,"target":72},{"source":474,"target":55},{"source":474,"target":57},{"source":475,"target":55},{"source":475,"target":62},{"source":475,"target":474},{"source":476,"target":476},{"source":477,"target":72},{"source":478,"target":72},{"source":479,"target":95},{"source":480,"target":4},{"source":480,"target":5},{"source":481,"target":279},{"source":84,"target":222},{"source":84,"target":482},{"source":84,"target":483},{"source":84,"target":84},{"source":84,"target":257},{"source":84,"target":73},{"source":84,"target":76},{"source":84,"target":126},{"source":84,"target":99},{"source":84,"target":89},{"source":484,"target":485},{"source":484,"target":4},{"source":484,"target":5},{"source":484,"target":486},{"source":487,"target":488},{"source":487,"target":489},{"source":487,"target":490},{"source":488,"target":490},{"source":490,"target":7},{"source":491,"target":7},{"source":491,"target":94}]}; 14 | const option = { 15 | legend: { 16 | data: ['HTMLElement', 'WebGL', 'SVG', 'CSS', 'Other'] 17 | }, 18 | series: [{ 19 | type: 'graph', 20 | layout: 'force', 21 | animation: false, 22 | label: { 23 | normal: { 24 | position: 'right', 25 | formatter: '{b}' 26 | } 27 | }, 28 | draggable: true, 29 | data: webkitDep.nodes.map(function (node, idx) { 30 | node.id = idx; 31 | return node; 32 | }), 33 | categories: webkitDep.categories, 34 | force: { 35 | // initLayout: 'circular' 36 | // repulsion: 20, 37 | edgeLength: 5, 38 | repulsion: 20, 39 | gravity: 0.2 40 | }, 41 | edges: webkitDep.links 42 | }] 43 | }; 44 | 45 | return ; 49 | }; 50 | 51 | export default Page; 52 | ``` 53 | -------------------------------------------------------------------------------- /docs/examples/loading.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Loading 3 | order: 5 4 | --- 5 | 6 | ## Loading 7 | 8 | ```tsx 9 | import React, { useState, useEffect } from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | const Page: React.FC = () => { 13 | const option = { 14 | title: { 15 | text: '基础雷达图' 16 | }, 17 | tooltip: {}, 18 | legend: { 19 | data: ['预算分配(Allocated Budget)', '实际开销(Actual Spending)'] 20 | }, 21 | radar: { 22 | // shape: 'circle', 23 | indicator: [ 24 | { name: '销售(sales)', max: 6500}, 25 | { name: '管理(Administration)', max: 16000}, 26 | { name: '信息技术(Information Techology)', max: 30000}, 27 | { name: '客服(Customer Support)', max: 38000}, 28 | { name: '研发(Development)', max: 52000}, 29 | { name: '市场(Marketing)', max: 25000} 30 | ] 31 | }, 32 | series: [{ 33 | name: '预算 vs 开销(Budget vs spending)', 34 | type: 'radar', 35 | // areaStyle: {normal: {}}, 36 | data : [ 37 | { 38 | value : [4300, 10000, 28000, 35000, 50000, 19000], 39 | name : '预算分配(Allocated Budget)' 40 | }, 41 | { 42 | value : [5000, 14000, 28000, 31000, 42000, 21000], 43 | name : '实际开销(Actual Spending)' 44 | } 45 | ] 46 | }] 47 | }; 48 | 49 | let timer; 50 | 51 | useEffect(() => { 52 | return () => clearTimeout(timer); 53 | }); 54 | 55 | const loadingOption = { 56 | text: '加载中...', 57 | color: '#4413c2', 58 | textColor: '#270240', 59 | maskColor: 'rgba(194, 88, 86, 0.3)', 60 | zlevel: 0 61 | }; 62 | 63 | function onChartReady(echarts) { 64 | timer = setTimeout(function() { 65 | echarts.hideLoading(); 66 | }, 3000); 67 | } 68 | 69 | return ; 76 | }; 77 | 78 | export default Page; 79 | ``` 80 | -------------------------------------------------------------------------------- /docs/examples/locale.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Locale 3 | order: 8 4 | --- 5 | 6 | ## Locale 7 | 8 | ```tsx 9 | import React from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | import "echarts/i18n/langFR"; 13 | 14 | const Page: React.FC = () => { 15 | const option = { 16 | title: { 17 | text: 'ECharts 入门示例' 18 | }, 19 | toolbox: { 20 | feature: { 21 | saveAsImage: {}, 22 | dataZoom: {}, 23 | restore: {} 24 | } 25 | }, 26 | tooltip: {}, 27 | legend: { 28 | data:['销量'] 29 | }, 30 | xAxis: { 31 | data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] 32 | }, 33 | yAxis: {}, 34 | series: [{ 35 | name: '销量', 36 | type: 'line', 37 | data: [5, 20, 36, 10, 10, 20] 38 | }] 39 | }; 40 | 41 | return ; 46 | }; 47 | 48 | export default Page; 49 | ``` 50 | -------------------------------------------------------------------------------- /docs/examples/simple.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Simple 3 | order: 1 4 | --- 5 | 6 | ## 简单堆积面积图 7 | 8 | ```tsx 9 | import React from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | const Page: React.FC = () => { 13 | const option = { 14 | title: { 15 | text: '堆叠区域图' 16 | }, 17 | tooltip : { 18 | trigger: 'axis' 19 | }, 20 | legend: { 21 | data:['邮件营销','联盟广告','视频广告'] 22 | }, 23 | toolbox: { 24 | feature: { 25 | saveAsImage: {} 26 | } 27 | }, 28 | grid: { 29 | left: '3%', 30 | right: '4%', 31 | bottom: '3%', 32 | containLabel: true 33 | }, 34 | xAxis : [ 35 | { 36 | type : 'category', 37 | boundaryGap : false, 38 | data : ['周一','周二','周三','周四','周五','周六','周日'] 39 | } 40 | ], 41 | yAxis : [ 42 | { 43 | type : 'value' 44 | } 45 | ], 46 | series : [ 47 | { 48 | name:'邮件营销', 49 | type:'line', 50 | stack: '总量', 51 | areaStyle: {normal: {}}, 52 | data:[120, 132, 101, 134, 90, 230, 210] 53 | }, 54 | { 55 | name:'联盟广告', 56 | type:'line', 57 | stack: '总量', 58 | areaStyle: {normal: {}}, 59 | data:[220, 182, 191, 234, 290, 330, 310] 60 | }, 61 | { 62 | name:'视频广告', 63 | type:'line', 64 | stack: '总量', 65 | areaStyle: {normal: {}}, 66 | data:[150, 232, 201, 154, 190, 330, 410] 67 | } 68 | ] 69 | }; 70 | 71 | return ; 75 | }; 76 | 77 | export default Page; 78 | ``` 79 | -------------------------------------------------------------------------------- /docs/examples/svg.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SVG 3 | order: 8 4 | --- 5 | 6 | ## SVG 7 | 8 | ```tsx 9 | import React from 'react'; 10 | import ReactECharts from 'echarts-for-react'; 11 | 12 | const Page: React.FC = () => { 13 | const option = { 14 | title: { 15 | text: 'ECharts 入门示例' 16 | }, 17 | tooltip: {}, 18 | legend: { 19 | data:['销量'] 20 | }, 21 | xAxis: { 22 | data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] 23 | }, 24 | yAxis: {}, 25 | series: [{ 26 | name: '销量', 27 | type: 'bar', 28 | data: [5, 20, 36, 10, 10, 20] 29 | }] 30 | }; 31 | 32 | return ; 37 | }; 38 | 39 | export default Page; 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/examples/theme.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Theme 3 | order: 3 4 | --- 5 | 6 | ## Theme 7 | 8 | ```tsx 9 | import React, { useState } from 'react'; 10 | import * as echarts from 'echarts'; 11 | import ReactECharts from 'echarts-for-react'; 12 | 13 | echarts.registerTheme('my_theme', { 14 | backgroundColor: '#f4cccc' 15 | }); 16 | echarts.registerTheme('another_theme', { 17 | backgroundColor: '#eee' 18 | }); 19 | 20 | const Page: React.FC = () => { 21 | const option = { 22 | title: { 23 | text: '阶梯瀑布图', 24 | subtext: 'From ExcelHome', 25 | sublink: 'http://e.weibo.com/1341556070/Aj1J2x5a5' 26 | }, 27 | tooltip : { 28 | trigger: 'axis', 29 | axisPointer : { // 坐标轴指示器,坐标轴触发有效 30 | type : 'shadow' // 默认为直线,可选为:'line' | 'shadow' 31 | } 32 | }, 33 | legend: { 34 | data:['支出','收入'] 35 | }, 36 | grid: { 37 | left: '3%', 38 | right: '4%', 39 | bottom: '3%', 40 | containLabel: true 41 | }, 42 | xAxis: { 43 | type : 'category', 44 | splitLine: {show:false}, 45 | data : ["11月1日", "11月2日", "11月3日", "11月4日", "11月5日", "11月6日", "11月7日", "11月8日", "11月9日", "11月10日", "11月11日"] 46 | }, 47 | yAxis: { 48 | type : 'value' 49 | }, 50 | series: [ 51 | { 52 | name: '辅助', 53 | type: 'bar', 54 | stack: '总量', 55 | itemStyle: { 56 | normal: { 57 | barBorderColor: 'rgba(0,0,0,0)', 58 | color: 'rgba(0,0,0,0)' 59 | }, 60 | emphasis: { 61 | barBorderColor: 'rgba(0,0,0,0)', 62 | color: 'rgba(0,0,0,0)' 63 | } 64 | }, 65 | data: [0, 900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292] 66 | }, 67 | { 68 | name: '收入', 69 | type: 'bar', 70 | stack: '总量', 71 | label: { 72 | normal: { 73 | show: true, 74 | position: 'top' 75 | } 76 | }, 77 | data: [900, 345, 393, '-', '-', 135, 178, 286, '-', '-', '-'] 78 | }, 79 | { 80 | name: '支出', 81 | type: 'bar', 82 | stack: '总量', 83 | label: { 84 | normal: { 85 | show: true, 86 | position: 'bottom' 87 | } 88 | }, 89 | data: ['-', '-', '-', 108, 154, '-', '-', '-', 119, 361, 203] 90 | } 91 | ] 92 | }; 93 | 94 | const [theme, setTheme] = useState(); 95 | const [className, setClassName] = useState('class_1'); 96 | 97 | function toggleTheme() { 98 | setTheme(theme === 'my_theme' ? 'another_theme' : 'my_theme'); 99 | } 100 | 101 | function toggleClassName() { 102 | setClassName(className === 'class_1' ? 'class_2' : 'class_1'); 103 | } 104 | 105 | return ( 106 | <> 107 | 113 |
114 |
115 | 116 | 117 |
118 | 119 | ); 120 | }; 121 | 122 | export default Page; 123 | ``` 124 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ECharts for React - 全网开发者下载量最高的 ECharts 的 React 组件封装 3 | order: 1 4 | hero: 5 | title: ECharts for React 6 | desc: 全网开发者下载量最高的 ECharts 的 React 组件封装 7 | actions: 8 | - text: 在线实例 9 | link: /examples/dynamic 10 | - text: 开源地址 11 | link: https://github.com/hustcc/echarts-for-react 12 | footer: Open-source MIT Licensed | Copyright © 2021-present 13 | --- 14 | 15 | 16 | ## 安装 17 | 18 | ```bash 19 | $ npm install echarts-for-react 20 | ``` 21 | 22 | 23 | ## 使用 24 | 25 | ```tsx | pure 26 | import React from 'react'; 27 | import ReactECharts from 'echarts-for-react'; 28 | 29 | const Page: React.FC = () => { 30 | const options = { 31 | grid: { top: 8, right: 8, bottom: 24, left: 36 }, 32 | xAxis: { 33 | type: 'category', 34 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 35 | }, 36 | yAxis: { 37 | type: 'value', 38 | }, 39 | series: [ 40 | { 41 | data: [820, 932, 901, 934, 1290, 1330, 1320], 42 | type: 'line', 43 | smooth: true, 44 | }, 45 | ], 46 | tooltip: { 47 | trigger: 'axis', 48 | }, 49 | }; 50 | 51 | return ; 52 | }; 53 | 54 | export default Page; 55 | ``` 56 | 57 | 最终结果: 58 | 59 | ```tsx 60 | import React from 'react'; 61 | import ReactECharts from 'echarts-for-react'; 62 | 63 | const Page: React.FC = () => { 64 | const options = { 65 | grid: { top: 8, right: 8, bottom: 24, left: 36 }, 66 | xAxis: { 67 | type: 'category', 68 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], 69 | }, 70 | yAxis: { 71 | type: 'value', 72 | }, 73 | series: [ 74 | { 75 | data: [820, 932, 901, 934, 1290, 1330, 1320], 76 | type: 'line', 77 | smooth: true, 78 | }, 79 | ], 80 | tooltip: { 81 | trigger: 'axis', 82 | }, 83 | }; 84 | 85 | return ; 86 | }; 87 | 88 | export default Page; 89 | ``` 90 | 91 | 92 | ## 反馈 93 | 94 | 请访问 [GitHub](https://github.com/hustcc/echarts-for-react)。 95 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "echarts-for-react", 3 | "version": "3.0.3", 4 | "description": " Apache Echarts components for React.", 5 | "main": "lib/index.js", 6 | "module": "esm/index.js", 7 | "types": "lib/index.d.ts", 8 | "files": [ 9 | "lib", 10 | "esm", 11 | "src" 12 | ], 13 | "scripts": { 14 | "docs:dev": "NODE_ENV=development dumi dev", 15 | "docs:build": "NODE_ENV=production dumi build", 16 | "docs:deploy": "rimraf dist && npm run docs:build && gh-pages -d dist", 17 | "start": "npm run docs:dev", 18 | "lint": "eslint src __tests__ && prettier src __tests__ --check", 19 | "fix": "eslint src __tests__ --fix && prettier src __tests__ --write", 20 | "clean": "rimraf lib esm dist", 21 | "test": "jest", 22 | "lib": "run-p lib:*", 23 | "lib:cjs": "tsc -p tsconfig.json --target ES5 --module commonjs --outDir lib", 24 | "lib:esm": "tsc -p tsconfig.json --target ES5 --module ESNext --outDir esm", 25 | "build": "npm run clean && npm run test && npm run lib" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/hustcc/echarts-for-react.git" 30 | }, 31 | "keywords": [ 32 | "react", 33 | "component", 34 | "echarts-react", 35 | "echarts", 36 | "react-echarts", 37 | "chart", 38 | "charts", 39 | "graph", 40 | "react-component" 41 | ], 42 | "author": "hustcc (http://github.com/hustcc)", 43 | "license": "MIT", 44 | "bugs": { 45 | "url": "https://github.com/hustcc/echarts-for-react/issues" 46 | }, 47 | "homepage": "https://github.com/hustcc/echarts-for-react", 48 | "devDependencies": { 49 | "@commitlint/cli": "^12.0.0", 50 | "@commitlint/config-angular": "^12.0.0", 51 | "@types/jest": "^24.0.0", 52 | "@types/node": "^14.14.31", 53 | "@types/react": "^17.0.2", 54 | "@typescript-eslint/eslint-plugin": "^4.15.2", 55 | "@typescript-eslint/parser": "^4.15.2", 56 | "cross-env": "^7.0.3", 57 | "dumi": "^1.1.6", 58 | "dumi-theme-default": "^1.0.6", 59 | "echarts": "^5.0.2", 60 | "echarts-gl": "^2.0.2", 61 | "eslint": "^7.20.0", 62 | "eslint-config-prettier": "^8.1.0", 63 | "eslint-plugin-import": "^2.22.1", 64 | "eslint-plugin-prettier": "^3.3.1", 65 | "gh-pages": "^3.1.0", 66 | "husky": "^5.1.1", 67 | "jest": "^24.0.0", 68 | "jest-canvas-mock": "^2.3.1", 69 | "jest-electron": "^0.1.11", 70 | "lint-md-cli": "^0.1.2", 71 | "lint-staged": "^10.5.4", 72 | "lodash.clonedeep": "^4.5.0", 73 | "miz": "^1.0.1", 74 | "npm-run-all": "^4.1.5", 75 | "prettier": "^2.2.1", 76 | "rimraf": "^3.0.2", 77 | "ts-jest": "^24.0.2", 78 | "ts-loader": "^8.0.17", 79 | "typescript": "^4.2.2" 80 | }, 81 | "dependencies": { 82 | "size-sensor": "^1.0.1", 83 | "fast-deep-equal": "^3.1.3" 84 | }, 85 | "peerDependencies": { 86 | "react": "^15.0.0 || >=16.0.0", 87 | "echarts": "^3.0.0 || ^4.0.0 || ^5.0.0" 88 | }, 89 | "jest": { 90 | "runner": "jest-electron/runner", 91 | "testEnvironment": "jest-electron/environment", 92 | "preset": "ts-jest", 93 | "collectCoverage": true, 94 | "collectCoverageFrom": [ 95 | "src/**/*.ts", 96 | "!**/node_modules/**", 97 | "!**/vendor/**" 98 | ], 99 | "testRegex": "/__tests__/.*-spec\\.tsx?$" 100 | }, 101 | "husky": { 102 | "hooks": { 103 | "pre-commit": "lint-staged", 104 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 105 | } 106 | }, 107 | "lint-staged": { 108 | "*.ts": [ 109 | "eslint --fix", 110 | "prettier --write" 111 | ], 112 | "*.md": [ 113 | "lint-md --fix" 114 | ] 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/core.tsx: -------------------------------------------------------------------------------- 1 | import type { ECharts } from 'echarts'; 2 | import React, { PureComponent } from 'react'; 3 | import { bind, clear } from 'size-sensor'; 4 | import { pick } from './helper/pick'; 5 | import { isFunction } from './helper/is-function'; 6 | import { isString } from './helper/is-string'; 7 | import { isEqual } from './helper/is-equal'; 8 | import { EChartsReactProps, EChartsInstance } from './types'; 9 | 10 | /** 11 | * core component for echarts binding 12 | */ 13 | export default class EChartsReactCore extends PureComponent { 14 | /** 15 | * echarts render container 16 | */ 17 | public ele: HTMLElement; 18 | 19 | /** 20 | * if this is the first time we are resizing 21 | */ 22 | private isInitialResize: boolean; 23 | 24 | /** 25 | * echarts library entry 26 | */ 27 | protected echarts: any; 28 | 29 | constructor(props: EChartsReactProps) { 30 | super(props); 31 | 32 | this.echarts = props.echarts; 33 | this.ele = null; 34 | this.isInitialResize = true; 35 | } 36 | 37 | componentDidMount() { 38 | this.renderNewEcharts(); 39 | } 40 | 41 | // update 42 | componentDidUpdate(prevProps: EChartsReactProps) { 43 | /** 44 | * if shouldSetOption return false, then return, not update echarts options 45 | * default is true 46 | */ 47 | const { shouldSetOption } = this.props; 48 | if (isFunction(shouldSetOption) && !shouldSetOption(prevProps, this.props)) { 49 | return; 50 | } 51 | 52 | // 以下属性修改的时候,需要 dispose 之后再新建 53 | // 1. 切换 theme 的时候 54 | // 2. 修改 opts 的时候 55 | if ( 56 | !isEqual(prevProps.theme, this.props.theme) || 57 | !isEqual(prevProps.opts, this.props.opts) 58 | ) { 59 | this.dispose(); 60 | 61 | this.renderNewEcharts(); // 重建 62 | return; 63 | } 64 | 65 | // 修改 onEvent 的时候先移除历史事件再添加 66 | const echartsInstance = this.getEchartsInstance(); 67 | if (!isEqual(prevProps.onEvents, this.props.onEvents)) { 68 | this.offEvents(echartsInstance, prevProps.onEvents); 69 | this.bindEvents(echartsInstance, this.props.onEvents); 70 | } 71 | 72 | // when these props are not isEqual, update echarts 73 | const pickKeys = ['option', 'notMerge', 'replaceMerge', 'lazyUpdate', 'showLoading', 'loadingOption']; 74 | if (!isEqual(pick(this.props, pickKeys), pick(prevProps, pickKeys))) { 75 | this.updateEChartsOption(); 76 | } 77 | 78 | /** 79 | * when style or class name updated, change size. 80 | */ 81 | if (!isEqual(prevProps.style, this.props.style) || !isEqual(prevProps.className, this.props.className)) { 82 | this.resize(); 83 | } 84 | } 85 | 86 | componentWillUnmount() { 87 | this.dispose(); 88 | } 89 | 90 | /* 91 | * initialise an echarts instance 92 | */ 93 | public async initEchartsInstance(): Promise { 94 | return new Promise((resolve) => { 95 | // create temporary echart instance 96 | this.echarts.init(this.ele, this.props.theme, this.props.opts); 97 | const echartsInstance = this.getEchartsInstance(); 98 | 99 | echartsInstance.on('finished', () => { 100 | // get final width and height 101 | const width = this.ele.clientWidth; 102 | const height = this.ele.clientHeight; 103 | 104 | // dispose temporary echart instance 105 | this.echarts.dispose(this.ele); 106 | 107 | // recreate echart instance 108 | // we use final width and height only if not originally provided as opts 109 | const opts = { 110 | width, 111 | height, 112 | ...this.props.opts, 113 | }; 114 | resolve(this.echarts.init(this.ele, this.props.theme, opts)); 115 | }); 116 | }); 117 | } 118 | 119 | /** 120 | * return the existing echart object 121 | */ 122 | public getEchartsInstance(): ECharts { 123 | return this.echarts.getInstanceByDom(this.ele); 124 | } 125 | 126 | /** 127 | * dispose echarts and clear size-sensor 128 | */ 129 | private dispose() { 130 | if (this.ele) { 131 | try { 132 | clear(this.ele); 133 | } catch (e) { 134 | console.warn(e); 135 | } 136 | // dispose echarts instance 137 | this.echarts.dispose(this.ele); 138 | } 139 | } 140 | 141 | /** 142 | * render a new echarts instance 143 | */ 144 | private async renderNewEcharts() { 145 | const { onEvents, onChartReady, autoResize = true } = this.props; 146 | 147 | // 1. init echarts instance 148 | await this.initEchartsInstance(); 149 | 150 | // 2. update echarts instance 151 | const echartsInstance = this.updateEChartsOption(); 152 | 153 | // 3. bind events 154 | this.bindEvents(echartsInstance, onEvents || {}); 155 | 156 | // 4. on chart ready 157 | if (isFunction(onChartReady)) onChartReady(echartsInstance); 158 | 159 | // 5. on resize 160 | if (this.ele && autoResize) { 161 | bind(this.ele, () => { 162 | this.resize(); 163 | }); 164 | } 165 | } 166 | 167 | // bind the events 168 | private bindEvents(instance, events: EChartsReactProps['onEvents']) { 169 | function _bindEvent(eventName: string, func: Function) { 170 | // ignore the event config which not satisfy 171 | if (isString(eventName) && isFunction(func)) { 172 | // binding event 173 | instance.on(eventName, (param) => { 174 | func(param, instance); 175 | }); 176 | } 177 | } 178 | 179 | // loop and bind 180 | for (const eventName in events) { 181 | if (Object.prototype.hasOwnProperty.call(events, eventName)) { 182 | _bindEvent(eventName, events[eventName]); 183 | } 184 | } 185 | } 186 | 187 | // off the events 188 | private offEvents(instance, events: EChartsReactProps['onEvents']) { 189 | if (!events) return; 190 | // loop and off 191 | for (const eventName in events) { 192 | if (isString(eventName)) { 193 | instance.off(eventName); 194 | } 195 | } 196 | } 197 | 198 | /** 199 | * render the echarts 200 | */ 201 | private updateEChartsOption(): EChartsInstance { 202 | const { 203 | option, 204 | notMerge = false, 205 | replaceMerge = null, 206 | lazyUpdate = false, 207 | showLoading, 208 | loadingOption = null, 209 | } = this.props; 210 | // 1. get or initial the echarts object 211 | const echartInstance = this.getEchartsInstance(); 212 | // 2. set the echarts option 213 | echartInstance.setOption(option, { notMerge, replaceMerge, lazyUpdate }); 214 | // 3. set loading mask 215 | if (showLoading) echartInstance.showLoading(loadingOption); 216 | else echartInstance.hideLoading(); 217 | 218 | return echartInstance; 219 | } 220 | 221 | /** 222 | * resize wrapper 223 | */ 224 | private resize() { 225 | // 1. get the echarts object 226 | const echartsInstance = this.getEchartsInstance(); 227 | 228 | // 2. call echarts instance resize if not the initial resize 229 | // resize should not happen on first render as it will cancel initial echarts animations 230 | if (!this.isInitialResize) { 231 | try { 232 | echartsInstance.resize({ 233 | width: 'auto', 234 | height: 'auto', 235 | }); 236 | } catch (e) { 237 | console.warn(e); 238 | } 239 | } 240 | 241 | // 3. update variable for future calls 242 | this.isInitialResize = false; 243 | } 244 | 245 | render(): JSX.Element { 246 | const { style, className = '' } = this.props; 247 | // default height = 300 248 | const newStyle = { height: 300, ...style }; 249 | 250 | return ( 251 |
{ 253 | this.ele = e; 254 | }} 255 | style={newStyle} 256 | className={`echarts-for-react ${className}`} 257 | /> 258 | ); 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /src/helper/is-equal.ts: -------------------------------------------------------------------------------- 1 | import isEqual from 'fast-deep-equal'; 2 | 3 | export { isEqual }; 4 | -------------------------------------------------------------------------------- /src/helper/is-function.ts: -------------------------------------------------------------------------------- 1 | export function isFunction(v: any): boolean { 2 | return typeof v === 'function'; 3 | } 4 | -------------------------------------------------------------------------------- /src/helper/is-string.ts: -------------------------------------------------------------------------------- 1 | export function isString(v: any): boolean { 2 | return typeof v === 'string'; 3 | } 4 | -------------------------------------------------------------------------------- /src/helper/pick.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 保留 object 中的部分内容 3 | * @param obj 4 | * @param keys 5 | */ 6 | export function pick(obj: Record, keys: string[]): Record { 7 | const r = {}; 8 | keys.forEach((key) => { 9 | r[key] = obj[key]; 10 | }); 11 | return r; 12 | } 13 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as echarts from 'echarts'; 2 | import { EChartsReactProps, EChartsOption, EChartsInstance } from './types'; 3 | import EChartsReactCore from './core'; 4 | 5 | export type { EChartsReactProps, EChartsOption, EChartsInstance }; 6 | 7 | // export the Component the echarts Object. 8 | export default class EChartsReact extends EChartsReactCore { 9 | constructor(props: EChartsReactProps) { 10 | super(props); 11 | 12 | // 初始化为 echarts 整个包 13 | this.echarts = echarts; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import type { CSSProperties } from 'react'; 2 | import type { EChartsType } from 'echarts'; 3 | 4 | /** 5 | * Solve the type conflict caused by multiple type files 6 | */ 7 | export type EChartsOption = any; 8 | 9 | export type EChartsInstance = EChartsType; 10 | 11 | export type Opts = { 12 | readonly devicePixelRatio?: number; 13 | readonly renderer?: 'canvas' | 'svg'; 14 | readonly width?: number | null | undefined | 'auto'; 15 | readonly height?: number | null | undefined | 'auto'; 16 | readonly locale?: string; 17 | }; 18 | 19 | export type EChartsReactProps = { 20 | /** 21 | * echarts library entry, use it for import necessary. 22 | */ 23 | readonly echarts?: any; 24 | /** 25 | * `className` for container 26 | */ 27 | readonly className?: string; 28 | /** 29 | * `style` for container 30 | */ 31 | readonly style?: CSSProperties; 32 | /** 33 | * echarts option 34 | */ 35 | readonly option: EChartsOption; 36 | /** 37 | * echarts theme config, can be: 38 | * 1. theme name string 39 | * 2. theme object 40 | */ 41 | readonly theme?: string | Record; 42 | /** 43 | * notMerge config for echarts, default is `false` 44 | */ 45 | readonly notMerge?: boolean; 46 | /** 47 | * replaceMerge config for echarts, default is `null` 48 | */ 49 | readonly replaceMerge?: string | string[]; 50 | /** 51 | * lazyUpdate config for echarts, default is `false` 52 | */ 53 | readonly lazyUpdate?: boolean; 54 | /** 55 | * showLoading config for echarts, default is `false` 56 | */ 57 | readonly showLoading?: boolean; 58 | /** 59 | * loadingOption config for echarts, default is `null` 60 | */ 61 | readonly loadingOption?: any; 62 | /** 63 | * echarts opts config, default is `{}` 64 | */ 65 | readonly opts?: Opts; 66 | /** 67 | * when after chart render, do the callback with echarts instance 68 | */ 69 | readonly onChartReady?: (instance: EChartsInstance) => void; 70 | /** 71 | * bind events, default is `{}` 72 | */ 73 | readonly onEvents?: Record; 74 | /** 75 | * should update echarts options 76 | */ 77 | readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean; 78 | 79 | /** 80 | * should trigger resize when window resize 81 | */ 82 | readonly autoResize?: boolean; 83 | }; 84 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "inlineSources": true, 7 | "target": "es5", 8 | "outDir": "lib", 9 | "declaration": true, 10 | "importHelpers": true, 11 | "moduleResolution": "node", 12 | "allowSyntheticDefaultImports": true, 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "skipLibCheck": true, 16 | "lib": ["esnext", "dom"], 17 | "types": ["jest", "react", "node"] 18 | }, 19 | "include": ["src"] 20 | } 21 | --------------------------------------------------------------------------------