[ZEPPELIN-1722] Modernize visualization/transformation using ES6 class and module syntax
### What is this PR for? Modernize visualization/transformation using ES6 class and module syntax. And remove global variable 'zeppelin' ### What type of PR is it? Refactoring ### Todos * [x] - Use ES6 class and module syntax ### What is the Jira issue? https://issues.apache.org/jira/browse/ZEPPELIN-1722 ### Questions: * Does the licenses files need update? no * Is there breaking changes for older versions? no * Does this needs documentation? no Author: Lee moon soo <m...@apache.org> Closes #1815 from Leemoonsoo/ZEPPELIN-1722 and squashes the following commits: f945e7e [Lee moon soo] make _renderSetting function aa33a04 [Lee moon soo] Use => and remove self refernece 59d1a6d [Lee moon soo] use class and import/export syntax for transformations(tabledata) and visualizations Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/d60dd6fd Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/d60dd6fd Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/d60dd6fd Branch: refs/heads/master Commit: d60dd6fd7924a5c883328c4464fa77e92cc36611 Parents: 90decd2 Author: Lee moon soo <m...@apache.org> Authored: Sun Jan 1 07:03:37 2017 -0800 Committer: Lee moon soo <m...@apache.org> Committed: Tue Jan 3 18:37:40 2017 -0800 ---------------------------------------------------------------------- .../src/app/handsontable/handsonHelper.js | 291 +++++----- .../paragraph/result/result.controller.js | 21 +- .../src/app/tabledata/columnselector.js | 96 ++-- zeppelin-web/src/app/tabledata/passthrough.js | 24 +- zeppelin-web/src/app/tabledata/pivot.js | 416 +++++++------- zeppelin-web/src/app/tabledata/tabledata.js | 96 ++-- .../src/app/tabledata/transformation.js | 150 ++--- .../builtins/visualization-areachart.js | 102 ++-- .../builtins/visualization-barchart.js | 94 ++-- .../builtins/visualization-linechart.js | 166 +++--- .../builtins/visualization-nvd3chart.js | 408 +++++++------- .../builtins/visualization-piechart.js | 92 +-- .../builtins/visualization-scatterchart.js | 562 ++++++++++--------- .../builtins/visualization-table.js | 79 +-- .../src/app/visualization/visualization.js | 297 +++++----- zeppelin-web/src/app/zeppelin.js | 21 - zeppelin-web/test/spec/tabledata/tabledata.js | 6 +- zeppelin-web/webpack.config.js | 4 - 18 files changed, 1453 insertions(+), 1472 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/handsontable/handsonHelper.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/handsontable/handsonHelper.js b/zeppelin-web/src/app/handsontable/handsonHelper.js index 7434e6f..bacb298 100644 --- a/zeppelin-web/src/app/handsontable/handsonHelper.js +++ b/zeppelin-web/src/app/handsontable/handsonHelper.js @@ -12,186 +12,187 @@ * limitations under the License. */ -import zeppelin from '../zeppelin'; - /** * HandsonHelper class */ -zeppelin.HandsonHelper = function(columns, rows, comment) { - this.columns = columns || []; - this.rows = rows || []; - this.comment = comment || ''; -}; - -zeppelin.HandsonHelper.prototype.getHandsonTableConfig = function(columns, columnNames, resultRows) { - return { - colHeaders: columnNames, - data: resultRows, - rowHeaders: false, - stretchH: 'all', - sortIndicator: true, - columns: columns, - columnSorting: true, - contextMenu: false, - manualColumnResize: true, - manualRowResize: true, - readOnly: true, - readOnlyCellClassName: '', - fillHandle: false, - fragmentSelection: true, - disableVisualSelection: true, - cells: function(ro, co, pro) { - var cellProperties = {}; - var colType = columns[co].type; - cellProperties.renderer = function(instance, td, row, col, prop, value, cellProperties) { - _cellRenderer(instance, td, row, col, prop, value, cellProperties, colType); - }; - return cellProperties; - }, - afterGetColHeader: function(col, TH) { - var instance = this; - var menu = _buildDropDownMenu(columns[col].type); - var button = _buildTypeSwitchButton(); - - _addButtonMenuEvent(button, menu); - - Handsontable.Dom.addEvent(menu, 'click', function(event) { - if (event.target.nodeName === 'LI') { - _setColumnType(columns, event.target.data.colType, instance, col); +export default class HandsonHelper { + constructor(columns, rows, comment) { + this.columns = columns || []; + this.rows = rows || []; + this.comment = comment || ''; + }; + + getHandsonTableConfig(columns, columnNames, resultRows) { + var self = this; + return { + colHeaders: columnNames, + data: resultRows, + rowHeaders: false, + stretchH: 'all', + sortIndicator: true, + columns: columns, + columnSorting: true, + contextMenu: false, + manualColumnResize: true, + manualRowResize: true, + readOnly: true, + readOnlyCellClassName: '', + fillHandle: false, + fragmentSelection: true, + disableVisualSelection: true, + cells: function(ro, co, pro) { + var cellProperties = {}; + var colType = columns[co].type; + cellProperties.renderer = function(instance, td, row, col, prop, value, cellProperties) { + self._cellRenderer(instance, td, row, col, prop, value, cellProperties, colType); + }; + return cellProperties; + }, + afterGetColHeader: function(col, TH) { + var instance = this; + var menu = self._buildDropDownMenu(columns[col].type); + var button = self._buildTypeSwitchButton(); + + self._addButtonMenuEvent(button, menu); + + Handsontable.Dom.addEvent(menu, 'click', function(event) { + if (event.target.nodeName === 'LI') { + self._setColumnType(columns, event.target.data.colType, instance, col); + } + }); + if (TH.firstChild.lastChild.nodeName === 'BUTTON') { + TH.firstChild.removeChild(TH.firstChild.lastChild); } - }); - if (TH.firstChild.lastChild.nodeName === 'BUTTON') { - TH.firstChild.removeChild(TH.firstChild.lastChild); + TH.firstChild.appendChild(button); + TH.style['white-space'] = 'normal'; } - TH.firstChild.appendChild(button); - TH.style['white-space'] = 'normal'; - } + }; }; -}; -/* -** Private Service Functions -*/ + /* + ** Private Service Functions + */ -function _addButtonMenuEvent(button, menu) { - Handsontable.Dom.addEvent(button, 'click', function(event) { - var changeTypeMenu; - var position; - var removeMenu; + _addButtonMenuEvent(button, menu) { + Handsontable.Dom.addEvent(button, 'click', function(event) { + var changeTypeMenu; + var position; + var removeMenu; - document.body.appendChild(menu); + document.body.appendChild(menu); - event.preventDefault(); - event.stopImmediatePropagation(); + event.preventDefault(); + event.stopImmediatePropagation(); - changeTypeMenu = document.querySelectorAll('.changeTypeMenu'); + changeTypeMenu = document.querySelectorAll('.changeTypeMenu'); - for (var i = 0, len = changeTypeMenu.length; i < len; i++) { - changeTypeMenu[i].style.display = 'none'; - } - menu.style.display = 'block'; - position = button.getBoundingClientRect(); + for (var i = 0, len = changeTypeMenu.length; i < len; i++) { + changeTypeMenu[i].style.display = 'none'; + } + menu.style.display = 'block'; + position = button.getBoundingClientRect(); - menu.style.top = (position.top + (window.scrollY || window.pageYOffset)) + 2 + 'px'; - menu.style.left = (position.left) + 'px'; + menu.style.top = (position.top + (window.scrollY || window.pageYOffset)) + 2 + 'px'; + menu.style.left = (position.left) + 'px'; - removeMenu = function(event) { - if (menu.parentNode) { - menu.parentNode.removeChild(menu); - } - }; - Handsontable.Dom.removeEvent(document, 'click', removeMenu); - Handsontable.Dom.addEvent(document, 'click', removeMenu); - }); -} + removeMenu = function(event) { + if (menu.parentNode) { + menu.parentNode.removeChild(menu); + } + }; + Handsontable.Dom.removeEvent(document, 'click', removeMenu); + Handsontable.Dom.addEvent(document, 'click', removeMenu); + }); + } -function _buildDropDownMenu(activeCellType) { - var menu = document.createElement('UL'); - var types = ['text', 'numeric', 'date']; - var item; + _buildDropDownMenu(activeCellType) { + var menu = document.createElement('UL'); + var types = ['text', 'numeric', 'date']; + var item; - menu.className = 'changeTypeMenu'; + menu.className = 'changeTypeMenu'; - for (var i = 0, len = types.length; i < len; i++) { - item = document.createElement('LI'); - if ('innerText' in item) { - item.innerText = types[i]; - } else { - item.textContent = types[i]; - } + for (var i = 0, len = types.length; i < len; i++) { + item = document.createElement('LI'); + if ('innerText' in item) { + item.innerText = types[i]; + } else { + item.textContent = types[i]; + } - item.data = {'colType': types[i]}; + item.data = {'colType': types[i]}; - if (activeCellType === types[i]) { - item.className = 'active'; + if (activeCellType === types[i]) { + item.className = 'active'; + } + menu.appendChild(item); } - menu.appendChild(item); - } - return menu; -} + return menu; + } -function _buildTypeSwitchButton() { - var button = document.createElement('BUTTON'); + _buildTypeSwitchButton() { + var button = document.createElement('BUTTON'); - button.innerHTML = '\u25BC'; - button.className = 'changeType'; + button.innerHTML = '\u25BC'; + button.className = 'changeType'; - return button; -} + return button; + } -function _isNumeric(value) { - if (!isNaN(value)) { - if (value.length !== 0) { - if (Number(value) <= Number.MAX_SAFE_INTEGER && Number(value) >= Number.MIN_SAFE_INTEGER) { - return true; + _isNumeric(value) { + if (!isNaN(value)) { + if (value.length !== 0) { + if (Number(value) <= Number.MAX_SAFE_INTEGER && Number(value) >= Number.MIN_SAFE_INTEGER) { + return true; + } } } + return false; } - return false; -} -function _cellRenderer(instance, td, row, col, prop, value, cellProperties, colType) { - if (colType === 'numeric' && _isNumeric(value)) { - cellProperties.format = '0,0.[00000]'; - td.style.textAlign = 'left'; - Handsontable.renderers.NumericRenderer.apply(this, arguments); - } else if (value.length > '%html'.length && '%html ' === value.substring(0, '%html '.length)) { - td.innerHTML = value.substring('%html'.length); - } else { - Handsontable.renderers.TextRenderer.apply(this, arguments); + _cellRenderer(instance, td, row, col, prop, value, cellProperties, colType) { + if (colType === 'numeric' && this._isNumeric(value)) { + cellProperties.format = '0,0.[00000]'; + td.style.textAlign = 'left'; + Handsontable.renderers.NumericRenderer.apply(this, arguments); + } else if (value.length > '%html'.length && '%html ' === value.substring(0, '%html '.length)) { + td.innerHTML = value.substring('%html'.length); + } else { + Handsontable.renderers.TextRenderer.apply(this, arguments); + } } -} -function _dateValidator(value, callback) { - var d = moment(value); - return callback(d.isValid()); -} + _dateValidator(value, callback) { + var d = moment(value); + return callback(d.isValid()); + } -function _numericValidator(value, callback) { - return callback(_isNumeric(value)); -} + _numericValidator(value, callback) { + return callback(this._isNumeric(value)); + } -function _setColumnType(columns, type, instance, col) { - columns[col].type = type; - _setColumnValidator(columns, col); - instance.updateSettings({columns: columns}); - instance.validateCells(null); - if (_isColumnSorted(instance, col)) { - instance.sort(col, instance.sortOrder); + _setColumnType(columns, type, instance, col) { + columns[col].type = type; + this._setColumnValidator(columns, col); + instance.updateSettings({columns: columns}); + instance.validateCells(null); + if (this._isColumnSorted(instance, col)) { + instance.sort(col, instance.sortOrder); + } } -} -function _isColumnSorted(instance, col) { - return instance.sortingEnabled && instance.sortColumn === col; -} + _isColumnSorted(instance, col) { + return instance.sortingEnabled && instance.sortColumn === col; + } -function _setColumnValidator(columns, col) { - if (columns[col].type === 'numeric') { - columns[col].validator = _numericValidator; - } else if (columns[col].type === 'date') { - columns[col].validator = _dateValidator; - } else { - columns[col].validator = null; + _setColumnValidator(columns, col) { + if (columns[col].type === 'numeric') { + columns[col].validator = this._numericValidator; + } else if (columns[col].type === 'date') { + columns[col].validator = this._dateValidator; + } else { + columns[col].validator = null; + } } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js b/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js index 77f2e28..c5360fe 100644 --- a/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/result/result.controller.js @@ -12,7 +12,13 @@ * limitations under the License. */ -import zeppelin from '../../../zeppelin'; +import TableData from '../../../tabledata/tabledata'; +import TableVisualization from '../../../visualization/builtins/visualization-table'; +import BarchartVisualization from '../../../visualization/builtins/visualization-barchart'; +import PiechartVisualization from '../../../visualization/builtins/visualization-piechart'; +import AreachartVisualization from '../../../visualization/builtins/visualization-areachart'; +import LinechartVisualization from '../../../visualization/builtins/visualization-linechart'; +import ScatterchartVisualization from '../../../visualization/builtins/visualization-scatterchart'; (function() { @@ -86,27 +92,27 @@ import zeppelin from '../../../zeppelin'; */ var builtInVisualizations = { 'table': { - class: zeppelin.TableVisualization, + class: TableVisualization, instance: undefined // created from setGraphMode() }, 'multiBarChart': { - class: zeppelin.BarchartVisualization, + class: BarchartVisualization, instance: undefined }, 'pieChart': { - class: zeppelin.PiechartVisualization, + class: PiechartVisualization, instance: undefined }, 'stackedAreaChart': { - class: zeppelin.AreachartVisualization, + class: AreachartVisualization, instance: undefined }, 'lineChart': { - class: zeppelin.LinechartVisualization, + class: LinechartVisualization, instance: undefined }, 'scatterChart': { - class: zeppelin.ScatterchartVisualization, + class: ScatterchartVisualization, instance: undefined } }; @@ -220,7 +226,6 @@ import zeppelin from '../../../zeppelin'; enableHelium = (index === paragraphRef.results.msg.length - 1); if ($scope.type === 'TABLE') { - var TableData = zeppelin.TableData; tableData = new TableData(); tableData.loadParagraphResult({type: $scope.type, msg: data}); $scope.tableDataColumns = tableData.columns; http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/tabledata/columnselector.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/tabledata/columnselector.js b/zeppelin-web/src/app/tabledata/columnselector.js index 1cb2445..4b9180a 100644 --- a/zeppelin-web/src/app/tabledata/columnselector.js +++ b/zeppelin-web/src/app/tabledata/columnselector.js @@ -12,7 +12,7 @@ * limitations under the License. */ -import zeppelin from '../zeppelin'; +import Transformation from './transformation'; /** * select columns @@ -25,58 +25,58 @@ import zeppelin from '../zeppelin'; * ... * ] */ -zeppelin.ColumnselectorTransformation = function(config, columnSelectorProp) { - zeppelin.Transformation.call(this, config); - this.props = columnSelectorProp; -}; - -zeppelin.ColumnselectorTransformation.prototype = Object.create(zeppelin.Transformation.prototype); +export default class ColumnselectorTransformation extends Transformation { + constructor(config, columnSelectorProp) { + super(config); + this.props = columnSelectorProp; + }; -zeppelin.ColumnselectorTransformation.prototype.getSetting = function() { - var self = this; - var configObj = self.config; - return { - template: 'app/tabledata/columnselector_settings.html', - scope: { - config: self.config, - props: self.props, - tableDataColumns: self.tableDataColumns, - save: function() { - self.emitConfig(configObj); - }, - remove: function(selectorName) { - configObj[selectorName] = null; - self.emitConfig(configObj); + getSetting() { + var self = this; + var configObj = self.config; + return { + template: 'app/tabledata/columnselector_settings.html', + scope: { + config: self.config, + props: self.props, + tableDataColumns: self.tableDataColumns, + save: function() { + self.emitConfig(configObj); + }, + remove: function(selectorName) { + configObj[selectorName] = null; + self.emitConfig(configObj); + } } - } + }; }; -}; -/** - * Method will be invoked when tableData or config changes - */ -zeppelin.ColumnselectorTransformation.prototype.transform = function(tableData) { - this.tableDataColumns = tableData.columns; - this.removeUnknown(); - return tableData; -}; + /** + * Method will be invoked when tableData or config changes + */ + transform(tableData) { + this.tableDataColumns = tableData.columns; + this.removeUnknown(); + return tableData; + }; -zeppelin.ColumnselectorTransformation.prototype.removeUnknown = function() { - var fields = this.config; - for (var f in fields) { - if (fields[f]) { - var found = false; - for (var i = 0; i < this.tableDataColumns.length; i++) { - var a = fields[f]; - var b = this.tableDataColumns[i]; - if (a.index === b.index && a.name === b.name) { - found = true; - break; + removeUnknown() { + var fields = this.config; + for (var f in fields) { + if (fields[f]) { + var found = false; + for (var i = 0; i < this.tableDataColumns.length; i++) { + var a = fields[f]; + var b = this.tableDataColumns[i]; + if (a.index === b.index && a.name === b.name) { + found = true; + break; + } + } + if (!found && (fields[f] instanceof Object) && !(fields[f] instanceof Array)) { + fields[f] = null; } - } - if (!found && (fields[f] instanceof Object) && !(fields[f] instanceof Array)) { - fields[f] = null; } } - } -}; + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/tabledata/passthrough.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/tabledata/passthrough.js b/zeppelin-web/src/app/tabledata/passthrough.js index a5579b4..b2d6ec4 100644 --- a/zeppelin-web/src/app/tabledata/passthrough.js +++ b/zeppelin-web/src/app/tabledata/passthrough.js @@ -12,20 +12,20 @@ * limitations under the License. */ -import zeppelin from '../zeppelin'; +import Transformation from './transformation'; /** * passthough the data */ -zeppelin.PassthroughTransformation = function(config) { - zeppelin.Transformation.call(this, config); -}; +export default class PassthroughTransformation extends Transformation { + constructor(config) { + super(config); + }; -zeppelin.PassthroughTransformation.prototype = Object.create(zeppelin.Transformation.prototype); - -/** - * Method will be invoked when tableData or config changes - */ -zeppelin.PassthroughTransformation.prototype.transform = function(tableData) { - return tableData; -}; + /** + * Method will be invoked when tableData or config changes + */ + transform(tableData) { + return tableData; + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/tabledata/pivot.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/tabledata/pivot.js b/zeppelin-web/src/app/tabledata/pivot.js index 2fc9799..366efee 100644 --- a/zeppelin-web/src/app/tabledata/pivot.js +++ b/zeppelin-web/src/app/tabledata/pivot.js @@ -12,251 +12,251 @@ * limitations under the License. */ -import zeppelin from '../zeppelin'; +import Transformation from './transformation'; /** * pivot table data and return d3 chart data */ -zeppelin.PivotTransformation = function(config) { - zeppelin.Transformation.call(this, config); -}; - -zeppelin.PivotTransformation.prototype = Object.create(zeppelin.Transformation.prototype); +export default class PivotTransformation extends Transformation { + constructor(config) { + super(config); + }; -zeppelin.PivotTransformation.prototype.getSetting = function() { - var self = this; + getSetting() { + var self = this; - var configObj = self.config; - console.log('getSetting', configObj); - return { - template: 'app/tabledata/pivot_settings.html', - scope: { - config: configObj.common.pivot, - tableDataColumns: self.tableDataColumns, - save: function() { - self.emitConfig(configObj); - }, - removeKey: function(idx) { - configObj.common.pivot.keys.splice(idx, 1); - self.emitConfig(configObj); - }, - removeGroup: function(idx) { - configObj.common.pivot.groups.splice(idx, 1); - self.emitConfig(configObj); - }, - removeValue: function(idx) { - configObj.common.pivot.values.splice(idx, 1); - self.emitConfig(configObj); - }, - setValueAggr: function(idx, aggr) { - configObj.common.pivot.values[idx].aggr = aggr; - self.emitConfig(configObj); + var configObj = self.config; + console.log('getSetting', configObj); + return { + template: 'app/tabledata/pivot_settings.html', + scope: { + config: configObj.common.pivot, + tableDataColumns: self.tableDataColumns, + save: function() { + self.emitConfig(configObj); + }, + removeKey: function(idx) { + configObj.common.pivot.keys.splice(idx, 1); + self.emitConfig(configObj); + }, + removeGroup: function(idx) { + configObj.common.pivot.groups.splice(idx, 1); + self.emitConfig(configObj); + }, + removeValue: function(idx) { + configObj.common.pivot.values.splice(idx, 1); + self.emitConfig(configObj); + }, + setValueAggr: function(idx, aggr) { + configObj.common.pivot.values[idx].aggr = aggr; + self.emitConfig(configObj); + } } - } + }; }; -}; - -/** - * Method will be invoked when tableData or config changes - */ -zeppelin.PivotTransformation.prototype.transform = function(tableData) { - this.tableDataColumns = tableData.columns; - this.config.common = this.config.common || {}; - this.config.common.pivot = this.config.common.pivot || {}; - var config = this.config.common.pivot; - var firstTime = (!config.keys && !config.groups && !config.values); - config.keys = config.keys || []; - config.groups = config.groups || []; - config.values = config.values || []; + /** + * Method will be invoked when tableData or config changes + */ + transform(tableData) { + this.tableDataColumns = tableData.columns; + this.config.common = this.config.common || {}; + this.config.common.pivot = this.config.common.pivot || {}; + var config = this.config.common.pivot; + var firstTime = (!config.keys && !config.groups && !config.values); - this.removeUnknown(); - if (firstTime) { - this.selectDefault(); - } - return this.pivot( - tableData, - config.keys, - config.groups, - config.values); -}; + config.keys = config.keys || []; + config.groups = config.groups || []; + config.values = config.values || []; -zeppelin.PivotTransformation.prototype.removeUnknown = function() { - var config = this.config.common.pivot; - var tableDataColumns = this.tableDataColumns; - var unique = function(list) { - for (var i = 0; i < list.length; i++) { - for (var j = i + 1; j < list.length; j++) { - if (angular.equals(list[i], list[j])) { - list.splice(j, 1); - } - } + this.removeUnknown(); + if (firstTime) { + this.selectDefault(); } + return this.pivot( + tableData, + config.keys, + config.groups, + config.values); }; - var removeUnknown = function(list) { - for (var i = 0; i < list.length; i++) { - // remove non existing column - var found = false; - for (var j = 0; j < tableDataColumns.length; j++) { - var a = list[i]; - var b = tableDataColumns[j]; - if (a.index === b.index && a.name === b.name) { - found = true; - break; + removeUnknown() { + var config = this.config.common.pivot; + var tableDataColumns = this.tableDataColumns; + var unique = function(list) { + for (var i = 0; i < list.length; i++) { + for (var j = i + 1; j < list.length; j++) { + if (angular.equals(list[i], list[j])) { + list.splice(j, 1); + } } } - if (!found) { - list.splice(i, 1); - } - } - }; + }; - unique(config.keys); - removeUnknown(config.keys); - unique(config.groups); - removeUnknown(config.groups); - removeUnknown(config.values); -}; + var removeUnknown = function(list) { + for (var i = 0; i < list.length; i++) { + // remove non existing column + var found = false; + for (var j = 0; j < tableDataColumns.length; j++) { + var a = list[i]; + var b = tableDataColumns[j]; + if (a.index === b.index && a.name === b.name) { + found = true; + break; + } + } + if (!found) { + list.splice(i, 1); + } + } + }; -zeppelin.PivotTransformation.prototype.selectDefault = function() { - var config = this.config.common.pivot; - if (config.keys.length === 0 && - config.groups.length === 0 && - config.values.length === 0) { - if (config.keys.length === 0 && this.tableDataColumns.length > 0) { - config.keys.push(this.tableDataColumns[0]); - } + unique(config.keys); + removeUnknown(config.keys); + unique(config.groups); + removeUnknown(config.groups); + removeUnknown(config.values); + }; - if (config.values.length === 0 && this.tableDataColumns.length > 1) { - config.values.push(this.tableDataColumns[1]); - } - } -}; + selectDefault() { + var config = this.config.common.pivot; + if (config.keys.length === 0 && + config.groups.length === 0 && + config.values.length === 0) { + if (config.keys.length === 0 && this.tableDataColumns.length > 0) { + config.keys.push(this.tableDataColumns[0]); + } -zeppelin.PivotTransformation.prototype.pivot = function(data, keys, groups, values) { - var aggrFunc = { - sum: function(a, b) { - var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; - var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; - return varA + varB; - }, - count: function(a, b) { - var varA = (a !== undefined) ? parseInt(a) : 0; - var varB = (b !== undefined) ? 1 : 0; - return varA + varB; - }, - min: function(a, b) { - var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; - var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; - return Math.min(varA,varB); - }, - max: function(a, b) { - var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; - var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; - return Math.max(varA,varB); - }, - avg: function(a, b, c) { - var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; - var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; - return varA + varB; + if (config.values.length === 0 && this.tableDataColumns.length > 1) { + config.values.push(this.tableDataColumns[1]); + } } }; - var aggrFuncDiv = { - sum: false, - count: false, - min: false, - max: false, - avg: true - }; + pivot(data, keys, groups, values) { + var aggrFunc = { + sum: function(a, b) { + var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; + var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; + return varA + varB; + }, + count: function(a, b) { + var varA = (a !== undefined) ? parseInt(a) : 0; + var varB = (b !== undefined) ? 1 : 0; + return varA + varB; + }, + min: function(a, b) { + var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; + var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; + return Math.min(varA,varB); + }, + max: function(a, b) { + var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; + var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; + return Math.max(varA,varB); + }, + avg: function(a, b, c) { + var varA = (a !== undefined) ? (isNaN(a) ? 1 : parseFloat(a)) : 0; + var varB = (b !== undefined) ? (isNaN(b) ? 1 : parseFloat(b)) : 0; + return varA + varB; + } + }; - var schema = {}; - var rows = {}; + var aggrFuncDiv = { + sum: false, + count: false, + min: false, + max: false, + avg: true + }; - for (var i = 0; i < data.rows.length; i++) { - var row = data.rows[i]; - var s = schema; - var p = rows; + var schema = {}; + var rows = {}; - for (var k = 0; k < keys.length; k++) { - var key = keys[k]; + for (var i = 0; i < data.rows.length; i++) { + var row = data.rows[i]; + var s = schema; + var p = rows; - // add key to schema - if (!s[key.name]) { - s[key.name] = { - order: k, - index: key.index, - type: 'key', - children: {} - }; - } - s = s[key.name].children; + for (var k = 0; k < keys.length; k++) { + var key = keys[k]; - // add key to row - var keyKey = row[key.index]; - if (!p[keyKey]) { - p[keyKey] = {}; + // add key to schema + if (!s[key.name]) { + s[key.name] = { + order: k, + index: key.index, + type: 'key', + children: {} + }; + } + s = s[key.name].children; + + // add key to row + var keyKey = row[key.index]; + if (!p[keyKey]) { + p[keyKey] = {}; + } + p = p[keyKey]; } - p = p[keyKey]; - } - for (var g = 0; g < groups.length; g++) { - var group = groups[g]; - var groupKey = row[group.index]; + for (var g = 0; g < groups.length; g++) { + var group = groups[g]; + var groupKey = row[group.index]; - // add group to schema - if (!s[groupKey]) { - s[groupKey] = { - order: g, - index: group.index, - type: 'group', - children: {} - }; - } - s = s[groupKey].children; + // add group to schema + if (!s[groupKey]) { + s[groupKey] = { + order: g, + index: group.index, + type: 'group', + children: {} + }; + } + s = s[groupKey].children; - // add key to row - if (!p[groupKey]) { - p[groupKey] = {}; + // add key to row + if (!p[groupKey]) { + p[groupKey] = {}; + } + p = p[groupKey]; } - p = p[groupKey]; - } - for (var v = 0; v < values.length; v++) { - var value = values[v]; - var valueKey = value.name + '(' + value.aggr + ')'; + for (var v = 0; v < values.length; v++) { + var value = values[v]; + var valueKey = value.name + '(' + value.aggr + ')'; - // add value to schema - if (!s[valueKey]) { - s[valueKey] = { - type: 'value', - order: v, - index: value.index - }; - } + // add value to schema + if (!s[valueKey]) { + s[valueKey] = { + type: 'value', + order: v, + index: value.index + }; + } - // add value to row - if (!p[valueKey]) { - p[valueKey] = { - value: (value.aggr !== 'count') ? row[value.index] : 1, - count: 1 - }; - } else { - p[valueKey] = { - value: aggrFunc[value.aggr](p[valueKey].value, row[value.index], p[valueKey].count + 1), - count: (aggrFuncDiv[value.aggr]) ? p[valueKey].count + 1 : p[valueKey].count - }; + // add value to row + if (!p[valueKey]) { + p[valueKey] = { + value: (value.aggr !== 'count') ? row[value.index] : 1, + count: 1 + }; + } else { + p[valueKey] = { + value: aggrFunc[value.aggr](p[valueKey].value, row[value.index], p[valueKey].count + 1), + count: (aggrFuncDiv[value.aggr]) ? p[valueKey].count + 1 : p[valueKey].count + }; + } } } - } - //console.log('schema=%o, rows=%o', schema, rows); - return { - keys: keys, - groups: groups, - values: values, - schema: schema, - rows: rows + //console.log('schema=%o, rows=%o', schema, rows); + return { + keys: keys, + groups: groups, + values: values, + schema: schema, + rows: rows + }; }; -}; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/tabledata/tabledata.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/tabledata/tabledata.js b/zeppelin-web/src/app/tabledata/tabledata.js index 550cf1d..69fd5dc 100644 --- a/zeppelin-web/src/app/tabledata/tabledata.js +++ b/zeppelin-web/src/app/tabledata/tabledata.js @@ -12,61 +12,61 @@ * limitations under the License. */ -import zeppelin from '../zeppelin'; - /** * Create table data object from paragraph table type result */ -zeppelin.TableData = function(columns, rows, comment) { - this.columns = columns || []; - this.rows = rows || []; - this.comment = comment || ''; -}; +export default class TableData { + constructor(columns, rows, comment) { + this.columns = columns || []; + this.rows = rows || []; + this.comment = comment || ''; + }; -zeppelin.TableData.prototype.loadParagraphResult = function(paragraphResult) { - if (!paragraphResult || paragraphResult.type !== 'TABLE') { - console.log('Can not load paragraph result'); - return; - } + loadParagraphResult(paragraphResult) { + if (!paragraphResult || paragraphResult.type !== 'TABLE') { + console.log('Can not load paragraph result'); + return; + } - var columnNames = []; - var rows = []; - var array = []; - var textRows = paragraphResult.msg.split('\n'); - var comment = ''; - var commentRow = false; + var columnNames = []; + var rows = []; + var array = []; + var textRows = paragraphResult.msg.split('\n'); + var comment = ''; + var commentRow = false; - for (var i = 0; i < textRows.length; i++) { - var textRow = textRows[i]; - if (commentRow) { - comment += textRow; - continue; - } + for (var i = 0; i < textRows.length; i++) { + var textRow = textRows[i]; + if (commentRow) { + comment += textRow; + continue; + } - if (textRow === '') { - if (rows.length > 0) { - commentRow = true; + if (textRow === '') { + if (rows.length > 0) { + commentRow = true; + } + continue; } - continue; - } - var textCols = textRow.split('\t'); - var cols = []; - var cols2 = []; - for (var j = 0; j < textCols.length; j++) { - var col = textCols[j]; - if (i === 0) { - columnNames.push({name: col, index: j, aggr: 'sum'}); - } else { - cols.push(col); - cols2.push({key: (columnNames[i]) ? columnNames[i].name : undefined, value: col}); + var textCols = textRow.split('\t'); + var cols = []; + var cols2 = []; + for (var j = 0; j < textCols.length; j++) { + var col = textCols[j]; + if (i === 0) { + columnNames.push({name: col, index: j, aggr: 'sum'}); + } else { + cols.push(col); + cols2.push({key: (columnNames[i]) ? columnNames[i].name : undefined, value: col}); + } + } + if (i !== 0) { + rows.push(cols); + array.push(cols2); } } - if (i !== 0) { - rows.push(cols); - array.push(cols2); - } - } - this.comment = comment; - this.columns = columnNames; - this.rows = rows; -}; + this.comment = comment; + this.columns = columnNames; + this.rows = rows; + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/tabledata/transformation.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/tabledata/transformation.js b/zeppelin-web/src/app/tabledata/transformation.js index 4d85c6b..bdd620b 100644 --- a/zeppelin-web/src/app/tabledata/transformation.js +++ b/zeppelin-web/src/app/tabledata/transformation.js @@ -12,92 +12,92 @@ * limitations under the License. */ -import zeppelin from '../zeppelin'; - /** * Base class for visualization */ -zeppelin.Transformation = function(config) { - this.config = config; - this._emitter; -}; - -/** - * return { - * template : angular template string or url (url should end with .html), - * scope : an object to bind to template scope - * } - */ -zeppelin.Transformation.prototype.getSetting = function() { - // override this -}; +export default class Transformation { + constructor(config) { + this.config = config; + this._emitter; + }; -/** - * Method will be invoked when tableData or config changes - */ -zeppelin.Transformation.prototype.transform = function(tableData) { - // override this -}; + /** + * return { + * template : angular template string or url (url should end with .html), + * scope : an object to bind to template scope + * } + */ + getSetting() { + // override this + }; -/** - * render setting - */ -zeppelin.Transformation.prototype.renderSetting = function(targetEl) { - var setting = this.getSetting(); - if (!setting) { - return; - } + /** + * Method will be invoked when tableData or config changes + */ + transform(tableData) { + // override this + }; - // already readered - if (this._scope) { - var self = this; - this._scope.$apply(function() { - for (var k in setting.scope) { - self._scope[k] = setting.scope[k]; - } + /** + * render setting + */ + renderSetting(targetEl) { + var setting = this.getSetting(); + if (!setting) { + return; + } - for (var k in self._prevSettingScope) { - if (!setting.scope[k]) { + // already readered + if (this._scope) { + var self = this; + this._scope.$apply(function() { + for (var k in setting.scope) { self._scope[k] = setting.scope[k]; } - } - }); - return; - } else { - this._prevSettingScope = setting.scope; - } - var scope = this._createNewScope(); - for (var k in setting.scope) { - scope[k] = setting.scope[k]; - } - var template = setting.template; + for (var k in self._prevSettingScope) { + if (!setting.scope[k]) { + self._scope[k] = setting.scope[k]; + } + } + }); + return; + } else { + this._prevSettingScope = setting.scope; + } + + var scope = this._createNewScope(); + for (var k in setting.scope) { + scope[k] = setting.scope[k]; + } + var template = setting.template; - if (template.split('\n').length === 1 && - template.endsWith('.html')) { // template is url - var self = this; - this._templateRequest(template).then(function(t) { - self._render(targetEl, t, scope); - }); - } else { - this._render(targetEl, template, scope); - } -}; + if (template.split('\n').length === 1 && + template.endsWith('.html')) { // template is url + var self = this; + this._templateRequest(template).then(function(t) { + self._render(targetEl, t, scope); + }); + } else { + this._render(targetEl, template, scope); + } + }; -zeppelin.Transformation.prototype._render = function(targetEl, template, scope) { - this._targetEl = targetEl; - targetEl.html(template); - this._compile(targetEl.contents())(scope); - this._scope = scope; -}; + _render(targetEl, template, scope) { + this._targetEl = targetEl; + targetEl.html(template); + this._compile(targetEl.contents())(scope); + this._scope = scope; + }; -zeppelin.Transformation.prototype.setConfig = function(config) { - this.config = config; -}; + setConfig(config) { + this.config = config; + }; -/** - * Emit config. config will sent to server and saved. - */ -zeppelin.Transformation.prototype.emitConfig = function(config) { - this._emitter(config); -}; + /** + * Emit config. config will sent to server and saved. + */ + emitConfig(config) { + this._emitter(config); + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/visualization/builtins/visualization-areachart.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-areachart.js b/zeppelin-web/src/app/visualization/builtins/visualization-areachart.js index 6b9f95c..719f3e3 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-areachart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-areachart.js @@ -12,68 +12,68 @@ * limitations under the License. */ -import zeppelin from '../../zeppelin'; +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import PivotTransformation from '../../tabledata/pivot'; /** * Visualize data in area chart */ -zeppelin.AreachartVisualization = function(targetEl, config) { - zeppelin.Nvd3ChartVisualization.call(this, targetEl, config); +export default class AreachartVisualization extends Nvd3ChartVisualization { + constructor(targetEl, config) { + super(targetEl, config); - var PivotTransformation = zeppelin.PivotTransformation; - this.pivot = new PivotTransformation(config); - this.xLables = []; -}; + this.pivot = new PivotTransformation(config); + this.xLables = []; + }; -zeppelin.AreachartVisualization.prototype = Object.create(zeppelin.Nvd3ChartVisualization.prototype); + type() { + return 'stackedAreaChart'; + }; -zeppelin.AreachartVisualization.prototype.type = function() { - return 'stackedAreaChart'; -}; + getTransformation() { + return this.pivot; + }; -zeppelin.AreachartVisualization.prototype.getTransformation = function() { - return this.pivot; -}; + render(pivot) { + var d3Data = this.d3DataFromPivot( + pivot.schema, + pivot.rows, + pivot.keys, + pivot.groups, + pivot.values, + false, + true, + false); -zeppelin.AreachartVisualization.prototype.render = function(pivot) { - var d3Data = this.d3DataFromPivot( - pivot.schema, - pivot.rows, - pivot.keys, - pivot.groups, - pivot.values, - false, - true, - false); + this.xLabels = d3Data.xLabels; + super.render(d3Data); + }; - this.xLabels = d3Data.xLabels; - zeppelin.Nvd3ChartVisualization.prototype.render.call(this, d3Data); -}; + /** + * Set new config + */ + setConfig(config) { + super.setConfig(config); + this.pivot.setConfig(config); + }; -/** - * Set new config - */ -zeppelin.AreachartVisualization.prototype.setConfig = function(config) { - zeppelin.Nvd3ChartVisualization.prototype.setConfig.call(this, config); - this.pivot.setConfig(config); -}; - -zeppelin.AreachartVisualization.prototype.configureChart = function(chart) { - var self = this; - chart.xAxis.tickFormat(function(d) {return self.xAxisTickFormat(d, self.xLabels);}); - chart.yAxisTickFormat(function(d) {return self.yAxisTickFormat(d);}); - chart.yAxis.axisLabelDistance(50); - chart.useInteractiveGuideline(true); // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691) + configureChart(chart) { + var self = this; + chart.xAxis.tickFormat(function(d) {return self.xAxisTickFormat(d, self.xLabels);}); + chart.yAxisTickFormat(function(d) {return self.yAxisTickFormat(d);}); + chart.yAxis.axisLabelDistance(50); + chart.useInteractiveGuideline(true); // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691) - this.chart.style(this.config.style || 'stack'); + this.chart.style(this.config.style || 'stack'); - var self = this; - this.chart.dispatch.on('stateChange', function(s) { - self.config.style = s.style; + var self = this; + this.chart.dispatch.on('stateChange', function(s) { + self.config.style = s.style; - // give some time to animation finish - setTimeout(function() { - self.emitConfig(self.config); - }, 500); - }); -}; + // give some time to animation finish + setTimeout(function() { + self.emitConfig(self.config); + }, 500); + }); + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/visualization/builtins/visualization-barchart.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-barchart.js b/zeppelin-web/src/app/visualization/builtins/visualization-barchart.js index 9d151ec..a0ac573 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-barchart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-barchart.js @@ -12,64 +12,64 @@ * limitations under the License. */ -import zeppelin from '../../zeppelin'; +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import PivotTransformation from '../../tabledata/pivot'; /** * Visualize data in bar char */ -zeppelin.BarchartVisualization = function(targetEl, config) { - zeppelin.Nvd3ChartVisualization.call(this, targetEl, config); +export default class BarchartVisualization extends Nvd3ChartVisualization { + constructor(targetEl, config) { + super(targetEl, config); - var PivotTransformation = zeppelin.PivotTransformation; - this.pivot = new PivotTransformation(config); -}; + this.pivot = new PivotTransformation(config); + }; -zeppelin.BarchartVisualization.prototype = Object.create(zeppelin.Nvd3ChartVisualization.prototype); + type() { + return 'multiBarChart'; + }; -zeppelin.BarchartVisualization.prototype.type = function() { - return 'multiBarChart'; -}; + getTransformation() { + return this.pivot; + }; -zeppelin.BarchartVisualization.prototype.getTransformation = function() { - return this.pivot; -}; + render(pivot) { + var d3Data = this.d3DataFromPivot( + pivot.schema, + pivot.rows, + pivot.keys, + pivot.groups, + pivot.values, + true, + false, + true); -zeppelin.BarchartVisualization.prototype.render = function(pivot) { - var d3Data = this.d3DataFromPivot( - pivot.schema, - pivot.rows, - pivot.keys, - pivot.groups, - pivot.values, - true, - false, - true); + super.render(d3Data); + }; - zeppelin.Nvd3ChartVisualization.prototype.render.call(this, d3Data); -}; + /** + * Set new config + */ + setConfig(config) { + super.setConfig(config); + this.pivot.setConfig(config); + }; -/** - * Set new config - */ -zeppelin.BarchartVisualization.prototype.setConfig = function(config) { - zeppelin.Nvd3ChartVisualization.prototype.setConfig.call(this, config); - this.pivot.setConfig(config); -}; - -zeppelin.BarchartVisualization.prototype.configureChart = function(chart) { - var self = this; - chart.yAxis.axisLabelDistance(50); - chart.yAxis.tickFormat(function(d) {return self.yAxisTickFormat(d);}); + configureChart(chart) { + var self = this; + chart.yAxis.axisLabelDistance(50); + chart.yAxis.tickFormat(function(d) {return self.yAxisTickFormat(d);}); - this.chart.stacked(this.config.stacked); + this.chart.stacked(this.config.stacked); - var self = this; - this.chart.dispatch.on('stateChange', function(s) { - self.config.stacked = s.stacked; + var self = this; + this.chart.dispatch.on('stateChange', function(s) { + self.config.stacked = s.stacked; - // give some time to animation finish - setTimeout(function() { - self.emitConfig(self.config); - }, 500); - }); -}; + // give some time to animation finish + setTimeout(function() { + self.emitConfig(self.config); + }, 500); + }); + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js b/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js index 1dc5a42..aab51f8 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js @@ -12,103 +12,103 @@ * limitations under the License. */ -import zeppelin from '../../zeppelin'; +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import PivotTransformation from '../../tabledata/pivot'; /** * Visualize data in line chart */ -zeppelin.LinechartVisualization = function(targetEl, config) { - zeppelin.Nvd3ChartVisualization.call(this, targetEl, config); +export default class LinechartVisualization extends Nvd3ChartVisualization { + constructor(targetEl, config) { + super(targetEl, config); - var PivotTransformation = zeppelin.PivotTransformation; - this.pivot = new PivotTransformation(config); - this.xLables = []; -}; - -zeppelin.LinechartVisualization.prototype = Object.create(zeppelin.Nvd3ChartVisualization.prototype); + this.pivot = new PivotTransformation(config); + this.xLables = []; + }; -zeppelin.LinechartVisualization.prototype.type = function() { - if (this.config.lineWithFocus) { - return 'lineWithFocusChart'; - } else { - return 'lineChart'; - } -}; + type() { + if (this.config.lineWithFocus) { + return 'lineWithFocusChart'; + } else { + return 'lineChart'; + } + }; -zeppelin.LinechartVisualization.prototype.getTransformation = function() { - return this.pivot; -}; + getTransformation() { + return this.pivot; + }; -zeppelin.LinechartVisualization.prototype.render = function(pivot) { - var d3Data = this.d3DataFromPivot( - pivot.schema, - pivot.rows, - pivot.keys, - pivot.groups, - pivot.values, - false, - true, - false); + render(pivot) { + var d3Data = this.d3DataFromPivot( + pivot.schema, + pivot.rows, + pivot.keys, + pivot.groups, + pivot.values, + false, + true, + false); - this.xLabels = d3Data.xLabels; - zeppelin.Nvd3ChartVisualization.prototype.render.call(this, d3Data); -}; + this.xLabels = d3Data.xLabels; + super.render(d3Data); + }; -/** - * Set new config - */ -zeppelin.LinechartVisualization.prototype.setConfig = function(config) { - zeppelin.Nvd3ChartVisualization.prototype.setConfig.call(this, config); - this.pivot.setConfig(config); + /** + * Set new config + */ + setConfig(config) { + super.setConfig(config); + this.pivot.setConfig(config); - // change mode - if (this.currentMode !== config.lineWithFocus) { - zeppelin.Nvd3ChartVisualization.prototype.destroy.call(this); - this.currentMode = config.lineWithFocus; - } -}; + // change mode + if (this.currentMode !== config.lineWithFocus) { + super.destroy(); + this.currentMode = config.lineWithFocus; + } + }; -zeppelin.LinechartVisualization.prototype.configureChart = function(chart) { - var self = this; - chart.xAxis.tickFormat(function(d) {return self.xAxisTickFormat(d, self.xLabels);}); - chart.yAxis.tickFormat(function(d) {return self.yAxisTickFormat(d, self.xLabels);}); - chart.yAxis.axisLabelDistance(50); - if (chart.useInteractiveGuideline) { // lineWithFocusChart hasn't got useInteractiveGuideline - chart.useInteractiveGuideline(true); // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691) - } - if (this.config.forceY) { - chart.forceY([0]); // force y-axis minimum to 0 for line chart. - } else { - chart.forceY([]); - } -}; + configureChart(chart) { + var self = this; + chart.xAxis.tickFormat(function(d) {return self.xAxisTickFormat(d, self.xLabels);}); + chart.yAxis.tickFormat(function(d) {return self.yAxisTickFormat(d, self.xLabels);}); + chart.yAxis.axisLabelDistance(50); + if (chart.useInteractiveGuideline) { // lineWithFocusChart hasn't got useInteractiveGuideline + chart.useInteractiveGuideline(true); // for better UX and performance issue. (https://github.com/novus/nvd3/issues/691) + } + if (this.config.forceY) { + chart.forceY([0]); // force y-axis minimum to 0 for line chart. + } else { + chart.forceY([]); + } + }; -zeppelin.LinechartVisualization.prototype.getSetting = function(chart) { - var self = this; - var configObj = self.config; + getSetting(chart) { + var self = this; + var configObj = self.config; - return { - template: `<div> - <label> - <input type="checkbox" - ng-model="config.forceY" - ng-click="save()" /> - force Y to 0 - </label> - <br/> + return { + template: `<div> + <label> + <input type="checkbox" + ng-model="config.forceY" + ng-click="save()" /> + force Y to 0 + </label> + <br/> - <label> - <input type="checkbox" - ng-model="config.lineWithFocus" - ng-click="save()" /> - show line chart with focus - </label> - </div>`, - scope: { - config: configObj, - save: function() { - self.emitConfig(configObj); + <label> + <input type="checkbox" + ng-model="config.lineWithFocus" + ng-click="save()" /> + show line chart with focus + </label> + </div>`, + scope: { + config: configObj, + save: function() { + self.emitConfig(configObj); + } } - } + }; }; -}; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js b/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js index cf04215..61de1d9 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js @@ -12,246 +12,246 @@ * limitations under the License. */ -import zeppelin from '../../zeppelin'; +import Visualization from '../visualization'; /** * Visualize data in table format */ -zeppelin.Nvd3ChartVisualization = function(targetEl, config) { - zeppelin.Visualization.call(this, targetEl, config); - this.targetEl.append('<svg></svg>'); -}; - -zeppelin.Nvd3ChartVisualization.prototype = Object.create(zeppelin.Visualization.prototype); - -zeppelin.Visualization.prototype.refresh = function() { - if (this.chart) { - this.chart.update(); - } -}; - -zeppelin.Nvd3ChartVisualization.prototype.render = function(data) { - var type = this.type(); - var d3g = data.d3g; - - if (!this.chart) { - this.chart = nv.models[type](); - } - - this.configureChart(this.chart); - - var animationDuration = 300; - var numberOfDataThreshold = 150; - var height = this.targetEl.height(); - - // turn off animation when dataset is too large. (for performance issue) - // still, since dataset is large, the chart content sequentially appears like animated. - try { - if (d3g[0].values.length > numberOfDataThreshold) { - animationDuration = 0; - } - } catch (ignoreErr) { - } - - d3.select('#' + this.targetEl[0].id + ' svg') - .attr('height', height) - .datum(d3g) - .transition() - .duration(animationDuration) - .call(this.chart); - d3.select('#' + this.targetEl[0].id + ' svg').style.height = height + 'px'; -}; - -zeppelin.Nvd3ChartVisualization.prototype.type = function() { - // override this and return chart type -}; - -zeppelin.Nvd3ChartVisualization.prototype.configureChart = function(chart) { - // override this to configure chart -}; - -zeppelin.Nvd3ChartVisualization.prototype.groupedThousandsWith3DigitsFormatter = function(x) { - return d3.format(',')(d3.round(x, 3)); -}; - -zeppelin.Nvd3ChartVisualization.prototype.customAbbrevFormatter = function(x) { - var s = d3.format('.3s')(x); - switch (s[s.length - 1]) { - case 'G': return s.slice(0, -1) + 'B'; - } - return s; -}; - -zeppelin.Nvd3ChartVisualization.prototype.xAxisTickFormat = function(d, xLabels) { - if (xLabels[d] && (isNaN(parseFloat(xLabels[d])) || !isFinite(xLabels[d]))) { // to handle string type xlabel - return xLabels[d]; - } else { - return d; - } -}; - -zeppelin.Nvd3ChartVisualization.prototype.yAxisTickFormat = function(d) { - if (Math.abs(d) >= Math.pow(10,6)) { - return this.customAbbrevFormatter(d); - } - return this.groupedThousandsWith3DigitsFormatter(d); -}; - -zeppelin.Nvd3ChartVisualization.prototype.d3DataFromPivot = function( - schema, rows, keys, groups, values, allowTextXAxis, fillMissingValues, multiBarChart) { - // construct table data - var d3g = []; - - var concat = function(o, n) { - if (!o) { - return n; - } else { - return o + '.' + n; - } +export default class Nvd3ChartVisualization extends Visualization { + constructor(targetEl, config) { + super(targetEl, config); + this.targetEl.append('<svg></svg>'); }; - var getSchemaUnderKey = function(key, s) { - for (var c in key.children) { - s[c] = {}; - getSchemaUnderKey(key.children[c], s[c]); + refresh() { + if (this.chart) { + this.chart.update(); } }; - var traverse = function(sKey, s, rKey, r, func, rowName, rowValue, colName) { - //console.log("TRAVERSE sKey=%o, s=%o, rKey=%o, r=%o, rowName=%o, rowValue=%o, colName=%o", sKey, s, rKey, r, rowName, rowValue, colName); - - if (s.type === 'key') { - rowName = concat(rowName, sKey); - rowValue = concat(rowValue, rKey); - } else if (s.type === 'group') { - colName = concat(colName, rKey); - } else if (s.type === 'value' && sKey === rKey || valueOnly) { - colName = concat(colName, rKey); - func(rowName, rowValue, colName, r); + render(data) { + var type = this.type(); + var d3g = data.d3g; + + if (!this.chart) { + this.chart = nv.models[type](); } - for (var c in s.children) { - if (fillMissingValues && s.children[c].type === 'group' && r[c] === undefined) { - var cs = {}; - getSchemaUnderKey(s.children[c], cs); - traverse(c, s.children[c], c, cs, func, rowName, rowValue, colName); - continue; - } + this.configureChart(this.chart); - for (var j in r) { - if (s.children[c].type === 'key' || c === j) { - traverse(c, s.children[c], j, r[j], func, rowName, rowValue, colName); - } + var animationDuration = 300; + var numberOfDataThreshold = 150; + var height = this.targetEl.height(); + + // turn off animation when dataset is too large. (for performance issue) + // still, since dataset is large, the chart content sequentially appears like animated. + try { + if (d3g[0].values.length > numberOfDataThreshold) { + animationDuration = 0; } + } catch (ignoreErr) { + } + + d3.select('#' + this.targetEl[0].id + ' svg') + .attr('height', height) + .datum(d3g) + .transition() + .duration(animationDuration) + .call(this.chart); + d3.select('#' + this.targetEl[0].id + ' svg').style.height = height + 'px'; + }; + + type() { + // override this and return chart type + }; + + configureChart(chart) { + // override this to configure chart + }; + + groupedThousandsWith3DigitsFormatter(x) { + return d3.format(',')(d3.round(x, 3)); + }; + + customAbbrevFormatter(x) { + var s = d3.format('.3s')(x); + switch (s[s.length - 1]) { + case 'G': return s.slice(0, -1) + 'B'; } + return s; }; - var valueOnly = (keys.length === 0 && groups.length === 0 && values.length > 0); - var noKey = (keys.length === 0); - var isMultiBarChart = multiBarChart; + xAxisTickFormat(d, xLabels) { + if (xLabels[d] && (isNaN(parseFloat(xLabels[d])) || !isFinite(xLabels[d]))) { // to handle string type xlabel + return xLabels[d]; + } else { + return d; + } + }; - var sKey = Object.keys(schema)[0]; + yAxisTickFormat(d) { + if (Math.abs(d) >= Math.pow(10,6)) { + return this.customAbbrevFormatter(d); + } + return this.groupedThousandsWith3DigitsFormatter(d); + }; - var rowNameIndex = {}; - var rowIdx = 0; - var colNameIndex = {}; - var colIdx = 0; - var rowIndexValue = {}; + d3DataFromPivot( + schema, rows, keys, groups, values, allowTextXAxis, fillMissingValues, multiBarChart) { + // construct table data + var d3g = []; - for (var k in rows) { - traverse(sKey, schema[sKey], k, rows[k], function(rowName, rowValue, colName, value) { - //console.log("RowName=%o, row=%o, col=%o, value=%o", rowName, rowValue, colName, value); - if (rowNameIndex[rowValue] === undefined) { - rowIndexValue[rowIdx] = rowValue; - rowNameIndex[rowValue] = rowIdx++; + var concat = function(o, n) { + if (!o) { + return n; + } else { + return o + '.' + n; } + }; - if (colNameIndex[colName] === undefined) { - colNameIndex[colName] = colIdx++; + var getSchemaUnderKey = function(key, s) { + for (var c in key.children) { + s[c] = {}; + getSchemaUnderKey(key.children[c], s[c]); } - var i = colNameIndex[colName]; - if (noKey && isMultiBarChart) { - i = 0; + }; + + var traverse = function(sKey, s, rKey, r, func, rowName, rowValue, colName) { + //console.log("TRAVERSE sKey=%o, s=%o, rKey=%o, r=%o, rowName=%o, rowValue=%o, colName=%o", sKey, s, rKey, r, rowName, rowValue, colName); + + if (s.type === 'key') { + rowName = concat(rowName, sKey); + rowValue = concat(rowValue, rKey); + } else if (s.type === 'group') { + colName = concat(colName, rKey); + } else if (s.type === 'value' && sKey === rKey || valueOnly) { + colName = concat(colName, rKey); + func(rowName, rowValue, colName, r); } - if (!d3g[i]) { - d3g[i] = { - values: [], - key: (noKey && isMultiBarChart) ? 'values' : colName - }; - } + for (var c in s.children) { + if (fillMissingValues && s.children[c].type === 'group' && r[c] === undefined) { + var cs = {}; + getSchemaUnderKey(s.children[c], cs); + traverse(c, s.children[c], c, cs, func, rowName, rowValue, colName); + continue; + } - var xVar = isNaN(rowValue) ? ((allowTextXAxis) ? rowValue : rowNameIndex[rowValue]) : parseFloat(rowValue); - var yVar = 0; - if (xVar === undefined) { xVar = colName; } - if (value !== undefined) { - yVar = isNaN(value.value) ? 0 : parseFloat(value.value) / parseFloat(value.count); + for (var j in r) { + if (s.children[c].type === 'key' || c === j) { + traverse(c, s.children[c], j, r[j], func, rowName, rowValue, colName); + } + } } - d3g[i].values.push({ - x: xVar, - y: yVar - }); - }); - } - - // clear aggregation name, if possible - var namesWithoutAggr = {}; - var colName; - var withoutAggr; - // TODO - This part could use som refactoring - Weird if/else with similar actions and variable names - for (colName in colNameIndex) { - withoutAggr = colName.substring(0, colName.lastIndexOf('(')); - if (!namesWithoutAggr[withoutAggr]) { - namesWithoutAggr[withoutAggr] = 1; - } else { - namesWithoutAggr[withoutAggr]++; - } - } + }; + + var valueOnly = (keys.length === 0 && groups.length === 0 && values.length > 0); + var noKey = (keys.length === 0); + var isMultiBarChart = multiBarChart; + + var sKey = Object.keys(schema)[0]; + + var rowNameIndex = {}; + var rowIdx = 0; + var colNameIndex = {}; + var colIdx = 0; + var rowIndexValue = {}; + + for (var k in rows) { + traverse(sKey, schema[sKey], k, rows[k], function(rowName, rowValue, colName, value) { + //console.log("RowName=%o, row=%o, col=%o, value=%o", rowName, rowValue, colName, value); + if (rowNameIndex[rowValue] === undefined) { + rowIndexValue[rowIdx] = rowValue; + rowNameIndex[rowValue] = rowIdx++; + } - if (valueOnly) { - for (var valueIndex = 0; valueIndex < d3g[0].values.length; valueIndex++) { - colName = d3g[0].values[valueIndex].x; - if (!colName) { - continue; - } + if (colNameIndex[colName] === undefined) { + colNameIndex[colName] = colIdx++; + } + var i = colNameIndex[colName]; + if (noKey && isMultiBarChart) { + i = 0; + } - withoutAggr = colName.substring(0, colName.lastIndexOf('(')); - if (namesWithoutAggr[withoutAggr] <= 1) { - d3g[0].values[valueIndex].x = withoutAggr; - } + if (!d3g[i]) { + d3g[i] = { + values: [], + key: (noKey && isMultiBarChart) ? 'values' : colName + }; + } + + var xVar = isNaN(rowValue) ? ((allowTextXAxis) ? rowValue : rowNameIndex[rowValue]) : parseFloat(rowValue); + var yVar = 0; + if (xVar === undefined) { xVar = colName; } + if (value !== undefined) { + yVar = isNaN(value.value) ? 0 : parseFloat(value.value) / parseFloat(value.count); + } + d3g[i].values.push({ + x: xVar, + y: yVar + }); + }); } - } else { - for (var d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) { - colName = d3g[d3gIndex].key; + + // clear aggregation name, if possible + var namesWithoutAggr = {}; + var colName; + var withoutAggr; + // TODO - This part could use som refactoring - Weird if/else with similar actions and variable names + for (colName in colNameIndex) { withoutAggr = colName.substring(0, colName.lastIndexOf('(')); - if (namesWithoutAggr[withoutAggr] <= 1) { - d3g[d3gIndex].key = withoutAggr; + if (!namesWithoutAggr[withoutAggr]) { + namesWithoutAggr[withoutAggr] = 1; + } else { + namesWithoutAggr[withoutAggr]++; } } - // use group name instead of group.value as a column name, if there're only one group and one value selected. - if (groups.length === 1 && values.length === 1) { - for (d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) { + if (valueOnly) { + for (var valueIndex = 0; valueIndex < d3g[0].values.length; valueIndex++) { + colName = d3g[0].values[valueIndex].x; + if (!colName) { + continue; + } + + withoutAggr = colName.substring(0, colName.lastIndexOf('(')); + if (namesWithoutAggr[withoutAggr] <= 1) { + d3g[0].values[valueIndex].x = withoutAggr; + } + } + } else { + for (var d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) { colName = d3g[d3gIndex].key; - colName = colName.split('.').slice(0, -1).join('.'); - d3g[d3gIndex].key = colName; + withoutAggr = colName.substring(0, colName.lastIndexOf('(')); + if (namesWithoutAggr[withoutAggr] <= 1) { + d3g[d3gIndex].key = withoutAggr; + } + } + + // use group name instead of group.value as a column name, if there're only one group and one value selected. + if (groups.length === 1 && values.length === 1) { + for (d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) { + colName = d3g[d3gIndex].key; + colName = colName.split('.').slice(0, -1).join('.'); + d3g[d3gIndex].key = colName; + } } } - } - return { - xLabels: rowIndexValue, - d3g: d3g + return { + xLabels: rowIndexValue, + d3g: d3g + }; }; -}; -/** - * method will be invoked when visualization need to be destroyed. - * Don't need to destroy this.targetEl. - */ -zeppelin.Visualization.prototype.destroy = function() { - if (this.chart) { - d3.selectAll('#' + this.targetEl[0].id + ' svg > *').remove(); - this.chart = undefined; - } -}; + /** + * method will be invoked when visualization need to be destroyed. + * Don't need to destroy this.targetEl. + */ + destroy() { + if (this.chart) { + d3.selectAll('#' + this.targetEl[0].id + ' svg > *').remove(); + this.chart = undefined; + } + }; +} http://git-wip-us.apache.org/repos/asf/zeppelin/blob/d60dd6fd/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js b/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js index a2a1fcf..fdc67b1 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js @@ -12,61 +12,61 @@ * limitations under the License. */ -import zeppelin from '../../zeppelin'; +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import PivotTransformation from '../../tabledata/pivot'; /** * Visualize data in pie chart */ -zeppelin.PiechartVisualization = function(targetEl, config) { - zeppelin.Nvd3ChartVisualization.call(this, targetEl, config); +export default class PiechartVisualization extends Nvd3ChartVisualization { + constructor(targetEl, config) { + super(targetEl, config); - var PivotTransformation = zeppelin.PivotTransformation; - this.pivot = new PivotTransformation(config); -}; + this.pivot = new PivotTransformation(config); + }; -zeppelin.PiechartVisualization.prototype = Object.create(zeppelin.Nvd3ChartVisualization.prototype); + type() { + return 'pieChart'; + }; -zeppelin.PiechartVisualization.prototype.type = function() { - return 'pieChart'; -}; + getTransformation() { + return this.pivot; + }; -zeppelin.PiechartVisualization.prototype.getTransformation = function() { - return this.pivot; -}; + render(pivot) { + var d3Data = this.d3DataFromPivot( + pivot.schema, + pivot.rows, + pivot.keys, + pivot.groups, + pivot.values, + true, + false, + false); -zeppelin.PiechartVisualization.prototype.render = function(pivot) { - var d3Data = this.d3DataFromPivot( - pivot.schema, - pivot.rows, - pivot.keys, - pivot.groups, - pivot.values, - true, - false, - false); - - var d = d3Data.d3g; - var d3g = []; - if (d.length > 0) { - for (var i = 0; i < d[0].values.length ; i++) { - var e = d[0].values[i]; - d3g.push({ - label: e.x, - value: e.y - }); + var d = d3Data.d3g; + var d3g = []; + if (d.length > 0) { + for (var i = 0; i < d[0].values.length ; i++) { + var e = d[0].values[i]; + d3g.push({ + label: e.x, + value: e.y + }); + } } - } - zeppelin.Nvd3ChartVisualization.prototype.render.call(this, {d3g: d3g}); -}; + super.render({d3g: d3g}); + }; -/** - * Set new config - */ -zeppelin.PiechartVisualization.prototype.setConfig = function(config) { - zeppelin.Nvd3ChartVisualization.prototype.setConfig.call(this, config); - this.pivot.setConfig(config); -}; + /** + * Set new config + */ + setConfig(config) { + super.setConfig(config); + this.pivot.setConfig(config); + }; -zeppelin.PiechartVisualization.prototype.configureChart = function(chart) { - chart.x(function(d) { return d.label;}).y(function(d) { return d.value;}); -}; + configureChart(chart) { + chart.x(function(d) { return d.label;}).y(function(d) { return d.value;}); + }; +}