commit 469acda80b900db4d5bc0e57a98ebb1026f87cd7 Author: hustcc Date: Sun Feb 7 18:03:59 2021 +0800 chore: init 3.0.0-beta.1 diff --git a/.commitlintrc.js b/.commitlintrc.js new file mode 100644 index 0000000..f8f4d21 --- /dev/null +++ b/.commitlintrc.js @@ -0,0 +1,10 @@ +module.exports = { + extends: ['@commitlint/config-angular'], + rules: { + 'type-enum': [ + 2, + 'always', + ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test', 'wip'], + ], + }, +}; diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a2f217c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[Makefile] +indent_style = tab +indent_size = 1 + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..b2f1269 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +node_modules +dist/ +test +build/ \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..e520023 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,40 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/eslint-recommended", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "plugins": ["prettier", "@typescript-eslint", "import"], + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "impliedStrict": true + }, + "rules": { + "no-sparse-arrays": 0, + "no-self-assign": 0, + "no-unused-vars": 0, // @typescript-eslint/no-unused-vars + "no-inner-declarations": 0, + "prettier/prettier": 2, + "@typescript-eslint/no-unused-vars": 1, + "@typescript-eslint/no-non-null-assertion": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-use-before-define": [2, { "functions": false }], + "@typescript-eslint/ban-ts-ignore": 0, + "@typescript-eslint/interface-name-prefix": 0, + "@typescript-eslint/no-empty-interface": 0, + "@typescript-eslint/camelcase": 0, + "@typescript-eslint/no-inferrable-types": 0, + "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/type-annotation-spacing": 0, + "@typescript-eslint/no-empty-function": 0, + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/ban-types": "off", + "no-undef": 0, + "@typescript-eslint/no-var-requires": 0, + "import/order": 0, + "import/no-default-export": 0 + } +} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..54367ac --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: build + +on: ["push", "pull_request"] + +jobs: + build: + runs-on: macOS-latest + steps: + - uses: actions/checkout@v1 + - name: Use Node.js 12 + uses: actions/setup-node@v1 + with: + node-version: 12.10.0 + - name: npm install + run: | + npm install + - name: build + run: | + npm run build + env: + CI: true + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb2439f --- /dev/null +++ b/.gitignore @@ -0,0 +1,83 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# lock +package-lock.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +yarn.lock + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +public +build +dist +temp +.DS_Store +.idea +.cache +demos/assets/screenshots +/lib +/esm +/dist + +*.sw* +*.un~ + +.vscode +/stats.json +.umi +.umi-production diff --git a/.lintmdrc b/.lintmdrc new file mode 100644 index 0000000..b153b89 --- /dev/null +++ b/.lintmdrc @@ -0,0 +1,5 @@ +{ + "rules": { + "no-long-code": 1 + } +} \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..5e199e6 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +stats.json +.cache +dist +.umi diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..a13afd8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "bracketSpacing": true, + "printWidth": 120, + "arrowParens": "always", + "endOfLine": "auto" +} diff --git a/.umirc.js b/.umirc.js new file mode 100644 index 0000000..d1dda6b --- /dev/null +++ b/.umirc.js @@ -0,0 +1,23 @@ +import { defineConfig } from 'dumi'; + +export default defineConfig({ + mode: 'site', + title: '\b', + base: '/', + publicPath: process.env.NODE_ENV === 'production' ? '/echarts-for-react/' : '/', + exportStatic: {}, + logo: 'https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/zh/images/logo.png?_v_=20200710_1', + styles: [ + '.__dumi-default-navbar-logo:not([data-plaintext]) { padding-left: 200px!important; }', + '.echarts-for-react.class_1 { height: 400px!important; }', + '.echarts-for-react.class_2 { height: 500px!important; }', + ], + navs: [ + null, + { title: '在线文档', path: 'https://github.com/hustcc/echarts-for-react' }, + { title: 'GitHub', path: 'https://github.com/hustcc/echarts-for-react' }, + ], + analytics: { + }, + // more config: https://d.umijs.org/config +}); \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ef16fe9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 AntV team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do { so, subject } to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f64edc --- /dev/null +++ b/README.md @@ -0,0 +1,306 @@ +# echarts-for-react + +A very simple React wrapper for [Apache ECharts (incubating)](https://github.com/apache/incubator-echarts). + +[![Build Status](https://github.com/hustcc/echarts-for-react/workflows/build/badge.svg?branch=master)](https://github.com/hustcc/echarts-for-react/actions?query=workflow%3Abuild) +[![Coverage](https://img.shields.io/coveralls/hustcc/echarts-for-react/master.svg)](https://coveralls.io/github/hustcc/echarts-for-react) +[![npm](https://img.shields.io/npm/v/echarts-for-react.svg)](https://www.npmjs.com/package/echarts-for-react) +[![NPM downloads](https://img.shields.io/npm/dm/echarts-for-react.svg)](https://www.npmjs.com/package/echarts-for-react) +[![License](https://img.shields.io/npm/l/echarts-for-react.svg)](https://www.npmjs.com/package/echarts-for-react) +![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) +![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) + + +# 1. install + +```sh +npm install --save echarts-for-react + +# `echarts` is the peerDependence of `echarts-for-react`, you can install echarts with your own version. +npm install --save echarts +``` + +Then use it. + +```js +import ReactEcharts from 'echarts-for-react'; + +// render echarts option. + +``` + +You can run demo by: + +```sh +git clone git@github.com:hustcc/echarts-for-react.git + +npm install + +npm start +``` + +then open [http://127.0.0.1:8080/](http://127.0.0.1:8080/) in your browser. or see [http://git.hust.cc/echarts-for-react/](http://git.hust.cc/echarts-for-react/) + +## GL + +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) + + - **`Install`** + +```sh +npm install --save echarts-gl +``` + + - **`Import`** + +```js +import 'echarts-gl' +import ReactEcharts from "echarts-for-react"; + + + +``` + + +# 2. usage + +Code of a simple demo code showed below. For more example can see: [http://git.hust.cc/echarts-for-react/](http://git.hust.cc/echarts-for-react/) + +### javascript + +```js +import React from 'react'; +import ReactEcharts from 'echarts-for-react'; // or var ReactEcharts = require('echarts-for-react'); + + +``` + +### typescript + +```js +import * as React from "react"; +import ReactEcharts from "echarts-for-react"; + + +``` + +Import ECharts.js modules manually to reduce bundle size + +```js +import React from 'react'; +// import the core library. +import ReactEchartsCore from 'echarts-for-react/lib/core'; + +// then import echarts modules those you have used manually. +import echarts from 'echarts/lib/echarts'; +// import 'echarts/lib/chart/line'; +import 'echarts/lib/chart/bar'; +// import 'echarts/lib/chart/pie'; +// import 'echarts/lib/chart/scatter'; +// import 'echarts/lib/chart/radar'; + +// import 'echarts/lib/chart/map'; +// import 'echarts/lib/chart/treemap'; +// import 'echarts/lib/chart/graph'; +// import 'echarts/lib/chart/gauge'; +// import 'echarts/lib/chart/funnel'; +// import 'echarts/lib/chart/parallel'; +// import 'echarts/lib/chart/sankey'; +// import 'echarts/lib/chart/boxplot'; +// import 'echarts/lib/chart/candlestick'; +// import 'echarts/lib/chart/effectScatter'; +// import 'echarts/lib/chart/lines'; +// import 'echarts/lib/chart/heatmap'; + +// import 'echarts/lib/component/graphic'; +// import 'echarts/lib/component/grid'; +// import 'echarts/lib/component/legend'; +import 'echarts/lib/component/tooltip'; +// import 'echarts/lib/component/polar'; +// import 'echarts/lib/component/geo'; +// import 'echarts/lib/component/parallel'; +// import 'echarts/lib/component/singleAxis'; +// import 'echarts/lib/component/brush'; + +import 'echarts/lib/component/title'; + +// import 'echarts/lib/component/dataZoom'; +// import 'echarts/lib/component/visualMap'; + +// import 'echarts/lib/component/markPoint'; +// import 'echarts/lib/component/markLine'; +// import 'echarts/lib/component/markArea'; + +// import 'echarts/lib/component/timeline'; +// import 'echarts/lib/component/toolbox'; + +// import 'zrender/lib/vml/vml'; + +// The usage of ReactEchartsCore are same with above. + +``` + +# 3. component props + + - **`option`** (required, object) + +the echarts option config, can see [https://echarts.apache.org/option.html#title](https://echarts.apache.org/option.html#title). + + - **`notMerge`** (optional, object) + +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). + + - **`lazyUpdate`** (optional, object) + +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). + + - **`style`** (optional, object) + +the `style` of echarts div. `object`, default is {height: '300px'}. + + - **`className`** (optional, string) + +the `class` of echarts div. you can setting the css style of charts by class name. + + - **`theme`** (optional, string) + +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. + +```js +// import echarts +import echarts from 'echarts'; +... +// register theme object +echarts.registerTheme('my_theme', { + backgroundColor: '#f4cccc' +}); +... +// render the echarts use option `theme` + +``` + + - **`onChartReady`** (optional, function) + +when the chart is ready, will callback the function with the `echarts object` as it's paramter. + + - **`loadingOption`** (optional, object) + +the echarts loading option config, can see [https://echarts.apache.org/api.html#echartsInstance.showLoading](https://echarts.apache.org/api.html#echartsInstance.showLoading). + + - **`showLoading`** (optional, bool, default: false) + +`bool`, when the chart is rendering, show the loading mask. + + - **`onEvents`** (optional, array(string=>function) ) + +binding the echarts event, will callback with the `echarts event object`, and `the echart object` as it's paramters. e.g: + +```js +let onEvents = { + 'click': this.onChartClick, + 'legendselectchanged': this.onChartLegendselectchanged +} +... + +``` +for more event key name, see: [https://echarts.apache.org/api.html#events](https://echarts.apache.org/api.html#events) + + - **`opts`** (optional, object) + +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). + +```js + +``` + + +# 4. Component API & Echarts API + +the Component only has `one API` named `getEchartsInstance`. + + - **`getEchartsInstance()`** : get the echarts instance object, then you can use any `API of echarts`. + +for example: + +```js +// render the echarts component below with rel + { this.echarts_react = e; }} + option={this.getOption()} /> + +// then get the `ReactEcharts` use this.echarts_react + +let echarts_instance = this.echarts_react.getEchartsInstance(); +// then you can use any API of echarts. +let base64 = echarts_instance.getDataURL(); +``` + +**About API of echarts, can see** [https://echarts.apache.org/api.html#echartsInstance](https://echarts.apache.org/api.html#echartsInstance). + +You can use the API to do: + +1. `binding / unbinding` event. +2. `dynamic charts` with dynamic data. +3. get the echarts dom / dataURL / base64, save the chart to png. +4. `release` the charts. + + +# 5. Q & A + + - How to render the chart with svg when using echarts 4.x + +Use the props `opts` of component with `renderer = 'svg'`. For example: + + +```js + +``` + + - How to resolve Error `Component series.scatter3D not exists. Load it first.` + +[Install and import `echarts-gl` first](#GL) + + +# 6. LICENSE + +MIT@[hustcc](https://github.com/hustcc). + + diff --git a/__tests__/charts/simple-spec.tsx b/__tests__/charts/simple-spec.tsx new file mode 100644 index 0000000..fc5fbe1 --- /dev/null +++ b/__tests__/charts/simple-spec.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import ReactECharts from '../../src/'; +import { render, destroy, createDiv, removeDom } from '../utils'; + +const options = { + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true, + }, + ], +}; + +describe('chart', () => { + it('simple', () => { + let instance; + const div = createDiv(); + const Comp = (instance = e)} option={options} />; + render(Comp, div); + + expect(instance).toBeDefined(); + expect(instance.getEchartsInstance()).toBeDefined(); + + destroy(div); + expect(div.querySelector('*')).toBe(null); + + removeDom(div); + }); +}); diff --git a/__tests__/helper/is-equal-spec.ts b/__tests__/helper/is-equal-spec.ts new file mode 100644 index 0000000..feddaac --- /dev/null +++ b/__tests__/helper/is-equal-spec.ts @@ -0,0 +1,7 @@ +import { isEqual } from '../../src/helper/is-equal'; + +describe('is-equal', () => { + it('isEqual', () => { + expect(isEqual({}, {})).toBe(true); + }); +}); diff --git a/__tests__/helper/is-fucntion-spec.ts b/__tests__/helper/is-fucntion-spec.ts new file mode 100644 index 0000000..0fac5f9 --- /dev/null +++ b/__tests__/helper/is-fucntion-spec.ts @@ -0,0 +1,10 @@ +import { isFunction } from '../../src/helper/is-function'; + +describe('is-function', () => { + it('isFunction', () => { + expect(isFunction(1)).toBe(false); + expect(isFunction('')).toBe(false); + expect(isFunction(true)).toBe(false); + expect(isFunction(() => {})).toBe(true); + }); +}); diff --git a/__tests__/helper/is-string-spec.ts b/__tests__/helper/is-string-spec.ts new file mode 100644 index 0000000..ec27c78 --- /dev/null +++ b/__tests__/helper/is-string-spec.ts @@ -0,0 +1,10 @@ +import { isString } from '../../src/helper/is-string'; + +describe('is-function', () => { + it('isFunction', () => { + expect(isString(1)).toBe(false); + expect(isString('')).toBe(true); + expect(isString(true)).toBe(false); + expect(isString(() => {})).toBe(false); + }); +}); diff --git a/__tests__/helper/pick-spec.ts b/__tests__/helper/pick-spec.ts new file mode 100644 index 0000000..57bf873 --- /dev/null +++ b/__tests__/helper/pick-spec.ts @@ -0,0 +1,10 @@ +import { pick } from '../../src/helper/pick'; + +describe('pick', () => { + it('pick', () => { + expect(pick({ a: 1 }, [])).toEqual({}); + expect(pick({ a: 1 }, ['b'])).toEqual({}); + expect(pick({ a: 1 }, ['a'])).toEqual({ a: 1 }); + expect(pick({ a: 1 }, ['a', 'b'])).toEqual({ a: 1 }); + }); +}); diff --git a/__tests__/utils/index.ts b/__tests__/utils/index.ts new file mode 100644 index 0000000..f458172 --- /dev/null +++ b/__tests__/utils/index.ts @@ -0,0 +1,44 @@ +import ReactDOM from 'react-dom'; + +/** + * 渲染组件 + * @param comp + * @param container + */ +export function render(comp: any, container: HTMLElement) { + ReactDOM.render(comp, container); +} + +/** + * 卸载组件 + * @param container + */ +export function destroy(container: HTMLElement) { + ReactDOM.unmountComponentAtNode(container); +} + +/** + * 创建一个 div 节点,并放到 container,默认放到 body 上 + * @param title + * @param container + * @param id 容器 id + */ +export function createDiv(container: HTMLElement = document.body): HTMLElement { + const div = document.createElement('div'); + + container.appendChild(div); + + return div; +} + +/** + * 移除 dom 元素 + * @param dom + */ +export function removeDom(dom: HTMLElement) { + const parent = dom.parentNode; + + if (parent) { + parent.removeChild(dom); + } +} diff --git a/docs/examples/api.md b/docs/examples/api.md new file mode 100644 index 0000000..725968e --- /dev/null +++ b/docs/examples/api.md @@ -0,0 +1,128 @@ +--- +title: ECharts API +order: 2 +--- + +## ECharts API + +```tsx +import React, { useRef } from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const option = { + title: { + text: '漏斗图', + subtext: '纯属虚构' + }, + tooltip: { + trigger: 'item', + formatter: "{a}
{b} : {c}%" + }, + toolbox: { + feature: { + dataView: {readOnly: false}, + restore: {}, + saveAsImage: {} + } + }, + legend: { + data: ['展现','点击','访问','咨询','订单'] + }, + series: [ + { + name: '预期', + type: 'funnel', + left: '10%', + width: '80%', + label: { + normal: { + formatter: '{b}预期' + }, + emphasis: { + position:'inside', + formatter: '{b}预期: {c}%' + } + }, + labelLine: { + normal: { + show: false + } + }, + itemStyle: { + normal: { + opacity: 0.7 + } + }, + data: [ + {value: 60, name: '访问'}, + {value: 40, name: '咨询'}, + {value: 20, name: '订单'}, + {value: 80, name: '点击'}, + {value: 100, name: '展现'} + ] + }, + { + name: '实际', + type: 'funnel', + left: '10%', + width: '80%', + maxSize: '80%', + label: { + normal: { + position: 'inside', + formatter: '{c}%', + textStyle: { + color: '#fff' + } + }, + emphasis: { + position:'inside', + formatter: '{b}实际: {c}%' + } + }, + itemStyle: { + normal: { + opacity: 0.5, + borderColor: '#fff', + borderWidth: 2 + } + }, + data: [ + {value: 30, name: '访问'}, + {value: 10, name: '咨询'}, + {value: 5, name: '订单'}, + {value: 50, name: '点击'}, + {value: 80, name: '展现'} + ] + } + ] + }; + + const instance = useRef(null); + + function clickBtn() { + const base64 = instance.current.getEchartsInstance().getDataURL(); + + const img = new Image(); + img.src = base64; + const newWin = window.open('', '_blank'); + newWin.document.write(img.outerHTML); + } + + return ( + <> + +
+ +
+ + ); +}; + +export default Page; +``` diff --git a/docs/examples/dynamic.md b/docs/examples/dynamic.md new file mode 100644 index 0000000..c462dea --- /dev/null +++ b/docs/examples/dynamic.md @@ -0,0 +1,178 @@ +--- +title: Dynamic +order: 6 +--- + +## Dynamic + +```tsx +import React, { useState, useEffect } from 'react'; +import ReactECharts from 'echarts-for-react'; +import cloneDeep from 'lodash.clonedeep'; + +const Page: React.FC = () => { + const DEFAULT_OPTION = { + title: { + text:'Hello Echarts-for-react.', + }, + tooltip: { + trigger: 'axis' + }, + legend: { + data:['最新成交价', '预购队列'] + }, + toolbox: { + show: true, + feature: { + dataView: {readOnly: false}, + restore: {}, + saveAsImage: {} + } + }, + grid: { + top: 60, + left: 30, + right: 60, + bottom:30 + }, + dataZoom: { + show: false, + start: 0, + end: 100 + }, + visualMap: { + show: false, + min: 0, + max: 1000, + color: ['#BE002F', '#F20C00', '#F00056', '#FF2D51', '#FF2121', '#FF4C00', '#FF7500', + '#FF8936', '#FFA400', '#F0C239', '#FFF143', '#FAFF72', '#C9DD22', '#AFDD22', + '#9ED900', '#00E500', '#0EB83A', '#0AA344', '#0C8918', '#057748', '#177CB0'] + }, + xAxis: [ + { + type: 'category', + boundaryGap: true, + data: (function (){ + let now = new Date(); + let res = []; + let len = 50; + while (len--) { + res.unshift(now.toLocaleTimeString().replace(/^\D*/,'')); + now = new Date(now - 2000); + } + return res; + })() + }, + { + type: 'category', + boundaryGap: true, + data: (function (){ + let res = []; + let len = 50; + while (len--) { + res.push(50 - len + 1); + } + return res; + })() + } + ], + yAxis: [ + { + type: 'value', + scale: true, + name: '价格', + max: 20, + min: 0, + boundaryGap: [0.2, 0.2] + }, + { + type: 'value', + scale: true, + name: '预购量', + max: 1200, + min: 0, + boundaryGap: [0.2, 0.2] + } + ], + series: [ + { + name:'预购队列', + type:'bar', + xAxisIndex: 1, + yAxisIndex: 1, + itemStyle: { + normal: { + barBorderRadius: 4, + } + }, + animationEasing: 'elasticOut', + animationDelay: function (idx) { + return idx * 10; + }, + animationDelayUpdate: function (idx) { + return idx * 10; + }, + data:(function (){ + let res = []; + let len = 50; + while (len--) { + res.push(Math.round(Math.random() * 1000)); + } + return res; + })() + }, + { + name:'最新成交价', + type:'line', + data:(function (){ + let res = []; + let len = 0; + while (len < 50) { + res.push((Math.random()*10 + 5).toFixed(1) - 0); + len++; + } + return res; + })() + } + ] + }; + + let count; + + const [option, setOption] = useState(DEFAULT_OPTION); + + function fetchNewData() { + const axisData = (new Date()).toLocaleTimeString().replace(/^\D*/,''); + const newOption = cloneDeep(option); // immutable + newOption.title.text = 'Hello Echarts-for-react.' + new Date().getSeconds(); + const data0 = newOption.series[0].data; + const data1 = newOption.series[1].data; + data0.shift(); + data0.push(Math.round(Math.random() * 1000)); + data1.shift(); + data1.push((Math.random() * 10 + 5).toFixed(1) - 0); + + newOption.xAxis[0].data.shift(); + newOption.xAxis[0].data.push(axisData); + newOption.xAxis[1].data.shift(); + newOption.xAxis[1].data.push(count++); + + setOption(newOption); + } + + useEffect(() => { + const timer = setInterval(() => { + fetchNewData(); + }, 1000); + + return () => clearInterval(timer); + }); + + return ; +}; + +export default Page; +``` diff --git a/docs/examples/event.md b/docs/examples/event.md new file mode 100644 index 0000000..110f0cc --- /dev/null +++ b/docs/examples/event.md @@ -0,0 +1,85 @@ +--- +title: Event +order: 4 +--- + +## Event + +```tsx +import React, { useState } from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const option = { + title : { + text: '某站点用户访问来源', + subtext: '纯属虚构', + x:'center' + }, + tooltip : { + trigger: 'item', + formatter: "{a}
{b} : {c} ({d}%)" + }, + legend: { + orient: 'vertical', + left: 'left', + data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎'] + }, + series : [ + { + name: '访问来源', + type: 'pie', + radius : '55%', + center: ['50%', '60%'], + data:[ + {value:335, name:'直接访问'}, + {value:310, name:'邮件营销'}, + {value:234, name:'联盟广告'}, + {value:135, name:'视频广告'}, + {value:1548, name:'搜索引擎'} + ], + itemStyle: { + emphasis: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + } + } + ] + }; + + const [count, setCount] = useState(0); + + function onChartReady(echarts) { + console.log('echarts is ready', echarts); + } + + function onChartClick(param, echarts) { + console.log(param, echarts); + setCount(count + 1); + }; + + function onChartLegendselectchanged(param, echarts) { + console.log(param, echarts); + }; + + return ( + <> + +
Click Count: {count}
+
Open console, see the log detail.
+ + ); +}; + +export default Page; +``` diff --git a/docs/examples/gl.md b/docs/examples/gl.md new file mode 100644 index 0000000..1b000da --- /dev/null +++ b/docs/examples/gl.md @@ -0,0 +1,36 @@ +--- +title: Web GL +order: 7 +--- + +## Web GL + +```tsx +import React from 'react'; +import ReactECharts from 'echarts-for-react'; +import 'echarts-gl'; + +const Page: React.FC = () => { + const option = { + grid3D: {}, + xAxis3D: {}, + yAxis3D: {}, + zAxis3D: {}, + series: [{ + type: 'scatter3D', + symbolSize: 50, + data: [[-1, -1, -1], [0, 0, 0], [1, 1, 1]], + itemStyle: { + opacity: 1 + } + }] + }; + + return ; +}; + +export default Page; +``` diff --git a/docs/examples/graph.md b/docs/examples/graph.md new file mode 100644 index 0000000..4c1639f --- /dev/null +++ b/docs/examples/graph.md @@ -0,0 +1,52 @@ +--- +title: Graph +order: 9 +--- + +## Graph + +```tsx +import React from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + 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}]}; + const option = { + legend: { + data: ['HTMLElement', 'WebGL', 'SVG', 'CSS', 'Other'] + }, + series: [{ + type: 'graph', + layout: 'force', + animation: false, + label: { + normal: { + position: 'right', + formatter: '{b}' + } + }, + draggable: true, + data: webkitDep.nodes.map(function (node, idx) { + node.id = idx; + return node; + }), + categories: webkitDep.categories, + force: { + // initLayout: 'circular' + // repulsion: 20, + edgeLength: 5, + repulsion: 20, + gravity: 0.2 + }, + edges: webkitDep.links + }] + }; + + return ; +}; + +export default Page; +``` diff --git a/docs/examples/loading.md b/docs/examples/loading.md new file mode 100644 index 0000000..fe31aa6 --- /dev/null +++ b/docs/examples/loading.md @@ -0,0 +1,79 @@ +--- +title: Loading +order: 5 +--- + +## Loading + +```tsx +import React, { useState, useEffect } from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const option = { + title: { + text: '基础雷达图' + }, + tooltip: {}, + legend: { + data: ['预算分配(Allocated Budget)', '实际开销(Actual Spending)'] + }, + radar: { + // shape: 'circle', + indicator: [ + { name: '销售(sales)', max: 6500}, + { name: '管理(Administration)', max: 16000}, + { name: '信息技术(Information Techology)', max: 30000}, + { name: '客服(Customer Support)', max: 38000}, + { name: '研发(Development)', max: 52000}, + { name: '市场(Marketing)', max: 25000} + ] + }, + series: [{ + name: '预算 vs 开销(Budget vs spending)', + type: 'radar', + // areaStyle: {normal: {}}, + data : [ + { + value : [4300, 10000, 28000, 35000, 50000, 19000], + name : '预算分配(Allocated Budget)' + }, + { + value : [5000, 14000, 28000, 31000, 42000, 21000], + name : '实际开销(Actual Spending)' + } + ] + }] + }; + + let timer; + + useEffect(() => { + return () => clearTimeout(timer); + }); + + const loadingOption = { + text: '加载中...', + color: '#4413c2', + textColor: '#270240', + maskColor: 'rgba(194, 88, 86, 0.3)', + zlevel: 0 + }; + + function onChartReady(echarts) { + timer = setTimeout(function() { + echarts.hideLoading(); + }, 3000); + } + + return ; +}; + +export default Page; +``` diff --git a/docs/examples/simple.md b/docs/examples/simple.md new file mode 100644 index 0000000..cf8bbf8 --- /dev/null +++ b/docs/examples/simple.md @@ -0,0 +1,78 @@ +--- +title: Simple +order: 1 +--- + +## 简单堆积面积图 + +```tsx +import React from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const option = { + title: { + text: '堆叠区域图' + }, + tooltip : { + trigger: 'axis' + }, + legend: { + data:['邮件营销','联盟广告','视频广告'] + }, + toolbox: { + feature: { + saveAsImage: {} + } + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis : [ + { + type : 'category', + boundaryGap : false, + data : ['周一','周二','周三','周四','周五','周六','周日'] + } + ], + yAxis : [ + { + type : 'value' + } + ], + series : [ + { + name:'邮件营销', + type:'line', + stack: '总量', + areaStyle: {normal: {}}, + data:[120, 132, 101, 134, 90, 230, 210] + }, + { + name:'联盟广告', + type:'line', + stack: '总量', + areaStyle: {normal: {}}, + data:[220, 182, 191, 234, 290, 330, 310] + }, + { + name:'视频广告', + type:'line', + stack: '总量', + areaStyle: {normal: {}}, + data:[150, 232, 201, 154, 190, 330, 410] + } + ] + }; + + return ; +}; + +export default Page; +``` diff --git a/docs/examples/svg.md b/docs/examples/svg.md new file mode 100644 index 0000000..c677301 --- /dev/null +++ b/docs/examples/svg.md @@ -0,0 +1,40 @@ +--- +title: SVG +order: 8 +--- + +## SVG + +```tsx +import React from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const option = { + title: { + text: 'ECharts 入门示例' + }, + tooltip: {}, + legend: { + data:['销量'] + }, + xAxis: { + data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] + }, + yAxis: {}, + series: [{ + name: '销量', + type: 'bar', + data: [5, 20, 36, 10, 10, 20] + }] + }; + + return ; +}; + +export default Page; +``` diff --git a/docs/examples/theme.md b/docs/examples/theme.md new file mode 100644 index 0000000..082fa33 --- /dev/null +++ b/docs/examples/theme.md @@ -0,0 +1,123 @@ +--- +title: Theme +order: 3 +--- + +## Theme + +```tsx +import React, { useState } from 'react'; +import * as echarts from 'echarts'; +import ReactECharts from 'echarts-for-react'; + +echarts.registerTheme('my_theme', { + backgroundColor: '#f4cccc' +}); +echarts.registerTheme('another_theme', { + backgroundColor: '#eee' +}); + +const Page: React.FC = () => { + const option = { + title: { + text: '阶梯瀑布图', + subtext: 'From ExcelHome', + sublink: 'http://e.weibo.com/1341556070/Aj1J2x5a5' + }, + tooltip : { + trigger: 'axis', + axisPointer : { // 坐标轴指示器,坐标轴触发有效 + type : 'shadow' // 默认为直线,可选为:'line' | 'shadow' + } + }, + legend: { + data:['支出','收入'] + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true + }, + xAxis: { + type : 'category', + splitLine: {show:false}, + data : ["11月1日", "11月2日", "11月3日", "11月4日", "11月5日", "11月6日", "11月7日", "11月8日", "11月9日", "11月10日", "11月11日"] + }, + yAxis: { + type : 'value' + }, + series: [ + { + name: '辅助', + type: 'bar', + stack: '总量', + itemStyle: { + normal: { + barBorderColor: 'rgba(0,0,0,0)', + color: 'rgba(0,0,0,0)' + }, + emphasis: { + barBorderColor: 'rgba(0,0,0,0)', + color: 'rgba(0,0,0,0)' + } + }, + data: [0, 900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292] + }, + { + name: '收入', + type: 'bar', + stack: '总量', + label: { + normal: { + show: true, + position: 'top' + } + }, + data: [900, 345, 393, '-', '-', 135, 178, 286, '-', '-', '-'] + }, + { + name: '支出', + type: 'bar', + stack: '总量', + label: { + normal: { + show: true, + position: 'bottom' + } + }, + data: ['-', '-', '-', 108, 154, '-', '-', '-', 119, 361, 203] + } + ] + }; + + const [theme, setTheme] = useState(); + const [className, setClassName] = useState('class_1'); + + function toggleTheme() { + setTheme(theme === 'my_theme' ? 'another_theme' : 'my_theme'); + } + + function toggleClassName() { + setClassName(className === 'class_1' ? 'class_2' : 'class_1'); + } + + return ( + <> + +
+
+ + +
+ + ); +}; + +export default Page; +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..debeb7d --- /dev/null +++ b/docs/index.md @@ -0,0 +1,86 @@ +--- +title: ECharts for React - 全网最好用的 ECharts 的 React 组件封装 +order: 10 +hero: + title: ECharts for React + desc: 全网最好用的 ECharts 的 React 组件封装 + actions: + - text: 查看在线 DEMO + link: /examples/dynamic +footer: Open-source MIT Licensed | Copyright © 2021-present +--- + + +## 安装 + +```bash +$ npm install echarts-for-react +``` + + +## 使用 + +```tsx | pure +import React from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const options = { + grid: { top: 8, right: 8, bottom: 24, left: 36 }, + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true, + }, + ], + }; + + return ; +}; + +export default Page; +``` + +最终结果: + +```tsx +import React from 'react'; +import ReactECharts from 'echarts-for-react'; + +const Page: React.FC = () => { + const options = { + grid: { top: 8, right: 8, bottom: 24, left: 36 }, + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true, + }, + ], + }; + + return ; +}; + +export default Page; +``` + + +## 反馈 + +请访问 [GitHub](https://github.com/hustcc/echarts-for-react)。 diff --git a/package.json b/package.json new file mode 100644 index 0000000..74a275c --- /dev/null +++ b/package.json @@ -0,0 +1,116 @@ +{ + "name": "echarts-for-react", + "version": "3.0.0-beta.1", + "description": " Apache Echarts(v5) components for React.", + "main": "lib/index.js", + "module": "esm/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib", + "esm", + "src" + ], + "scripts": { + "docs:dev": "dumi dev", + "docs:build": "dumi build", + "docs:deploy": "rimraf dist && npm run docs:build && gh-pages -d dist", + "start": "webpack-dev-server --watch", + "lint": "eslint src __tests__ && prettier src __tests__ --check", + "fix": "eslint src __tests__ --fix && prettier src __tests__ --write", + "clean": "rimraf lib esm dist", + "test": "jest", + "lib": "run-p lib:*", + "lib:cjs": "tsc -p tsconfig.json --target ES5 --module commonjs --outDir lib", + "lib:esm": "tsc -p tsconfig.json --target ES5 --module ESNext --outDir esm", + "build": "npm run clean && npm run test && npm run lib" + }, + "repository": { + "type": "git", + "url": "https://github.com/hustcc/echarts-for-react.git" + }, + "keywords": [ + "react", + "component", + "echarts-react", + "echarts", + "react-echarts", + "chart", + "charts", + "graph", + "react-component" + ], + "author": "hustcc (http://github.com/hustcc)", + "license": "MIT", + "bugs": { + "url": "https://github.com/hustcc/echarts-for-react/issues" + }, + "homepage": "https://github.com/hustcc/echarts-for-react", + "devDependencies": { + "@commitlint/cli": "^11.0.0", + "@commitlint/config-angular": "^11.0.0", + "@types/jest": "^26.0.20", + "@types/node": "^14.14.14", + "@types/react": "^17.0.1", + "@typescript-eslint/eslint-plugin": "^4.14.2", + "@typescript-eslint/parser": "^4.11.0", + "cross-env": "^5.1.3", + "dumi": "^1.1.4", + "dumi-theme-default": "^1.0.4", + "echarts": "^5.0.2", + "echarts-gl": "^2.0.1", + "eslint": "^7.19.0", + "eslint-config-prettier": "^7.1.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-prettier": "^3.3.1", + "gh-pages": "^3.1.0", + "husky": "^4.3.8", + "jest": "^26.6.3", + "jest-canvas-mock": "^2.3.0", + "jest-electron": "^0.1.11", + "lint-md-cli": "^0.1.2", + "lint-staged": "^10.5.3", + "lodash.clonedeep": "^4.5.0", + "miz": "^1.0.1", + "npm-run-all": "^4.1.5", + "prettier": "^2.2.1", + "rimraf": "^2.6.2", + "ts-jest": "^26.5.0", + "ts-loader": "^8.0.15", + "typescript": "^4.1.3" + }, + "dependencies": { + "size-sensor": "^1.0.0", + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "react": ">=16.8.0", + "echarts": "^5.0.0" + }, + "jest": { + "runner": "jest-electron/runner", + "testEnvironment": "jest-electron/environment", + "preset": "ts-jest", + "collectCoverage": true, + "collectCoverageFrom": [ + "src/**/*.ts", + "!**/node_modules/**", + "!**/vendor/**" + ], + "testRegex": "/__tests__/.*-spec\\.tsx?$" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged", + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" + } + }, + "lint-staged": { + "*.ts": [ + "eslint --fix", + "prettier --write" + ], + "*.md": [ + "lint-md --fix" + ] + } +} diff --git a/src/core.tsx b/src/core.tsx new file mode 100644 index 0000000..b7082a3 --- /dev/null +++ b/src/core.tsx @@ -0,0 +1,185 @@ +import React, { PureComponent } from 'react'; +import { bind, clear } from 'size-sensor'; +import { pick } from './helper/pick'; +import { isFunction } from './helper/is-function'; +import { isString } from './helper/is-string'; +import { isEqual } from './helper/is-equal'; +import { EChartsReactProps, EChartsInstance } from './types'; + +/** + * core component for echarts binding + */ +export default class EChartsReactCore extends PureComponent { + /** + * echarts render container + */ + public ele: HTMLElement; + + /** + * echarts library entry + */ + protected echarts: any; + + constructor(props: EChartsReactProps) { + super(props); + + this.echarts = props.echarts; + this.ele = null; + } + + componentDidMount() { + this.renderNewEcharts(); + } + + // update + componentDidUpdate(prevProps: EChartsReactProps) { + /** + * if shouldSetOption return false, then return, not update echarts options + * default is true + */ + const { shouldSetOption } = this.props; + if (isFunction(shouldSetOption) && !shouldSetOption(prevProps, this.props)) { + return; + } + + // 以下属性修改的时候,需要 dispose 之后再新建 + // 1. 切换 theme 的时候 + // 2. 修改 opts 的时候 + // 3. 修改 onEvents 的时候,这样可以取消所有之前绑定的事件 issue #151 + if ( + !isEqual(prevProps.theme, this.props.theme) || + !isEqual(prevProps.opts, this.props.opts) || + !isEqual(prevProps.onEvents, this.props.onEvents) + ) { + this.dispose(); + + this.renderNewEcharts(); // 重建 + return; + } + + // when thoes props isEqual, do not update echarts + const pickKeys = ['option', 'notMerge', 'lazyUpdate', 'showLoading', 'loadingOption']; + if (isEqual(pick(this.props, pickKeys), pick(prevProps, pickKeys))) { + return; + } + + const echartsInstance = this.updateEChartsOption(); + /** + * when style or class name updated, change size. + */ + if (!isEqual(prevProps.style, this.props.style) || !isEqual(prevProps.className, this.props.className)) { + try { + echartsInstance.resize(); + } catch (e) { + console.warn(e); + } + } + } + + componentWillUnmount() { + this.dispose(); + } + + /** + * return the echart object + * 1. if exist, return the existed instance + * 2. or new one instance + */ + public getEchartsInstance() { + return this.echarts.getInstanceByDom(this.ele) || this.echarts.init(this.ele, this.props.theme, this.props.opts); + } + + /** + * dispose echarts and clear size-sensor + */ + private dispose() { + if (this.ele) { + try { + clear(this.ele); + } catch (e) { + console.warn(e); + } + // dispose echarts instance + this.echarts.dispose(this.ele); + } + } + + /** + * render a new echarts instance + */ + private renderNewEcharts() { + const { onEvents, onChartReady } = this.props; + + // 1. new echarts instance + const echartsInstance = this.updateEChartsOption(); + + // 2. bind events + this.bindEvents(echartsInstance, onEvents || {}); + + // 3. on chart ready + if (isFunction(onChartReady)) onChartReady(echartsInstance); + + // 4. on resize + if (this.ele) { + bind(this.ele, () => { + try { + echartsInstance.resize(); + } catch (e) { + console.warn(e); + } + }); + } + } + + // bind the events + private bindEvents(instance, events: EChartsReactProps['onEvents']) { + function _bindEvent(eventName: string, func: Function) { + // ignore the event config which not satisfy + if (isString(eventName) && isFunction(func)) { + // binding event + instance.on(eventName, (param) => { + func(param, instance); + }); + } + } + + // loop and bind + for (const eventName in events) { + if (Object.prototype.hasOwnProperty.call(events, eventName)) { + _bindEvent(eventName, events[eventName]); + } + } + } + + /** + * render the echarts + */ + private updateEChartsOption(): EChartsInstance { + const { option, notMerge = false, lazyUpdate = false, showLoading, loadingOption = null } = this.props; + // 1. get or initial the echarts object + const echartInstance = this.getEchartsInstance(); + // 2. set the echarts option + echartInstance.setOption(option, notMerge, lazyUpdate); + // 3. set loading mask + if (showLoading) echartInstance.showLoading(loadingOption); + else echartInstance.hideLoading(); + + return echartInstance; + } + + render(): JSX.Element { + const { style, className = '' } = this.props; + // default height = 300 + const newStyle = { height: 300, ...style }; + + return ( +
{ + this.ele = e; + }} + style={newStyle} + className={`echarts-for-react ${className}`} + /> + ); + } +} diff --git a/src/helper/is-equal.ts b/src/helper/is-equal.ts new file mode 100644 index 0000000..7d7e552 --- /dev/null +++ b/src/helper/is-equal.ts @@ -0,0 +1,3 @@ +import isEqual from 'fast-deep-equal'; + +export { isEqual }; diff --git a/src/helper/is-function.ts b/src/helper/is-function.ts new file mode 100644 index 0000000..c254be4 --- /dev/null +++ b/src/helper/is-function.ts @@ -0,0 +1,3 @@ +export function isFunction(v: any): boolean { + return typeof v === 'function'; +} diff --git a/src/helper/is-string.ts b/src/helper/is-string.ts new file mode 100644 index 0000000..26e196d --- /dev/null +++ b/src/helper/is-string.ts @@ -0,0 +1,3 @@ +export function isString(v: any): boolean { + return typeof v === 'string'; +} diff --git a/src/helper/pick.ts b/src/helper/pick.ts new file mode 100644 index 0000000..ded83f8 --- /dev/null +++ b/src/helper/pick.ts @@ -0,0 +1,12 @@ +/** + * 保留 object 中的部分内容 + * @param obj + * @param keys + */ +export function pick(obj: Record, keys: string[]): Record { + const r = {}; + keys.forEach((key) => { + r[key] = obj[key]; + }); + return r; +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..e743d5a --- /dev/null +++ b/src/index.ts @@ -0,0 +1,15 @@ +import * as echarts from 'echarts'; +import { EChartsReactProps, EChartsOption, EChartsInstance } from './types'; +import EChartsReactCore from './core'; + +export { EChartsReactProps, EChartsOption, EChartsInstance }; + +// export the Component the echarts Object. +export default class EChartsReact extends EChartsReactCore { + constructor(props: EChartsReactProps) { + super(props); + + // 初始化为 echarts 整个包 + this.echarts = echarts; + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..7b8bd1a --- /dev/null +++ b/src/types.ts @@ -0,0 +1,69 @@ +import { CSSProperties } from 'react'; + +export type EChartsOption = any; + +export type EChartsInstance = any; + +export type Opts = { + readonly devicePixelRatio?: number; + readonly renderer?: 'canvas' | 'svg'; + readonly width?: number | null | undefined | 'auto'; + readonly height?: number | null | undefined | 'auto'; +}; + +export type EChartsReactProps = { + /** + * echarts library entry, use it for import necessary. + */ + readonly echarts?: any; + /** + * `className` for container + */ + readonly className?: string; + /** + * `style` for container + */ + readonly style?: CSSProperties; + /** + * echarts option + */ + readonly option: EChartsOption; + /** + * echarts theme config, can be: + * 1. theme name string + * 2. theme object + */ + readonly theme?: string | Record; + /** + * notMerge config for echarts, default is `false` + */ + readonly notMerge?: boolean; + /** + * lazyUpdate config for echarts, default is `false` + */ + readonly lazyUpdate?: boolean; + /** + * showLoading config for echarts, default is `false` + */ + readonly showLoading?: boolean; + /** + * loadingOption config for echarts, default is `null` + */ + readonly loadingOption?: any; + /** + * echarts opts config, default is `{}` + */ + readonly opts?: Opts; + /** + * when after chart reander, do the callback widht echarts instance + */ + readonly onChartReady?: (instance: EChartsInstance) => void; + /** + * bind events, default is `{}` + */ + readonly onEvents?: Record; + /** + * should update echarts options + */ + readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean; +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..72042f4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "jsx": "react", + "module": "commonjs", + "sourceMap": true, + "inlineSources": true, + "target": "es5", + "outDir": "lib", + "declaration": true, + "importHelpers": true, + "moduleResolution": "node", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "lib": ["esnext", "dom"], + "types": ["jest", "react", "node"] + }, + "include": ["src"] +}