UNPKG

react-google-charts-with-key

Version:

temporary package as a fix to react-google-charts to add maps apiKey

498 lines (434 loc) 18.6 kB
'use strict'; exports.__esModule = true; exports.default = undefined; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug); var _DEFAULT_CHART_COLORS = require('../constants/DEFAULT_CHART_COLORS'); var _DEFAULT_CHART_COLORS2 = _interopRequireDefault(_DEFAULT_CHART_COLORS); var _GoogleChartLoader = require('./GoogleChartLoader'); var _GoogleChartLoader2 = _interopRequireDefault(_GoogleChartLoader); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint react/forbid-prop-types: "off" */ var debug = new _debug2.default('react-google-charts:Chart'); var uniqueID = 0; var generateUniqueID = function generateUniqueID() { uniqueID += 1; return 'reactgooglegraph-' + uniqueID; }; var Chart = function (_React$Component) { _inherits(Chart, _React$Component); function Chart(props) { _classCallCheck(this, Chart); debug('constructor', props); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _this.state = { graphID: props.graph_id || generateUniqueID() }; _this.chart = null; _this.wrapper = null; _this.hidden_columns = {}; _this.dataTable = []; _this.debounce = _this.debounce.bind(_this); _this.onResize = _this.onResize.bind(_this); _this.drawChart = _this.drawChart.bind(_this); _this.togglePoints = _this.togglePoints.bind(_this); _this.buildDataTableFromProps = _this.buildDataTableFromProps.bind(_this); _this.listenToChartEvents = _this.listenToChartEvents.bind(_this); _this.addChartActions = _this.addChartActions.bind(_this); _this.updateDataTable = _this.updateDataTable.bind(_this); _this.onSelectToggle = _this.onSelectToggle.bind(_this); _this.addSourceColumnTo = _this.addSourceColumnTo.bind(_this); _this.restoreColorTo = _this.restoreColorTo.bind(_this); _this.hideColumn = _this.hideColumn.bind(_this); return _this; } Chart.prototype.componentDidMount = function componentDidMount() { var _this2 = this; debug('componentDidMount'); if (typeof window === 'undefined') { return; } if (this.props.loadCharts) { _GoogleChartLoader2.default.init(this.props.chartPackages, this.props.chartVersion, this.props.mapsApiKey).then(function () { _this2.drawChart(); }); this.onResize = this.debounce(this.onResize, 200); window.addEventListener('resize', this.onResize); } else { this.drawChart(); } }; Chart.prototype.componentDidUpdate = function componentDidUpdate() { var _this3 = this; debug('componentDidUpdate'); if (!this.props.loadCharts) { this.drawChart(); } else if (_GoogleChartLoader2.default.isLoading) { _GoogleChartLoader2.default.initPromise.then(function () { _this3.drawChart(); }); } else if (_GoogleChartLoader2.default.isLoaded) { this.drawChart(); } }; Chart.prototype.componentWillUnmount = function componentWillUnmount() { try { if (window) { if (window.google && window.google.visualization) { window.google.visualization.events.removeAllListeners(this.wrapper); } window.removeEventListener('resize', this.onResize); } } catch (err) { return; } }; Chart.prototype.onResize = function onResize() { debug('Chart::onResize'); this.drawChart(); }; Chart.prototype.onSelectToggle = function onSelectToggle() { debug('onSelectToggle'); var selection = this.chart.getSelection(); if (selection.length > 0) { if (selection[0].row == null) { var column = selection[0].column; this.togglePoints(column); } } }; Chart.prototype.getColumnColor = function getColumnColor(columnIndex) { if (this.props.options.colors) { if (this.props.options.colors[columnIndex]) { return this.props.options.colors[columnIndex]; } } else if (columnIndex in _DEFAULT_CHART_COLORS2.default) { return _DEFAULT_CHART_COLORS2.default[columnIndex]; } return _DEFAULT_CHART_COLORS2.default[0]; }; Chart.prototype.buildDataTableFromProps = function buildDataTableFromProps() { debug('buildDataTableFromProps', this.props); if (this.props.diffdata) { var diffdata = this.props.diffdata; var oldData = window.google.visualization.arrayToDataTable(diffdata.old); var newData = window.google.visualization.arrayToDataTable(diffdata.new); // must take computeDiff from prototypes since not available with charts early in process var computeDiff = window.google.visualization[this.props.chartType].prototype.computeDiff; var chartDiff = computeDiff(oldData, newData); return chartDiff; } if (this.props.data === null && this.props.rows.length === 0 && !this.props.allowEmptyRows) { throw new Error("Can't build DataTable from rows and columns: rows array in props is empty"); } else if (this.props.data === null && this.props.columns.length === 0) { throw new Error("Can't build DataTable from rows and columns: columns array in props is empty"); } if (this.props.data !== null) { try { this.wrapper.setDataTable(this.props.data); var _dataTable = this.wrapper.getDataTable(); return _dataTable; } catch (err) { // console.error('Failed to set DataTable from data props ! ', err); throw new Error('Failed to set DataTable from data props ! ', err); } } var dataTable = new window.google.visualization.DataTable(); this.props.columns.forEach(function (column) { dataTable.addColumn(column); }); dataTable.addRows(this.props.rows); if (this.props.numberFormat) { var formatter = new window.google.visualization.NumberFormat(this.props.numberFormat.options); formatter.format(dataTable, this.props.numberFormat.column); } if (this.props.dateFormat) { var dateFormat = new window.google.visualization.DateFormat(this.props.dateFormat.options); this.props.dateFormat.columns.forEach(function (columnIdx) { dateFormat.format(dataTable, columnIdx); }); } return dataTable; }; Chart.prototype.updateDataTable = function updateDataTable() { debug('updateDataTable'); window.google.visualization.errors.removeAll(document.getElementById(this.wrapper.getContainerId())); this.dataTable.removeRows(0, this.dataTable.getNumberOfRows()); this.dataTable.removeColumns(0, this.dataTable.getNumberOfColumns()); this.dataTable = this.buildDataTableFromProps(); return this.dataTable; }; Chart.prototype.drawChart = function drawChart() { var _this4 = this; debug('drawChart', this); if (!this.wrapper) { var chartConfig = { chartType: this.props.chartType, options: this.props.options, containerId: this.state.graphID }; this.wrapper = new window.google.visualization.ChartWrapper(chartConfig); this.dataTable = this.buildDataTableFromProps(); this.wrapper.setDataTable(this.dataTable); window.google.visualization.events.addOneTimeListener(this.wrapper, 'ready', function () { _this4.chart = _this4.wrapper.getChart(); _this4.listenToChartEvents(); _this4.addChartActions(); }); } else { this.updateDataTable(); this.wrapper.setDataTable(this.dataTable); // this.wrapper.setChartType(this.props.chartType) this.wrapper.setOptions(this.props.options); if (this.wrapper.getChartType() !== this.props.chartType) { window.google.visualization.events.removeAllListeners(this.wrapper); this.wrapper.setChartType(this.props.chartType); var self = this; window.google.visualization.events.addOneTimeListener(this.wrapper, 'ready', function () { self.chart = self.wrapper.getChart(); self.listenToChartEvents.call(self); }); } } this.wrapper.draw(); }; Chart.prototype.addChartActions = function addChartActions() { var _this5 = this; debug('addChartActions', this.props.chartActions); if (this.props.chartActions === null) { return; } this.props.chartActions.forEach(function (chartAction) { _this5.chart.setAction({ id: chartAction.id, text: chartAction.text, action: chartAction.action.bind(_this5, _this5.chart) }); }); }; Chart.prototype.listenToChartEvents = function listenToChartEvents() { var _this6 = this; debug('listenToChartEvents', this.props.legend_toggle, this.props.chartEvents); if (this.props.legend_toggle) { window.google.visualization.events.addListener(this.wrapper, 'select', this.onSelectToggle); } this.props.chartEvents.forEach(function (chartEvent) { if (chartEvent.eventName === 'ready') { chartEvent.callback(_this6); } else { (function (event) { window.google.visualization.events.addListener(_this6.chart, event.eventName, function (e) { event.callback(_this6, e); }); })(chartEvent); } }); }; Chart.prototype.buildColumnFromSourceData = function buildColumnFromSourceData(columnIndex) { debug('buildColumnFromSourceData', columnIndex); return { label: this.dataTable.getColumnLabel(columnIndex), type: this.dataTable.getColumnType(columnIndex), sourceColumn: columnIndex, // addedBy minam.cho(devbada) cause of 'All series on a given // axis must be of the same data type': July 10, 2017 role: this.dataTable.getColumnRole(columnIndex) }; }; Chart.prototype.buildEmptyColumnFromSourceData = function buildEmptyColumnFromSourceData(columnIndex) { debug('buildEmptyColumnFromSourceData', columnIndex); return { label: this.dataTable.getColumnLabel(columnIndex), type: this.dataTable.getColumnType(columnIndex), calc: function calc() { return null; }, // addedBy minam.cho(devbada) cause of 'All series on a given // axis must be of the same data type': July 10, 2017 role: this.dataTable.getColumnRole(columnIndex) }; }; Chart.prototype.addEmptyColumnTo = function addEmptyColumnTo(columns, columnIndex) { debug('addEmptyColumnTo', columns, columnIndex); var emptyColumn = this.buildEmptyColumnFromSourceData(columnIndex); columns.push(emptyColumn); }; Chart.prototype.hideColumn = function hideColumn(colors, columnIndex) { debug('hideColumn', colors, columnIndex); if (!this.isHidden(columnIndex)) { this.hidden_columns[columnIndex] = { color: this.getColumnColor(columnIndex - 1) }; } colors.push('#CCCCCC'); }; Chart.prototype.addSourceColumnTo = function addSourceColumnTo(columns, columnIndex) { debug('addSourceColumnTo', columns, columnIndex); var sourceColumn = this.buildColumnFromSourceData(columnIndex); columns.push(sourceColumn); }; Chart.prototype.isHidden = function isHidden(columnIndex) { return this.hidden_columns[columnIndex] !== undefined; }; Chart.prototype.restoreColorTo = function restoreColorTo(colors, columnIndex) { debug('restoreColorTo', colors, columnIndex); debug('hidden_columns', this.hidden_columns); var previousColor = void 0; if (this.isHidden(columnIndex)) { previousColor = this.hidden_columns[columnIndex].color; delete this.hidden_columns[columnIndex]; } else { previousColor = this.getColumnColor(columnIndex - 1); } if (columnIndex !== 0) { colors.push(previousColor); } }; // eslint-disable-next-line class-methods-use-this Chart.prototype.debounce = function debounce(func, wait) { var timeout = void 0; return function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var context = this; clearTimeout(timeout); timeout = setTimeout(function () { return func.apply(context, args); }, wait); }; }; Chart.prototype.togglePoints = function togglePoints(column) { debug('togglePoints', column); var view = new window.google.visualization.DataView(this.wrapper.getDataTable()); var columnCount = view.getNumberOfColumns(); var colors = []; // eslint-disable-line prefer-const var columns = []; // eslint-disable-line prefer-const for (var i = 0; i < columnCount; i += 1) { // If user clicked on legend if (i === 0) { this.addSourceColumnTo(columns, i); } else if (i === column) { if (this.isHidden(i)) { this.addSourceColumnTo(columns, i); this.restoreColorTo(colors, i); } else { this.addEmptyColumnTo(columns, i); this.hideColumn(colors, i); } } else if (this.isHidden(i)) { this.addEmptyColumnTo(columns, i); this.hideColumn(colors, i); } else { this.addSourceColumnTo(columns, i); this.restoreColorTo(colors, i); } } view.setColumns(columns); this.props.options.colors = colors; this.chart.draw(view, this.props.options); }; Chart.prototype.render = function render() { debug('render', this.props, this.state); var divStyle = { height: this.props.height || this.props.options.height, width: this.props.width || this.props.options.width }; return _react2.default.createElement( 'div', { id: this.state.graphID, style: divStyle }, this.props.loader ? this.props.loader : 'Rendering Chart...' ); }; return Chart; }(_react2.default.Component); exports.default = Chart; process.env.NODE_ENV !== "production" ? Chart.propTypes = { graph_id: _propTypes2.default.string, chartType: _propTypes2.default.string, rows: _propTypes2.default.arrayOf(_propTypes2.default.array), columns: _propTypes2.default.arrayOf(_propTypes2.default.object), data: _propTypes2.default.arrayOf(_propTypes2.default.array), options: _propTypes2.default.any, width: _propTypes2.default.string, height: _propTypes2.default.string, chartEvents: _propTypes2.default.arrayOf(_propTypes2.default.shape({ // https://github.com/yannickcr/eslint-plugin-react/issues/819 eventName: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types callback: _propTypes2.default.func // eslint-disable-line react/no-unused-prop-types })), chartActions: _propTypes2.default.arrayOf(_propTypes2.default.shape({ id: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types text: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types action: _propTypes2.default.func // eslint-disable-line react/no-unused-prop-types })), loadCharts: _propTypes2.default.bool, loader: _propTypes2.default.node, legend_toggle: _propTypes2.default.bool, allowEmptyRows: _propTypes2.default.bool, chartPackages: _propTypes2.default.arrayOf(_propTypes2.default.string), chartVersion: _propTypes2.default.string, mapsApiKey: _propTypes2.default.string, numberFormat: _propTypes2.default.shape({ column: _propTypes2.default.number, // eslint-disable-line react/no-unused-prop-types options: _propTypes2.default.shape({ decimalSymbol: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types fractionDigits: _propTypes2.default.number, // eslint-disable-line react/no-unused-prop-types groupingSymbol: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types negativeColor: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types negativeParens: _propTypes2.default.bool, // eslint-disable-line react/no-unused-prop-types pattern: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types prefix: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types suffix: _propTypes2.default.string // eslint-disable-line react/no-unused-prop-types }) }), dateFormat: _propTypes2.default.shape({ // eslint-disable-next-line react/no-unused-prop-types columns: _propTypes2.default.arrayOf(_propTypes2.default.number), options: _propTypes2.default.shape({ formatType: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types pattern: _propTypes2.default.string, // eslint-disable-line react/no-unused-prop-types timeZone: _propTypes2.default.number // eslint-disable-line react/no-unused-prop-types }) }), diffdata: _propTypes2.default.shape({ on: _propTypes2.default.array, // eslint-disable-line react/no-unused-prop-types off: _propTypes2.default.array // eslint-disable-line react/no-unused-prop-types }) } : void 0; Chart.defaultProps = { chartType: 'LineChart', rows: [], columns: [], options: { chart: { title: 'Chart Title', subtitle: 'Subtitle' }, hAxis: { title: 'X Label' }, vAxis: { title: 'Y Label' }, width: '400px', height: '300px' }, width: '400px', height: '300px', chartEvents: [], chartActions: null, data: null, legend_toggle: false, allowEmptyRows: false, loadCharts: true, loader: _react2.default.createElement( 'div', null, 'Rendering Chart' ), chartPackages: ['corechart'], chartVersion: 'current', numberFormat: null, dateFormat: null, diffdata: null }; module.exports = exports['default'];