Skip to content

Commit 0164cce

Browse files
committed
add props opts for echarts@4.x svg renderer, #138
1 parent 197cd70 commit 0164cce

File tree

10 files changed

+155
-24
lines changed

10 files changed

+155
-24
lines changed

README.md

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ import ReactEcharts from 'echarts-for-react'; // or var ReactEcharts = require(
3939
lazyUpdate={true}
4040
theme={"theme_name"}
4141
onChartReady={this.onChartReadyCallback}
42-
onEvents={EventsDict} />
42+
onEvents={EventsDict}
43+
opts={} />
4344
```
4445

4546
### typescript
@@ -49,12 +50,13 @@ import * as React from "react";
4950
import ReactEcharts from "echarts-for-react";
5051

5152
<ReactEcharts
52-
option={this.getOption()}
53-
notMerge={true}
54-
lazyUpdate={true}
55-
theme={"theme_name"}
56-
onChartReady={this.onChartReadyCallback}
57-
onEvents={EventsDict} />
53+
option={this.getOption()}
54+
notMerge={true}
55+
lazyUpdate={true}
56+
theme={"theme_name"}
57+
onChartReady={this.onChartReadyCallback}
58+
onEvents={EventsDict}
59+
opts={} />
5860
```
5961

6062
If you have only used bar chart (or others), you can import echarts modules manually to reduce bundle file size, e.g.
@@ -77,7 +79,8 @@ import 'echarts/lib/component/tooltip';
7779
lazyUpdate={true}
7880
theme={"theme_name"}
7981
onChartReady={this.onChartReadyCallback}
80-
onEvents={EventsDict} />
82+
onEvents={EventsDict}
83+
opts={} />
8184
```
8285

8386

@@ -107,7 +110,6 @@ the `class` of echarts div. you can setting the css style of charts by class nam
107110

108111
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.
109112

110-
111113
```js
112114
// import echarts
113115
import echarts from 'echarts';
@@ -154,6 +156,18 @@ let onEvents = {
154156
```
155157
for more event key name, see: [http://echarts.baidu.com/api.html#events](http://echarts.baidu.com/api.html#events)
156158

159+
- **`opts`** (optional, object)
160+
161+
the `opts` of echarts. `object`, will be used when initial echarts instance by `echarts.init`. Document [here](http://echarts.baidu.com/api.html#echarts.init).
162+
163+
```js
164+
<ReactEcharts
165+
option={this.getOption()}
166+
style={{height: '300px'}}
167+
opts={{renderer: 'svg'}} // use svg to render the chart.
168+
/>
169+
```
170+
157171

158172
# 4. Component API & Echarts API
159173

@@ -185,7 +199,23 @@ You can use the API to do:
185199
4. `release` the charts.
186200

187201

188-
# 5. LICENSE
202+
# 5. Q & A
203+
204+
- How to render the chart with svg when using echarts 4.x
205+
206+
Use the props `opts` of component with `renderer = 'svg'`. For example:
207+
208+
209+
```js
210+
<ReactEcharts
211+
option={this.getOption()}
212+
style={{height: '300px'}}
213+
opts={{renderer: 'svg'}} // use svg to render the chart.
214+
/>
215+
```
216+
217+
218+
# 6. LICENSE
189219

190220
MIT@[hustcc](https://github.com/hustcc).
191221

__tests__/core.spec.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe('core.js', () => {
3434
expect(typeof component.props().onChartReady).toEqual('function');
3535
expect(component.props().showLoading).toEqual(false);
3636
expect(component.props().onEvents).toEqual({});
37+
expect(component.props().opts).toEqual({});
3738
});
3839

3940
test('override props', () => {
@@ -50,6 +51,7 @@ describe('core.js', () => {
5051
showLoading
5152
onEvents={{ onClick: testFunc }}
5253
echarts={echarts}
54+
opts={{ renderer: 'svg' }}
5355
/>);
5456

5557
// default props
@@ -62,6 +64,7 @@ describe('core.js', () => {
6264
expect(typeof component.props().onChartReady).toEqual('function');
6365
expect(component.props().showLoading).toEqual(true);
6466
expect(component.props().onEvents).toEqual({ onClick: testFunc });
67+
expect(component.props().opts).toEqual({ renderer: 'svg' });
6568

6669
expect(testOnChartReadyFunc).toBeCalled();
6770
});

__tests__/index.spec.jsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ describe('index.js', () => {
9999
expect(component.instance().getEchartsInstance().id.substring(0, 3)).toBe('ec_');
100100
});
101101

102-
test('upadte theme', () => {
102+
// update theme, should dispose echarts instance.
103+
test('update theme', () => {
103104
const component = mount(<EchartsReact
104105
option={option}
105106
theme="hello"
@@ -115,6 +116,32 @@ describe('index.js', () => {
115116
expect(preId).not.toBe(component.instance().getEchartsInstance().id);
116117
});
117118

119+
// update opts, should dispose echarts instance.
120+
test('update opts', () => {
121+
const component = mount(<EchartsReact
122+
option={option}
123+
opts={{renderer: 'svg'}}
124+
125+
/>);
126+
127+
const preId = component.instance().getEchartsInstance().id;
128+
// udpate props
129+
component.setProps({
130+
opts: {renderer: 'svg'}
131+
});
132+
133+
component.update(); // force update
134+
expect(preId).toBe(component.instance().getEchartsInstance().id);
135+
136+
// udpate props
137+
component.setProps({
138+
opts: {renderer: 'canvas'}
139+
});
140+
141+
component.update(); // force update
142+
expect(preId).not.toBe(component.instance().getEchartsInstance().id);
143+
});
144+
118145
test('unmount', () => {
119146
const component = mount(<EchartsReact
120147
option={option}

demo/dist/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/src/App.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export default class App extends PureComponent {
3434
<Link to="/echarts/gcalendar">GCalendar</Link> |
3535
<Link to="/echarts/lunar">Lunar</Link> |
3636
<Link to="/echarts/gl">gl</Link> |
37-
<Link to="/echarts/sunburst">Sunburst</Link>
37+
<Link to="/echarts/sunburst">Sunburst</Link> |
38+
<Link to="/echarts/svg">SVG</Link>
3839
</h4>
3940
{ children || <Dynamic /> }
4041

demo/src/Chart.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Graph from './charts/Graph.jsx';
1818
import Lunar from './charts/Lunar.jsx';
1919
import Treemap from './charts/Treemap.jsx';
2020
import Sunburst from './charts/Sunburst.jsx';
21+
import Svg from './charts/Svg.jsx';
2122

2223
const Components = {
2324
Simple,
@@ -36,6 +37,7 @@ const Components = {
3637
Lunar,
3738
Gl,
3839
Sunburst,
40+
Svg,
3941
};
4042

4143
export default class Chart extends PureComponent {

demo/src/charts/Svg.jsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React, { PureComponent } from 'react';
2+
import ReactEcharts from '../../../src/index';
3+
4+
export default class Svg extends PureComponent {
5+
getOption = () => ({
6+
title: {
7+
text: 'ECharts 入门示例'
8+
},
9+
tooltip: {},
10+
legend: {
11+
data:['销量']
12+
},
13+
xAxis: {
14+
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
15+
},
16+
yAxis: {},
17+
series: [{
18+
name: '销量',
19+
type: 'bar',
20+
data: [5, 20, 36, 10, 10, 20]
21+
}]
22+
})
23+
24+
render() {
25+
let code = "<ReactEcharts \n" +
26+
" option={this.getOtion()} \n" +
27+
" style={{height: '400px', width: '100%'}} \n" +
28+
" opts={{renderer: 'svg'}} \n" +
29+
" className='react_for_echarts' />";
30+
return (
31+
<div className='examples'>
32+
<div className='parent'>
33+
<label> SVG renderer chart </label>
34+
<ReactEcharts
35+
option={this.getOption()}
36+
style={{height: '400px', width: '100%'}}
37+
opts={{ renderer: 'svg' }}
38+
className='react_for_echarts' />
39+
<label> code below: </label>
40+
<pre>
41+
<code>{code}</code>
42+
</pre>
43+
</div>
44+
</div>
45+
);
46+
}
47+
}

lib/core.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var EchartsReactCore = function (_Component) {
4242
var _this = _possibleConstructorReturn(this, (EchartsReactCore.__proto__ || Object.getPrototypeOf(EchartsReactCore)).call(this, props));
4343

4444
_this.getEchartsInstance = function () {
45-
return _this.echartsInstance.getInstanceByDom(_this.echartsElement) || _this.echartsInstance.init(_this.echartsElement, _this.props.theme);
45+
return _this.echartsInstance.getInstanceByDom(_this.echartsElement) || _this.echartsInstance.init(_this.echartsElement, _this.props.theme, _this.props.opts);
4646
};
4747

4848
_this.dispose = function () {
@@ -125,8 +125,9 @@ var EchartsReactCore = function (_Component) {
125125
var echartObj = this.renderEchartDom();
126126
this.bindEvents(echartObj, this.props.onEvents || {});
127127

128-
// 切换 theme 的时候,需要 dispost 之后才新建
129-
if (this.props.theme !== prevProps.theme) {
128+
// 1. 切换 theme 的时候,需要 dispose 之后再新建
129+
// 2. 修改 opts 的时候,需要 dispose 之后再新建
130+
if (this.props.theme !== prevProps.theme || !isEqual(prevProps.opts, this.props.opts)) {
130131
this.dispose();
131132

132133
this.rerender(); // 重建
@@ -200,7 +201,13 @@ EchartsReactCore.propTypes = {
200201
onChartReady: _propTypes2['default'].func,
201202
showLoading: _propTypes2['default'].bool,
202203
loadingOption: _propTypes2['default'].object, // eslint-disable-line react/forbid-prop-types
203-
onEvents: _propTypes2['default'].object // eslint-disable-line react/forbid-prop-types
204+
onEvents: _propTypes2['default'].object, // eslint-disable-line react/forbid-prop-types
205+
opts: _propTypes2['default'].shape({
206+
devicePixelRatio: _propTypes2['default'].number,
207+
renderer: _propTypes2['default'].oneOf(['canvas', 'svg']),
208+
width: _propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].oneOf([null, undefined, 'auto'])]),
209+
height: _propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].oneOf([null, undefined, 'auto'])])
210+
})
204211
};
205212

206213
EchartsReactCore.defaultProps = {
@@ -213,5 +220,6 @@ EchartsReactCore.defaultProps = {
213220
onChartReady: function onChartReady() {},
214221
showLoading: false,
215222
loadingOption: null,
216-
onEvents: {}
223+
onEvents: {},
224+
opts: {}
217225
};

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "echarts-for-react",
3-
"version": "2.0.5",
3+
"version": "2.0.6",
44
"description": "baidu Echarts(v3.x & v4.x) components for react.",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",
@@ -16,7 +16,6 @@
1616
"demo": "webpack",
1717
"dev": "webpack --watch",
1818
"build": "npm run clean && cross-env NODE_ENV=production babel src -d lib && npm run demo",
19-
"prepublish": "npm run build",
2019
"cover": "jest --coverage",
2120
"coveralls": "cat ./coverage/lcov.info | coveralls"
2221
},

src/core.jsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ export default class EchartsReactCore extends Component {
2121
const echartObj = this.renderEchartDom();
2222
this.bindEvents(echartObj, this.props.onEvents || {});
2323

24-
// 切换 theme 的时候,需要 dispost 之后才新建
25-
if (this.props.theme !== prevProps.theme) {
24+
// 1. 切换 theme 的时候,需要 dispose 之后再新建
25+
// 2. 修改 opts 的时候,需要 dispose 之后再新建
26+
if (this.props.theme !== prevProps.theme || !isEqual(prevProps.opts, this.props.opts)) {
2627
this.dispose();
2728

2829
this.rerender(); // 重建
@@ -43,7 +44,7 @@ export default class EchartsReactCore extends Component {
4344

4445
// return the echart object
4546
getEchartsInstance = () => this.echartsInstance.getInstanceByDom(this.echartsElement) ||
46-
this.echartsInstance.init(this.echartsElement, this.props.theme);
47+
this.echartsInstance.init(this.echartsElement, this.props.theme, this.props.opts);
4748

4849
// dispose echarts and element-resize-event
4950
dispose = () => {
@@ -132,7 +133,19 @@ EchartsReactCore.propTypes = {
132133
onChartReady: PropTypes.func,
133134
showLoading: PropTypes.bool,
134135
loadingOption: PropTypes.object, // eslint-disable-line react/forbid-prop-types
135-
onEvents: PropTypes.object // eslint-disable-line react/forbid-prop-types
136+
onEvents: PropTypes.object, // eslint-disable-line react/forbid-prop-types
137+
opts: PropTypes.shape({
138+
devicePixelRatio: PropTypes.number,
139+
renderer: PropTypes.oneOf(['canvas', 'svg']),
140+
width: PropTypes.oneOfType([
141+
PropTypes.number,
142+
PropTypes.oneOf([null, undefined, 'auto'])
143+
]),
144+
height: PropTypes.oneOfType([
145+
PropTypes.number,
146+
PropTypes.oneOf([null, undefined, 'auto'])
147+
]),
148+
})
136149
};
137150

138151
EchartsReactCore.defaultProps = {
@@ -146,4 +159,5 @@ EchartsReactCore.defaultProps = {
146159
showLoading: false,
147160
loadingOption: null,
148161
onEvents: {},
162+
opts: {},
149163
};

0 commit comments

Comments
 (0)