http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/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 6d47a9e..df161b9 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-linechart.js @@ -12,39 +12,39 @@ * limitations under the License. */ -import Nvd3ChartVisualization from './visualization-nvd3chart' -import PivotTransformation from '../../tabledata/pivot' -import moment from 'moment' +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import PivotTransformation from '../../tabledata/pivot'; +import moment from 'moment'; /** * Visualize data in line chart */ export default class LinechartVisualization extends Nvd3ChartVisualization { - constructor (targetEl, config) { - super(targetEl, config) + constructor(targetEl, config) { + super(targetEl, config); - this.pivot = new PivotTransformation(config) + this.pivot = new PivotTransformation(config); try { - this.config.rotate = {degree: config.rotate.degree} + this.config.rotate = {degree: config.rotate.degree}; } catch (e) { - this.config.rotate = {degree: '-45'} + this.config.rotate = {degree: '-45'}; } } - type () { + type() { if (this.config.lineWithFocus) { - return 'lineWithFocusChart' + return 'lineWithFocusChart'; } else { - return 'lineChart' + return 'lineChart'; } } - getTransformation () { - return this.pivot + getTransformation() { + return this.pivot; } - render (pivot) { + render(pivot) { let d3Data = this.d3DataFromPivot( pivot.schema, pivot.rows, @@ -53,113 +53,113 @@ export default class LinechartVisualization extends Nvd3ChartVisualization { pivot.values, false, true, - false) + false); - this.xLabels = d3Data.xLabels - super.render(d3Data) - this.config.changeXLabel(this.config.xLabelStatus) + this.xLabels = d3Data.xLabels; + super.render(d3Data); + this.config.changeXLabel(this.config.xLabelStatus); } /** * Set new config */ - setConfig (config) { - super.setConfig(config) - this.pivot.setConfig(config) + setConfig(config) { + super.setConfig(config); + this.pivot.setConfig(config); // change mode if (this.currentMode !== config.lineWithFocus) { - super.destroy() - this.currentMode = config.lineWithFocus + super.destroy(); + this.currentMode = config.lineWithFocus; } } - configureChart (chart) { - let self = this - let configObj = self.config + configureChart(chart) { + let self = this; + let configObj = self.config; - chart.xAxis.tickFormat(function (d) { + chart.xAxis.tickFormat(function(d) { if (self.config.isDateFormat) { if (self.config.dateFormat) { - return moment(new Date(self.xAxisTickFormat(d, self.xLabels))).format(self.config.dateFormat) + return moment(new Date(self.xAxisTickFormat(d, self.xLabels))).format(self.config.dateFormat); } else { - return moment(new Date(self.xAxisTickFormat(d, self.xLabels))).format('YYYY-MM-DD HH:mm:ss') + return moment(new Date(self.xAxisTickFormat(d, self.xLabels))).format('YYYY-MM-DD HH:mm:ss'); } } - return self.xAxisTickFormat(d, self.xLabels) - }) - chart.yAxis.tickFormat(function (d) { + return self.xAxisTickFormat(d, self.xLabels); + }); + chart.yAxis.tickFormat(function(d) { if (d === undefined) { - return 'N/A' + return 'N/A'; } - return self.yAxisTickFormat(d, self.xLabels) - }) - chart.yAxis.axisLabelDistance(50) + 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) + 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. + chart.forceY([0]); // force y-axis minimum to 0 for line chart. } else { - chart.forceY([]) + chart.forceY([]); } self.config.changeXLabel = function(type) { switch (type) { case 'default': - self.chart._options['showXAxis'] = true - self.chart._options['margin'] = {bottom: 50} - self.chart.xAxis.rotateLabels(0) - configObj.xLabelStatus = 'default' - break + self.chart._options['showXAxis'] = true; + self.chart._options['margin'] = {bottom: 50}; + self.chart.xAxis.rotateLabels(0); + configObj.xLabelStatus = 'default'; + break; case 'rotate': - self.chart._options['showXAxis'] = true - self.chart._options['margin'] = {bottom: 140} - self.chart.xAxis.rotateLabels(configObj.rotate.degree) - configObj.xLabelStatus = 'rotate' - break + self.chart._options['showXAxis'] = true; + self.chart._options['margin'] = {bottom: 140}; + self.chart.xAxis.rotateLabels(configObj.rotate.degree); + configObj.xLabelStatus = 'rotate'; + break; case 'hide': - self.chart._options['showXAxis'] = false - self.chart._options['margin'] = {bottom: 50} - d3.select('#' + self.targetEl[0].id + '> svg').select('g.nv-axis.nv-x').selectAll('*').remove() - configObj.xLabelStatus = 'hide' - break + self.chart._options['showXAxis'] = false; + self.chart._options['margin'] = {bottom: 50}; + d3.select('#' + self.targetEl[0].id + '> svg').select('g.nv-axis.nv-x').selectAll('*').remove(); + configObj.xLabelStatus = 'hide'; + break; } - self.emitConfig(configObj) - } + self.emitConfig(configObj); + }; self.config.isXLabelStatus = function(type) { if (configObj.xLabelStatus === type) { - return true + return true; } else { - return false + return false; } - } + }; self.config.setDegree = function(type) { - configObj.rotate.degree = type - self.chart.xAxis.rotateLabels(type) - self.emitConfig(configObj) - } - - self.config.setDateFormat = function (format) { - configObj.dateFormat = format - self.emitConfig(configObj) - } + configObj.rotate.degree = type; + self.chart.xAxis.rotateLabels(type); + self.emitConfig(configObj); + }; + + self.config.setDateFormat = function(format) { + configObj.dateFormat = format; + self.emitConfig(configObj); + }; } - getSetting (chart) { - let self = this - let configObj = self.config + getSetting(chart) { + let self = this; + let configObj = self.config; // default to visualize xLabel if (typeof (configObj.xLabelStatus) === 'undefined') { - configObj.changeXLabel('default') + configObj.changeXLabel('default'); } if (typeof (configObj.rotate.degree) === 'undefined' || configObj.rotate.degree === '') { - configObj.rotate.degree = '-45' - self.emitConfig(configObj) + configObj.rotate.degree = '-45'; + self.emitConfig(configObj); } return { @@ -199,14 +199,14 @@ export default class LinechartVisualization extends Nvd3ChartVisualization { </ng-include>`, scope: { config: configObj, - save: function () { - self.emitConfig(configObj) - } - } - } + save: function() { + self.emitConfig(configObj); + }, + }, + }; } - defaultY () { - return undefined + defaultY() { + return undefined; } }
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/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 f99fa3d..b3e6ec6 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-nvd3chart.js @@ -12,42 +12,42 @@ * limitations under the License. */ -import Visualization from '../visualization' +import Visualization from '../visualization'; /** * Visualize data in table format */ export default class Nvd3ChartVisualization extends Visualization { - constructor (targetEl, config) { - super(targetEl, config) - this.targetEl.append('<svg></svg>') + constructor(targetEl, config) { + super(targetEl, config); + this.targetEl.append('<svg></svg>'); } - refresh () { + refresh() { if (this.chart) { - this.chart.update() + this.chart.update(); } } - render (data) { - let type = this.type() - let d3g = data.d3g + render(data) { + let type = this.type(); + let d3g = data.d3g; if (!this.chart) { - this.chart = nv.models[type]() + this.chart = nv.models[type](); } - this.configureChart(this.chart) + this.configureChart(this.chart); - let animationDuration = 300 - let numberOfDataThreshold = 150 - let height = this.targetEl.height() + let animationDuration = 300; + let numberOfDataThreshold = 150; + let 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 + animationDuration = 0; } } catch (err) { /** ignore */ } @@ -56,206 +56,214 @@ export default class Nvd3ChartVisualization extends Visualization { .datum(d3g) .transition() .duration(animationDuration) - .call(this.chart) - d3.select('#' + this.targetEl[0].id + ' svg').style.height = height + 'px' + .call(this.chart); + d3.select('#' + this.targetEl[0].id + ' svg').style.height = height + 'px'; } - type () { + type() { // override this and return chart type } - configureChart (chart) { + configureChart(chart) { // override this to configure chart } - groupedThousandsWith3DigitsFormatter (x) { - return d3.format(',')(d3.round(x, 3)) + groupedThousandsWith3DigitsFormatter(x) { + return d3.format(',')(d3.round(x, 3)); } - customAbbrevFormatter (x) { - let s = d3.format('.3s')(x) + customAbbrevFormatter(x) { + let s = d3.format('.3s')(x); switch (s[s.length - 1]) { - case 'G': return s.slice(0, -1) + 'B' + case 'G': return s.slice(0, -1) + 'B'; } - return s + return s; } - defaultY () { - return 0 + defaultY() { + return 0; } - xAxisTickFormat (d, xLabels) { + xAxisTickFormat(d, xLabels) { if (xLabels[d] && (isNaN(parseFloat(xLabels[d])) || !isFinite(xLabels[d]))) { // to handle string type xlabel - return xLabels[d] + return xLabels[d]; } else { - return d + return d; } } - yAxisTickFormat (d) { + yAxisTickFormat(d) { if (Math.abs(d) >= Math.pow(10, 6)) { - return this.customAbbrevFormatter(d) + return this.customAbbrevFormatter(d); } - return this.groupedThousandsWith3DigitsFormatter(d) + return this.groupedThousandsWith3DigitsFormatter(d); } - d3DataFromPivot ( + d3DataFromPivot( schema, rows, keys, groups, values, allowTextXAxis, fillMissingValues, multiBarChart) { - let self = this + let self = this; // construct table data - let d3g = [] + let d3g = []; - let concat = function (o, n) { + let concat = function(o, n) { if (!o) { - return n + return n; } else { - return o + '.' + n + return o + '.' + n; } - } + }; - const getSchemaUnderKey = function (key, s) { + const getSchemaUnderKey = function(key, s) { for (let c in key.children) { - s[c] = {} - getSchemaUnderKey(key.children[c], s[c]) + if(key.children.hasOwnProperty(c)) { + s[c] = {}; + getSchemaUnderKey(key.children[c], s[c]); + } } - } + }; - const traverse = function (sKey, s, rKey, r, func, rowName, rowValue, colName) { + const 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) + rowName = concat(rowName, sKey); + rowValue = concat(rowValue, rKey); } else if (s.type === 'group') { - colName = concat(colName, rKey) + colName = concat(colName, rKey); } else if (s.type === 'value' && sKey === rKey || valueOnly) { - colName = concat(colName, rKey) - func(rowName, rowValue, colName, r) + colName = concat(colName, rKey); + func(rowName, rowValue, colName, r); } for (let c in s.children) { if (fillMissingValues && s.children[c].type === 'group' && r[c] === undefined) { - let cs = {} - getSchemaUnderKey(s.children[c], cs) - traverse(c, s.children[c], c, cs, func, rowName, rowValue, colName) - continue + let cs = {}; + getSchemaUnderKey(s.children[c], cs); + traverse(c, s.children[c], c, cs, func, rowName, rowValue, colName); + continue; } for (let j in r) { if (s.children[c].type === 'key' || c === j) { - traverse(c, s.children[c], j, r[j], func, rowName, rowValue, colName) + traverse(c, s.children[c], j, r[j], func, rowName, rowValue, colName); } } } - } + }; - const valueOnly = (keys.length === 0 && groups.length === 0 && values.length > 0) - let noKey = (keys.length === 0) - let isMultiBarChart = multiBarChart + const valueOnly = (keys.length === 0 && groups.length === 0 && values.length > 0); + let noKey = (keys.length === 0); + let isMultiBarChart = multiBarChart; - let sKey = Object.keys(schema)[0] + let sKey = Object.keys(schema)[0]; - let rowNameIndex = {} - let rowIdx = 0 - let colNameIndex = {} - let colIdx = 0 - let rowIndexValue = {} + let rowNameIndex = {}; + let rowIdx = 0; + let colNameIndex = {}; + let colIdx = 0; + let rowIndexValue = {}; for (let 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 (rows.hasOwnProperty(k)) { + 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 (colNameIndex[colName] === undefined) { - colNameIndex[colName] = colIdx++ - } - let i = colNameIndex[colName] - if (noKey && isMultiBarChart) { - i = 0 - } + if (colNameIndex[colName] === undefined) { + colNameIndex[colName] = colIdx++; + } + let i = colNameIndex[colName]; + if (noKey && isMultiBarChart) { + i = 0; + } - if (!d3g[i]) { - d3g[i] = { - values: [], - key: (noKey && isMultiBarChart) ? 'values' : colName + if (!d3g[i]) { + d3g[i] = { + values: [], + key: (noKey && isMultiBarChart) ? 'values' : colName, + }; } - } - let xVar = isNaN(rowValue) ? ((allowTextXAxis) ? rowValue : rowNameIndex[rowValue]) : parseFloat(rowValue) - let yVar = self.defaultY() - if (xVar === undefined) { xVar = colName } - if (value !== undefined) { - yVar = isNaN(value.value) ? self.defaultY() : parseFloat(value.value) / parseFloat(value.count) - } - d3g[i].values.push({ - x: xVar, - y: yVar - }) - }) + let xVar = isNaN(rowValue) ? ((allowTextXAxis) ? rowValue : rowNameIndex[rowValue]) : parseFloat(rowValue); + let yVar = self.defaultY(); + if (xVar === undefined) { + xVar = colName; + } + if (value !== undefined) { + yVar = isNaN(value.value) ? self.defaultY() : parseFloat(value.value) / parseFloat(value.count); + } + d3g[i].values.push({ + x: xVar, + y: yVar, + }); + }); + } } // clear aggregation name, if possible - let namesWithoutAggr = {} - let colName - let withoutAggr + let namesWithoutAggr = {}; + let colName; + let 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]++ + if (colNameIndex.hasOwnProperty(colName)) { + withoutAggr = colName.substring(0, colName.lastIndexOf('(')); + if (!namesWithoutAggr[withoutAggr]) { + namesWithoutAggr[withoutAggr] = 1; + } else { + namesWithoutAggr[withoutAggr]++; + } } } if (valueOnly) { for (let valueIndex = 0; valueIndex < d3g[0].values.length; valueIndex++) { - colName = d3g[0].values[valueIndex].x + colName = d3g[0].values[valueIndex].x; if (!colName) { - continue + continue; } - withoutAggr = colName.substring(0, colName.lastIndexOf('(')) + withoutAggr = colName.substring(0, colName.lastIndexOf('(')); if (namesWithoutAggr[withoutAggr] <= 1) { - d3g[0].values[valueIndex].x = withoutAggr + d3g[0].values[valueIndex].x = withoutAggr; } } } else { for (let d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) { - colName = d3g[d3gIndex].key - withoutAggr = colName.substring(0, colName.lastIndexOf('(')) + colName = d3g[d3gIndex].key; + withoutAggr = colName.substring(0, colName.lastIndexOf('(')); if (namesWithoutAggr[withoutAggr] <= 1) { - d3g[d3gIndex].key = withoutAggr + 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 (let d3gIndex = 0; d3gIndex < d3g.length; d3gIndex++) { - colName = d3g[d3gIndex].key - colName = colName.split('.').slice(0, -1).join('.') - d3g[d3gIndex].key = colName + colName = d3g[d3gIndex].key; + colName = colName.split('.').slice(0, -1).join('.'); + d3g[d3gIndex].key = colName; } } } return { xLabels: rowIndexValue, - d3g: d3g - } + d3g: d3g, + }; } /** * method will be invoked when visualization need to be destroyed. * Don't need to destroy this.targetEl. */ - destroy () { + destroy() { if (this.chart) { - d3.selectAll('#' + this.targetEl[0].id + ' svg > *').remove() - this.chart = undefined + d3.selectAll('#' + this.targetEl[0].id + ' svg > *').remove(); + this.chart = undefined; } } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/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 4f80654..84479cb 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-piechart.js @@ -12,29 +12,29 @@ * limitations under the License. */ -import Nvd3ChartVisualization from './visualization-nvd3chart' -import PivotTransformation from '../../tabledata/pivot' +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import PivotTransformation from '../../tabledata/pivot'; /** * Visualize data in pie chart */ export default class PiechartVisualization extends Nvd3ChartVisualization { - constructor (targetEl, config) { - super(targetEl, config) - this.pivot = new PivotTransformation(config) + constructor(targetEl, config) { + super(targetEl, config); + this.pivot = new PivotTransformation(config); } - type () { - return 'pieChart' + type() { + return 'pieChart'; } - getTransformation () { - return this.pivot + getTransformation() { + return this.pivot; } - render (pivot) { + render(pivot) { // [ZEPPELIN-2253] New chart function will be created each time inside super.render() - this.chart = null + this.chart = null; const d3Data = this.d3DataFromPivot( pivot.schema, pivot.rows, @@ -43,41 +43,45 @@ export default class PiechartVisualization extends Nvd3ChartVisualization { pivot.values, true, false, - false) - const d = d3Data.d3g + false); + const d = d3Data.d3g; - let generateLabel + let generateLabel; // data is grouped if (pivot.groups && pivot.groups.length > 0) { - generateLabel = (suffix, prefix) => `${prefix}.${suffix}` + generateLabel = (suffix, prefix) => `${prefix}.${suffix}`; } else { // data isn't grouped - generateLabel = suffix => suffix + generateLabel = (suffix) => suffix; } - let d3g = d.map(group => { - return group.values.map(row => ({ + let d3g = d.map((group) => { + return group.values.map((row) => ({ label: generateLabel(row.x, group.key), - value: row.y - })) - }) + value: row.y, + })); + }); // the map function returns d3g as a nested array // [].concat flattens it, http://stackoverflow.com/a/10865042/5154397 - d3g = [].concat.apply([], d3g) // eslint-disable-line prefer-spread - super.render({d3g: d3g}) + d3g = [].concat.apply([], d3g); // eslint-disable-line prefer-spread + super.render({d3g: d3g}); } /** * Set new config */ - setConfig (config) { - super.setConfig(config) - this.pivot.setConfig(config) + setConfig(config) { + super.setConfig(config); + this.pivot.setConfig(config); } - configureChart (chart) { - chart.x(function (d) { return d.label }) - .y(function (d) { return d.value }) - .showLabels(false) - .showTooltipPercent(true) + configureChart(chart) { + chart.x(function(d) { + return d.label; + }) + .y(function(d) { + return d.value; + }) + .showLabels(false) + .showTooltipPercent(true); } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/app/visualization/builtins/visualization-scatterchart.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-scatterchart.js b/zeppelin-web/src/app/visualization/builtins/visualization-scatterchart.js index d7c00db..fad7500 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-scatterchart.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-scatterchart.js @@ -12,25 +12,25 @@ * limitations under the License. */ -import Nvd3ChartVisualization from './visualization-nvd3chart' -import ColumnselectorTransformation from '../../tabledata/columnselector' +import Nvd3ChartVisualization from './visualization-nvd3chart'; +import ColumnselectorTransformation from '../../tabledata/columnselector'; /** * Visualize data in scatter char */ export default class ScatterchartVisualization extends Nvd3ChartVisualization { - constructor (targetEl, config) { - super(targetEl, config) + constructor(targetEl, config) { + super(targetEl, config); this.columnselectorProps = [ { - name: 'xAxis' + name: 'xAxis', }, { - name: 'yAxis' + name: 'yAxis', }, { - name: 'group' + name: 'group', }, { name: 'size', @@ -39,322 +39,330 @@ export default class ScatterchartVisualization extends Nvd3ChartVisualization { 'number of values in corresponding coordinate' will be used. Zeppelin considers values as discrete when input values contain a string or the number of distinct values is greater than 5% of the total number of values. - This field turns grey when the selected option is invalid.` - } - ] - this.columnselector = new ColumnselectorTransformation(config, this.columnselectorProps) + This field turns grey when the selected option is invalid.`, + }, + ]; + this.columnselector = new ColumnselectorTransformation(config, this.columnselectorProps); } - type () { - return 'scatterChart' + type() { + return 'scatterChart'; } - getTransformation () { - return this.columnselector + getTransformation() { + return this.columnselector; } - render (tableData) { - this.tableData = tableData - this.selectDefault() - let d3Data = this.setScatterChart(tableData, true) - this.xLabels = d3Data.xLabels - this.yLabels = d3Data.yLabels + render(tableData) { + this.tableData = tableData; + this.selectDefault(); + let d3Data = this.setScatterChart(tableData, true); + this.xLabels = d3Data.xLabels; + this.yLabels = d3Data.yLabels; - super.render(d3Data) + super.render(d3Data); } - configureChart (chart) { - let self = this + configureChart(chart) { + let self = this; - chart.xAxis.tickFormat(function (d) { // TODO remove round after bump to nvd3 > 1.8.5 - return self.xAxisTickFormat(Math.round(d * 1e3) / 1e3, self.xLabels) - }) + chart.xAxis.tickFormat(function(d) { // TODO remove round after bump to nvd3 > 1.8.5 + return self.xAxisTickFormat(Math.round(d * 1e3) / 1e3, self.xLabels); + }); - chart.yAxis.tickFormat(function (d) { // TODO remove round after bump to nvd3 > 1.8.5 - return self.yAxisTickFormat(Math.round(d * 1e3) / 1e3, self.yLabels) - }) + chart.yAxis.tickFormat(function(d) { // TODO remove round after bump to nvd3 > 1.8.5 + return self.yAxisTickFormat(Math.round(d * 1e3) / 1e3, self.yLabels); + }); - chart.showDistX(true).showDistY(true) + chart.showDistX(true).showDistY(true); // handle the problem of tooltip not showing when muliple points have same value. } - yAxisTickFormat (d, yLabels) { + yAxisTickFormat(d, yLabels) { if (yLabels[d] && (isNaN(parseFloat(yLabels[d])) || !isFinite(yLabels[d]))) { // to handle string type xlabel - return yLabels[d] + return yLabels[d]; } else { - return super.yAxisTickFormat(d) + return super.yAxisTickFormat(d); } } - selectDefault () { + selectDefault() { if (!this.config.xAxis && !this.config.yAxis) { if (this.tableData.columns.length > 1) { - this.config.xAxis = this.tableData.columns[0] - this.config.yAxis = this.tableData.columns[1] + this.config.xAxis = this.tableData.columns[0]; + this.config.yAxis = this.tableData.columns[1]; } else if (this.tableData.columns.length === 1) { - this.config.xAxis = this.tableData.columns[0] + this.config.xAxis = this.tableData.columns[0]; } } } - setScatterChart (data, refresh) { - let xAxis = this.config.xAxis - let yAxis = this.config.yAxis - let group = this.config.group - let size = this.config.size - - let xValues = [] - let yValues = [] - let rows = {} - let d3g = [] - - let rowNameIndex = {} - let colNameIndex = {} - let grpNameIndex = {} - let rowIndexValue = {} - let colIndexValue = {} - let grpIndexValue = {} - let rowIdx = 0 - let colIdx = 0 - let grpIdx = 0 - let grpName = '' - - let xValue - let yValue - let row + setScatterChart(data, refresh) { + let xAxis = this.config.xAxis; + let yAxis = this.config.yAxis; + let group = this.config.group; + let size = this.config.size; + + let xValues = []; + let yValues = []; + let rows = {}; + let d3g = []; + + let rowNameIndex = {}; + let colNameIndex = {}; + let grpNameIndex = {}; + let rowIndexValue = {}; + let colIndexValue = {}; + let grpIndexValue = {}; + let rowIdx = 0; + let colIdx = 0; + let grpIdx = 0; + let grpName = ''; + + let xValue; + let yValue; + let row; if (!xAxis && !yAxis) { return { - d3g: [] - } + d3g: [], + }; } for (let i = 0; i < data.rows.length; i++) { - row = data.rows[i] + row = data.rows[i]; if (xAxis) { - xValue = row[xAxis.index] - xValues[i] = xValue + xValue = row[xAxis.index]; + xValues[i] = xValue; } if (yAxis) { - yValue = row[yAxis.index] - yValues[i] = yValue + yValue = row[yAxis.index]; + yValues[i] = yValue; } } let isAllDiscrete = ((xAxis && yAxis && this.isDiscrete(xValues) && this.isDiscrete(yValues)) || (!xAxis && this.isDiscrete(yValues)) || - (!yAxis && this.isDiscrete(xValues))) + (!yAxis && this.isDiscrete(xValues))); if (isAllDiscrete) { - rows = this.setDiscreteScatterData(data) + rows = this.setDiscreteScatterData(data); } else { - rows = data.rows + rows = data.rows; } if (!group && isAllDiscrete) { - grpName = 'count' + grpName = 'count'; } else if (!group && !size) { if (xAxis && yAxis) { - grpName = '(' + xAxis.name + ', ' + yAxis.name + ')' + grpName = '(' + xAxis.name + ', ' + yAxis.name + ')'; } else if (xAxis && !yAxis) { - grpName = xAxis.name + grpName = xAxis.name; } else if (!xAxis && yAxis) { - grpName = yAxis.name + grpName = yAxis.name; } } else if (!group && size) { - grpName = size.name + grpName = size.name; } - let epsilon = 1e-4 // TODO remove after bump to nvd3 > 1.8.5 + let epsilon = 1e-4; // TODO remove after bump to nvd3 > 1.8.5 for (let i = 0; i < rows.length; i++) { - row = rows[i] + row = rows[i]; if (xAxis) { - xValue = row[xAxis.index] + xValue = row[xAxis.index]; } if (yAxis) { - yValue = row[yAxis.index] + yValue = row[yAxis.index]; } if (group) { - grpName = row[group.index] + grpName = row[group.index]; } - let sz = (isAllDiscrete) ? row[row.length - 1] : ((size) ? row[size.index] : 1) + let sz = (isAllDiscrete) ? row[row.length - 1] : ((size) ? row[size.index] : 1); if (grpNameIndex[grpName] === undefined) { - grpIndexValue[grpIdx] = grpName - grpNameIndex[grpName] = grpIdx++ + grpIndexValue[grpIdx] = grpName; + grpNameIndex[grpName] = grpIdx++; } if (xAxis && rowNameIndex[xValue] === undefined) { - rowIndexValue[rowIdx] = xValue - rowNameIndex[xValue] = rowIdx++ + rowIndexValue[rowIdx] = xValue; + rowNameIndex[xValue] = rowIdx++; } if (yAxis && colNameIndex[yValue] === undefined) { - colIndexValue[colIdx] = yValue - colNameIndex[yValue] = colIdx++ + colIndexValue[colIdx] = yValue; + colNameIndex[yValue] = colIdx++; } if (!d3g[grpNameIndex[grpName]]) { d3g[grpNameIndex[grpName]] = { key: grpName, - values: [] - } + values: [], + }; } // TODO remove epsilon jitter after bump to nvd3 > 1.8.5 - let xval = 0 - let yval = 0 + let xval = 0; + let yval = 0; if (xAxis) { - xval = (isNaN(xValue) ? rowNameIndex[xValue] : parseFloat(xValue)) + Math.random() * epsilon + xval = (isNaN(xValue) ? rowNameIndex[xValue] : parseFloat(xValue)) + Math.random() * epsilon; } if (yAxis) { - yval = (isNaN(yValue) ? colNameIndex[yValue] : parseFloat(yValue)) + Math.random() * epsilon + yval = (isNaN(yValue) ? colNameIndex[yValue] : parseFloat(yValue)) + Math.random() * epsilon; } d3g[grpNameIndex[grpName]].values.push({ x: xval, y: yval, - size: isNaN(parseFloat(sz)) ? 1 : parseFloat(sz) - }) + size: isNaN(parseFloat(sz)) ? 1 : parseFloat(sz), + }); } // TODO remove sort and dedup after bump to nvd3 > 1.8.5 - let d3gvalues = d3g[grpNameIndex[grpName]].values - d3gvalues.sort(function (a, b) { - return ((a['x'] - b['x']) || (a['y'] - b['y'])) - }) + let d3gvalues = d3g[grpNameIndex[grpName]].values; + d3gvalues.sort(function(a, b) { + return ((a['x'] - b['x']) || (a['y'] - b['y'])); + }); for (let i = 0; i < d3gvalues.length - 1;) { if ((Math.abs(d3gvalues[i]['x'] - d3gvalues[i + 1]['x']) < epsilon) && (Math.abs(d3gvalues[i]['y'] - d3gvalues[i + 1]['y']) < epsilon)) { - d3gvalues.splice(i + 1, 1) + d3gvalues.splice(i + 1, 1); } else { - i++ + i++; } } return { xLabels: rowIndexValue, yLabels: colIndexValue, - d3g: d3g - } + d3g: d3g, + }; } - setDiscreteScatterData (data) { - let xAxis = this.config.xAxis - let yAxis = this.config.yAxis - let group = this.config.group + setDiscreteScatterData(data) { + let xAxis = this.config.xAxis; + let yAxis = this.config.yAxis; + let group = this.config.group; - let xValue - let yValue - let grp + let xValue; + let yValue; + let grp; - let rows = {} + let rows = {}; for (let i = 0; i < data.rows.length; i++) { - let row = data.rows[i] + let row = data.rows[i]; if (xAxis) { - xValue = row[xAxis.index] + xValue = row[xAxis.index]; } if (yAxis) { - yValue = row[yAxis.index] + yValue = row[yAxis.index]; } if (group) { - grp = row[group.index] + grp = row[group.index]; } - let key = xValue + ',' + yValue + ',' + grp + let key = xValue + ',' + yValue + ',' + grp; if (!rows[key]) { rows[key] = { x: xValue, y: yValue, group: grp, - size: 1 - } + size: 1, + }; } else { - rows[key].size++ + rows[key].size++; } } // change object into array - let newRows = [] + let newRows = []; for (let r in rows) { - let newRow = [] - if (xAxis) { newRow[xAxis.index] = rows[r].x } - if (yAxis) { newRow[yAxis.index] = rows[r].y } - if (group) { newRow[group.index] = rows[r].group } - newRow[data.rows[0].length] = rows[r].size - newRows.push(newRow) + if (rows.hasOwnProperty(r)) { + let newRow = []; + if (xAxis) { + newRow[xAxis.index] = rows[r].x; + } + if (yAxis) { + newRow[yAxis.index] = rows[r].y; + } + if (group) { + newRow[group.index] = rows[r].group; + } + newRow[data.rows[0].length] = rows[r].size; + newRows.push(newRow); + } } - return newRows + return newRows; } - isDiscrete (field) { - let getUnique = function (f) { - let uniqObj = {} - let uniqArr = [] - let j = 0 + isDiscrete(field) { + let getUnique = function(f) { + let uniqObj = {}; + let uniqArr = []; + let j = 0; for (let i = 0; i < f.length; i++) { - let item = f[i] + let item = f[i]; if (uniqObj[item] !== 1) { - uniqObj[item] = 1 - uniqArr[j++] = item + uniqObj[item] = 1; + uniqArr[j++] = item; } } - return uniqArr - } + return uniqArr; + }; for (let i = 0; i < field.length; i++) { if (isNaN(parseFloat(field[i])) && (typeof field[i] === 'string' || field[i] instanceof String)) { - return true + return true; } } - let threshold = 0.05 - let unique = getUnique(field) + let threshold = 0.05; + let unique = getUnique(field); if (unique.length / field.length < threshold) { - return true + return true; } else { - return false + return false; } } - isValidSizeOption (options) { - let xValues = [] - let yValues = [] - let rows = this.tableData.rows + isValidSizeOption(options) { + let xValues = []; + let yValues = []; + let rows = this.tableData.rows; for (let i = 0; i < rows.length; i++) { - let row = rows[i] - let size = row[options.size.index] + let row = rows[i]; + let size = row[options.size.index]; // check if the field is numeric if (isNaN(parseFloat(size)) || !isFinite(size)) { - return false + return false; } if (options.xAxis) { - let x = row[options.xAxis.index] - xValues[i] = x + let x = row[options.xAxis.index]; + xValues[i] = x; } if (options.yAxis) { - let y = row[options.yAxis.index] - yValues[i] = y + let y = row[options.yAxis.index]; + yValues[i] = y; } } // check if all existing fields are discrete let isAllDiscrete = ((options.xAxis && options.yAxis && this.isDiscrete(xValues) && this.isDiscrete(yValues)) || (!options.xAxis && this.isDiscrete(yValues)) || - (!options.yAxis && this.isDiscrete(xValues))) + (!options.yAxis && this.isDiscrete(xValues))); if (isAllDiscrete) { - return false + return false; } - return true + return true; } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/app/visualization/builtins/visualization-table.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-table.js b/zeppelin-web/src/app/visualization/builtins/visualization-table.js index afb5394..d77efbc 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-table.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-table.js @@ -12,8 +12,8 @@ * limitations under the License. */ -import Visualization from '../visualization' -import PassthroughTransformation from '../../tabledata/passthrough' +import Visualization from '../visualization'; +import PassthroughTransformation from '../../tabledata/passthrough'; import { Widget, ValueType, @@ -22,9 +22,9 @@ import { initializeTableConfig, resetTableOptionConfig, DefaultTableColumnType, TableColumnType, updateColumnTypeState, parseTableOption, -} from './visualization-util' +} from './visualization-util'; -const SETTING_TEMPLATE = require('./visualization-table-setting.html') +const SETTING_TEMPLATE = require('./visualization-table-setting.html'); const TABLE_OPTION_SPECS = [ { @@ -48,41 +48,43 @@ const TABLE_OPTION_SPECS = [ widget: Widget.CHECKBOX, description: 'Enable a footer for displaying aggregated values', }, -] +]; /** * Visualize data in table format */ export default class TableVisualization extends Visualization { - constructor (targetEl, config) { - super(targetEl, config) - this.passthrough = new PassthroughTransformation(config) - this.emitTimeout = null - this.isRestoring = false + constructor(targetEl, config) { + super(targetEl, config); + this.passthrough = new PassthroughTransformation(config); + this.emitTimeout = null; + this.isRestoring = false; - initializeTableConfig(config, TABLE_OPTION_SPECS) + initializeTableConfig(config, TABLE_OPTION_SPECS); } getColumnMinWidth(colName) { - let width = 150 // default - const calculatedWidth = colName.length * 10 + let width = 150; // default + const calculatedWidth = colName.length * 10; // use the broad one - if (calculatedWidth > width) { width = calculatedWidth } + if (calculatedWidth > width) { + width = calculatedWidth; + } - return width + return width; } createGridOptions(tableData, onRegisterApiCallback, config) { - const rows = tableData.rows - const columnNames = tableData.columns.map(c => c.name) + const rows = tableData.rows; + const columnNames = tableData.columns.map((c) => c.name); - const gridData = rows.map(r => { + const gridData = rows.map((r) => { return columnNames.reduce((acc, colName, index) => { - acc[colName] = r[index] - return acc - }, {}) - }) + acc[colName] = r[index]; + return acc; + }, {}); + }); const gridOptions = { data: gridData, @@ -94,7 +96,7 @@ export default class TableVisualization extends Visualization { fastWatch: false, treeRowHeaderAlwaysVisible: false, - columnDefs: columnNames.map(colName => { + columnDefs: columnNames.map((colName) => { return { displayName: colName, name: colName, @@ -111,7 +113,7 @@ export default class TableVisualization extends Visualization { `, minWidth: this.getColumnMinWidth(colName), width: '*', - } + }; }), rowEditWaitInterval: -1, /** disable saveRow event */ enableRowHashing: true, @@ -126,127 +128,131 @@ export default class TableVisualization extends Visualization { saveTreeView: true, saveFilter: true, saveSelection: false, - } + }; - return gridOptions + return gridOptions; } getGridElemId() { // angular doesn't allow `-` in scope variable name - const gridElemId = `${this.targetEl[0].id}_grid`.replace('-', '_') - return gridElemId + const gridElemId = `${this.targetEl[0].id}_grid`.replace('-', '_'); + return gridElemId; } getGridApiId() { // angular doesn't allow `-` in scope variable name - const gridApiId = `${this.targetEl[0].id}_gridApi`.replace('-', '_') - return gridApiId + const gridApiId = `${this.targetEl[0].id}_gridApi`.replace('-', '_'); + return gridApiId; } refresh() { - const gridElemId = this.getGridElemId() - const gridElem = angular.element(`#${gridElemId}`) + const gridElemId = this.getGridElemId(); + const gridElem = angular.element(`#${gridElemId}`); if (gridElem) { - gridElem.css('height', this.targetEl.height() - 10) + gridElem.css('height', this.targetEl.height() - 10); } } refreshGrid() { - const gridElemId = this.getGridElemId() - const gridElem = angular.element(`#${gridElemId}`) + const gridElemId = this.getGridElemId(); + const gridElem = angular.element(`#${gridElemId}`); if (gridElem) { - const scope = this.getScope() - const gridApiId = this.getGridApiId() - scope[gridApiId].core.notifyDataChange(this._uiGridConstants.dataChange.ALL) + const scope = this.getScope(); + const gridApiId = this.getGridApiId(); + scope[gridApiId].core.notifyDataChange(this._uiGridConstants.dataChange.ALL); } } updateColDefType(colDef, type) { - if (type === colDef.type) { return } + if (type === colDef.type) { + return; + } - colDef.type = type - const colName = colDef.name - const config = this.config + colDef.type = type; + const colName = colDef.name; + const config = this.config; if (config.tableColumnTypeState.names && config.tableColumnTypeState.names[colName]) { - config.tableColumnTypeState.names[colName] = type - this.persistConfigWithGridState(this.config) + config.tableColumnTypeState.names[colName] = type; + this.persistConfigWithGridState(this.config); } } addColumnMenus(gridOptions) { - if (!gridOptions || !gridOptions.columnDefs) { return } + if (!gridOptions || !gridOptions.columnDefs) { + return; + } - const self = this // for closure + const self = this; // for closure // SHOULD use `function() { ... }` syntax for each action to get `this` - gridOptions.columnDefs.map(colDef => { + gridOptions.columnDefs.map((colDef) => { colDef.menuItems = [ { title: 'Type: String', action: function() { - self.updateColDefType(this.context.col.colDef, TableColumnType.STRING) + self.updateColDefType(this.context.col.colDef, TableColumnType.STRING); }, active: function() { - return this.context.col.colDef.type === TableColumnType.STRING + return this.context.col.colDef.type === TableColumnType.STRING; }, }, { title: 'Type: Number', action: function() { - self.updateColDefType(this.context.col.colDef, TableColumnType.NUMBER) + self.updateColDefType(this.context.col.colDef, TableColumnType.NUMBER); }, active: function() { - return this.context.col.colDef.type === TableColumnType.NUMBER + return this.context.col.colDef.type === TableColumnType.NUMBER; }, }, { title: 'Type: Date', action: function() { - self.updateColDefType(this.context.col.colDef, TableColumnType.DATE) + self.updateColDefType(this.context.col.colDef, TableColumnType.DATE); }, active: function() { - return this.context.col.colDef.type === TableColumnType.DATE + return this.context.col.colDef.type === TableColumnType.DATE; }, }, - ] - }) + ]; + }); } setDynamicGridOptions(gridOptions, config) { // parse based on their type definitions - const parsed = parseTableOption(TABLE_OPTION_SPECS, config.tableOptionValue) + const parsed = parseTableOption(TABLE_OPTION_SPECS, config.tableOptionValue); - const { showAggregationFooter, useFilter, showPagination, } = parsed + const {showAggregationFooter, useFilter, showPagination} = parsed; - gridOptions.showGridFooter = false - gridOptions.showColumnFooter = showAggregationFooter - gridOptions.enableFiltering = useFilter + gridOptions.showGridFooter = false; + gridOptions.showColumnFooter = showAggregationFooter; + gridOptions.enableFiltering = useFilter; - gridOptions.enablePagination = showPagination - gridOptions.enablePaginationControls = showPagination + gridOptions.enablePagination = showPagination; + gridOptions.enablePaginationControls = showPagination; if (showPagination) { - gridOptions.paginationPageSize = 50 - gridOptions.paginationPageSizes = [25, 50, 100, 250, 1000] + gridOptions.paginationPageSize = 50; + gridOptions.paginationPageSizes = [25, 50, 100, 250, 1000]; } // selection can't be rendered dynamically in ui-grid 4.0.4 - gridOptions.enableRowSelection = false - gridOptions.enableRowHeaderSelection = false - gridOptions.enableFullRowSelection = false - gridOptions.enableSelectAll = false - gridOptions.enableGroupHeaderSelection = false - gridOptions.enableSelectionBatchEvent = false + gridOptions.enableRowSelection = false; + gridOptions.enableRowHeaderSelection = false; + gridOptions.enableFullRowSelection = false; + gridOptions.enableSelectAll = false; + gridOptions.enableGroupHeaderSelection = false; + gridOptions.enableSelectionBatchEvent = false; } - render (tableData) { - const gridElemId = this.getGridElemId() - let gridElem = document.getElementById(gridElemId) + render(tableData) { + const gridElemId = this.getGridElemId(); + let gridElem = document.getElementById(gridElemId); - const config = this.config - const self = this // for closure + const config = this.config; + const self = this; // for closure if (!gridElem) { // create, compile and append grid elem @@ -261,125 +267,147 @@ export default class TableVisualization extends Visualization { ui-grid-move-columns ui-grid-grouping ui-grid-save-state - ui-grid-exporter></div>`) + ui-grid-exporter></div>`); - gridElem.css('height', this.targetEl.height() - 10) - const scope = this.getScope() - gridElem = this._compile(gridElem)(scope) - this.targetEl.append(gridElem) + gridElem.css('height', this.targetEl.height() - 10); + const scope = this.getScope(); + gridElem = this._compile(gridElem)(scope); + this.targetEl.append(gridElem); // set gridOptions for this elem - const gridOptions = this.createGridOptions(tableData, onRegisterApiCallback, config) - this.setDynamicGridOptions(gridOptions, config) - this.addColumnMenus(gridOptions) - scope[gridElemId] = gridOptions + const gridOptions = this.createGridOptions(tableData, onRegisterApiCallback, config); + this.setDynamicGridOptions(gridOptions, config); + this.addColumnMenus(gridOptions); + scope[gridElemId] = gridOptions; // set gridApi for this elem - const gridApiId = this.getGridApiId() + const gridApiId = this.getGridApiId(); const onRegisterApiCallback = (gridApi) => { - scope[gridApiId] = gridApi + scope[gridApiId] = gridApi; // should restore state before registering APIs // register callbacks for change evens // should persist `self.config` instead `config` (closure issue) - gridApi.core.on.columnVisibilityChanged(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.colMovable.on.columnPositionChanged(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.core.on.sortChanged(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.core.on.filterChanged(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.grouping.on.aggregationChanged(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.grouping.on.groupingChanged(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.treeBase.on.rowCollapsed(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.treeBase.on.rowExpanded(scope, () => { self.persistConfigWithGridState(self.config) }) - gridApi.colResizable.on.columnSizeChanged(scope, () => { self.persistConfigWithGridState(self.config) }) + gridApi.core.on.columnVisibilityChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.colMovable.on.columnPositionChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.core.on.sortChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.core.on.filterChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.grouping.on.aggregationChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.grouping.on.groupingChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.treeBase.on.rowCollapsed(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.treeBase.on.rowExpanded(scope, () => { + self.persistConfigWithGridState(self.config); + }); + gridApi.colResizable.on.columnSizeChanged(scope, () => { + self.persistConfigWithGridState(self.config); + }); // pagination doesn't follow usual life-cycle in ui-grid v4.0.4 // gridApi.pagination.on.paginationChanged(scope, () => { self.persistConfigWithGridState(self.config) }) // TBD: do we need to propagate row selection? // gridApi.selection.on.rowSelectionChanged(scope, () => { self.persistConfigWithGridState(self.config) }) // gridApi.selection.on.rowSelectionChangedBatch(scope, () => { self.persistConfigWithGridState(self.config) }) - } - gridOptions.onRegisterApi = onRegisterApiCallback + }; + gridOptions.onRegisterApi = onRegisterApiCallback; } else { // don't need to update gridOptions.data since it's synchronized by paragraph execution - const gridOptions = this.getGridOptions() - this.setDynamicGridOptions(gridOptions, config) - this.refreshGrid() + const gridOptions = this.getGridOptions(); + this.setDynamicGridOptions(gridOptions, config); + this.refreshGrid(); } - const columnDefs = this.getGridOptions().columnDefs - updateColumnTypeState(tableData.columns, config, columnDefs) + const columnDefs = this.getGridOptions().columnDefs; + updateColumnTypeState(tableData.columns, config, columnDefs); // SHOULD restore grid state after columnDefs are updated - this.restoreGridState(config.tableGridState) + this.restoreGridState(config.tableGridState); } restoreGridState(gridState) { - if (!gridState) { return } + if (!gridState) { + return; + } // should set isRestoring to avoid that changed* events are triggered while restoring - this.isRestoring = true - const gridApi = this.getGridApi() + this.isRestoring = true; + const gridApi = this.getGridApi(); // restore grid state when gridApi is available if (!gridApi) { - setTimeout(() => this.restoreGridState(gridState), 100) + setTimeout(() => this.restoreGridState(gridState), 100); } else { - gridApi.saveState.restore(this.getScope(), gridState) - this.isRestoring = false + gridApi.saveState.restore(this.getScope(), gridState); + this.isRestoring = false; } } - destroy () { + destroy() { } - getTransformation () { - return this.passthrough + getTransformation() { + return this.passthrough; } getScope() { - const scope = this.targetEl.scope() - return scope + const scope = this.targetEl.scope(); + return scope; } getGridOptions() { - const scope = this.getScope() - const gridElemId = this.getGridElemId() - return scope[gridElemId] + const scope = this.getScope(); + const gridElemId = this.getGridElemId(); + return scope[gridElemId]; } getGridApi() { - const scope = this.targetEl.scope() - const gridApiId = this.getGridApiId() - return scope[gridApiId] + const scope = this.targetEl.scope(); + const gridApiId = this.getGridApiId(); + return scope[gridApiId]; } persistConfigImmediatelyWithGridState(config) { - this.persistConfigWithGridState(config) + this.persistConfigWithGridState(config); } persistConfigWithGridState(config) { - if (this.isRestoring) { return } + if (this.isRestoring) { + return; + } - const gridApi = this.getGridApi() - config.tableGridState = gridApi.saveState.save() - this.emitConfig(config) + const gridApi = this.getGridApi(); + config.tableGridState = gridApi.saveState.save(); + this.emitConfig(config); } persistConfig(config) { - this.emitConfig(config) + this.emitConfig(config); } - getSetting (chart) { - const self = this // for closure in scope - const configObj = self.config + getSetting(chart) { + const self = this; // for closure in scope + const configObj = self.config; // emit config if it's updated in `render` if (configObj.initialized) { - configObj.initialized = false - this.persistConfig(configObj) // should persist w/o state + configObj.initialized = false; + this.persistConfig(configObj); // should persist w/o state } else if (configObj.tableColumnTypeState && configObj.tableColumnTypeState.updated) { - configObj.tableColumnTypeState.updated = false - this.persistConfig(configObj) // should persist w/o state + configObj.tableColumnTypeState.updated = false; + this.persistConfig(configObj); // should persist w/o state } return { @@ -393,27 +421,27 @@ export default class TableVisualization extends Visualization { isTextareaWidget: isTextareaWidget, isBtnGroupWidget: isBtnGroupWidget, tableOptionValueChanged: () => { - self.persistConfigWithGridState(configObj) + self.persistConfigWithGridState(configObj); }, saveTableOption: () => { - self.persistConfigWithGridState(configObj) + self.persistConfigWithGridState(configObj); }, resetTableOption: () => { - resetTableOptionConfig(configObj) - initializeTableConfig(configObj, TABLE_OPTION_SPECS) - self.persistConfigWithGridState(configObj) + resetTableOptionConfig(configObj); + initializeTableConfig(configObj, TABLE_OPTION_SPECS); + self.persistConfigWithGridState(configObj); }, tableWidgetOnKeyDown: (event, optSpec) => { - const code = event.keyCode || event.which + const code = event.keyCode || event.which; if (code === 13 && isInputWidget(optSpec)) { - self.persistConfigWithGridState(configObj) + self.persistConfigWithGridState(configObj); } else if (code === 13 && event.shiftKey && isTextareaWidget(optSpec)) { - self.persistConfigWithGridState(configObj) + self.persistConfigWithGridState(configObj); } - event.stopPropagation() /** avoid to conflict with paragraph shortcuts */ - } - } - } + event.stopPropagation(); /** avoid to conflict with paragraph shortcuts */ + }, + }, + }; } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/app/visualization/builtins/visualization-util.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/builtins/visualization-util.js b/zeppelin-web/src/app/visualization/builtins/visualization-util.js index cd9cd48..a82a18e 100644 --- a/zeppelin-web/src/app/visualization/builtins/visualization-util.js +++ b/zeppelin-web/src/app/visualization/builtins/visualization-util.js @@ -18,7 +18,7 @@ export const Widget = { TEXTAREA: 'textarea', OPTION: 'option', BTN_GROUP: 'btn-group', -} +}; export const ValueType = { INT: 'int', @@ -26,7 +26,7 @@ export const ValueType = { BOOLEAN: 'boolean', STRING: 'string', JSON: 'JSON', -} +}; export const TableColumnType = { STRING: 'string', @@ -35,138 +35,170 @@ export const TableColumnType = { DATE: 'date', OBJECT: 'object', NUMBER_STR: 'numberStr', -} +}; -export const DefaultTableColumnType = TableColumnType.STRING +export const DefaultTableColumnType = TableColumnType.STRING; -export function isInputWidget (spec) { return spec.widget === Widget.INPUT } -export function isOptionWidget (spec) { return spec.widget === Widget.OPTION } -export function isCheckboxWidget (spec) { return spec.widget === Widget.CHECKBOX } -export function isTextareaWidget (spec) { return spec.widget === Widget.TEXTAREA } -export function isBtnGroupWidget (spec) { return spec.widget === Widget.BTN_GROUP } +export function isInputWidget(spec) { + return spec.widget === Widget.INPUT; +} +export function isOptionWidget(spec) { + return spec.widget === Widget.OPTION; +} +export function isCheckboxWidget(spec) { + return spec.widget === Widget.CHECKBOX; +} +export function isTextareaWidget(spec) { + return spec.widget === Widget.TEXTAREA; +} +export function isBtnGroupWidget(spec) { + return spec.widget === Widget.BTN_GROUP; +} export function resetTableOptionConfig(config) { - delete config.tableOptionSpecHash - config.tableOptionSpecHash = {} - delete config.tableOptionValue - config.tableOptionValue = {} - delete config.tableColumnTypeState.names - config.tableColumnTypeState.names = {} - config.updated = false - return config + delete config.tableOptionSpecHash; + config.tableOptionSpecHash = {}; + delete config.tableOptionValue; + config.tableOptionValue = {}; + delete config.tableColumnTypeState.names; + config.tableColumnTypeState.names = {}; + config.updated = false; + return config; } export function initializeTableConfig(config, tableOptionSpecs) { - if (typeof config.tableOptionValue === 'undefined') { config.tableOptionValue = {} } - if (typeof config.tableGridState === 'undefined') { config.tableGridState = {} } - if (typeof config.tableColumnTypeState === 'undefined') { config.tableColumnTypeState = {} } + if (typeof config.tableOptionValue === 'undefined') { + config.tableOptionValue = {}; + } + if (typeof config.tableGridState === 'undefined') { + config.tableGridState = {}; + } + if (typeof config.tableColumnTypeState === 'undefined') { + config.tableColumnTypeState = {}; + } // should remove `$$hashKey` using angular.toJson - const newSpecHash = JSON.stringify(JSON.parse(angular.toJson(tableOptionSpecs))) - const previousSpecHash = config.tableOptionSpecHash + const newSpecHash = JSON.stringify(JSON.parse(angular.toJson(tableOptionSpecs))); + const previousSpecHash = config.tableOptionSpecHash; // check whether spec is updated or not if (typeof previousSpecHash === 'undefined' || (previousSpecHash !== newSpecHash)) { - resetTableOptionConfig(config) + resetTableOptionConfig(config); - config.tableOptionSpecHash = newSpecHash - config.initialized = true + config.tableOptionSpecHash = newSpecHash; + config.initialized = true; // reset all persisted option values if spec is updated for (let i = 0; i < tableOptionSpecs.length; i++) { - const option = tableOptionSpecs[i] - config.tableOptionValue[option.name] = option.defaultValue + const option = tableOptionSpecs[i]; + config.tableOptionValue[option.name] = option.defaultValue; } } - return config + return config; } export function parseTableOption(specs, persistedTableOption) { /** copy original params */ - const parsed = JSON.parse(JSON.stringify(persistedTableOption)) + const parsed = JSON.parse(JSON.stringify(persistedTableOption)); for (let i = 0; i < specs.length; i++) { - const s = specs[i] - const name = s.name + const s = specs[i]; + const name = s.name; if (s.valueType === ValueType.INT && typeof parsed[name] !== 'number') { - try { parsed[name] = parseInt(parsed[name]) } catch (error) { parsed[name] = s.defaultValue } + try { + parsed[name] = parseInt(parsed[name]); + } catch (error) { + parsed[name] = s.defaultValue; + } } else if (s.valueType === ValueType.FLOAT && typeof parsed[name] !== 'number') { - try { parsed[name] = parseFloat(parsed[name]) } catch (error) { parsed[name] = s.defaultValue } + try { + parsed[name] = parseFloat(parsed[name]); + } catch (error) { + parsed[name] = s.defaultValue; + } } else if (s.valueType === ValueType.BOOLEAN) { if (parsed[name] === 'false') { - parsed[name] = false + parsed[name] = false; } else if (parsed[name] === 'true') { - parsed[name] = true + parsed[name] = true; } else if (typeof parsed[name] !== 'boolean') { - parsed[name] = s.defaultValue + parsed[name] = s.defaultValue; } } else if (s.valueType === ValueType.JSON) { if (parsed[name] !== null && typeof parsed[name] !== 'object') { - try { parsed[name] = JSON.parse(parsed[name]) } catch (error) { parsed[name] = s.defaultValue } + try { + parsed[name] = JSON.parse(parsed[name]); + } catch (error) { + parsed[name] = s.defaultValue; + } } else if (parsed[name] === null) { - parsed[name] = s.defaultValue + parsed[name] = s.defaultValue; } } } - return parsed + return parsed; } export function isColumnNameUpdated(prevColumnNames, newColumnNames) { - if (typeof prevColumnNames === 'undefined') { return true } + if (typeof prevColumnNames === 'undefined') { + return true; + } - let columnNameUpdated = false + let columnNameUpdated = false; for (let prevColName in prevColumnNames) { if (!newColumnNames[prevColName]) { - return true + return true; } } if (!columnNameUpdated) { for (let newColName in newColumnNames) { if (!prevColumnNames[newColName]) { - return true + return true; } } } - return false + return false; } export function updateColumnTypeState(columns, config, columnDefs) { - const columnTypeState = config.tableColumnTypeState + const columnTypeState = config.tableColumnTypeState; - if (!columnTypeState) { return } + if (!columnTypeState) { + return; + } // compare objects because order might be changed - const prevColumnNames = columnTypeState.names || {} + const prevColumnNames = columnTypeState.names || {}; const newColumnNames = columns.reduce((acc, c) => { - const prevColumnType = prevColumnNames[c.name] + const prevColumnType = prevColumnNames[c.name]; // use previous column type if exists if (prevColumnType) { - acc[c.name] = prevColumnType + acc[c.name] = prevColumnType; } else { - acc[c.name] = DefaultTableColumnType + acc[c.name] = DefaultTableColumnType; } - return acc - }, {}) + return acc; + }, {}); - let columnNameUpdated = isColumnNameUpdated(prevColumnNames, newColumnNames) + let columnNameUpdated = isColumnNameUpdated(prevColumnNames, newColumnNames); if (columnNameUpdated) { - columnTypeState.names = newColumnNames - columnTypeState.updated = true + columnTypeState.names = newColumnNames; + columnTypeState.updated = true; } // update `columnDefs[n].type` for (let i = 0; i < columnDefs.length; i++) { - const colName = columnDefs[i].name - columnDefs[i].type = columnTypeState.names[colName] + const colName = columnDefs[i].name; + columnDefs[i].type = columnTypeState.names[colName]; } } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/app/visualization/visualization.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/app/visualization/visualization.js b/zeppelin-web/src/app/visualization/visualization.js index 6b6e36a..f6475cb 100644 --- a/zeppelin-web/src/app/visualization/visualization.js +++ b/zeppelin-web/src/app/visualization/visualization.js @@ -16,12 +16,12 @@ * Base class for visualization. */ export default class Visualization { - constructor (targetEl, config) { - this.targetEl = targetEl - this.config = config - this._dirty = false - this._active = false - this._emitter = () => {} + constructor(targetEl, config) { + this.targetEl = targetEl; + this.config = config; + this._dirty = false; + this._active = false; + this._emitter = () => {}; } /** @@ -29,33 +29,33 @@ export default class Visualization { * @abstract * @return {Transformation} */ - getTransformation () { + getTransformation() { // override this - throw new TypeError('Visualization.getTransformation() should be overrided') + throw new TypeError('Visualization.getTransformation() should be overrided'); } /** * Method will be invoked when data or configuration changed. * @abstract */ - render (tableData) { + render(tableData) { // override this - throw new TypeError('Visualization.render() should be overrided') + throw new TypeError('Visualization.render() should be overrided'); } /** * Refresh visualization. */ - refresh () { + refresh() { // override this - console.warn('A chart is missing refresh function, it might not work preperly') + console.warn('A chart is missing refresh function, it might not work preperly'); } /** * Method will be invoked when visualization need to be destroyed. * Don't need to destroy this.targetEl. */ - destroy () { + destroy() { // override this } @@ -65,113 +65,117 @@ export default class Visualization { * scope : an object to bind to template scope * } */ - getSetting () { + getSetting() { // override this } /** * Activate. Invoked when visualization is selected. */ - activate () { + activate() { if (!this._active || this._dirty) { - this.refresh() - this._dirty = false + this.refresh(); + this._dirty = false; } - this._active = true + this._active = true; } /** * Deactivate. Invoked when visualization is de selected. */ - deactivate () { - this._active = false + deactivate() { + this._active = false; } /** * Is active. */ - isActive () { - return this._active + isActive() { + return this._active; } /** * When window or paragraph is resized. */ - resize () { + resize() { if (this.isActive()) { - this.refresh() + this.refresh(); } else { - this._dirty = true + this._dirty = true; } } /** * Set new config. */ - setConfig (config) { - this.config = config + setConfig(config) { + this.config = config; if (this.isActive()) { - this.refresh() + this.refresh(); } else { - this._dirty = true + this._dirty = true; } } /** * Emit config. config will sent to server and saved. */ - emitConfig (config) { - this._emitter(config) + emitConfig(config) { + this._emitter(config); } /** * Render setting. */ - renderSetting (targetEl) { - let setting = this.getSetting() + renderSetting(targetEl) { + let setting = this.getSetting(); if (!setting) { - return + return; } // already readered if (this._scope) { - let self = this - this._scope.$apply(function () { + let self = this; + this._scope.$apply(function() { for (let k in setting.scope) { - self._scope[k] = setting.scope[k] + if (setting.scope.hasOwnProperty(k)) { + self._scope[k] = setting.scope[k]; + } } for (let k in self._prevSettingScope) { if (!setting.scope[k]) { - self._scope[k] = setting.scope[k] + self._scope[k] = setting.scope[k]; } } - }) - return + }); + return; } else { - this._prevSettingScope = setting.scope + this._prevSettingScope = setting.scope; } - let scope = this._createNewScope() + let scope = this._createNewScope(); for (let k in setting.scope) { - scope[k] = setting.scope[k] + if (setting.scope.hasOwnProperty(k)) { + scope[k] = setting.scope[k]; + } } - let template = setting.template + let template = setting.template; if (template.split('\n').length === 1 && template.endsWith('.html')) { // template is url - this._templateRequest(template).then(t => + this._templateRequest(template).then((t) => _renderSetting(this, targetEl, t, scope) - ) + ); } else { - _renderSetting(this, targetEl, template, scope) + _renderSetting(this, targetEl, template, scope); } } } -function _renderSetting (instance, targetEl, template, scope) { - instance._targetEl = targetEl - targetEl.html(template) - instance._compile(targetEl.contents())(scope) - instance._scope = scope +function _renderSetting(instance, targetEl, template, scope) { + instance._targetEl = targetEl; + targetEl.html(template); + instance._compile(targetEl.contents())(scope); + instance._scope = scope; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/components/array-ordering/array-ordering.service.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/array-ordering/array-ordering.service.js b/zeppelin-web/src/components/array-ordering/array-ordering.service.js index 6fa1ad9..1f275e6 100644 --- a/zeppelin-web/src/components/array-ordering/array-ordering.service.js +++ b/zeppelin-web/src/components/array-ordering/array-ordering.service.js @@ -12,51 +12,51 @@ * limitations under the License. */ -angular.module('zeppelinWebApp').service('arrayOrderingSrv', ArrayOrderingService) +angular.module('zeppelinWebApp').service('arrayOrderingSrv', ArrayOrderingService); function ArrayOrderingService(TRASH_FOLDER_ID) { - 'ngInject' + 'ngInject'; - let arrayOrderingSrv = this + let arrayOrderingSrv = this; - this.noteListOrdering = function (note) { + this.noteListOrdering = function(note) { if (note.id === TRASH_FOLDER_ID) { - return '\uFFFF' + return '\uFFFF'; } - return arrayOrderingSrv.getNoteName(note) - } + return arrayOrderingSrv.getNoteName(note); + }; - this.getNoteName = function (note) { + this.getNoteName = function(note) { if (note.name === undefined || note.name.trim() === '') { - return 'Note ' + note.id + return 'Note ' + note.id; } else { - return note.name + return note.name; } - } + }; - this.noteComparator = function (v1, v2) { - let note1 = v1.value || v1 - let note2 = v2.value || v2 + this.noteComparator = function(v1, v2) { + let note1 = v1.value || v1; + let note2 = v2.value || v2; if (note1.id === TRASH_FOLDER_ID) { - return 1 + return 1; } if (note2.id === TRASH_FOLDER_ID) { - return -1 + return -1; } if (note1.children === undefined && note2.children !== undefined) { - return 1 + return 1; } if (note1.children !== undefined && note2.children === undefined) { - return -1 + return -1; } - let noteName1 = arrayOrderingSrv.getNoteName(note1) - let noteName2 = arrayOrderingSrv.getNoteName(note2) + let noteName1 = arrayOrderingSrv.getNoteName(note1); + let noteName2 = arrayOrderingSrv.getNoteName(note2); - return noteName1.localeCompare(noteName2) - } + return noteName1.localeCompare(noteName2); + }; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/components/base-url/base-url.service.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/base-url/base-url.service.js b/zeppelin-web/src/components/base-url/base-url.service.js index 6ef55b9..845293c 100644 --- a/zeppelin-web/src/components/base-url/base-url.service.js +++ b/zeppelin-web/src/components/base-url/base-url.service.js @@ -12,39 +12,39 @@ * limitations under the License. */ -angular.module('zeppelinWebApp').service('baseUrlSrv', BaseUrlService) +angular.module('zeppelinWebApp').service('baseUrlSrv', BaseUrlService); function BaseUrlService() { - this.getPort = function () { - let port = Number(location.port) + this.getPort = function() { + let port = Number(location.port); if (!port) { - port = 80 + port = 80; if (location.protocol === 'https:') { - port = 443 + port = 443; } } // Exception for when running locally via grunt if (port === process.env.WEB_PORT) { - port = process.env.SERVER_PORT + port = process.env.SERVER_PORT; } - return port - } + return port; + }; - this.getWebsocketUrl = function () { - let wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:' + this.getWebsocketUrl = function() { + let wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:'; return wsProtocol + '//' + location.hostname + ':' + this.getPort() + - skipTrailingSlash(location.pathname) + '/ws' - } + skipTrailingSlash(location.pathname) + '/ws'; + }; this.getBase = function() { - return location.protocol + '//' + location.hostname + ':' + this.getPort() + location.pathname - } + return location.protocol + '//' + location.hostname + ':' + this.getPort() + location.pathname; + }; - this.getRestApiBase = function () { - return skipTrailingSlash(this.getBase()) + '/api' - } + this.getRestApiBase = function() { + return skipTrailingSlash(this.getBase()) + '/api'; + }; - const skipTrailingSlash = function (path) { - return path.replace(/\/$/, '') - } + const skipTrailingSlash = function(path) { + return path.replace(/\/$/, ''); + }; } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/components/login/login.controller.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/login/login.controller.js b/zeppelin-web/src/components/login/login.controller.js index 9190950..9a42d5f 100644 --- a/zeppelin-web/src/components/login/login.controller.js +++ b/zeppelin-web/src/components/login/login.controller.js @@ -12,73 +12,73 @@ * limitations under the License. */ -angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl) +angular.module('zeppelinWebApp').controller('LoginCtrl', LoginCtrl); -function LoginCtrl ($scope, $rootScope, $http, $httpParamSerializer, baseUrlSrv, $location, $timeout) { - 'ngInject' +function LoginCtrl($scope, $rootScope, $http, $httpParamSerializer, baseUrlSrv, $location, $timeout) { + 'ngInject'; - $scope.SigningIn = false - $scope.loginParams = {} - $scope.login = function () { - $scope.SigningIn = true + $scope.SigningIn = false; + $scope.loginParams = {}; + $scope.login = function() { + $scope.SigningIn = true; $http({ method: 'POST', url: baseUrlSrv.getRestApiBase() + '/login', headers: { - 'Content-Type': 'application/x-www-form-urlencoded' + 'Content-Type': 'application/x-www-form-urlencoded', }, data: $httpParamSerializer({ 'userName': $scope.loginParams.userName, - 'password': $scope.loginParams.password - }) - }).then(function successCallback (response) { - $rootScope.ticket = response.data.body - angular.element('#loginModal').modal('toggle') - $rootScope.$broadcast('loginSuccess', true) - $rootScope.userName = $scope.loginParams.userName - $scope.SigningIn = false + 'password': $scope.loginParams.password, + }), + }).then(function successCallback(response) { + $rootScope.ticket = response.data.body; + angular.element('#loginModal').modal('toggle'); + $rootScope.$broadcast('loginSuccess', true); + $rootScope.userName = $scope.loginParams.userName; + $scope.SigningIn = false; // redirect to the page from where the user originally was if ($location.search() && $location.search()['ref']) { - $timeout(function () { - let redirectLocation = $location.search()['ref'] - $location.$$search = {} - $location.path(redirectLocation) - }, 100) + $timeout(function() { + let redirectLocation = $location.search()['ref']; + $location.$$search = {}; + $location.path(redirectLocation); + }, 100); } - }, function errorCallback (errorResponse) { - $scope.loginParams.errorText = 'The username and password that you entered don\'t match.' - $scope.SigningIn = false - }) - } + }, function errorCallback(errorResponse) { + $scope.loginParams.errorText = 'The username and password that you entered don\'t match.'; + $scope.SigningIn = false; + }); + }; - let initValues = function () { + let initValues = function() { $scope.loginParams = { userName: '', - password: '' - } - } + password: '', + }; + }; // handle session logout message received from WebSocket - $rootScope.$on('session_logout', function (event, data) { + $rootScope.$on('session_logout', function(event, data) { if ($rootScope.userName !== '') { - $rootScope.userName = '' - $rootScope.ticket = undefined + $rootScope.userName = ''; + $rootScope.ticket = undefined; - setTimeout(function () { - $scope.loginParams = {} - $scope.loginParams.errorText = data.info - angular.element('.nav-login-btn').click() - }, 1000) - let locationPath = $location.path() - $location.path('/').search('ref', locationPath) + setTimeout(function() { + $scope.loginParams = {}; + $scope.loginParams.errorText = data.info; + angular.element('.nav-login-btn').click(); + }, 1000); + let locationPath = $location.path(); + $location.path('/').search('ref', locationPath); } - }) + }); /* ** $scope.$on functions below */ - $scope.$on('initLoginValues', function () { - initValues() - }) + $scope.$on('initLoginValues', function() { + initValues(); + }); } http://git-wip-us.apache.org/repos/asf/zeppelin/blob/ed517a20/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js ---------------------------------------------------------------------- diff --git a/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js index e4280e8..58629af 100644 --- a/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js +++ b/zeppelin-web/src/components/navbar/expand-collapse/expand-collapse.directive.js @@ -12,37 +12,37 @@ * limitations under the License. */ -import './expand-collapse.css' +import './expand-collapse.css'; -angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapseDirective) +angular.module('zeppelinWebApp').directive('expandCollapse', expandCollapseDirective); function expandCollapseDirective() { return { restrict: 'EA', - link: function (scope, element, attrs) { - angular.element(element).click(function (event) { + link: function(scope, element, attrs) { + angular.element(element).click(function(event) { if (angular.element(element).next('.expandable:visible').length > 1) { - angular.element(element).next('.expandable:visible').slideUp('slow') - angular.element(element).find('i.fa-folder-open').toggleClass('fa-folder fa-folder-open') + angular.element(element).next('.expandable:visible').slideUp('slow'); + angular.element(element).find('i.fa-folder-open').toggleClass('fa-folder fa-folder-open'); } else { - angular.element(element).next('.expandable').first().slideToggle('200', function () { + angular.element(element).next('.expandable').first().slideToggle('200', function() { // do not toggle trash folder if (angular.element(element).find('.fa-trash-o').length === 0) { - angular.element(element).find('i').first().toggleClass('fa-folder fa-folder-open') + angular.element(element).find('i').first().toggleClass('fa-folder fa-folder-open'); } - }) + }); } - let target = event.target + let target = event.target; // add note if (target.classList !== undefined && target.classList.contains('fa-plus') && target.tagName.toLowerCase() === 'i') { - return + return; } - event.stopPropagation() - }) - } - } + event.stopPropagation(); + }); + }, + }; }