anychart-react
Version:
React component for AnyChart JavaScript charting library
187 lines (168 loc) • 4.36 kB
JSX
import React from 'react';
import 'anychart';
/**
* AnyChart React plugin.
*/
class AnyChart extends React.Component {
constructor(props) {
super(props);
/**
* Instance (stage or chart).
* @type {Object}
*/
this.instance = null;
/**
* Whether instance is stage.
* @type {boolean}
*/
this.isStage = false;
/**
* Should we dispose instance or not.
* @type {boolean}
*/
this.disposeInstance = false;
/**
* Properties of AnyChart which expected as array of [entity_index, json].
* E.g. <AnyChart yAxis={[1, {orientation: 'right'}]} />
* @type {Array.<string>}
*/
this.multipleEntities = ['xAxis', 'yAxis', 'lineMarker', 'rangeMarker', 'textMarker', 'grid', 'minorGrid'];
/**
* Container for chart/stage.
* @type {string}
*/
this.containerId = props.id || 'ac-chart-container';
}
/**
* Remove instance (dispose it if necessary).
*/
removeInstance() {
if (this.instance) {
if (this.disposeInstance)
this.instance.dispose();
else {
if (this.isStage)
this.instance.remove();
else
this.instance.container().getStage().remove();
}
}
}
/**
* Checker for array.
* @param {*} value Value to check.
* @return {boolean}
*/
isArray(value) {
return ((typeof value == 'object') && (value instanceof Array))
}
/**
* Applies props.
* @param {Object} props Properties.
*/
applyProps(props) {
for (let key of Object.keys(props)) {
let value = props[key];
if ((key == 'width' || key == 'height') && !this.isStage)
this.instance.container().getStage()[key](value);
if (this.instance[key]) {
if (~this.multipleEntities.indexOf(key)) {
if (!this.isArray(value))
value = [value];
this.instance[key](...value)
} else
this.instance[key](value)
}
}
}
/**
* Create instance to render chart or use instance property.
* @param {Object} props Properties.
*/
createInstance(props) {
if (props.instance) {
this.removeInstance();
this.instance = props.instance;
this.isStage = ((typeof this.instance.draw) !== 'function');
delete props.instance;
this.disposeInstance = false;
} else if (props.type) {
this.removeInstance();
this.disposeInstance = true;
this.instance = anychart[props.type](props.data);
this.isStage = false;
delete props.type;
delete props.data;
}
if (this.instance)
this.instance.container(this.containerId);
delete props.id;
}
/**
* Draws chart.
* @param {Object} props Properties.
*/
drawInstance(props) {
if (!this.instance) return;
if (this.isStage) {
this.instance.suspend();
let charts = props.charts;
delete props.charts;
this.applyProps(props);
for (let chart of charts) {
chart.container(this.instance).draw();
}
this.instance.resume();
} else {
this.applyProps(props);
this.instance.draw();
}
}
/**
* Method that
* @param {Object} prevProps
*/
createAndDraw(prevProps) {
var props = Object.assign(prevProps, this.props);
this.createInstance(props);
this.drawInstance(props);
}
/**
* Render container for future chart drawing.
*/
render() {
return (
<div id={this.containerId}></div>
)
}
/**
* Component has rendered.
*/
componentDidMount() {
this.createAndDraw({});
}
componentWillUpdate(nextProps, nextState) {
this.containerId = nextProps.id || this.containerId;
}
/**
* Component has re-rendered.
* @param {Object} prevProps Previous properties.
* @param {Object} prevState Previous state.
*/
componentDidUpdate(prevProps, prevState) {
var props = Object.assign({}, prevProps);
delete props.type;
delete props.instance;
this.createAndDraw(props)
}
/**
* Unmount react component.
*/
componentWillUnmount() {
this.removeInstance();
}
}
/**
* Default export.
*/
export default AnyChart