0.0.0.4
This commit is contained in:
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../echarts@6.0.0/node_modules/echarts
|
||||
Generated
Vendored
+21
@@ -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.
|
||||
Generated
Vendored
+424
@@ -0,0 +1,424 @@
|
||||
# echarts-for-react
|
||||
|
||||
The simplest, and the best React wrapper for [Apache ECharts](https://github.com/apache/incubator-echarts). Using visualization with MCP Server [mcp-server-chart](https://github.com/antvis/mcp-server-chart).
|
||||
|
||||
[](https://www.npmjs.com/package/echarts-for-react)
|
||||
[](https://github.com/hustcc/echarts-for-react/actions/workflows/build.yml)
|
||||
[](https://coveralls.io/github/hustcc/echarts-for-react)
|
||||
[](https://www.npmjs.com/package/echarts-for-react)
|
||||
[](https://www.npmjs.com/package/echarts-for-react)
|
||||

|
||||

|
||||
|
||||
|
||||
## Install
|
||||
|
||||
```bach
|
||||
$ 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.
|
||||
|
||||
```ts
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
|
||||
// render echarts option.
|
||||
<ReactECharts option={this.getOption()} />
|
||||
```
|
||||
|
||||
You can run website.
|
||||
|
||||
```bash
|
||||
$ git clone git@github.com:hustcc/echarts-for-react.git
|
||||
|
||||
$ npm install
|
||||
|
||||
$ npm start
|
||||
```
|
||||
|
||||
Then open [http://127.0.0.1:8081/](http://127.0.0.1:8081/) in your browser. or see [https://git.hust.cc/echarts-for-react/](https://git.hust.cc/echarts-for-react/) which is deploy on gh-pages.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Code of a simple demo code showed below. For more example can see: [https://git.hust.cc/echarts-for-react/](https://git.hust.cc/echarts-for-react/)
|
||||
|
||||
```ts
|
||||
import React from 'react';
|
||||
import ReactECharts from 'echarts-for-react'; // or var ReactECharts = require('echarts-for-react');
|
||||
|
||||
<ReactECharts
|
||||
option={this.getOption()}
|
||||
notMerge={true}
|
||||
lazyUpdate={true}
|
||||
theme={"theme_name"}
|
||||
onChartReady={this.onChartReadyCallback}
|
||||
onEvents={EventsDict}
|
||||
opts={}
|
||||
/>
|
||||
```
|
||||
|
||||
Import ECharts.js modules manually to reduce bundle size
|
||||
|
||||
**With Echarts.js v5 or v6:**
|
||||
|
||||
```ts
|
||||
import React from 'react';
|
||||
// import the core library.
|
||||
import ReactEChartsCore from 'echarts-for-react/lib/core';
|
||||
// Import the echarts core module, which provides the necessary interfaces for using echarts.
|
||||
import * as echarts from 'echarts/core';
|
||||
// Import charts, all with Chart suffix
|
||||
import {
|
||||
// LineChart,
|
||||
BarChart,
|
||||
// PieChart,
|
||||
// ScatterChart,
|
||||
// RadarChart,
|
||||
// MapChart,
|
||||
// TreeChart,
|
||||
// TreemapChart,
|
||||
// GraphChart,
|
||||
// GaugeChart,
|
||||
// FunnelChart,
|
||||
// ParallelChart,
|
||||
// SankeyChart,
|
||||
// BoxplotChart,
|
||||
// CandlestickChart,
|
||||
// EffectScatterChart,
|
||||
// LinesChart,
|
||||
// HeatmapChart,
|
||||
// PictorialBarChart,
|
||||
// ThemeRiverChart,
|
||||
// SunburstChart,
|
||||
// CustomChart,
|
||||
} from 'echarts/charts';
|
||||
// import components, all suffixed with Component
|
||||
import {
|
||||
// GridSimpleComponent,
|
||||
GridComponent,
|
||||
// PolarComponent,
|
||||
// RadarComponent,
|
||||
// GeoComponent,
|
||||
// SingleAxisComponent,
|
||||
// ParallelComponent,
|
||||
// CalendarComponent,
|
||||
// GraphicComponent,
|
||||
// ToolboxComponent,
|
||||
TooltipComponent,
|
||||
// AxisPointerComponent,
|
||||
// BrushComponent,
|
||||
TitleComponent,
|
||||
// TimelineComponent,
|
||||
// MarkPointComponent,
|
||||
// MarkLineComponent,
|
||||
// MarkAreaComponent,
|
||||
// LegendComponent,
|
||||
// LegendScrollComponent,
|
||||
// LegendPlainComponent,
|
||||
// DataZoomComponent,
|
||||
// DataZoomInsideComponent,
|
||||
// DataZoomSliderComponent,
|
||||
// VisualMapComponent,
|
||||
// VisualMapContinuousComponent,
|
||||
// VisualMapPiecewiseComponent,
|
||||
// AriaComponent,
|
||||
// TransformComponent,
|
||||
DatasetComponent,
|
||||
} from 'echarts/components';
|
||||
// Import renderer, note that introducing the CanvasRenderer or SVGRenderer is a required step
|
||||
import {
|
||||
CanvasRenderer,
|
||||
// SVGRenderer,
|
||||
} from 'echarts/renderers';
|
||||
|
||||
// Register the required components
|
||||
echarts.use(
|
||||
[TitleComponent, TooltipComponent, GridComponent, BarChart, CanvasRenderer]
|
||||
);
|
||||
|
||||
// The usage of ReactEChartsCore are same with above.
|
||||
<ReactEChartsCore
|
||||
echarts={echarts}
|
||||
option={this.getOption()}
|
||||
notMerge={true}
|
||||
lazyUpdate={true}
|
||||
theme={"theme_name"}
|
||||
onChartReady={this.onChartReadyCallback}
|
||||
onEvents={EventsDict}
|
||||
opts={}
|
||||
/>
|
||||
```
|
||||
|
||||
**With Echarts.js v3 or v4:**
|
||||
|
||||
```ts
|
||||
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.
|
||||
<ReactEChartsCore
|
||||
echarts={echarts}
|
||||
option={this.getOption()}
|
||||
notMerge={true}
|
||||
lazyUpdate={true}
|
||||
theme={"theme_name"}
|
||||
onChartReady={this.onChartReadyCallback}
|
||||
onEvents={EventsDict}
|
||||
opts={}
|
||||
/>
|
||||
```
|
||||
|
||||
For **Next.js** user, code transpilation is needed. For Next.js 13.1 or higher, as all `next-transpile-modules` features are natively built-in and the package has been deprecated, so please add `transpilePackages: ['echarts', 'zrender']` into `nextConfig` object:
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
/** @type {import('next').NextConfig} */
|
||||
|
||||
const nextConfig = {
|
||||
// ...existing properties,
|
||||
transpilePackages: ['echarts', 'zrender'],
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
```
|
||||
|
||||
For Next.js with version < 13.1:
|
||||
|
||||
```js
|
||||
// next.config.js
|
||||
const withTM = require("next-transpile-modules")(["echarts", "zrender"]);
|
||||
|
||||
module.exports = withTM({})
|
||||
```
|
||||
|
||||
## Props of Component
|
||||
|
||||
- **`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).
|
||||
|
||||
- **`replaceMerge`** (optional, string | string[])
|
||||
|
||||
when `setOption`, default is `null`. 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.
|
||||
|
||||
```ts
|
||||
// import echarts
|
||||
import echarts from 'echarts';
|
||||
...
|
||||
// register theme object
|
||||
echarts.registerTheme('my_theme', {
|
||||
backgroundColor: '#f4cccc'
|
||||
});
|
||||
...
|
||||
// render the echarts use option `theme`
|
||||
<ReactECharts
|
||||
option={this.getOption()}
|
||||
style={{height: '300px', width: '100%'}}
|
||||
className='echarts-for-echarts'
|
||||
theme='my_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:
|
||||
|
||||
```ts
|
||||
const onEvents = {
|
||||
'click': this.onChartClick,
|
||||
'legendselectchanged': this.onChartLegendselectchanged
|
||||
}
|
||||
...
|
||||
<ReactECharts
|
||||
option={this.getOption()}
|
||||
style={{ height: '300px', width: '100%' }}
|
||||
onEvents={onEvents}
|
||||
/>
|
||||
```
|
||||
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).
|
||||
|
||||
```ts
|
||||
<ReactECharts
|
||||
option={this.getOption()}
|
||||
style={{ height: '300px' }}
|
||||
opts={{renderer: 'svg'}} // use svg to render the chart.
|
||||
/>
|
||||
```
|
||||
|
||||
- **`autoResize`** (optional, boolean)
|
||||
|
||||
decide whether to trigger `this.resize` when window resize. default is `true`.
|
||||
|
||||
|
||||
## 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:
|
||||
|
||||
```ts
|
||||
// render the echarts component below with rel
|
||||
<ReactECharts
|
||||
ref={(e) => { this.echartRef = e; }}
|
||||
option={this.getOption()}
|
||||
/>
|
||||
|
||||
// then get the `ReactECharts` use this.echarts_react
|
||||
|
||||
const echartInstance = this.echartRef.getEchartsInstance();
|
||||
// then you can use any API of echarts.
|
||||
const base64 = echartInstance.getDataURL();
|
||||
```
|
||||
|
||||
TypeScript and `useRef()` example:
|
||||
|
||||
```ts
|
||||
const getOption = () => {/** */};
|
||||
|
||||
export default function App() {
|
||||
const echartsRef = useRef<InstanceType<typeof ReactEcharts>>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (echartsRef.current) {
|
||||
const echartsInstance = echartsRef.current.getEchartsInstance();
|
||||
// do something
|
||||
echartsInstance.resize();
|
||||
}
|
||||
}, []);
|
||||
return <ReactEcharts ref={echartsRef} option={getOption()} />;
|
||||
}
|
||||
```
|
||||
|
||||
**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.
|
||||
|
||||
|
||||
## FAQ
|
||||
|
||||
### How to render the chart with svg when using echarts 4.x
|
||||
|
||||
Use the props `opts` of component with `renderer = 'svg'`. For example:
|
||||
|
||||
|
||||
```ts
|
||||
<ReactECharts
|
||||
option={this.getOption()}
|
||||
style={{height: '300px'}}
|
||||
opts={{renderer: 'svg'}} // use svg to render the chart.
|
||||
/>
|
||||
```
|
||||
|
||||
### How to resolve Error `Component series.scatter3D not exists. Load it first.`
|
||||
|
||||
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)
|
||||
|
||||
```sh
|
||||
npm install --save echarts-gl
|
||||
```
|
||||
|
||||
```ts
|
||||
import 'echarts-gl'
|
||||
import ReactECharts from "echarts-for-react";
|
||||
|
||||
<ReactECharts
|
||||
option={GL_OPTION}
|
||||
/>
|
||||
```
|
||||
|
||||
|
||||
## LICENSE
|
||||
|
||||
MIT@[hustcc](https://github.com/hustcc).
|
||||
Generated
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
import type { ECharts } from 'echarts';
|
||||
import { PureComponent } from 'react';
|
||||
import { EChartsReactProps } from './types';
|
||||
/**
|
||||
* core component for echarts binding
|
||||
*/
|
||||
export default class EChartsReactCore extends PureComponent<EChartsReactProps> {
|
||||
/**
|
||||
* echarts render container
|
||||
*/
|
||||
ele: HTMLElement;
|
||||
/**
|
||||
* if this is the first time we are resizing
|
||||
*/
|
||||
private isInitialResize;
|
||||
/**
|
||||
* echarts library entry
|
||||
*/
|
||||
protected echarts: any;
|
||||
constructor(props: EChartsReactProps);
|
||||
componentDidMount(): void;
|
||||
componentDidUpdate(prevProps: EChartsReactProps): void;
|
||||
componentWillUnmount(): void;
|
||||
initEchartsInstance(): Promise<ECharts>;
|
||||
/**
|
||||
* return the existing echart object
|
||||
*/
|
||||
getEchartsInstance(): ECharts;
|
||||
/**
|
||||
* dispose echarts and clear size-sensor
|
||||
*/
|
||||
private dispose;
|
||||
/**
|
||||
* render a new echarts instance
|
||||
*/
|
||||
private renderNewEcharts;
|
||||
private bindEvents;
|
||||
private offEvents;
|
||||
/**
|
||||
* render the echarts
|
||||
*/
|
||||
private updateEChartsOption;
|
||||
/**
|
||||
* resize wrapper
|
||||
*/
|
||||
private resize;
|
||||
render(): JSX.Element;
|
||||
}
|
||||
Generated
Vendored
+221
@@ -0,0 +1,221 @@
|
||||
import { __assign, __awaiter, __extends, __generator, __rest } from "tslib";
|
||||
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';
|
||||
/**
|
||||
* core component for echarts binding
|
||||
*/
|
||||
var EChartsReactCore = /** @class */ (function (_super) {
|
||||
__extends(EChartsReactCore, _super);
|
||||
function EChartsReactCore(props) {
|
||||
var _this = _super.call(this, props) || this;
|
||||
_this.echarts = props.echarts;
|
||||
_this.ele = null;
|
||||
_this.isInitialResize = true;
|
||||
return _this;
|
||||
}
|
||||
EChartsReactCore.prototype.componentDidMount = function () {
|
||||
this.renderNewEcharts();
|
||||
};
|
||||
// update
|
||||
EChartsReactCore.prototype.componentDidUpdate = function (prevProps) {
|
||||
/**
|
||||
* if shouldSetOption return false, then return, not update echarts options
|
||||
* default is true
|
||||
*/
|
||||
var shouldSetOption = this.props.shouldSetOption;
|
||||
if (isFunction(shouldSetOption) && !shouldSetOption(prevProps, this.props)) {
|
||||
return;
|
||||
}
|
||||
// 以下属性修改的时候,需要 dispose 之后再新建
|
||||
// 1. 切换 theme 的时候
|
||||
// 2. 修改 opts 的时候
|
||||
if (!isEqual(prevProps.theme, this.props.theme) || !isEqual(prevProps.opts, this.props.opts)) {
|
||||
this.dispose();
|
||||
this.renderNewEcharts(); // 重建
|
||||
return;
|
||||
}
|
||||
// 修改 onEvent 的时候先移除历史事件再添加
|
||||
var echartsInstance = this.getEchartsInstance();
|
||||
if (!isEqual(prevProps.onEvents, this.props.onEvents)) {
|
||||
this.offEvents(echartsInstance, prevProps.onEvents);
|
||||
this.bindEvents(echartsInstance, this.props.onEvents);
|
||||
}
|
||||
// when these props are not isEqual, update echarts
|
||||
var pickKeys = ['option', 'notMerge', 'replaceMerge', 'lazyUpdate', 'showLoading', 'loadingOption'];
|
||||
if (!isEqual(pick(this.props, pickKeys), pick(prevProps, pickKeys))) {
|
||||
this.updateEChartsOption();
|
||||
}
|
||||
/**
|
||||
* when style or class name updated, change size.
|
||||
*/
|
||||
if (!isEqual(prevProps.style, this.props.style) || !isEqual(prevProps.className, this.props.className)) {
|
||||
this.resize();
|
||||
}
|
||||
};
|
||||
EChartsReactCore.prototype.componentWillUnmount = function () {
|
||||
this.dispose();
|
||||
};
|
||||
/*
|
||||
* initialise an echarts instance
|
||||
*/
|
||||
EChartsReactCore.prototype.initEchartsInstance = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
return [2 /*return*/, new Promise(function (resolve) {
|
||||
// create temporary echart instance
|
||||
_this.echarts.init(_this.ele, _this.props.theme, _this.props.opts);
|
||||
var echartsInstance = _this.getEchartsInstance();
|
||||
echartsInstance.on('finished', function () {
|
||||
// get final width and height
|
||||
var width = _this.ele.clientWidth;
|
||||
var height = _this.ele.clientHeight;
|
||||
// dispose temporary echart instance
|
||||
_this.echarts.dispose(_this.ele);
|
||||
// recreate echart instance
|
||||
// we use final width and height only if not originally provided as opts
|
||||
var opts = __assign({ width: width, height: height }, _this.props.opts);
|
||||
resolve(_this.echarts.init(_this.ele, _this.props.theme, opts));
|
||||
});
|
||||
})];
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* return the existing echart object
|
||||
*/
|
||||
EChartsReactCore.prototype.getEchartsInstance = function () {
|
||||
return this.echarts.getInstanceByDom(this.ele);
|
||||
};
|
||||
/**
|
||||
* dispose echarts and clear size-sensor
|
||||
*/
|
||||
EChartsReactCore.prototype.dispose = function () {
|
||||
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
|
||||
*/
|
||||
EChartsReactCore.prototype.renderNewEcharts = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _a, onEvents, onChartReady, _b, autoResize, echartsInstance;
|
||||
var _this = this;
|
||||
return __generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
_a = this.props, onEvents = _a.onEvents, onChartReady = _a.onChartReady, _b = _a.autoResize, autoResize = _b === void 0 ? true : _b;
|
||||
// 1. init echarts instance
|
||||
return [4 /*yield*/, this.initEchartsInstance()];
|
||||
case 1:
|
||||
// 1. init echarts instance
|
||||
_c.sent();
|
||||
echartsInstance = this.updateEChartsOption();
|
||||
// 3. bind events
|
||||
this.bindEvents(echartsInstance, onEvents || {});
|
||||
// 4. on chart ready
|
||||
if (isFunction(onChartReady))
|
||||
onChartReady(echartsInstance);
|
||||
// 5. on resize
|
||||
if (this.ele && autoResize) {
|
||||
bind(this.ele, function () {
|
||||
_this.resize();
|
||||
});
|
||||
}
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
// bind the events
|
||||
EChartsReactCore.prototype.bindEvents = function (instance, events) {
|
||||
function _bindEvent(eventName, func) {
|
||||
// ignore the event config which not satisfy
|
||||
if (isString(eventName) && isFunction(func)) {
|
||||
// binding event
|
||||
instance.on(eventName, function (param) {
|
||||
func(param, instance);
|
||||
});
|
||||
}
|
||||
}
|
||||
// loop and bind
|
||||
for (var eventName in events) {
|
||||
if (Object.prototype.hasOwnProperty.call(events, eventName)) {
|
||||
_bindEvent(eventName, events[eventName]);
|
||||
}
|
||||
}
|
||||
};
|
||||
// off the events
|
||||
EChartsReactCore.prototype.offEvents = function (instance, events) {
|
||||
if (!events)
|
||||
return;
|
||||
// loop and off
|
||||
for (var eventName in events) {
|
||||
if (isString(eventName)) {
|
||||
instance.off(eventName, events[eventName]);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* render the echarts
|
||||
*/
|
||||
EChartsReactCore.prototype.updateEChartsOption = function () {
|
||||
var _a = this.props, option = _a.option, _b = _a.notMerge, notMerge = _b === void 0 ? false : _b, _c = _a.replaceMerge, replaceMerge = _c === void 0 ? null : _c, _d = _a.lazyUpdate, lazyUpdate = _d === void 0 ? false : _d, showLoading = _a.showLoading, _e = _a.loadingOption, loadingOption = _e === void 0 ? null : _e;
|
||||
// 1. get or initial the echarts object
|
||||
var echartInstance = this.getEchartsInstance();
|
||||
// 2. set the echarts option
|
||||
echartInstance.setOption(option, { notMerge: notMerge, replaceMerge: replaceMerge, lazyUpdate: lazyUpdate });
|
||||
// 3. set loading mask
|
||||
if (showLoading)
|
||||
echartInstance.showLoading(loadingOption);
|
||||
else
|
||||
echartInstance.hideLoading();
|
||||
return echartInstance;
|
||||
};
|
||||
/**
|
||||
* resize wrapper
|
||||
*/
|
||||
EChartsReactCore.prototype.resize = function () {
|
||||
// 1. get the echarts object
|
||||
var echartsInstance = this.getEchartsInstance();
|
||||
// 2. call echarts instance resize if not the initial resize
|
||||
// resize should not happen on first render as it will cancel initial echarts animations
|
||||
if (!this.isInitialResize) {
|
||||
try {
|
||||
echartsInstance.resize({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
// 3. update variable for future calls
|
||||
this.isInitialResize = false;
|
||||
};
|
||||
EChartsReactCore.prototype.render = function () {
|
||||
var _this = this;
|
||||
var _a = this.props, style = _a.style, _b = _a.className, className = _b === void 0 ? '' : _b, echarts = _a.echarts, option = _a.option, theme = _a.theme, notMerge = _a.notMerge, replaceMerge = _a.replaceMerge, lazyUpdate = _a.lazyUpdate, showLoading = _a.showLoading, loadingOption = _a.loadingOption, opts = _a.opts, onChartReady = _a.onChartReady, onEvents = _a.onEvents, shouldSetOption = _a.shouldSetOption, autoResize = _a.autoResize, divHTMLAttributes = __rest(_a, ["style", "className", "echarts", "option", "theme", "notMerge", "replaceMerge", "lazyUpdate", "showLoading", "loadingOption", "opts", "onChartReady", "onEvents", "shouldSetOption", "autoResize"]);
|
||||
// default height = 300
|
||||
var newStyle = __assign({ height: 300 }, style);
|
||||
return (React.createElement("div", __assign({ ref: function (e) {
|
||||
_this.ele = e;
|
||||
}, style: newStyle, className: "echarts-for-react ".concat(className) }, divHTMLAttributes)));
|
||||
};
|
||||
return EChartsReactCore;
|
||||
}(PureComponent));
|
||||
export default EChartsReactCore;
|
||||
//# sourceMappingURL=core.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import isEqual from 'fast-deep-equal';
|
||||
export { isEqual };
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import isEqual from 'fast-deep-equal';
|
||||
export { isEqual };
|
||||
//# sourceMappingURL=is-equal.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-equal.js","sourceRoot":"","sources":["../../src/helper/is-equal.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,iBAAiB,CAAC;AAEtC,OAAO,EAAE,OAAO,EAAE,CAAC","sourcesContent":["import isEqual from 'fast-deep-equal';\n\nexport { isEqual };\n"]}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare function isFunction(v: any): boolean;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
export function isFunction(v) {
|
||||
return typeof v === 'function';
|
||||
}
|
||||
//# sourceMappingURL=is-function.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-function.js","sourceRoot":"","sources":["../../src/helper/is-function.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,CAAM;IAC/B,OAAO,OAAO,CAAC,KAAK,UAAU,CAAC;AACjC,CAAC","sourcesContent":["export function isFunction(v: any): boolean {\n return typeof v === 'function';\n}\n"]}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare function isString(v: any): boolean;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
export function isString(v) {
|
||||
return typeof v === 'string';
|
||||
}
|
||||
//# sourceMappingURL=is-string.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-string.js","sourceRoot":"","sources":["../../src/helper/is-string.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,CAAM;IAC7B,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC;AAC/B,CAAC","sourcesContent":["export function isString(v: any): boolean {\n return typeof v === 'string';\n}\n"]}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 保留 object 中的部分内容
|
||||
* @param obj
|
||||
* @param keys
|
||||
*/
|
||||
export declare function pick<T extends object>(obj: T, keys: readonly (keyof T)[]): Partial<T>;
|
||||
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* 保留 object 中的部分内容
|
||||
* @param obj
|
||||
* @param keys
|
||||
*/
|
||||
export function pick(obj, keys) {
|
||||
var r = {};
|
||||
keys.forEach(function (key) {
|
||||
r[key] = obj[key];
|
||||
});
|
||||
return r;
|
||||
}
|
||||
//# sourceMappingURL=pick.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../../src/helper/pick.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAmB,GAAM,EAAE,IAA0B;IACvE,IAAM,CAAC,GAAG,EAAgB,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,UAAC,GAAG;QACf,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,CAAC;AACX,CAAC","sourcesContent":["/**\n * 保留 object 中的部分内容\n * @param obj\n * @param keys\n */\nexport function pick<T extends object>(obj: T, keys: readonly (keyof T)[]): Partial<T> {\n const r = {} as Partial<T>;\n keys.forEach((key) => {\n r[key] = obj[key];\n });\n return r;\n}\n"]}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { EChartsReactProps, EChartsOption, EChartsInstance } from './types';
|
||||
import EChartsReactCore from './core';
|
||||
export type { EChartsReactProps, EChartsOption, EChartsInstance };
|
||||
export default class EChartsReact extends EChartsReactCore {
|
||||
constructor(props: EChartsReactProps);
|
||||
}
|
||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
import { __extends } from "tslib";
|
||||
import * as echarts from 'echarts';
|
||||
import EChartsReactCore from './core';
|
||||
// export the Component the echarts Object.
|
||||
var EChartsReact = /** @class */ (function (_super) {
|
||||
__extends(EChartsReact, _super);
|
||||
function EChartsReact(props) {
|
||||
var _this = _super.call(this, props) || this;
|
||||
// 初始化为 echarts 整个包
|
||||
_this.echarts = echarts;
|
||||
return _this;
|
||||
}
|
||||
return EChartsReact;
|
||||
}(EChartsReactCore));
|
||||
export default EChartsReact;
|
||||
//# sourceMappingURL=index.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,OAAO,gBAAgB,MAAM,QAAQ,CAAC;AAItC,2CAA2C;AAC3C;IAA0C,gCAAgB;IACxD,sBAAY,KAAwB;QAApC,YACE,kBAAM,KAAK,CAAC,SAIb;QAFC,mBAAmB;QACnB,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;;IACzB,CAAC;IACH,mBAAC;AAAD,CAAC,AAPD,CAA0C,gBAAgB,GAOzD","sourcesContent":["import * as echarts from 'echarts';\nimport { EChartsReactProps, EChartsOption, EChartsInstance } from './types';\nimport EChartsReactCore from './core';\n\nexport type { EChartsReactProps, EChartsOption, EChartsInstance };\n\n// export the Component the echarts Object.\nexport default class EChartsReact extends EChartsReactCore {\n constructor(props: EChartsReactProps) {\n super(props);\n\n // 初始化为 echarts 整个包\n this.echarts = echarts;\n }\n}\n"]}
|
||||
Generated
Vendored
+70
@@ -0,0 +1,70 @@
|
||||
/// <reference types="react" />
|
||||
import type { EChartsType } from 'echarts';
|
||||
/**
|
||||
* Solve the type conflict caused by multiple type files
|
||||
*/
|
||||
export type EChartsOption = any;
|
||||
export type EChartsInstance = EChartsType;
|
||||
export type Opts = {
|
||||
readonly devicePixelRatio?: number;
|
||||
readonly renderer?: 'canvas' | 'svg';
|
||||
readonly width?: number | null | undefined | 'auto';
|
||||
readonly height?: number | null | undefined | 'auto';
|
||||
readonly locale?: string;
|
||||
};
|
||||
export type EChartsReactProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
/**
|
||||
* echarts library entry, use it for import necessary.
|
||||
*/
|
||||
readonly echarts?: any;
|
||||
/**
|
||||
* echarts option
|
||||
*/
|
||||
readonly option: EChartsOption;
|
||||
/**
|
||||
* echarts theme config, can be:
|
||||
* 1. theme name string
|
||||
* 2. theme object
|
||||
*/
|
||||
readonly theme?: string | Record<string, any>;
|
||||
/**
|
||||
* notMerge config for echarts, default is `false`
|
||||
*/
|
||||
readonly notMerge?: boolean;
|
||||
/**
|
||||
* replaceMerge config for echarts, default is `null`
|
||||
*/
|
||||
readonly replaceMerge?: string | string[];
|
||||
/**
|
||||
* 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 render, do the callback with echarts instance
|
||||
*/
|
||||
readonly onChartReady?: (instance: EChartsInstance) => void;
|
||||
/**
|
||||
* bind events, default is `{}`
|
||||
*/
|
||||
readonly onEvents?: Record<string, Function>;
|
||||
/**
|
||||
* should update echarts options
|
||||
*/
|
||||
readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean;
|
||||
/**
|
||||
* should trigger resize when window resize
|
||||
*/
|
||||
readonly autoResize?: boolean;
|
||||
};
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
export {};
|
||||
//# sourceMappingURL=types.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { EChartsType } from 'echarts';\n\n/**\n * Solve the type conflict caused by multiple type files\n */\nexport type EChartsOption = any;\n\nexport type EChartsInstance = EChartsType;\n\nexport type Opts = {\n readonly devicePixelRatio?: number;\n readonly renderer?: 'canvas' | 'svg';\n readonly width?: number | null | undefined | 'auto';\n readonly height?: number | null | undefined | 'auto';\n readonly locale?: string;\n};\n\nexport type EChartsReactProps = React.HTMLAttributes<HTMLDivElement> & {\n /**\n * echarts library entry, use it for import necessary.\n */\n readonly echarts?: any;\n /**\n * echarts option\n */\n readonly option: EChartsOption;\n /**\n * echarts theme config, can be:\n * 1. theme name string\n * 2. theme object\n */\n readonly theme?: string | Record<string, any>;\n /**\n * notMerge config for echarts, default is `false`\n */\n readonly notMerge?: boolean;\n /**\n * replaceMerge config for echarts, default is `null`\n */\n readonly replaceMerge?: string | string[];\n /**\n * lazyUpdate config for echarts, default is `false`\n */\n readonly lazyUpdate?: boolean;\n /**\n * showLoading config for echarts, default is `false`\n */\n readonly showLoading?: boolean;\n /**\n * loadingOption config for echarts, default is `null`\n */\n readonly loadingOption?: any;\n /**\n * echarts opts config, default is `{}`\n */\n readonly opts?: Opts;\n /**\n * when after chart render, do the callback with echarts instance\n */\n readonly onChartReady?: (instance: EChartsInstance) => void;\n /**\n * bind events, default is `{}`\n */\n readonly onEvents?: Record<string, Function>;\n /**\n * should update echarts options\n */\n readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean;\n\n /**\n * should trigger resize when window resize\n */\n readonly autoResize?: boolean;\n};\n"]}
|
||||
Generated
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
import type { ECharts } from 'echarts';
|
||||
import { PureComponent } from 'react';
|
||||
import { EChartsReactProps } from './types';
|
||||
/**
|
||||
* core component for echarts binding
|
||||
*/
|
||||
export default class EChartsReactCore extends PureComponent<EChartsReactProps> {
|
||||
/**
|
||||
* echarts render container
|
||||
*/
|
||||
ele: HTMLElement;
|
||||
/**
|
||||
* if this is the first time we are resizing
|
||||
*/
|
||||
private isInitialResize;
|
||||
/**
|
||||
* echarts library entry
|
||||
*/
|
||||
protected echarts: any;
|
||||
constructor(props: EChartsReactProps);
|
||||
componentDidMount(): void;
|
||||
componentDidUpdate(prevProps: EChartsReactProps): void;
|
||||
componentWillUnmount(): void;
|
||||
initEchartsInstance(): Promise<ECharts>;
|
||||
/**
|
||||
* return the existing echart object
|
||||
*/
|
||||
getEchartsInstance(): ECharts;
|
||||
/**
|
||||
* dispose echarts and clear size-sensor
|
||||
*/
|
||||
private dispose;
|
||||
/**
|
||||
* render a new echarts instance
|
||||
*/
|
||||
private renderNewEcharts;
|
||||
private bindEvents;
|
||||
private offEvents;
|
||||
/**
|
||||
* render the echarts
|
||||
*/
|
||||
private updateEChartsOption;
|
||||
/**
|
||||
* resize wrapper
|
||||
*/
|
||||
private resize;
|
||||
render(): JSX.Element;
|
||||
}
|
||||
Generated
Vendored
+223
@@ -0,0 +1,223 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var tslib_1 = require("tslib");
|
||||
var react_1 = tslib_1.__importStar(require("react"));
|
||||
var size_sensor_1 = require("size-sensor");
|
||||
var pick_1 = require("./helper/pick");
|
||||
var is_function_1 = require("./helper/is-function");
|
||||
var is_string_1 = require("./helper/is-string");
|
||||
var is_equal_1 = require("./helper/is-equal");
|
||||
/**
|
||||
* core component for echarts binding
|
||||
*/
|
||||
var EChartsReactCore = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(EChartsReactCore, _super);
|
||||
function EChartsReactCore(props) {
|
||||
var _this = _super.call(this, props) || this;
|
||||
_this.echarts = props.echarts;
|
||||
_this.ele = null;
|
||||
_this.isInitialResize = true;
|
||||
return _this;
|
||||
}
|
||||
EChartsReactCore.prototype.componentDidMount = function () {
|
||||
this.renderNewEcharts();
|
||||
};
|
||||
// update
|
||||
EChartsReactCore.prototype.componentDidUpdate = function (prevProps) {
|
||||
/**
|
||||
* if shouldSetOption return false, then return, not update echarts options
|
||||
* default is true
|
||||
*/
|
||||
var shouldSetOption = this.props.shouldSetOption;
|
||||
if ((0, is_function_1.isFunction)(shouldSetOption) && !shouldSetOption(prevProps, this.props)) {
|
||||
return;
|
||||
}
|
||||
// 以下属性修改的时候,需要 dispose 之后再新建
|
||||
// 1. 切换 theme 的时候
|
||||
// 2. 修改 opts 的时候
|
||||
if (!(0, is_equal_1.isEqual)(prevProps.theme, this.props.theme) || !(0, is_equal_1.isEqual)(prevProps.opts, this.props.opts)) {
|
||||
this.dispose();
|
||||
this.renderNewEcharts(); // 重建
|
||||
return;
|
||||
}
|
||||
// 修改 onEvent 的时候先移除历史事件再添加
|
||||
var echartsInstance = this.getEchartsInstance();
|
||||
if (!(0, is_equal_1.isEqual)(prevProps.onEvents, this.props.onEvents)) {
|
||||
this.offEvents(echartsInstance, prevProps.onEvents);
|
||||
this.bindEvents(echartsInstance, this.props.onEvents);
|
||||
}
|
||||
// when these props are not isEqual, update echarts
|
||||
var pickKeys = ['option', 'notMerge', 'replaceMerge', 'lazyUpdate', 'showLoading', 'loadingOption'];
|
||||
if (!(0, is_equal_1.isEqual)((0, pick_1.pick)(this.props, pickKeys), (0, pick_1.pick)(prevProps, pickKeys))) {
|
||||
this.updateEChartsOption();
|
||||
}
|
||||
/**
|
||||
* when style or class name updated, change size.
|
||||
*/
|
||||
if (!(0, is_equal_1.isEqual)(prevProps.style, this.props.style) || !(0, is_equal_1.isEqual)(prevProps.className, this.props.className)) {
|
||||
this.resize();
|
||||
}
|
||||
};
|
||||
EChartsReactCore.prototype.componentWillUnmount = function () {
|
||||
this.dispose();
|
||||
};
|
||||
/*
|
||||
* initialise an echarts instance
|
||||
*/
|
||||
EChartsReactCore.prototype.initEchartsInstance = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var _this = this;
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
return [2 /*return*/, new Promise(function (resolve) {
|
||||
// create temporary echart instance
|
||||
_this.echarts.init(_this.ele, _this.props.theme, _this.props.opts);
|
||||
var echartsInstance = _this.getEchartsInstance();
|
||||
echartsInstance.on('finished', function () {
|
||||
// get final width and height
|
||||
var width = _this.ele.clientWidth;
|
||||
var height = _this.ele.clientHeight;
|
||||
// dispose temporary echart instance
|
||||
_this.echarts.dispose(_this.ele);
|
||||
// recreate echart instance
|
||||
// we use final width and height only if not originally provided as opts
|
||||
var opts = tslib_1.__assign({ width: width, height: height }, _this.props.opts);
|
||||
resolve(_this.echarts.init(_this.ele, _this.props.theme, opts));
|
||||
});
|
||||
})];
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* return the existing echart object
|
||||
*/
|
||||
EChartsReactCore.prototype.getEchartsInstance = function () {
|
||||
return this.echarts.getInstanceByDom(this.ele);
|
||||
};
|
||||
/**
|
||||
* dispose echarts and clear size-sensor
|
||||
*/
|
||||
EChartsReactCore.prototype.dispose = function () {
|
||||
if (this.ele) {
|
||||
try {
|
||||
(0, size_sensor_1.clear)(this.ele);
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
// dispose echarts instance
|
||||
this.echarts.dispose(this.ele);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* render a new echarts instance
|
||||
*/
|
||||
EChartsReactCore.prototype.renderNewEcharts = function () {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||||
var _a, onEvents, onChartReady, _b, autoResize, echartsInstance;
|
||||
var _this = this;
|
||||
return tslib_1.__generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
_a = this.props, onEvents = _a.onEvents, onChartReady = _a.onChartReady, _b = _a.autoResize, autoResize = _b === void 0 ? true : _b;
|
||||
// 1. init echarts instance
|
||||
return [4 /*yield*/, this.initEchartsInstance()];
|
||||
case 1:
|
||||
// 1. init echarts instance
|
||||
_c.sent();
|
||||
echartsInstance = this.updateEChartsOption();
|
||||
// 3. bind events
|
||||
this.bindEvents(echartsInstance, onEvents || {});
|
||||
// 4. on chart ready
|
||||
if ((0, is_function_1.isFunction)(onChartReady))
|
||||
onChartReady(echartsInstance);
|
||||
// 5. on resize
|
||||
if (this.ele && autoResize) {
|
||||
(0, size_sensor_1.bind)(this.ele, function () {
|
||||
_this.resize();
|
||||
});
|
||||
}
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
// bind the events
|
||||
EChartsReactCore.prototype.bindEvents = function (instance, events) {
|
||||
function _bindEvent(eventName, func) {
|
||||
// ignore the event config which not satisfy
|
||||
if ((0, is_string_1.isString)(eventName) && (0, is_function_1.isFunction)(func)) {
|
||||
// binding event
|
||||
instance.on(eventName, function (param) {
|
||||
func(param, instance);
|
||||
});
|
||||
}
|
||||
}
|
||||
// loop and bind
|
||||
for (var eventName in events) {
|
||||
if (Object.prototype.hasOwnProperty.call(events, eventName)) {
|
||||
_bindEvent(eventName, events[eventName]);
|
||||
}
|
||||
}
|
||||
};
|
||||
// off the events
|
||||
EChartsReactCore.prototype.offEvents = function (instance, events) {
|
||||
if (!events)
|
||||
return;
|
||||
// loop and off
|
||||
for (var eventName in events) {
|
||||
if ((0, is_string_1.isString)(eventName)) {
|
||||
instance.off(eventName, events[eventName]);
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* render the echarts
|
||||
*/
|
||||
EChartsReactCore.prototype.updateEChartsOption = function () {
|
||||
var _a = this.props, option = _a.option, _b = _a.notMerge, notMerge = _b === void 0 ? false : _b, _c = _a.replaceMerge, replaceMerge = _c === void 0 ? null : _c, _d = _a.lazyUpdate, lazyUpdate = _d === void 0 ? false : _d, showLoading = _a.showLoading, _e = _a.loadingOption, loadingOption = _e === void 0 ? null : _e;
|
||||
// 1. get or initial the echarts object
|
||||
var echartInstance = this.getEchartsInstance();
|
||||
// 2. set the echarts option
|
||||
echartInstance.setOption(option, { notMerge: notMerge, replaceMerge: replaceMerge, lazyUpdate: lazyUpdate });
|
||||
// 3. set loading mask
|
||||
if (showLoading)
|
||||
echartInstance.showLoading(loadingOption);
|
||||
else
|
||||
echartInstance.hideLoading();
|
||||
return echartInstance;
|
||||
};
|
||||
/**
|
||||
* resize wrapper
|
||||
*/
|
||||
EChartsReactCore.prototype.resize = function () {
|
||||
// 1. get the echarts object
|
||||
var echartsInstance = this.getEchartsInstance();
|
||||
// 2. call echarts instance resize if not the initial resize
|
||||
// resize should not happen on first render as it will cancel initial echarts animations
|
||||
if (!this.isInitialResize) {
|
||||
try {
|
||||
echartsInstance.resize({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
// 3. update variable for future calls
|
||||
this.isInitialResize = false;
|
||||
};
|
||||
EChartsReactCore.prototype.render = function () {
|
||||
var _this = this;
|
||||
var _a = this.props, style = _a.style, _b = _a.className, className = _b === void 0 ? '' : _b, echarts = _a.echarts, option = _a.option, theme = _a.theme, notMerge = _a.notMerge, replaceMerge = _a.replaceMerge, lazyUpdate = _a.lazyUpdate, showLoading = _a.showLoading, loadingOption = _a.loadingOption, opts = _a.opts, onChartReady = _a.onChartReady, onEvents = _a.onEvents, shouldSetOption = _a.shouldSetOption, autoResize = _a.autoResize, divHTMLAttributes = tslib_1.__rest(_a, ["style", "className", "echarts", "option", "theme", "notMerge", "replaceMerge", "lazyUpdate", "showLoading", "loadingOption", "opts", "onChartReady", "onEvents", "shouldSetOption", "autoResize"]);
|
||||
// default height = 300
|
||||
var newStyle = tslib_1.__assign({ height: 300 }, style);
|
||||
return (react_1.default.createElement("div", tslib_1.__assign({ ref: function (e) {
|
||||
_this.ele = e;
|
||||
}, style: newStyle, className: "echarts-for-react ".concat(className) }, divHTMLAttributes)));
|
||||
};
|
||||
return EChartsReactCore;
|
||||
}(react_1.PureComponent));
|
||||
exports.default = EChartsReactCore;
|
||||
//# sourceMappingURL=core.js.map
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import isEqual from 'fast-deep-equal';
|
||||
export { isEqual };
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isEqual = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var fast_deep_equal_1 = tslib_1.__importDefault(require("fast-deep-equal"));
|
||||
exports.isEqual = fast_deep_equal_1.default;
|
||||
//# sourceMappingURL=is-equal.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-equal.js","sourceRoot":"","sources":["../../src/helper/is-equal.ts"],"names":[],"mappings":";;;;AAAA,4EAAsC;AAE7B,kBAFF,yBAAO,CAEE","sourcesContent":["import isEqual from 'fast-deep-equal';\n\nexport { isEqual };\n"]}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare function isFunction(v: any): boolean;
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isFunction = void 0;
|
||||
function isFunction(v) {
|
||||
return typeof v === 'function';
|
||||
}
|
||||
exports.isFunction = isFunction;
|
||||
//# sourceMappingURL=is-function.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-function.js","sourceRoot":"","sources":["../../src/helper/is-function.ts"],"names":[],"mappings":";;;AAAA,SAAgB,UAAU,CAAC,CAAM;IAC/B,OAAO,OAAO,CAAC,KAAK,UAAU,CAAC;AACjC,CAAC;AAFD,gCAEC","sourcesContent":["export function isFunction(v: any): boolean {\n return typeof v === 'function';\n}\n"]}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare function isString(v: any): boolean;
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isString = void 0;
|
||||
function isString(v) {
|
||||
return typeof v === 'string';
|
||||
}
|
||||
exports.isString = isString;
|
||||
//# sourceMappingURL=is-string.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"is-string.js","sourceRoot":"","sources":["../../src/helper/is-string.ts"],"names":[],"mappings":";;;AAAA,SAAgB,QAAQ,CAAC,CAAM;IAC7B,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC;AAC/B,CAAC;AAFD,4BAEC","sourcesContent":["export function isString(v: any): boolean {\n return typeof v === 'string';\n}\n"]}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* 保留 object 中的部分内容
|
||||
* @param obj
|
||||
* @param keys
|
||||
*/
|
||||
export declare function pick<T extends object>(obj: T, keys: readonly (keyof T)[]): Partial<T>;
|
||||
Generated
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.pick = void 0;
|
||||
/**
|
||||
* 保留 object 中的部分内容
|
||||
* @param obj
|
||||
* @param keys
|
||||
*/
|
||||
function pick(obj, keys) {
|
||||
var r = {};
|
||||
keys.forEach(function (key) {
|
||||
r[key] = obj[key];
|
||||
});
|
||||
return r;
|
||||
}
|
||||
exports.pick = pick;
|
||||
//# sourceMappingURL=pick.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pick.js","sourceRoot":"","sources":["../../src/helper/pick.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,SAAgB,IAAI,CAAmB,GAAM,EAAE,IAA0B;IACvE,IAAM,CAAC,GAAG,EAAgB,CAAC;IAC3B,IAAI,CAAC,OAAO,CAAC,UAAC,GAAG;QACf,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,CAAC;AACX,CAAC;AAND,oBAMC","sourcesContent":["/**\n * 保留 object 中的部分内容\n * @param obj\n * @param keys\n */\nexport function pick<T extends object>(obj: T, keys: readonly (keyof T)[]): Partial<T> {\n const r = {} as Partial<T>;\n keys.forEach((key) => {\n r[key] = obj[key];\n });\n return r;\n}\n"]}
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { EChartsReactProps, EChartsOption, EChartsInstance } from './types';
|
||||
import EChartsReactCore from './core';
|
||||
export type { EChartsReactProps, EChartsOption, EChartsInstance };
|
||||
export default class EChartsReact extends EChartsReactCore {
|
||||
constructor(props: EChartsReactProps);
|
||||
}
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var tslib_1 = require("tslib");
|
||||
var echarts = tslib_1.__importStar(require("echarts"));
|
||||
var core_1 = tslib_1.__importDefault(require("./core"));
|
||||
// export the Component the echarts Object.
|
||||
var EChartsReact = /** @class */ (function (_super) {
|
||||
tslib_1.__extends(EChartsReact, _super);
|
||||
function EChartsReact(props) {
|
||||
var _this = _super.call(this, props) || this;
|
||||
// 初始化为 echarts 整个包
|
||||
_this.echarts = echarts;
|
||||
return _this;
|
||||
}
|
||||
return EChartsReact;
|
||||
}(core_1.default));
|
||||
exports.default = EChartsReact;
|
||||
//# sourceMappingURL=index.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uDAAmC;AAEnC,wDAAsC;AAItC,2CAA2C;AAC3C;IAA0C,wCAAgB;IACxD,sBAAY,KAAwB;QAApC,YACE,kBAAM,KAAK,CAAC,SAIb;QAFC,mBAAmB;QACnB,KAAI,CAAC,OAAO,GAAG,OAAO,CAAC;;IACzB,CAAC;IACH,mBAAC;AAAD,CAAC,AAPD,CAA0C,cAAgB,GAOzD","sourcesContent":["import * as echarts from 'echarts';\nimport { EChartsReactProps, EChartsOption, EChartsInstance } from './types';\nimport EChartsReactCore from './core';\n\nexport type { EChartsReactProps, EChartsOption, EChartsInstance };\n\n// export the Component the echarts Object.\nexport default class EChartsReact extends EChartsReactCore {\n constructor(props: EChartsReactProps) {\n super(props);\n\n // 初始化为 echarts 整个包\n this.echarts = echarts;\n }\n}\n"]}
|
||||
Generated
Vendored
+70
@@ -0,0 +1,70 @@
|
||||
/// <reference types="react" />
|
||||
import type { EChartsType } from 'echarts';
|
||||
/**
|
||||
* Solve the type conflict caused by multiple type files
|
||||
*/
|
||||
export type EChartsOption = any;
|
||||
export type EChartsInstance = EChartsType;
|
||||
export type Opts = {
|
||||
readonly devicePixelRatio?: number;
|
||||
readonly renderer?: 'canvas' | 'svg';
|
||||
readonly width?: number | null | undefined | 'auto';
|
||||
readonly height?: number | null | undefined | 'auto';
|
||||
readonly locale?: string;
|
||||
};
|
||||
export type EChartsReactProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
/**
|
||||
* echarts library entry, use it for import necessary.
|
||||
*/
|
||||
readonly echarts?: any;
|
||||
/**
|
||||
* echarts option
|
||||
*/
|
||||
readonly option: EChartsOption;
|
||||
/**
|
||||
* echarts theme config, can be:
|
||||
* 1. theme name string
|
||||
* 2. theme object
|
||||
*/
|
||||
readonly theme?: string | Record<string, any>;
|
||||
/**
|
||||
* notMerge config for echarts, default is `false`
|
||||
*/
|
||||
readonly notMerge?: boolean;
|
||||
/**
|
||||
* replaceMerge config for echarts, default is `null`
|
||||
*/
|
||||
readonly replaceMerge?: string | string[];
|
||||
/**
|
||||
* 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 render, do the callback with echarts instance
|
||||
*/
|
||||
readonly onChartReady?: (instance: EChartsInstance) => void;
|
||||
/**
|
||||
* bind events, default is `{}`
|
||||
*/
|
||||
readonly onEvents?: Record<string, Function>;
|
||||
/**
|
||||
* should update echarts options
|
||||
*/
|
||||
readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean;
|
||||
/**
|
||||
* should trigger resize when window resize
|
||||
*/
|
||||
readonly autoResize?: boolean;
|
||||
};
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=types.js.map
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { EChartsType } from 'echarts';\n\n/**\n * Solve the type conflict caused by multiple type files\n */\nexport type EChartsOption = any;\n\nexport type EChartsInstance = EChartsType;\n\nexport type Opts = {\n readonly devicePixelRatio?: number;\n readonly renderer?: 'canvas' | 'svg';\n readonly width?: number | null | undefined | 'auto';\n readonly height?: number | null | undefined | 'auto';\n readonly locale?: string;\n};\n\nexport type EChartsReactProps = React.HTMLAttributes<HTMLDivElement> & {\n /**\n * echarts library entry, use it for import necessary.\n */\n readonly echarts?: any;\n /**\n * echarts option\n */\n readonly option: EChartsOption;\n /**\n * echarts theme config, can be:\n * 1. theme name string\n * 2. theme object\n */\n readonly theme?: string | Record<string, any>;\n /**\n * notMerge config for echarts, default is `false`\n */\n readonly notMerge?: boolean;\n /**\n * replaceMerge config for echarts, default is `null`\n */\n readonly replaceMerge?: string | string[];\n /**\n * lazyUpdate config for echarts, default is `false`\n */\n readonly lazyUpdate?: boolean;\n /**\n * showLoading config for echarts, default is `false`\n */\n readonly showLoading?: boolean;\n /**\n * loadingOption config for echarts, default is `null`\n */\n readonly loadingOption?: any;\n /**\n * echarts opts config, default is `{}`\n */\n readonly opts?: Opts;\n /**\n * when after chart render, do the callback with echarts instance\n */\n readonly onChartReady?: (instance: EChartsInstance) => void;\n /**\n * bind events, default is `{}`\n */\n readonly onEvents?: Record<string, Function>;\n /**\n * should update echarts options\n */\n readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean;\n\n /**\n * should trigger resize when window resize\n */\n readonly autoResize?: boolean;\n};\n"]}
|
||||
Generated
Vendored
+116
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"name": "echarts-for-react",
|
||||
"version": "3.0.5",
|
||||
"description": " Apache Echarts components for React.",
|
||||
"main": "lib/index.js",
|
||||
"module": "esm/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
"files": [
|
||||
"lib",
|
||||
"esm",
|
||||
"src"
|
||||
],
|
||||
"scripts": {
|
||||
"docs:dev": "NODE_ENV=development dumi dev",
|
||||
"docs:build": "NODE_ENV=production dumi build",
|
||||
"docs:deploy": "rimraf dist && npm run docs:build && gh-pages -d dist",
|
||||
"start": "npm run docs:dev",
|
||||
"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": "^12.0.0",
|
||||
"@commitlint/config-angular": "^12.0.0",
|
||||
"@types/jest": "^24.0.0",
|
||||
"@types/node": "^14.14.31",
|
||||
"@types/react": "^17.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
||||
"@typescript-eslint/parser": "^4.15.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"dumi": "^1.1.6",
|
||||
"dumi-theme-default": "^1.0.6",
|
||||
"echarts": "^6.0.0",
|
||||
"echarts-gl": "^2.0.2",
|
||||
"eslint": "^7.20.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"gh-pages": "^3.1.0",
|
||||
"husky": "^5.1.1",
|
||||
"jest": "^24.0.0",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-electron": "^0.1.11",
|
||||
"lint-md-cli": "^0.1.2",
|
||||
"lint-staged": "^10.5.4",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"miz": "^1.0.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.2.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ts-jest": "^24.0.2",
|
||||
"ts-loader": "^8.0.17",
|
||||
"typescript": "^4.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"size-sensor": "^1.0.1",
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.0.0 || >=16.0.0",
|
||||
"echarts": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.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"
|
||||
]
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+275
@@ -0,0 +1,275 @@
|
||||
import type { ECharts } from 'echarts';
|
||||
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<EChartsReactProps> {
|
||||
/**
|
||||
* echarts render container
|
||||
*/
|
||||
public ele: HTMLElement;
|
||||
|
||||
/**
|
||||
* if this is the first time we are resizing
|
||||
*/
|
||||
private isInitialResize: boolean;
|
||||
|
||||
/**
|
||||
* echarts library entry
|
||||
*/
|
||||
protected echarts: any;
|
||||
|
||||
constructor(props: EChartsReactProps) {
|
||||
super(props);
|
||||
|
||||
this.echarts = props.echarts;
|
||||
this.ele = null;
|
||||
this.isInitialResize = true;
|
||||
}
|
||||
|
||||
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 的时候
|
||||
if (!isEqual(prevProps.theme, this.props.theme) || !isEqual(prevProps.opts, this.props.opts)) {
|
||||
this.dispose();
|
||||
|
||||
this.renderNewEcharts(); // 重建
|
||||
return;
|
||||
}
|
||||
|
||||
// 修改 onEvent 的时候先移除历史事件再添加
|
||||
const echartsInstance = this.getEchartsInstance();
|
||||
if (!isEqual(prevProps.onEvents, this.props.onEvents)) {
|
||||
this.offEvents(echartsInstance, prevProps.onEvents);
|
||||
this.bindEvents(echartsInstance, this.props.onEvents);
|
||||
}
|
||||
|
||||
// when these props are not isEqual, update echarts
|
||||
const pickKeys = ['option', 'notMerge', 'replaceMerge', 'lazyUpdate', 'showLoading', 'loadingOption'] as const;
|
||||
if (!isEqual(pick(this.props, pickKeys), pick(prevProps as any, pickKeys))) {
|
||||
this.updateEChartsOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* when style or class name updated, change size.
|
||||
*/
|
||||
if (!isEqual(prevProps.style, this.props.style) || !isEqual(prevProps.className, this.props.className)) {
|
||||
this.resize();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
/*
|
||||
* initialise an echarts instance
|
||||
*/
|
||||
public async initEchartsInstance(): Promise<ECharts> {
|
||||
return new Promise((resolve) => {
|
||||
// create temporary echart instance
|
||||
this.echarts.init(this.ele, this.props.theme, this.props.opts);
|
||||
const echartsInstance = this.getEchartsInstance();
|
||||
|
||||
echartsInstance.on('finished', () => {
|
||||
// get final width and height
|
||||
const width = this.ele.clientWidth;
|
||||
const height = this.ele.clientHeight;
|
||||
|
||||
// dispose temporary echart instance
|
||||
this.echarts.dispose(this.ele);
|
||||
|
||||
// recreate echart instance
|
||||
// we use final width and height only if not originally provided as opts
|
||||
const opts = {
|
||||
width,
|
||||
height,
|
||||
...this.props.opts,
|
||||
};
|
||||
resolve(this.echarts.init(this.ele, this.props.theme, opts));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* return the existing echart object
|
||||
*/
|
||||
public getEchartsInstance(): ECharts {
|
||||
return this.echarts.getInstanceByDom(this.ele);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 async renderNewEcharts() {
|
||||
const { onEvents, onChartReady, autoResize = true } = this.props;
|
||||
|
||||
// 1. init echarts instance
|
||||
await this.initEchartsInstance();
|
||||
|
||||
// 2. update echarts instance
|
||||
const echartsInstance = this.updateEChartsOption();
|
||||
|
||||
// 3. bind events
|
||||
this.bindEvents(echartsInstance, onEvents || {});
|
||||
|
||||
// 4. on chart ready
|
||||
if (isFunction(onChartReady)) onChartReady(echartsInstance);
|
||||
|
||||
// 5. on resize
|
||||
if (this.ele && autoResize) {
|
||||
bind(this.ele, () => {
|
||||
this.resize();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// off the events
|
||||
private offEvents(instance, events: EChartsReactProps['onEvents']) {
|
||||
if (!events) return;
|
||||
// loop and off
|
||||
for (const eventName in events) {
|
||||
if (isString(eventName)) {
|
||||
instance.off(eventName, events[eventName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* render the echarts
|
||||
*/
|
||||
private updateEChartsOption(): EChartsInstance {
|
||||
const {
|
||||
option,
|
||||
notMerge = false,
|
||||
replaceMerge = null,
|
||||
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, replaceMerge, lazyUpdate });
|
||||
// 3. set loading mask
|
||||
if (showLoading) echartInstance.showLoading(loadingOption);
|
||||
else echartInstance.hideLoading();
|
||||
|
||||
return echartInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* resize wrapper
|
||||
*/
|
||||
private resize() {
|
||||
// 1. get the echarts object
|
||||
const echartsInstance = this.getEchartsInstance();
|
||||
|
||||
// 2. call echarts instance resize if not the initial resize
|
||||
// resize should not happen on first render as it will cancel initial echarts animations
|
||||
if (!this.isInitialResize) {
|
||||
try {
|
||||
echartsInstance.resize({
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. update variable for future calls
|
||||
this.isInitialResize = false;
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
const {
|
||||
style,
|
||||
className = '',
|
||||
echarts,
|
||||
option,
|
||||
theme,
|
||||
notMerge,
|
||||
replaceMerge,
|
||||
lazyUpdate,
|
||||
showLoading,
|
||||
loadingOption,
|
||||
opts,
|
||||
onChartReady,
|
||||
onEvents,
|
||||
shouldSetOption,
|
||||
autoResize,
|
||||
...divHTMLAttributes
|
||||
} = this.props;
|
||||
// default height = 300
|
||||
const newStyle = { height: 300, ...style };
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={(e: HTMLElement) => {
|
||||
this.ele = e;
|
||||
}}
|
||||
style={newStyle}
|
||||
className={`echarts-for-react ${className}`}
|
||||
{...divHTMLAttributes}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import isEqual from 'fast-deep-equal';
|
||||
|
||||
export { isEqual };
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export function isFunction(v: any): boolean {
|
||||
return typeof v === 'function';
|
||||
}
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export function isString(v: any): boolean {
|
||||
return typeof v === 'string';
|
||||
}
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* 保留 object 中的部分内容
|
||||
* @param obj
|
||||
* @param keys
|
||||
*/
|
||||
export function pick<T extends object>(obj: T, keys: readonly (keyof T)[]): Partial<T> {
|
||||
const r = {} as Partial<T>;
|
||||
keys.forEach((key) => {
|
||||
r[key] = obj[key];
|
||||
});
|
||||
return r;
|
||||
}
|
||||
Generated
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
import * as echarts from 'echarts';
|
||||
import { EChartsReactProps, EChartsOption, EChartsInstance } from './types';
|
||||
import EChartsReactCore from './core';
|
||||
|
||||
export type { EChartsReactProps, EChartsOption, EChartsInstance };
|
||||
|
||||
// export the Component the echarts Object.
|
||||
export default class EChartsReact extends EChartsReactCore {
|
||||
constructor(props: EChartsReactProps) {
|
||||
super(props);
|
||||
|
||||
// 初始化为 echarts 整个包
|
||||
this.echarts = echarts;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
import type { EChartsType } from 'echarts';
|
||||
|
||||
/**
|
||||
* Solve the type conflict caused by multiple type files
|
||||
*/
|
||||
export type EChartsOption = any;
|
||||
|
||||
export type EChartsInstance = EChartsType;
|
||||
|
||||
export type Opts = {
|
||||
readonly devicePixelRatio?: number;
|
||||
readonly renderer?: 'canvas' | 'svg';
|
||||
readonly width?: number | null | undefined | 'auto';
|
||||
readonly height?: number | null | undefined | 'auto';
|
||||
readonly locale?: string;
|
||||
};
|
||||
|
||||
export type EChartsReactProps = React.HTMLAttributes<HTMLDivElement> & {
|
||||
/**
|
||||
* echarts library entry, use it for import necessary.
|
||||
*/
|
||||
readonly echarts?: any;
|
||||
/**
|
||||
* echarts option
|
||||
*/
|
||||
readonly option: EChartsOption;
|
||||
/**
|
||||
* echarts theme config, can be:
|
||||
* 1. theme name string
|
||||
* 2. theme object
|
||||
*/
|
||||
readonly theme?: string | Record<string, any>;
|
||||
/**
|
||||
* notMerge config for echarts, default is `false`
|
||||
*/
|
||||
readonly notMerge?: boolean;
|
||||
/**
|
||||
* replaceMerge config for echarts, default is `null`
|
||||
*/
|
||||
readonly replaceMerge?: string | string[];
|
||||
/**
|
||||
* 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 render, do the callback with echarts instance
|
||||
*/
|
||||
readonly onChartReady?: (instance: EChartsInstance) => void;
|
||||
/**
|
||||
* bind events, default is `{}`
|
||||
*/
|
||||
readonly onEvents?: Record<string, Function>;
|
||||
/**
|
||||
* should update echarts options
|
||||
*/
|
||||
readonly shouldSetOption?: (prevProps: EChartsReactProps, props: EChartsReactProps) => boolean;
|
||||
|
||||
/**
|
||||
* should trigger resize when window resize
|
||||
*/
|
||||
readonly autoResize?: boolean;
|
||||
};
|
||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../fast-deep-equal@3.1.3/node_modules/fast-deep-equal
|
||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../react@19.2.0/node_modules/react
|
||||
Generated
Vendored
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../size-sensor@1.0.2/node_modules/size-sensor
|
||||
Reference in New Issue
Block a user