From d4c4752cc9589ea2155656eb714865bbef073ee6 Mon Sep 17 00:00:00 2001 From: Rohan Dey Date: Mon, 17 Dec 2018 13:10:12 +0530 Subject: [PATCH 1/8] Added support for TimeSeries. --- example/ChartViewer.js | 96 ++++++++++++++++++++++++++++++++++++------ lib/ReactFC.js | 4 +- lib/utils/utils.js | 59 ++++++++++++++++++++++++++ package.json | 2 +- src/ReactFC.js | 12 +++++- src/utils/utils.js | 57 ++++++++++++++++++++++++- 6 files changed, 210 insertions(+), 20 deletions(-) diff --git a/example/ChartViewer.js b/example/ChartViewer.js index 9e2ead0..fb2f56b 100644 --- a/example/ChartViewer.js +++ b/example/ChartViewer.js @@ -1,43 +1,53 @@ import React from 'react'; import FusionCharts from 'fusioncharts'; import Charts from 'fusioncharts/fusioncharts.charts'; +import TimeSeries from 'fusioncharts/fusioncharts.timeseries'; import OceanTheme from 'fusioncharts/themes/fusioncharts.theme.ocean'; import ReactFC from '../lib/ReactFC'; Charts(FusionCharts); +TimeSeries(FusionCharts); OceanTheme(FusionCharts); const myDataSource = { chart: { - caption: 'Harry\'s ss', + caption: "Harry's ss", subCaption: 'Top 5 stores in last month by revenue', numberPrefix: '$', - theme: 'ocean', + theme: 'ocean' }, data: [ { label: 'Bakersfield Central', - value: '880000', + value: '880000' }, { label: 'Garden Groove harbour', - value: '730000', + value: '730000' }, { label: 'Los Angeles Topanga', - value: '590000', + value: '590000' }, { label: 'Compton-Rancho Dom', - value: '520000', + value: '520000' }, { label: 'Daly City Serramonte', - value: '330000', - }, - ], + value: '330000' + } + ] }; +const jsonify = res => res.json(); +const dataFetch = fetch( + 'https://raw.githubusercontent.com/fusioncharts/dev_centre_docs/fusiontime-beta-release/charts-resources/fusiontime/online-sales-single-series/data.json' +).then(jsonify); +const schemaFetch = fetch( + 'https://raw.githubusercontent.com/fusioncharts/dev_centre_docs/fusiontime-beta-release/charts-resources/fusiontime/online-sales-single-series/schema.json' +).then(jsonify); + class ChartViewer extends React.Component { constructor(props) { super(props); @@ -48,9 +58,35 @@ class ChartViewer extends React.Component { height: 400, dataFormat: 'json', dataSource: myDataSource, + timeseriesDs: { + type: 'timeseries', + renderAt: 'container', + width: '90%', + height: 350, + dataSource: { + data: null, + yAxis: [ + { + plot: [ + { + value: 'Sales ($)' + } + ] + } + ], + caption: { + text: 'Online Sales of a SuperStore in the US' + } + } + } }; this.onClick = this.onClick.bind(this); + this.onFetchData = this.onFetchData.bind(this); + } + + componentDidMount() { + this.onFetchData(); } onClick() { @@ -67,20 +103,54 @@ class ChartViewer extends React.Component { - `, + ` + }); + } + + onFetchData() { + Promise.all([dataFetch, schemaFetch]).then(res => { + const data = res[0]; + const schema = res[1]; + + // console.log(data); + // console.log(schema); + const fusionTable = new FusionCharts.DataStore().createDataTable( + data, + schema + ); + + this.setState( + { + timeseriesDs: { + ...this.state.timeseriesDs, + dataSource: { + ...this.state.timeseriesDs.dataSource, + data: fusionTable + } + } + }, + () => { + // console.log(this.state.timeseriesDs); + } + ); }); } render() { return (
- + {/* */} + {this.state.timeseriesDs.dataSource.data ? ( + + ) : ( + 'loading' + )}
- +
); } } -export default ChartViewer; \ No newline at end of file +export default ChartViewer; diff --git a/lib/ReactFC.js b/lib/ReactFC.js index f2bccad..f80541a 100644 --- a/lib/ReactFC.js +++ b/lib/ReactFC.js @@ -170,7 +170,7 @@ function (_React$Component) { }, { key: "isSameChartData", value: function isSameChartData(currData, oldData) { - if (utils.isObject(currData) && utils.isObject(oldData)) { + if (utils.isObject(currData) && utils.isObject(oldData) && !utils.checkIfDataTableExists(currData) && !utils.checkIfDataTableExists(oldData)) { return utils.isSameObjectContent(currData, oldData); } @@ -311,7 +311,7 @@ function (_React$Component) { Object.assign(inlineOptions, chartConfig); - if (utils.isObject(inlineOptions.dataSource)) { + if (utils.isObject(inlineOptions.dataSource) && !utils.checkIfDataTableExists(inlineOptions.dataSource)) { inlineOptions.dataSource = utils.deepCopyOf(inlineOptions.dataSource); } diff --git a/lib/utils/utils.js b/lib/utils/utils.js index d731ffb..e2b9ca8 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -8,9 +8,12 @@ exports.isCallable = isCallable; exports.isSameObjectContent = isSameObjectContent; exports.isUndefined = isUndefined; exports.deepCopyOf = deepCopyOf; +exports.checkIfDataTableExists = checkIfDataTableExists; +exports.cloneDataSource = cloneDataSource; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } +/* eslint-disable guard-for-in */ function isObject(value) { return value !== null && _typeof(value) === 'object'; } @@ -49,4 +52,60 @@ function isUndefined(value) { function deepCopyOf(obj) { return JSON.parse(JSON.stringify(obj)); +} + +function checkIfDataTableExists(dataSource) { + // eslint-disable-next-line no-underscore-dangle + if (dataSource && dataSource.data && dataSource.data._dataStore) { + return true; + } + + return false; +} + +function cloneDataSource(obj) { + var type = _typeof(obj); + + if (type === 'string' || type === 'number' || type === 'function' || type === 'boolean') { + return obj; + } + + if (obj === null || obj === undefined) { + return obj; + } + + if (Array.isArray(obj)) { + var arr = []; + + for (var i = 0; i < obj.length; i++) { + arr.push(this.cloneDataSource(obj[i])); + } + + return arr; + } + + if (_typeof(obj) === 'object') { + var clonedObj = {}; // eslint-disable-next-line guard-for-in + // eslint-disable-next-line no-restricted-syntax + + for (var prop in obj) { + // Edge case handling for DataTable + if (prop === 'data') { + // eslint-disable-next-line no-underscore-dangle + if (obj[prop]._dataStore) { + clonedObj[prop] = '-'; + } else { + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + + continue; + } + + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + + return clonedObj; + } + + return undefined; } \ No newline at end of file diff --git a/package.json b/package.json index 8858a57..5fb10ef 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "eslint-plugin-import": "^2.9.0", "eslint-plugin-jsx-a11y": "^6.0.3", "eslint-plugin-react": "^7.7.0", - "fusioncharts": "^3.13.1-sr.2", + "fusioncharts": "^3.13.3", "jest": "^22.4.2", "lodash": "^4.17.11", "prop-types": "^15.6.2", diff --git a/src/ReactFC.js b/src/ReactFC.js index daaf881..5a0bf9f 100644 --- a/src/ReactFC.js +++ b/src/ReactFC.js @@ -137,7 +137,12 @@ class ReactFC extends React.Component { } isSameChartData(currData, oldData) { - if (utils.isObject(currData) && utils.isObject(oldData)) { + if ( + utils.isObject(currData) && + utils.isObject(oldData) && + !utils.checkIfDataTableExists(currData) && + !utils.checkIfDataTableExists(oldData) + ) { return utils.isSameObjectContent(currData, oldData); } return currData === oldData; @@ -263,7 +268,10 @@ class ReactFC extends React.Component { }, {}); Object.assign(inlineOptions, chartConfig); - if (utils.isObject(inlineOptions.dataSource)) { + if ( + utils.isObject(inlineOptions.dataSource) && + !utils.checkIfDataTableExists(inlineOptions.dataSource) + ) { inlineOptions.dataSource = utils.deepCopyOf(inlineOptions.dataSource); } if (utils.isObject(inlineOptions.link)) { diff --git a/src/utils/utils.js b/src/utils/utils.js index e4efa90..9b8acf1 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -1,3 +1,4 @@ +/* eslint-disable guard-for-in */ export function isObject(value) { return value !== null && typeof value === 'object'; } @@ -7,7 +8,9 @@ export function isCallable(value) { } export function isSameObjectContent(obj1, obj2) { - if (Object.keys(obj1).length !== Object.keys(obj2).length) { return false; } + if (Object.keys(obj1).length !== Object.keys(obj2).length) { + return false; + } const keys = Object.keys(obj1); for (let i = 0; i < keys.length; i += 1) { @@ -25,10 +28,60 @@ export function isSameObjectContent(obj1, obj2) { export function isUndefined(value) { // eslint-disable-next-line no-void - const UNDEFINED = void (0); + const UNDEFINED = void 0; return value === UNDEFINED; } export function deepCopyOf(obj) { return JSON.parse(JSON.stringify(obj)); } + +export function checkIfDataTableExists(dataSource) { + // eslint-disable-next-line no-underscore-dangle + if (dataSource && dataSource.data && dataSource.data._dataStore) { + return true; + } + return false; +} + +export function cloneDataSource(obj) { + const type = typeof obj; + if ( + type === 'string' || + type === 'number' || + type === 'function' || + type === 'boolean' + ) { + return obj; + } + if (obj === null || obj === undefined) { + return obj; + } + if (Array.isArray(obj)) { + const arr = []; + for (let i = 0; i < obj.length; i++) { + arr.push(this.cloneDataSource(obj[i])); + } + return arr; + } + if (typeof obj === 'object') { + const clonedObj = {}; + // eslint-disable-next-line guard-for-in + // eslint-disable-next-line no-restricted-syntax + for (const prop in obj) { + // Edge case handling for DataTable + if (prop === 'data') { + // eslint-disable-next-line no-underscore-dangle + if (obj[prop]._dataStore) { + clonedObj[prop] = '-'; + } else { + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + continue; + } + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + return clonedObj; + } + return undefined; +} From e3df97c05fbf6972910efb6cfc35e276fba3ab63 Mon Sep 17 00:00:00 2001 From: Rohan Dey Date: Mon, 17 Dec 2018 16:38:54 +0530 Subject: [PATCH 2/8] Fixed update logic for TimeSeries chart. --- example/ChartViewer.js | 52 ++++++++++++++++++++-------------------- lib/ReactFC.js | 45 +++++++++++++++++++++++++++++++---- lib/utils/utils.js | 6 ++++- src/ReactFC.js | 54 ++++++++++++++++++++++++++++++++++++------ src/utils/utils.js | 7 ++++-- 5 files changed, 123 insertions(+), 41 deletions(-) diff --git a/example/ChartViewer.js b/example/ChartViewer.js index fb2f56b..168d9bd 100644 --- a/example/ChartViewer.js +++ b/example/ChartViewer.js @@ -53,17 +53,13 @@ class ChartViewer extends React.Component { super(props); this.state = { - type: 'column2d', - width: 600, - height: 400, - dataFormat: 'json', - dataSource: myDataSource, timeseriesDs: { type: 'timeseries', renderAt: 'container', width: '90%', height: 350, dataSource: { + caption: { text: 'Online Sales of a SuperStore in the US' }, data: null, yAxis: [ { @@ -73,37 +69,26 @@ class ChartViewer extends React.Component { } ] } - ], - caption: { - text: 'Online Sales of a SuperStore in the US' - } + ] } } }; - this.onClick = this.onClick.bind(this); + this.onChangeSize = this.onChangeSize.bind(this); this.onFetchData = this.onFetchData.bind(this); + this.onChangeCaption = this.onChangeCaption.bind(this); } componentDidMount() { this.onFetchData(); } - onClick() { - this.setState({ - dataFormat: 'xml', - dataSource: ` - - - - - - - - - - - ` + onChangeSize() { + const timeseriesDs = { ...this.state.timeseriesDs }; + timeseriesDs.height = 600; + timeseriesDs.width = 600; + this.setState({ timeseriesDs }, () => { + // console.log(this.state.timeseriesDs); }); } @@ -136,6 +121,20 @@ class ChartViewer extends React.Component { }); } + onChangeCaption() { + // console.log(this.state.timeseriesDs); + const timeseriesDs = { ...this.state.timeseriesDs }; + timeseriesDs.dataSource.caption.text = 'Random'; + this.setState( + { + timeseriesDs + }, + () => { + // console.log(this.state.timeseriesDs); + } + ); + } + render() { return (
@@ -146,7 +145,8 @@ class ChartViewer extends React.Component { 'loading' )}
- + +
); diff --git a/lib/ReactFC.js b/lib/ReactFC.js index f80541a..3e0e7e3 100644 --- a/lib/ReactFC.js +++ b/lib/ReactFC.js @@ -97,6 +97,8 @@ function (_React$Component) { var currentOptions = this.resolveChartOptions(nextProps); var oldOptions = this.oldOptions; var optionsUpdatedNatively = ['width', 'height', 'type', 'dataFormat', 'dataSource', 'events']; + console.log('currentOptions', currentOptions); + console.log('oldOptions', oldOptions); this.checkAndUpdateChartDimensions(currentOptions, oldOptions); this.checkAndUpdateChartType(currentOptions, oldOptions); this.checkAndUpdateChartData(currentOptions, oldOptions); @@ -151,6 +153,10 @@ function (_React$Component) { var currData = currentOptions.dataSource; var oldDataFormat = oldOptions.dataFormat; var oldData = oldOptions.dataSource; + console.log({ + currDataFormat: currDataFormat, + oldDataFormat: oldDataFormat + }); if (String(currDataFormat).toLowerCase() !== String(oldDataFormat).toLowerCase()) { if (!utils.isUndefined(currDataFormat) && !utils.isUndefined(currData)) { @@ -158,8 +164,11 @@ function (_React$Component) { // animate the chart to show the changes this.chartObj.render(); + return; } - } else if (!this.isSameChartData(currData, oldData)) { + } + + if (!this.isSameChartData(currData, oldData)) { if (!utils.isUndefined(currData)) { this.chartObj.setChartData(currData, // When dataFormat is not given, but data is changed, // then use 'json' as default dataFormat @@ -170,11 +179,35 @@ function (_React$Component) { }, { key: "isSameChartData", value: function isSameChartData(currData, oldData) { - if (utils.isObject(currData) && utils.isObject(oldData) && !utils.checkIfDataTableExists(currData) && !utils.checkIfDataTableExists(oldData)) { - return utils.isSameObjectContent(currData, oldData); - } + /* TODO + 1. Current has DataStore and Old doesn't + 2. Old has and Current doesn't + 3. Both has, check ref is equal, return false only if not equal + 4. Clone oldData for diff + 5. Clone currentData for diff + 6. return string check. + */ + // 1. Current has DataStore and Old doesn't + if (utils.checkIfDataTableExists(currData) && !utils.checkIfDataTableExists(oldData)) { + return false; + } // 2. Old has and Current doesn't + + + if (!utils.checkIfDataTableExists(currData) && utils.checkIfDataTableExists(oldData)) { + return false; + } // 3. Both has, check ref is equal, return false only if not equal + + + if (utils.checkIfDataTableExists(currData) && utils.checkIfDataTableExists(oldData) && currData.data !== oldData.data) { + return false; + } // 4. Clone oldData for diff + + + var oldDataStringified = JSON.stringify(utils.cloneDataSource(oldData, 'diff')); // 5. Clone currentData for diff + + var currentDataStringified = JSON.stringify(utils.cloneDataSource(currData, 'diff')); // 6. return string check. - return currData === oldData; + return oldDataStringified === currentDataStringified; } }, { key: "checkAndUpdateEvents", @@ -313,6 +346,8 @@ function (_React$Component) { if (utils.isObject(inlineOptions.dataSource) && !utils.checkIfDataTableExists(inlineOptions.dataSource)) { inlineOptions.dataSource = utils.deepCopyOf(inlineOptions.dataSource); + } else if (utils.isObject(inlineOptions.dataSource) && utils.checkIfDataTableExists(inlineOptions.dataSource)) { + inlineOptions.dataSource = utils.cloneDataSource(inlineOptions.dataSource, 'clone'); } if (utils.isObject(inlineOptions.link)) { diff --git a/lib/utils/utils.js b/lib/utils/utils.js index e2b9ca8..46c1d8a 100644 --- a/lib/utils/utils.js +++ b/lib/utils/utils.js @@ -64,6 +64,8 @@ function checkIfDataTableExists(dataSource) { } function cloneDataSource(obj) { + var purpose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'clone'; + var type = _typeof(obj); if (type === 'string' || type === 'number' || type === 'function' || type === 'boolean') { @@ -92,7 +94,9 @@ function cloneDataSource(obj) { // Edge case handling for DataTable if (prop === 'data') { // eslint-disable-next-line no-underscore-dangle - if (obj[prop]._dataStore) { + if (obj[prop]._dataStore && purpose === 'clone') { + clonedObj[prop] = obj[prop]; // eslint-disable-next-line no-underscore-dangle + } else if (obj[prop]._dataStore && purpose === 'diff') { clonedObj[prop] = '-'; } else { clonedObj[prop] = this.cloneDataSource(obj[prop]); diff --git a/src/ReactFC.js b/src/ReactFC.js index 5a0bf9f..2056304 100644 --- a/src/ReactFC.js +++ b/src/ReactFC.js @@ -110,7 +110,6 @@ class ReactFC extends React.Component { const currData = currentOptions.dataSource; const oldDataFormat = oldOptions.dataFormat; const oldData = oldOptions.dataSource; - if ( String(currDataFormat).toLowerCase() !== String(oldDataFormat).toLowerCase() @@ -123,8 +122,10 @@ class ReactFC extends React.Component { // If the chart dataFormat is changed then // animate the chart to show the changes this.chartObj.render(); + return; } - } else if (!this.isSameChartData(currData, oldData)) { + } + if (!this.isSameChartData(currData, oldData)) { if (!utils.isUndefined(currData)) { this.chartObj.setChartData( currData, @@ -137,15 +138,46 @@ class ReactFC extends React.Component { } isSameChartData(currData, oldData) { + /* TODO + 1. Current has DataStore and Old doesn't + 2. Old has and Current doesn't + 3. Both has, check ref is equal, return false only if not equal + 4. Clone oldData for diff + 5. Clone currentData for diff + 6. return string check. + */ + // 1. Current has DataStore and Old doesn't if ( - utils.isObject(currData) && - utils.isObject(oldData) && - !utils.checkIfDataTableExists(currData) && + utils.checkIfDataTableExists(currData) && !utils.checkIfDataTableExists(oldData) ) { - return utils.isSameObjectContent(currData, oldData); + return false; + } + // 2. Old has and Current doesn't + if ( + !utils.checkIfDataTableExists(currData) && + utils.checkIfDataTableExists(oldData) + ) { + return false; } - return currData === oldData; + // 3. Both has, check ref is equal, return false only if not equal + if ( + utils.checkIfDataTableExists(currData) && + utils.checkIfDataTableExists(oldData) && + currData.data !== oldData.data + ) { + return false; + } + // 4. Clone oldData for diff + const oldDataStringified = JSON.stringify( + utils.cloneDataSource(oldData, 'diff') + ); + // 5. Clone currentData for diff + const currentDataStringified = JSON.stringify( + utils.cloneDataSource(currData, 'diff') + ); + // 6. return string check. + return oldDataStringified === currentDataStringified; } checkAndUpdateEvents(currentOptions, oldOptions) { @@ -273,6 +305,14 @@ class ReactFC extends React.Component { !utils.checkIfDataTableExists(inlineOptions.dataSource) ) { inlineOptions.dataSource = utils.deepCopyOf(inlineOptions.dataSource); + } else if ( + utils.isObject(inlineOptions.dataSource) && + utils.checkIfDataTableExists(inlineOptions.dataSource) + ) { + inlineOptions.dataSource = utils.cloneDataSource( + inlineOptions.dataSource, + 'clone' + ); } if (utils.isObject(inlineOptions.link)) { inlineOptions.link = utils.deepCopyOf(inlineOptions.link); diff --git a/src/utils/utils.js b/src/utils/utils.js index 9b8acf1..7be3151 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -44,7 +44,7 @@ export function checkIfDataTableExists(dataSource) { return false; } -export function cloneDataSource(obj) { +export function cloneDataSource(obj, purpose = 'clone') { const type = typeof obj; if ( type === 'string' || @@ -72,7 +72,10 @@ export function cloneDataSource(obj) { // Edge case handling for DataTable if (prop === 'data') { // eslint-disable-next-line no-underscore-dangle - if (obj[prop]._dataStore) { + if (obj[prop]._dataStore && purpose === 'clone') { + clonedObj[prop] = obj[prop]; + // eslint-disable-next-line no-underscore-dangle + } else if (obj[prop]._dataStore && purpose === 'diff') { clonedObj[prop] = '-'; } else { clonedObj[prop] = this.cloneDataSource(obj[prop]); From c3c073984a157e7d79e1f9d7b799ba28ed8eacae Mon Sep 17 00:00:00 2001 From: Rohan Dey Date: Mon, 17 Dec 2018 16:43:32 +0530 Subject: [PATCH 3/8] Added build files --- dist/drill-down.js | 105 +++++++++++++++++++++++++++++++-- dist/drill-down.min.js | 2 +- dist/react-fusioncharts.js | 102 ++++++++++++++++++++++++++++++-- dist/react-fusioncharts.min.js | 2 +- lib/ReactFC.js | 6 -- 5 files changed, 197 insertions(+), 20 deletions(-) diff --git a/dist/drill-down.js b/dist/drill-down.js index b3df75d..3a8d18c 100644 --- a/dist/drill-down.js +++ b/dist/drill-down.js @@ -1463,8 +1463,11 @@ function (_React$Component) { // animate the chart to show the changes this.chartObj.render(); + return; } - } else if (!this.isSameChartData(currData, oldData)) { + } + + if (!this.isSameChartData(currData, oldData)) { if (!utils.isUndefined(currData)) { this.chartObj.setChartData(currData, // When dataFormat is not given, but data is changed, // then use 'json' as default dataFormat @@ -1475,11 +1478,35 @@ function (_React$Component) { }, { key: "isSameChartData", value: function isSameChartData(currData, oldData) { - if (utils.isObject(currData) && utils.isObject(oldData)) { - return utils.isSameObjectContent(currData, oldData); - } + /* TODO + 1. Current has DataStore and Old doesn't + 2. Old has and Current doesn't + 3. Both has, check ref is equal, return false only if not equal + 4. Clone oldData for diff + 5. Clone currentData for diff + 6. return string check. + */ + // 1. Current has DataStore and Old doesn't + if (utils.checkIfDataTableExists(currData) && !utils.checkIfDataTableExists(oldData)) { + return false; + } // 2. Old has and Current doesn't + + + if (!utils.checkIfDataTableExists(currData) && utils.checkIfDataTableExists(oldData)) { + return false; + } // 3. Both has, check ref is equal, return false only if not equal + + + if (utils.checkIfDataTableExists(currData) && utils.checkIfDataTableExists(oldData) && currData.data !== oldData.data) { + return false; + } // 4. Clone oldData for diff + - return currData === oldData; + var oldDataStringified = JSON.stringify(utils.cloneDataSource(oldData, 'diff')); // 5. Clone currentData for diff + + var currentDataStringified = JSON.stringify(utils.cloneDataSource(currData, 'diff')); // 6. return string check. + + return oldDataStringified === currentDataStringified; } }, { key: "checkAndUpdateEvents", @@ -1616,8 +1643,10 @@ function (_React$Component) { Object.assign(inlineOptions, chartConfig); - if (utils.isObject(inlineOptions.dataSource)) { + if (utils.isObject(inlineOptions.dataSource) && !utils.checkIfDataTableExists(inlineOptions.dataSource)) { inlineOptions.dataSource = utils.deepCopyOf(inlineOptions.dataSource); + } else if (utils.isObject(inlineOptions.dataSource) && utils.checkIfDataTableExists(inlineOptions.dataSource)) { + inlineOptions.dataSource = utils.cloneDataSource(inlineOptions.dataSource, 'clone'); } if (utils.isObject(inlineOptions.link)) { @@ -1774,6 +1803,8 @@ exports.isCallable = isCallable; exports.isSameObjectContent = isSameObjectContent; exports.isUndefined = isUndefined; exports.deepCopyOf = deepCopyOf; +exports.checkIfDataTableExists = checkIfDataTableExists; +exports.cloneDataSource = cloneDataSource; function _typeof(obj) { if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") { @@ -1788,6 +1819,8 @@ function _typeof(obj) { return _typeof(obj); } +/* eslint-disable guard-for-in */ + function isObject(value) { return value !== null && _typeof(value) === 'object'; @@ -1829,6 +1862,66 @@ function deepCopyOf(obj) { return JSON.parse(JSON.stringify(obj)); } +function checkIfDataTableExists(dataSource) { + // eslint-disable-next-line no-underscore-dangle + if (dataSource && dataSource.data && dataSource.data._dataStore) { + return true; + } + + return false; +} + +function cloneDataSource(obj) { + var purpose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'clone'; + + var type = _typeof(obj); + + if (type === 'string' || type === 'number' || type === 'function' || type === 'boolean') { + return obj; + } + + if (obj === null || obj === undefined) { + return obj; + } + + if (Array.isArray(obj)) { + var arr = []; + + for (var i = 0; i < obj.length; i++) { + arr.push(this.cloneDataSource(obj[i])); + } + + return arr; + } + + if (_typeof(obj) === 'object') { + var clonedObj = {}; // eslint-disable-next-line guard-for-in + // eslint-disable-next-line no-restricted-syntax + + for (var prop in obj) { + // Edge case handling for DataTable + if (prop === 'data') { + // eslint-disable-next-line no-underscore-dangle + if (obj[prop]._dataStore && purpose === 'clone') { + clonedObj[prop] = obj[prop]; // eslint-disable-next-line no-underscore-dangle + } else if (obj[prop]._dataStore && purpose === 'diff') { + clonedObj[prop] = '-'; + } else { + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + + continue; + } + + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + + return clonedObj; + } + + return undefined; +} + /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { diff --git a/dist/drill-down.min.js b/dist/drill-down.min.js index d36fbd6..2943d50 100644 --- a/dist/drill-down.min.js +++ b/dist/drill-down.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("fusioncharts")):"function"==typeof define&&define.amd?define("DrillDown",["react","fusioncharts"],t):"object"==typeof exports?exports.DrillDown=t(require("react"),require("fusioncharts")):e.DrillDown=t(e.React,e.FusionCharts)}(window,function(e,t){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t,n){e.exports=n(5)()},function(t,n){t.exports=e},function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=l(n(1)),i=l(n(7)),a=l(n(8)),s=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)if(Object.prototype.hasOwnProperty.call(e,n)){var r=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(e,n):{};r.get||r.set?Object.defineProperty(t,n,r):t[n]=e[n]}return t.default=e,t}(n(11)),c=l(n(12));function l(e){return e&&e.__esModule?e:{default:e}}function u(e){return(u="function"==typeof Symbol&&"symbol"===r(Symbol.iterator)?function(e){return r(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":r(e)})(e)}function f(e,t){return!t||"object"!==u(t)&&"function"!=typeof t?function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e):t}function p(e){return(p=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function d(e,t){for(var n=0;n1?n-1:0),o=1;o0&&(void 0===t.events?t.events=n:t.events=Object.assign(t.events,n)),this.chartObj=new this.FusionCharts(t),this.chartObj.render(),this.oldOptions=t,this.props.onRender&&"function"==typeof this.props.onRender&&this.props.onRender(this.chartObj)}},{key:"resolveChartOptions",value:function(e){var t=e.chartConfig?e.chartConfig:{},n=c.default.reduce(function(t,n){return t[n]=e[n],t},{});return Object.assign(n,t),s.isObject(n.dataSource)&&(n.dataSource=s.deepCopyOf(n.dataSource)),s.isObject(n.link)&&(n.link=s.deepCopyOf(n.link)),s.isObject(n.events)&&(n.events=Object.assign({},n.events)),n}},{key:"render",value:function(){return o.default.createElement("div",{className:this.props.className,id:this.containerId})}}]),t}();t.default=g},function(e,t,n){e.exports=n(4).default},function(e,t,n){"use strict";n.r(t);var r=n(1),o=n.n(r),i=n(0),a=n.n(i),s=n(2),c=n.n(s);function l(){return(l=Object.assign||function(e){for(var t=1;t1?t-1:0),r=1;r-1&&(t=!0),"object"===u(e)&&(n=!0))}),t&&n?"invalid":t?"number":n?"object":"noop"}},{key:"plotClicked",value:function(e){var t=e.data.index,n=(Array.isArray(this.props.children)?this.props.children:[this.props.children]).length,r=this.props.plotChildMap;if(0!==n){var o=this.determinePlotMapType(r);if("number"===o){var i=r[t];if(null===i||void 0===i||i>=n||i<0)return;this.setState({selectedChild:i,isDrilledDown:!0})}if("object"===o)for(var a=0;a-1)return void this.setState({selectedChild:l,isDrilledDown:!0})}"invalid"===o&&console.log("Invalid heterogeneous data: Please check proptypes for - plotChildMap")}}},{key:"cloneReactFCChild",value:function(e,t){return o.a.cloneElement(e,t)}},{key:"onChildRendered",value:function(){this.props.toggleParentBtnVisibility&&this.props.toggleParentBtnVisibility(!1)}},{key:"toggleParentBtnVisibility",value:function(e){this.setState({isBtnVisible:e})}},{key:"onBtnClick",value:function(){this.setState({isDrilledDown:!1}),this.props.toggleParentBtnVisibility&&this.props.toggleParentBtnVisibility(!0)}},{key:"render",value:function(){var e,t=this.state,n=t.selectedChild,r=t.isBtnVisible,i=this.props,a=i.children,s={width:i.width,height:i.height,onRender:this.onChildRendered,toggleParentBtnVisibility:this.toggleParentBtnVisibility};if(this.state.isDrilledDown){var u=Array.isArray(a)?a:[a];e=o.a.createElement("div",{style:this.wrapperStyle},this.cloneReactFCChild(u[n],s),r?o.a.createElement("button",{style:this.finBtnStyle,onClick:this.onBtnClick},this.finalBtnConfig.text):null)}else e=o.a.createElement(c.a,l({},this.props,{"fcEvent-dataplotClick":this.plotClicked}));return e}}]),t}();m.defaultProps={plotChildMap:[],btnConfig:{text:"Back",color:"#000000",backgroundColor:"#F6F6F6",borderColor:"#000000",fontSize:"14px",fontWeight:"bold",padding:"3px",fontFamily:"Verdana, sans",placement:"top-right",margin:"10px"},btnStyle:void 0,dataSource:{},dataFormat:"json",type:"",height:"",width:""},m.propTypes={plotChildMap:a.a.oneOfType([a.a.arrayOf(a.a.shape({plotPosition:a.a.number,childPosition:a.a.number})),a.a.arrayOf(a.a.number)]),btnConfig:a.a.shape({text:a.a.string,color:a.a.string,backgroundColor:a.a.string,borderColor:a.a.string,fontSize:a.a.string,fontWeight:a.a.string,padding:a.a.string,fontFamily:a.a.string,placement:a.a.oneOf(["top-left","top-right","bottom-left","bottom-right"]),margin:a.a.string}),btnStyle:a.a.object,dataSource:a.a.object,dataFormat:a.a.string,type:a.a.string,height:a.a.string,width:a.a.string},t.default=m},function(e,t,n){"use strict";var r=n(6);function o(){}e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=o,n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,n){e.exports=t},function(e,t,n){var r=n(9),o=n(10);e.exports=function(e,t,n){var i=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var a=(e=e||{}).random||(e.rng||r)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t)for(var s=0;s<16;++s)t[i+s]=a[s];return t||o(a)}},function(e,t){var n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(n){var r=new Uint8Array(16);e.exports=function(){return n(r),r}}else{var o=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),o[t]=e>>>((3&t)<<3)&255;return o}}},function(e,t){for(var n=[],r=0;r<256;++r)n[r]=(r+256).toString(16).substr(1);e.exports=function(e,t){var r=t||0,o=n;return[o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]]].join("")}},function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e){return(o="function"==typeof Symbol&&"symbol"===r(Symbol.iterator)?function(e){return r(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":r(e)})(e)}function i(e){return null!==e&&"object"===o(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.isObject=i,t.isCallable=function(e){return"function"==typeof e},t.isSameObjectContent=function e(t,n){if(Object.keys(t).length!==Object.keys(n).length)return!1;var r=Object.keys(t);for(var o=0;o1?n-1:0),o=1;o0&&(void 0===t.events?t.events=n:t.events=Object.assign(t.events,n)),this.chartObj=new this.FusionCharts(t),this.chartObj.render(),this.oldOptions=t,this.props.onRender&&"function"==typeof this.props.onRender&&this.props.onRender(this.chartObj)}},{key:"resolveChartOptions",value:function(e){var t=e.chartConfig?e.chartConfig:{},n=c.default.reduce(function(t,n){return t[n]=e[n],t},{});return Object.assign(n,t),s.isObject(n.dataSource)&&!s.checkIfDataTableExists(n.dataSource)?n.dataSource=s.deepCopyOf(n.dataSource):s.isObject(n.dataSource)&&s.checkIfDataTableExists(n.dataSource)&&(n.dataSource=s.cloneDataSource(n.dataSource,"clone")),s.isObject(n.link)&&(n.link=s.deepCopyOf(n.link)),s.isObject(n.events)&&(n.events=Object.assign({},n.events)),n}},{key:"render",value:function(){return o.default.createElement("div",{className:this.props.className,id:this.containerId})}}]),t}();t.default=g},function(e,t,n){e.exports=n(4).default},function(e,t,n){"use strict";n.r(t);var r=n(1),o=n.n(r),a=n(0),i=n.n(a),s=n(2),c=n.n(s);function l(){return(l=Object.assign||function(e){for(var t=1;t1?t-1:0),r=1;r-1&&(t=!0),"object"===u(e)&&(n=!0))}),t&&n?"invalid":t?"number":n?"object":"noop"}},{key:"plotClicked",value:function(e){var t=e.data.index,n=(Array.isArray(this.props.children)?this.props.children:[this.props.children]).length,r=this.props.plotChildMap;if(0!==n){var o=this.determinePlotMapType(r);if("number"===o){var a=r[t];if(null===a||void 0===a||a>=n||a<0)return;this.setState({selectedChild:a,isDrilledDown:!0})}if("object"===o)for(var i=0;i-1)return void this.setState({selectedChild:l,isDrilledDown:!0})}"invalid"===o&&console.log("Invalid heterogeneous data: Please check proptypes for - plotChildMap")}}},{key:"cloneReactFCChild",value:function(e,t){return o.a.cloneElement(e,t)}},{key:"onChildRendered",value:function(){this.props.toggleParentBtnVisibility&&this.props.toggleParentBtnVisibility(!1)}},{key:"toggleParentBtnVisibility",value:function(e){this.setState({isBtnVisible:e})}},{key:"onBtnClick",value:function(){this.setState({isDrilledDown:!1}),this.props.toggleParentBtnVisibility&&this.props.toggleParentBtnVisibility(!0)}},{key:"render",value:function(){var e,t=this.state,n=t.selectedChild,r=t.isBtnVisible,a=this.props,i=a.children,s={width:a.width,height:a.height,onRender:this.onChildRendered,toggleParentBtnVisibility:this.toggleParentBtnVisibility};if(this.state.isDrilledDown){var u=Array.isArray(i)?i:[i];e=o.a.createElement("div",{style:this.wrapperStyle},this.cloneReactFCChild(u[n],s),r?o.a.createElement("button",{style:this.finBtnStyle,onClick:this.onBtnClick},this.finalBtnConfig.text):null)}else e=o.a.createElement(c.a,l({},this.props,{"fcEvent-dataplotClick":this.plotClicked}));return e}}]),t}();m.defaultProps={plotChildMap:[],btnConfig:{text:"Back",color:"#000000",backgroundColor:"#F6F6F6",borderColor:"#000000",fontSize:"14px",fontWeight:"bold",padding:"3px",fontFamily:"Verdana, sans",placement:"top-right",margin:"10px"},btnStyle:void 0,dataSource:{},dataFormat:"json",type:"",height:"",width:""},m.propTypes={plotChildMap:i.a.oneOfType([i.a.arrayOf(i.a.shape({plotPosition:i.a.number,childPosition:i.a.number})),i.a.arrayOf(i.a.number)]),btnConfig:i.a.shape({text:i.a.string,color:i.a.string,backgroundColor:i.a.string,borderColor:i.a.string,fontSize:i.a.string,fontWeight:i.a.string,padding:i.a.string,fontFamily:i.a.string,placement:i.a.oneOf(["top-left","top-right","bottom-left","bottom-right"]),margin:i.a.string}),btnStyle:i.a.object,dataSource:i.a.object,dataFormat:i.a.string,type:i.a.string,height:i.a.string,width:i.a.string},t.default=m},function(e,t,n){"use strict";var r=n(6);function o(){}e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=o,n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,n){e.exports=t},function(e,t,n){var r=n(9),o=n(10);e.exports=function(e,t,n){var a=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var i=(e=e||{}).random||(e.rng||r)();if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,t)for(var s=0;s<16;++s)t[a+s]=i[s];return t||o(i)}},function(e,t){var n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(n){var r=new Uint8Array(16);e.exports=function(){return n(r),r}}else{var o=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),o[t]=e>>>((3&t)<<3)&255;return o}}},function(e,t){for(var n=[],r=0;r<256;++r)n[r]=(r+256).toString(16).substr(1);e.exports=function(e,t){var r=t||0,o=n;return[o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],"-",o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]],o[e[r++]]].join("")}},function(e,t,n){"use strict";function r(e){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(e){return(o="function"==typeof Symbol&&"symbol"===r(Symbol.iterator)?function(e){return r(e)}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":r(e)})(e)}function a(e){return null!==e&&"object"===o(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.isObject=a,t.isCallable=function(e){return"function"==typeof e},t.isSameObjectContent=function e(t,n){if(Object.keys(t).length!==Object.keys(n).length)return!1;var r=Object.keys(t);for(var o=0;o1&&void 0!==arguments[1]?arguments[1]:"clone",n=o(e);if("string"===n||"number"===n||"function"===n||"boolean"===n)return e;if(null===e||void 0===e)return e;if(Array.isArray(e)){for(var r=[],a=0;a 1 && arguments[1] !== undefined ? arguments[1] : 'clone'; + + var type = _typeof(obj); + + if (type === 'string' || type === 'number' || type === 'function' || type === 'boolean') { + return obj; + } + + if (obj === null || obj === undefined) { + return obj; + } + + if (Array.isArray(obj)) { + var arr = []; + + for (var i = 0; i < obj.length; i++) { + arr.push(this.cloneDataSource(obj[i])); + } + + return arr; + } + + if (_typeof(obj) === 'object') { + var clonedObj = {}; // eslint-disable-next-line guard-for-in + // eslint-disable-next-line no-restricted-syntax + + for (var prop in obj) { + // Edge case handling for DataTable + if (prop === 'data') { + // eslint-disable-next-line no-underscore-dangle + if (obj[prop]._dataStore && purpose === 'clone') { + clonedObj[prop] = obj[prop]; // eslint-disable-next-line no-underscore-dangle + } else if (obj[prop]._dataStore && purpose === 'diff') { + clonedObj[prop] = '-'; + } else { + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + + continue; + } + + clonedObj[prop] = this.cloneDataSource(obj[prop]); + } + + return clonedObj; + } + + return undefined; +} /***/ }), /* 8 */ diff --git a/dist/react-fusioncharts.min.js b/dist/react-fusioncharts.min.js index 2ac4f1c..b91fe3c 100644 --- a/dist/react-fusioncharts.min.js +++ b/dist/react-fusioncharts.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("fusioncharts")):"function"==typeof define&&define.amd?define("ReactFC",["react","fusioncharts"],t):"object"==typeof exports?exports.ReactFC=t(require("react"),require("fusioncharts")):e.ReactFC=t(e.React,e.FusionCharts)}(window,function(e,t){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t,n){var r=n(4),a=n(5);e.exports=function(e,t,n){var o=t&&n||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var s=(e=e||{}).random||(e.rng||r)();if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,t)for(var i=0;i<16;++i)t[o+i]=s[i];return t||a(s)}},function(e,t,n){e.exports=n(6).default},function(e,t){var n="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(n){var r=new Uint8Array(16);e.exports=function(){return n(r),r}}else{var a=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),a[t]=e>>>((3&t)<<3)&255;return a}}},function(e,t){for(var n=[],r=0;r<256;++r)n[r]=(r+256).toString(16).substr(1);e.exports=function(e,t){var r=t||0,a=n;return[a[e[r++]],a[e[r++]],a[e[r++]],a[e[r++]],"-",a[e[r++]],a[e[r++]],"-",a[e[r++]],a[e[r++]],"-",a[e[r++]],a[e[r++]],"-",a[e[r++]],a[e[r++]],a[e[r++]],a[e[r++]],a[e[r++]],a[e[r++]]].join("")}},function(e,t,n){"use strict";n.r(t);var r=n(0),a=n.n(r),o=n(1),s=n.n(o),i=n(2),c=n.n(i);function u(e){return(u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function f(e){return null!==e&&"object"===u(e)}function l(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n=Object.keys(e),r=0;r1?n-1:0),a=1;a0&&(void 0===t.events?t.events=n:t.events=Object.assign(t.events,n)),this.chartObj=new this.FusionCharts(t),this.chartObj.render(),this.oldOptions=t,this.props.onRender&&"function"==typeof this.props.onRender&&this.props.onRender(this.chartObj)}},{key:"resolveChartOptions",value:function(e){var t=e.chartConfig?e.chartConfig:{},n=h.reduce(function(t,n){return t[n]=e[n],t},{});return Object.assign(n,t),f(n.dataSource)&&(n.dataSource=d(n.dataSource)),f(n.link)&&(n.link=d(n.link)),f(n.events)&&(n.events=Object.assign({},n.events)),n}},{key:"render",value:function(){return a.a.createElement("div",{className:this.props.className,id:this.containerId})}}]),t}();t.default=S}])}); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("fusioncharts")):"function"==typeof define&&define.amd?define("ReactFC",["react","fusioncharts"],t):"object"==typeof exports?exports.ReactFC=t(require("react"),require("fusioncharts")):e.ReactFC=t(e.React,e.FusionCharts)}(window,function(e,t){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,r),a.l=!0,a.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(n,a,function(t){return e[t]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=3)}([function(t,r){t.exports=e},function(e,r){e.exports=t},function(e,t,r){var n=r(4),a=r(5);e.exports=function(e,t,r){var o=t&&r||0;"string"==typeof e&&(t="binary"===e?new Array(16):null,e=null);var i=(e=e||{}).random||(e.rng||n)();if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,t)for(var s=0;s<16;++s)t[o+s]=i[s];return t||a(i)}},function(e,t,r){e.exports=r(6).default},function(e,t){var r="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof window.msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto);if(r){var n=new Uint8Array(16);e.exports=function(){return r(n),n}}else{var a=new Array(16);e.exports=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),a[t]=e>>>((3&t)<<3)&255;return a}}},function(e,t){for(var r=[],n=0;n<256;++n)r[n]=(n+256).toString(16).substr(1);e.exports=function(e,t){var n=t||0,a=r;return[a[e[n++]],a[e[n++]],a[e[n++]],a[e[n++]],"-",a[e[n++]],a[e[n++]],"-",a[e[n++]],a[e[n++]],"-",a[e[n++]],a[e[n++]],"-",a[e[n++]],a[e[n++]],a[e[n++]],a[e[n++]],a[e[n++]],a[e[n++]]].join("")}},function(e,t,r){"use strict";r.r(t);var n=r(0),a=r.n(n),o=r(1),i=r.n(o),s=r(2),c=r.n(s);function u(e){return(u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function f(e){return null!==e&&"object"===u(e)}function d(e){return void 0===e}function l(e){return JSON.parse(JSON.stringify(e))}function p(e){return!!(e&&e.data&&e.data._dataStore)}function h(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"clone",r=u(e);if("string"===r||"number"===r||"function"===r||"boolean"===r)return e;if(null===e||void 0===e)return e;if(Array.isArray(e)){for(var n=[],a=0;a1?r-1:0),a=1;a0&&(void 0===t.events?t.events=r:t.events=Object.assign(t.events,r)),this.chartObj=new this.FusionCharts(t),this.chartObj.render(),this.oldOptions=t,this.props.onRender&&"function"==typeof this.props.onRender&&this.props.onRender(this.chartObj)}},{key:"resolveChartOptions",value:function(e){var t=e.chartConfig?e.chartConfig:{},r=g.reduce(function(t,r){return t[r]=e[r],t},{});return Object.assign(r,t),f(r.dataSource)&&!p(r.dataSource)?r.dataSource=l(r.dataSource):f(r.dataSource)&&p(r.dataSource)&&(r.dataSource=h(r.dataSource,"clone")),f(r.link)&&(r.link=l(r.link)),f(r.events)&&(r.events=Object.assign({},r.events)),r}},{key:"render",value:function(){return a.a.createElement("div",{className:this.props.className,id:this.containerId})}}]),t}();t.default=C}])}); \ No newline at end of file diff --git a/lib/ReactFC.js b/lib/ReactFC.js index 3e0e7e3..9900e76 100644 --- a/lib/ReactFC.js +++ b/lib/ReactFC.js @@ -97,8 +97,6 @@ function (_React$Component) { var currentOptions = this.resolveChartOptions(nextProps); var oldOptions = this.oldOptions; var optionsUpdatedNatively = ['width', 'height', 'type', 'dataFormat', 'dataSource', 'events']; - console.log('currentOptions', currentOptions); - console.log('oldOptions', oldOptions); this.checkAndUpdateChartDimensions(currentOptions, oldOptions); this.checkAndUpdateChartType(currentOptions, oldOptions); this.checkAndUpdateChartData(currentOptions, oldOptions); @@ -153,10 +151,6 @@ function (_React$Component) { var currData = currentOptions.dataSource; var oldDataFormat = oldOptions.dataFormat; var oldData = oldOptions.dataSource; - console.log({ - currDataFormat: currDataFormat, - oldDataFormat: oldDataFormat - }); if (String(currDataFormat).toLowerCase() !== String(oldDataFormat).toLowerCase()) { if (!utils.isUndefined(currDataFormat) && !utils.isUndefined(currData)) { From 7be7b22ac7c43020eaa74ba588ff720b76cdcd00 Mon Sep 17 00:00:00 2001 From: Rohan Dey Date: Wed, 26 Dec 2018 14:09:15 +0530 Subject: [PATCH 4/8] Added README for TimeSeries --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++- example/ChartViewer.js | 41 +++++++++---------- 2 files changed, 106 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f4359c0..b48be71 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ A simple and lightweight official React component for FusionCharts JavaScript ch - [Custom Components](#custom-components) - [Drill Down](#drill-down-component) - [Going Beyond Charts](#going-beyond-charts) +- [Usage and Integration of FusionTime](#usage-and-integration-of-fusionTime) - [For Contributors](#for-contributors) - [Licensing](#licensing) @@ -76,7 +77,7 @@ ReactFC.fcRoot(FusionCharts); Here is a basic sample that shows how to create a chart using `react-fusioncharts`: -``` +```javascript import React from 'react; import ReactDOM from 'react-dom'; import FusionCharts from 'fusioncharts'; @@ -263,6 +264,92 @@ class Chart extends Component { ReactDOM.render(, document.getElementById('root')); ``` +## Usage and integration of FusionTime + +From `fusioncharts@3.13.3-sr.1` and `react-fusioncharts@3.0.0`, You can visualize timeseries data easily on react. + +Learn more about FusionTime [here](https://www.fusioncharts.com/fusiontime). + +### Consider the example below for integration of FusionTime + +```javascript +import React from 'react'; +import FusionCharts from 'fusioncharts'; +import TimeSeries from 'fusioncharts/fusioncharts.timeseries'; +import ReactFC from '../lib/ReactFC'; + +ReactFC.fcRoot(FusionCharts, TimeSeries); + +const jsonify = res => res.json(); +const dataFetch = fetch( + 'https://raw.githubusercontent.com/fusioncharts/dev_centre_docs/fusiontime-beta-release/charts-resources/fusiontime/online-sales-single-series/data.json' +).then(jsonify); +const schemaFetch = fetch( + 'https://raw.githubusercontent.com/fusioncharts/dev_centre_docs/fusiontime-beta-release/charts-resources/fusiontime/online-sales-single-series/schema.json' +).then(jsonify); + +class ChartViewer extends React.Component { + constructor(props) { + super(props); + + this.state = { + timeseriesDs: { + type: 'timeseries', + renderAt: 'container', + width: '600', + height: '400', + dataSource: { + caption: { text: 'Online Sales of a SuperStore in the US' }, + data: null, + yAxis: [ + { + plot: [ + { + value: 'Sales ($)' + } + ] + } + ] + } + } + }; + this.onFetchData = this.onFetchData.bind(this); + } + + componentDidMount() { + this.onFetchData(); + } + + onFetchData() { + Promise.all([dataFetch, schemaFetch]).then(res => { + const data = res[0]; + const schema = res[1]; + const fusionTable = new FusionCharts.DataStore().createDataTable( + data, + schema + ); + const timeseriesDs = Object.assign({}, this.state.timeseriesDs); + timeseriesDs.dataSource.data = fusionTable; + this.setState({ + timeseriesDs + }); + }); + } + + render() { + return ( +
+ {this.state.timeseriesDs.dataSource.data ? ( + + ) : ( + 'loading' + )} +
+ ); + } +} +``` + ## Drill Down Component A custom component to easily add drill down to your react application. diff --git a/example/ChartViewer.js b/example/ChartViewer.js index 168d9bd..50e6e80 100644 --- a/example/ChartViewer.js +++ b/example/ChartViewer.js @@ -5,9 +5,10 @@ import TimeSeries from 'fusioncharts/fusioncharts.timeseries'; import OceanTheme from 'fusioncharts/themes/fusioncharts.theme.ocean'; import ReactFC from '../lib/ReactFC'; -Charts(FusionCharts); -TimeSeries(FusionCharts); -OceanTheme(FusionCharts); +// Charts(FusionCharts); +// TimeSeries(FusionCharts); +// OceanTheme(FusionCharts); +ReactFC.fcRoot(FusionCharts, Charts, TimeSeries); const myDataSource = { chart: { @@ -77,6 +78,7 @@ class ChartViewer extends React.Component { this.onChangeSize = this.onChangeSize.bind(this); this.onFetchData = this.onFetchData.bind(this); this.onChangeCaption = this.onChangeCaption.bind(this); + this.onChange = this.onChange.bind(this); } componentDidMount() { @@ -88,7 +90,7 @@ class ChartViewer extends React.Component { timeseriesDs.height = 600; timeseriesDs.width = 600; this.setState({ timeseriesDs }, () => { - // console.log(this.state.timeseriesDs); + console.log(this.state.timeseriesDs); }); } @@ -96,28 +98,15 @@ class ChartViewer extends React.Component { Promise.all([dataFetch, schemaFetch]).then(res => { const data = res[0]; const schema = res[1]; - - // console.log(data); - // console.log(schema); const fusionTable = new FusionCharts.DataStore().createDataTable( data, schema ); - - this.setState( - { - timeseriesDs: { - ...this.state.timeseriesDs, - dataSource: { - ...this.state.timeseriesDs.dataSource, - data: fusionTable - } - } - }, - () => { - // console.log(this.state.timeseriesDs); - } - ); + const timeseriesDs = Object.assign({}, this.state.timeseriesDs); + timeseriesDs.dataSource.data = fusionTable; + this.setState({ + timeseriesDs + }); }); } @@ -130,11 +119,16 @@ class ChartViewer extends React.Component { timeseriesDs }, () => { - // console.log(this.state.timeseriesDs); + // this.onChangeSize(); } ); } + onChange() { + this.onChangeCaption(); + this.onChangeSize(); + } + render() { return (
@@ -147,6 +141,7 @@ class ChartViewer extends React.Component {
+
); From 5d4c30c53e5f1960b80852dcd199f309a8f47f7c Mon Sep 17 00:00:00 2001 From: Rohan Dey Date: Wed, 26 Dec 2018 14:46:35 +0530 Subject: [PATCH 5/8] Updated README --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b48be71..7cd796b 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,7 @@ const schemaFetch = fetch( class ChartViewer extends React.Component { constructor(props) { super(props); - + this.onFetchData = this.onFetchData.bind(this); this.state = { timeseriesDs: { type: 'timeseries', @@ -313,7 +313,6 @@ class ChartViewer extends React.Component { } } }; - this.onFetchData = this.onFetchData.bind(this); } componentDidMount() { @@ -350,6 +349,11 @@ class ChartViewer extends React.Component { } ``` +Useful links for FusionTime + +- [How FusionTime works](https://www.fusioncharts.com/dev/fusiontime/getting-started/how-fusion-time-works) +- [Create your first chart](https://www.fusioncharts.com/dev/fusiontime/getting-started/create-your-first-chart-in-fusiontime) + ## Drill Down Component A custom component to easily add drill down to your react application. From 5ddb11e9347817e72734d2390e2c0c8ab3279c08 Mon Sep 17 00:00:00 2001 From: Rohan Dey Date: Wed, 26 Dec 2018 14:49:34 +0530 Subject: [PATCH 6/8] Removed code from example --- example/ChartViewer.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/example/ChartViewer.js b/example/ChartViewer.js index 50e6e80..cb8db96 100644 --- a/example/ChartViewer.js +++ b/example/ChartViewer.js @@ -78,7 +78,6 @@ class ChartViewer extends React.Component { this.onChangeSize = this.onChangeSize.bind(this); this.onFetchData = this.onFetchData.bind(this); this.onChangeCaption = this.onChangeCaption.bind(this); - this.onChange = this.onChange.bind(this); } componentDidMount() { @@ -124,11 +123,6 @@ class ChartViewer extends React.Component { ); } - onChange() { - this.onChangeCaption(); - this.onChangeSize(); - } - render() { return (
@@ -141,7 +135,6 @@ class ChartViewer extends React.Component {
-
); From e1c0f2334c8d6c5fe73356518c0ab9cecf63ca8e Mon Sep 17 00:00:00 2001 From: Ashok mandal Date: Wed, 26 Dec 2018 17:25:11 +0530 Subject: [PATCH 7/8] readme-fix: Fixed semi colon for proper formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7cd796b..8ce983a 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ ReactFC.fcRoot(FusionCharts); Here is a basic sample that shows how to create a chart using `react-fusioncharts`: ```javascript -import React from 'react; +import React from 'react'; import ReactDOM from 'react-dom'; import FusionCharts from 'fusioncharts'; import Charts from 'fusioncharts/fusioncharts.charts'; From 02e787aadeb435d428dce061f78903ecdcce40d3 Mon Sep 17 00:00:00 2001 From: Ashok mandal Date: Wed, 26 Dec 2018 17:43:39 +0530 Subject: [PATCH 8/8] Bumped version to 3.0.0 --- package.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5fb10ef..3b371e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-fusioncharts", - "version": "2.0.7", + "version": "3.0.0", "description": "Simple and Lightweight React component for FusionCharts JavaScript Charting Library", "main": "lib/ReactFC.js", "author": { @@ -18,6 +18,16 @@ "name": "Subrata Mal", "email": "subrata@fusioncharts.com", "url": "https://github.com/subratamal" + }, + { + "name": "Ashok Mandal", + "email": "askipop@gmail.com", + "url": "https://github.com/ashok1994" + }, + { + "name": "Rohan Dey", + "email": "rohanoid5@gmail.com", + "url": "https://github.com/rohanoid5" } ], "homepage": "https://github.com/fusioncharts/react-fusioncharts-component",