mirror of
https://github.com/apache/zeppelin
synced 2026-05-24 09:38:26 +00:00
Render multiple results
This commit is contained in:
parent
95b6037425
commit
57d6b2f647
20 changed files with 663 additions and 642 deletions
|
|
@ -462,7 +462,7 @@ public class RemoteInterpreterServer
|
|||
combinedResult);
|
||||
}
|
||||
*/
|
||||
return resultMessages;
|
||||
return new InterpreterResult(result.code(), resultMessages);
|
||||
} finally {
|
||||
InterpreterContext.remove();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-17")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class InterpreterCompletion implements org.apache.thrift.TBase<InterpreterCompletion, InterpreterCompletion._Fields>, java.io.Serializable, Cloneable, Comparable<InterpreterCompletion> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InterpreterCompletion");
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-17")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class RemoteApplicationResult implements org.apache.thrift.TBase<RemoteApplicationResult, RemoteApplicationResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteApplicationResult> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteApplicationResult");
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-17")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteInterpreterContext, RemoteInterpreterContext._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterContext> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterContext");
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-17")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class RemoteInterpreterEvent implements org.apache.thrift.TBase<RemoteInterpreterEvent, RemoteInterpreterEvent._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterEvent> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterEvent");
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public enum RemoteInterpreterEventType implements org.apache.thrift.TEnum {
|
|||
return ANGULAR_REGISTRY_PUSH;
|
||||
case 13:
|
||||
return APP_STATUS_UPDATE;
|
||||
case 12:
|
||||
case 14:
|
||||
return META_INFOS;
|
||||
default:
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-17")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteInterpreterResult, RemoteInterpreterResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResult> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResult");
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-14")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class RemoteInterpreterResultMessage implements org.apache.thrift.TBase<RemoteInterpreterResultMessage, RemoteInterpreterResultMessage._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResultMessage> {
|
||||
private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResultMessage");
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-17")
|
||||
@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-18")
|
||||
public class RemoteInterpreterService {
|
||||
|
||||
public interface Iface {
|
||||
|
|
|
|||
|
|
@ -99,83 +99,6 @@
|
|||
|
||||
var angularObjectRegistry = {};
|
||||
|
||||
/**
|
||||
* Built-in visualizations
|
||||
*/
|
||||
$scope.builtInTableDataVisualizationList = [
|
||||
{
|
||||
id: 'table', // paragraph.config.graph.mode
|
||||
name: 'Table', // human readable name. tooltip
|
||||
icon: 'fa fa-table'
|
||||
},
|
||||
{
|
||||
id: 'multiBarChart',
|
||||
name: 'Bar Chart',
|
||||
icon: 'fa fa-bar-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'pieChart',
|
||||
name: 'Pie Chart',
|
||||
icon: 'fa fa-pie-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'stackedAreaChart',
|
||||
name: 'Area Chart',
|
||||
icon: 'fa fa-area-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'lineChart',
|
||||
name: 'Line Chart',
|
||||
icon: 'fa fa-line-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'scatterChart',
|
||||
name: 'Scatter Chart',
|
||||
icon: 'cf cf-scatter-chart'
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* Holds class and actual runtime instance and related infos of built-in visualizations
|
||||
*/
|
||||
var builtInVisualizations = {
|
||||
'table': {
|
||||
class: zeppelin.TableVisualization,
|
||||
instance: undefined // created from setGraphMode()
|
||||
},
|
||||
'multiBarChart': {
|
||||
class: zeppelin.BarchartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'pieChart': {
|
||||
class: zeppelin.PiechartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'stackedAreaChart': {
|
||||
class: zeppelin.AreachartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'lineChart': {
|
||||
class: zeppelin.LinechartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'scatterChart': {
|
||||
class: zeppelin.ScatterchartVisualization,
|
||||
instance: undefined
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TableData instance
|
||||
*/
|
||||
var tableData;
|
||||
|
||||
// available columns in tabledata
|
||||
$scope.tableDataColumns = [];
|
||||
|
||||
// Controller init
|
||||
$scope.init = function(newParagraph, note) {
|
||||
|
|
@ -195,21 +118,6 @@
|
|||
|
||||
initializeDefault();
|
||||
|
||||
if ($scope.getResultType() === 'TABLE') {
|
||||
var TableData = zeppelin.TableData;
|
||||
tableData = new TableData();
|
||||
tableData.loadParagraphResult($scope.paragraph.result);
|
||||
$scope.tableDataColumns = tableData.columns;
|
||||
$scope.tableDataComment = tableData.comment;
|
||||
$scope.setGraphMode($scope.getGraphMode(), false, false);
|
||||
} else if ($scope.getResultType() === 'HTML') {
|
||||
$scope.renderHtml();
|
||||
} else if ($scope.getResultType() === 'ANGULAR') {
|
||||
$scope.renderAngular();
|
||||
} else if ($scope.getResultType() === 'TEXT') {
|
||||
$scope.renderText();
|
||||
}
|
||||
|
||||
getApplicationStates();
|
||||
getSuggestions();
|
||||
|
||||
|
|
@ -220,89 +128,6 @@
|
|||
}
|
||||
};
|
||||
|
||||
$scope.renderHtml = function() {
|
||||
var retryRenderer = function() {
|
||||
var htmlEl = angular.element('#p' + $scope.paragraph.id + '_html');
|
||||
if (htmlEl.length) {
|
||||
try {
|
||||
htmlEl.html($scope.paragraph.result.msg);
|
||||
|
||||
htmlEl.find('pre code').each(function(i, e) {
|
||||
hljs.highlightBlock(e);
|
||||
});
|
||||
/*eslint new-cap: [2, {"capIsNewExceptions": ["MathJax.Hub.Queue"]}]*/
|
||||
MathJax.Hub.Queue(['Typeset', MathJax.Hub, htmlEl[0]]);
|
||||
} catch (err) {
|
||||
console.log('HTML rendering error %o', err);
|
||||
}
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
};
|
||||
|
||||
$scope.renderAngular = function() {
|
||||
var retryRenderer = function() {
|
||||
if (angular.element('#p' + $scope.paragraph.id + '_angular').length) {
|
||||
try {
|
||||
angular.element('#p' + $scope.paragraph.id + '_angular').html($scope.paragraph.result.msg);
|
||||
|
||||
$compile(angular.element('#p' + $scope.paragraph.id + '_angular').contents())(paragraphScope);
|
||||
} catch (err) {
|
||||
console.log('ANGULAR rendering error %o', err);
|
||||
}
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
};
|
||||
|
||||
$scope.renderText = function() {
|
||||
var retryRenderer = function() {
|
||||
|
||||
var textEl = angular.element('#p' + $scope.paragraph.id + '_text');
|
||||
if (textEl.length) {
|
||||
// clear all lines before render
|
||||
$scope.clearTextOutput();
|
||||
|
||||
if ($scope.paragraph.result && $scope.paragraph.result.msg) {
|
||||
$scope.appendTextOutput($scope.paragraph.result.msg);
|
||||
}
|
||||
|
||||
angular.element('#p' + $scope.paragraph.id + '_text').bind('mousewheel', function(e) {
|
||||
$scope.keepScrollDown = false;
|
||||
});
|
||||
$scope.flushStreamingOutput = true;
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
};
|
||||
|
||||
$scope.clearTextOutput = function() {
|
||||
var textEl = angular.element('#p' + $scope.paragraph.id + '_text');
|
||||
if (textEl.length) {
|
||||
textEl.children().remove();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.appendTextOutput = function(msg) {
|
||||
var textEl = angular.element('#p' + $scope.paragraph.id + '_text');
|
||||
if (textEl.length) {
|
||||
var lines = msg.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
textEl.append(angular.element('<div></div>').text(lines[i]));
|
||||
}
|
||||
}
|
||||
if ($scope.keepScrollDown) {
|
||||
var doc = angular.element('#p' + $scope.paragraph.id + '_text');
|
||||
doc[0].scrollTop = doc[0].scrollHeight;
|
||||
}
|
||||
};
|
||||
|
||||
var initializeDefault = function() {
|
||||
var config = $scope.paragraph.config;
|
||||
|
||||
|
|
@ -310,37 +135,6 @@
|
|||
config.colWidth = 12;
|
||||
}
|
||||
|
||||
if (!config.graph) {
|
||||
config.graph = {};
|
||||
}
|
||||
|
||||
if (!config.graph.mode) {
|
||||
config.graph.mode = 'table';
|
||||
}
|
||||
|
||||
if (!config.graph.height) {
|
||||
config.graph.height = 300;
|
||||
}
|
||||
|
||||
if (!config.graph.optionOpen) {
|
||||
config.graph.optionOpen = false;
|
||||
}
|
||||
|
||||
if (!config.graph.keys) {
|
||||
config.graph.keys = [];
|
||||
}
|
||||
|
||||
if (!config.graph.values) {
|
||||
config.graph.values = [];
|
||||
}
|
||||
|
||||
if (!config.graph.groups) {
|
||||
config.graph.groups = [];
|
||||
}
|
||||
|
||||
if (!config.graph.scatter) {
|
||||
config.graph.scatter = {};
|
||||
}
|
||||
|
||||
if (config.enabled === undefined) {
|
||||
config.enabled = true;
|
||||
|
|
@ -1003,271 +797,10 @@
|
|||
return cell;
|
||||
};
|
||||
|
||||
$scope.setGraphMode = function(type, emit, refresh) {
|
||||
if (emit) {
|
||||
setNewMode(type);
|
||||
} else {
|
||||
clearUnknownColsFromGraphOption();
|
||||
// set graph height
|
||||
var height = $scope.paragraph.config.graph.height;
|
||||
var graphContainerEl = angular.element('#p' + $scope.paragraph.id + '_graph');
|
||||
graphContainerEl.height(height);
|
||||
|
||||
if (!type) {
|
||||
type = 'table';
|
||||
}
|
||||
|
||||
var builtInViz = builtInVisualizations[type];
|
||||
if (builtInViz) {
|
||||
// deactive previsouly active visualization
|
||||
for (var t in builtInVisualizations) {
|
||||
var v = builtInVisualizations[t].instance;
|
||||
if (t !== type && v && v.isActive()) {
|
||||
v.deactivate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!builtInViz.instance) { // not instantiated yet
|
||||
// render when targetEl is available
|
||||
var retryRenderer = function() {
|
||||
var targetEl = angular.element('#p' + $scope.paragraph.id + '_' + type);
|
||||
|
||||
if (targetEl.length) {
|
||||
try {
|
||||
// set height
|
||||
targetEl.height(height);
|
||||
|
||||
// instantiate visualization
|
||||
var Visualization = builtInViz.class;
|
||||
builtInViz.instance = new Visualization(targetEl, $scope.paragraph.config.graph);
|
||||
builtInViz.instance.render(tableData);
|
||||
builtInViz.instance.activate();
|
||||
angular.element(window).resize(function() {
|
||||
builtInViz.instance.resize();
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Graph drawing error %o', err);
|
||||
}
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
} else if (refresh) {
|
||||
console.log('Refresh data');
|
||||
// when graph options or data are changed
|
||||
var retryRenderer = function() {
|
||||
var targetEl = angular.element('#p' + $scope.paragraph.id + '_' + type);
|
||||
if (targetEl.length) {
|
||||
targetEl.height(height);
|
||||
builtInViz.instance.setConfig($scope.paragraph.config.graph);
|
||||
builtInViz.instance.render(tableData);
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
} else {
|
||||
var retryRenderer = function() {
|
||||
var targetEl = angular.element('#p' + $scope.paragraph.id + '_' + type);
|
||||
if (targetEl.length) {
|
||||
targetEl.height(height);
|
||||
builtInViz.instance.activate();
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var setNewMode = function(newMode) {
|
||||
var newConfig = angular.copy($scope.paragraph.config);
|
||||
var newParams = angular.copy($scope.paragraph.settings.params);
|
||||
|
||||
// graph options
|
||||
newConfig.graph.mode = newMode;
|
||||
|
||||
// see switchApp()
|
||||
_.set(newConfig, 'helium.activeApp', undefined);
|
||||
|
||||
commitParagraph($scope.paragraph.title, $scope.paragraph.text, newConfig, newParams);
|
||||
};
|
||||
|
||||
var commitParagraph = function(title, text, config, params) {
|
||||
websocketMsgSrv.commitParagraph($scope.paragraph.id, title, text, config, params);
|
||||
};
|
||||
|
||||
$scope.isGraphMode = function(graphName) {
|
||||
var activeAppId = _.get($scope.paragraph.config, 'helium.activeApp');
|
||||
if ($scope.getResultType() === 'TABLE' && $scope.getGraphMode() === graphName && !activeAppId) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onGraphOptionChange = function() {
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeGraphOptionKeys = function(idx) {
|
||||
$scope.paragraph.config.graph.keys.splice(idx, 1);
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeGraphOptionValues = function(idx) {
|
||||
$scope.paragraph.config.graph.values.splice(idx, 1);
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeGraphOptionGroups = function(idx) {
|
||||
$scope.paragraph.config.graph.groups.splice(idx, 1);
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.setGraphOptionValueAggr = function(idx, aggr) {
|
||||
$scope.paragraph.config.graph.values[idx].aggr = aggr;
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionXaxis = function(idx) {
|
||||
$scope.paragraph.config.graph.scatter.xAxis = null;
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionYaxis = function(idx) {
|
||||
$scope.paragraph.config.graph.scatter.yAxis = null;
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionGroup = function(idx) {
|
||||
$scope.paragraph.config.graph.scatter.group = null;
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionSize = function(idx) {
|
||||
$scope.paragraph.config.graph.scatter.size = null;
|
||||
clearUnknownColsFromGraphOption();
|
||||
$scope.setGraphMode($scope.paragraph.config.graph.mode, true, false);
|
||||
};
|
||||
|
||||
/* Clear unknown columns from graph option */
|
||||
var clearUnknownColsFromGraphOption = function() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var removeUnknown = function(list) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
// remove non existing column
|
||||
var found = false;
|
||||
for (var j = 0; j < tableData.columns.length; j++) {
|
||||
var a = list[i];
|
||||
var b = tableData.columns[j];
|
||||
if (a.index === b.index && a.name === b.name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
list.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var removeUnknownFromFields = function(fields) {
|
||||
for (var f in fields) {
|
||||
if (fields[f]) {
|
||||
var found = false;
|
||||
for (var i = 0; i < tableData.columns.length; i++) {
|
||||
var a = fields[f];
|
||||
var b = tableData.columns[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unique($scope.paragraph.config.graph.keys);
|
||||
removeUnknown($scope.paragraph.config.graph.keys);
|
||||
|
||||
removeUnknown($scope.paragraph.config.graph.values);
|
||||
|
||||
unique($scope.paragraph.config.graph.groups);
|
||||
removeUnknown($scope.paragraph.config.graph.groups);
|
||||
|
||||
removeUnknownFromFields($scope.paragraph.config.graph.scatter);
|
||||
};
|
||||
|
||||
/* select default key and value if there're none selected */
|
||||
var selectDefaultColsForGraphOption = function() {
|
||||
if ($scope.paragraph.config.graph.keys.length === 0 && tableData.columns.length > 0) {
|
||||
$scope.paragraph.config.graph.keys.push(tableData.columns[0]);
|
||||
}
|
||||
|
||||
if ($scope.paragraph.config.graph.values.length === 0 && tableData.columns.length > 1) {
|
||||
$scope.paragraph.config.graph.values.push(tableData.columns[1]);
|
||||
}
|
||||
|
||||
if (!$scope.paragraph.config.graph.scatter.xAxis && !$scope.paragraph.config.graph.scatter.yAxis) {
|
||||
if (tableData.columns.length > 1) {
|
||||
$scope.paragraph.config.graph.scatter.xAxis = tableData.columns[0];
|
||||
$scope.paragraph.config.graph.scatter.yAxis = tableData.columns[1];
|
||||
} else if (tableData.columns.length === 1) {
|
||||
$scope.paragraph.config.graph.scatter.xAxis = tableData.columns[0];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.isValidSizeOption = function(options) {
|
||||
var builtInViz = builtInVisualizations.scatterChart;
|
||||
if (builtInViz && builtInViz.instance) {
|
||||
return builtInViz.instance.isValidSizeOption(options);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.resizeParagraph = function(width, height) {
|
||||
$scope.changeColWidth(width);
|
||||
$timeout(function() {
|
||||
autoAdjustEditorHeight($scope.paragraph.id + '_editor');
|
||||
$scope.changeHeight(height);
|
||||
}, 200);
|
||||
};
|
||||
|
||||
$scope.changeHeight = function(height) {
|
||||
var newParams = angular.copy($scope.paragraph.settings.params);
|
||||
var newConfig = angular.copy($scope.paragraph.config);
|
||||
|
||||
newConfig.graph.height = height;
|
||||
|
||||
commitParagraph($scope.paragraph.title, $scope.paragraph.text, newConfig, newParams);
|
||||
};
|
||||
|
||||
/** Utility function */
|
||||
if (typeof String.prototype.startsWith !== 'function') {
|
||||
|
|
@ -1311,33 +844,6 @@
|
|||
$scope.keepScrollDown = false;
|
||||
};
|
||||
|
||||
$scope.exportToDSV = function(delimiter) {
|
||||
var dsv = '';
|
||||
for (var titleIndex in tableData.columns) {
|
||||
dsv += tableData.columns[titleIndex].name + delimiter;
|
||||
}
|
||||
dsv = dsv.substring(0, dsv.length - 1) + '\n';
|
||||
for (var r in tableData.rows) {
|
||||
var row = tableData.rows[r];
|
||||
var dsvRow = '';
|
||||
for (var index in row) {
|
||||
var stringValue = (row[index]).toString();
|
||||
if (stringValue.contains(delimiter)) {
|
||||
dsvRow += '"' + stringValue + '"' + delimiter;
|
||||
} else {
|
||||
dsvRow += row[index] + delimiter;
|
||||
}
|
||||
}
|
||||
dsv += dsvRow.substring(0, dsvRow.length - 1) + '\n';
|
||||
}
|
||||
var extension = '';
|
||||
if (delimiter === '\t') {
|
||||
extension = 'tsv';
|
||||
} else if (delimiter === ',') {
|
||||
extension = 'csv';
|
||||
}
|
||||
saveAsService.saveAs(dsv, 'data', extension);
|
||||
};
|
||||
|
||||
// Helium ---------------------------------------------
|
||||
|
||||
|
|
@ -1648,22 +1154,10 @@
|
|||
!angular.equals(data.paragraph.settings, $scope.paragraph.settings) ||
|
||||
!angular.equals(data.paragraph.config, $scope.paragraph.config))
|
||||
) {
|
||||
|
||||
var oldType = $scope.getResultType();
|
||||
var newType = $scope.getResultType(data.paragraph);
|
||||
var oldGraphMode = $scope.getGraphMode();
|
||||
var newGraphMode = $scope.getGraphMode(data.paragraph);
|
||||
var oldActiveApp = _.get($scope.paragraph.config, 'helium.activeApp');
|
||||
var newActiveApp = _.get(data.paragraph.config, 'helium.activeApp');
|
||||
|
||||
var statusChanged = (data.paragraph.status !== $scope.paragraph.status);
|
||||
|
||||
var resultRefreshed = (data.paragraph.dateFinished !== $scope.paragraph.dateFinished) ||
|
||||
isEmpty(data.paragraph.result) !== isEmpty($scope.paragraph.result) ||
|
||||
data.paragraph.status === 'ERROR' || (data.paragraph.status === 'FINISHED' && statusChanged) ||
|
||||
(!newActiveApp && oldActiveApp !== newActiveApp);
|
||||
|
||||
//console.log("updateParagraph oldData %o, newData %o. type %o -> %o, mode %o -> %o", $scope.paragraph, data, oldType, newType, oldGraphMode, newGraphMode);
|
||||
data.paragraph.status === 'ERROR' || (data.paragraph.status === 'FINISHED' && statusChanged);
|
||||
|
||||
if ($scope.paragraph.text !== data.paragraph.text) {
|
||||
if ($scope.dirtyText) { // check if editor has local update
|
||||
|
|
@ -1680,6 +1174,20 @@
|
|||
}
|
||||
}
|
||||
|
||||
/** broadcast update to result controller **/
|
||||
if (data.paragraph.result) {
|
||||
for (var i in data.paragraph.result.msg) {
|
||||
var newResult = data.paragraph.result.msg[i];
|
||||
var oldResult = $scope.paragraph.result.msg[i];
|
||||
var newConfig = data.paragraph.config.result ? data.paragraph.config.result[i] : {};
|
||||
var oldConfig = $scope.paragraph.config.result ? $scope.paragraph.config.result[i] : {};
|
||||
if (!angular.equals(newResult, oldResult) ||
|
||||
!angular.equals(newConfig, oldConfig)) {
|
||||
$rootScope.$broadcast('updateResult', newResult, newConfig, data.paragraph, parseInt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** push the rest */
|
||||
$scope.paragraph.aborted = data.paragraph.aborted;
|
||||
$scope.paragraph.user = data.paragraph.user;
|
||||
|
|
@ -1705,38 +1213,6 @@
|
|||
$scope.paragraph.config = data.paragraph.config;
|
||||
}
|
||||
|
||||
if (newType === 'TABLE') {
|
||||
if (oldType !== 'TABLE' || resultRefreshed) {
|
||||
var TableData = zeppelin.TableData;
|
||||
tableData = new TableData();
|
||||
tableData.loadParagraphResult($scope.paragraph.result);
|
||||
$scope.tableDataColumns = tableData.columns;
|
||||
$scope.tableDataComment = tableData.comment;
|
||||
clearUnknownColsFromGraphOption();
|
||||
selectDefaultColsForGraphOption();
|
||||
}
|
||||
/** User changed the chart type? */
|
||||
if (oldGraphMode !== newGraphMode) {
|
||||
$scope.setGraphMode(newGraphMode, false, false);
|
||||
} else {
|
||||
$scope.setGraphMode(newGraphMode, false, true);
|
||||
}
|
||||
} else if (newType === 'HTML' && resultRefreshed) {
|
||||
$scope.renderHtml();
|
||||
} else if (newType === 'ANGULAR' && resultRefreshed) {
|
||||
$scope.renderAngular();
|
||||
} else if (newType === 'TEXT' && resultRefreshed) {
|
||||
$scope.renderText();
|
||||
}
|
||||
|
||||
getApplicationStates();
|
||||
getSuggestions();
|
||||
|
||||
if (newActiveApp && newActiveApp !== oldActiveApp) {
|
||||
var app = _.find($scope.apps, {id: newActiveApp});
|
||||
renderApp(app);
|
||||
}
|
||||
|
||||
if (statusChanged || resultRefreshed) {
|
||||
// when last paragraph runs, zeppelin automatically appends new paragraph.
|
||||
// this broadcast will focus to the newly inserted paragraph
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ limitations under the License.
|
|||
<div class="tableDisplay"
|
||||
ng-show="!paragraph.config.tableHide"
|
||||
ng-controller="ResultCtrl"
|
||||
ng-repeat="result in paragraph.result"
|
||||
ng-init="init(result)"
|
||||
ng-include src="'app/notebook/paragraph/result.html'"
|
||||
ng-repeat="result in paragraph.result.msg track by $index"
|
||||
ng-init="init(result, paragraph.config.result[$index], paragraph, $index)"
|
||||
ng-include src="'app/notebook/paragraph/result/result.html'"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,23 +12,22 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
-->
|
||||
|
||||
<div id="{{paragraph.id}}_switch"
|
||||
ng-if="(paragraph.result.type == 'TABLE' || apps.length > 0 || suggestion.available && suggestion.available.length > 0) && !asIframe && !viewOnly"
|
||||
<div id="{{id}}_switch"
|
||||
ng-if="(type == 'TABLE' || apps.length > 0 || suggestion.available && suggestion.available.length > 0) && !asIframe && !viewOnly"
|
||||
class="btn-group"
|
||||
style="margin-bottom: 10px;">
|
||||
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
ng-if="paragraph.result.type == 'TABLE'"
|
||||
ng-if="type == 'TABLE'"
|
||||
ng-repeat="viz in builtInTableDataVisualizationList track by $index"
|
||||
ng-class="{'active' : isGraphMode(viz.id)}"
|
||||
ng-click="setGraphMode(viz.id, true, false)"
|
||||
tooltip="{{viz.name}}" tooltip-placement="bottom"><i ng-class="viz.icon"></i>
|
||||
ng-class="{'active' : viz.id == graphMode}"
|
||||
ng-click="switchViz(viz.id)"><i ng-class="viz.icon"></i>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
ng-if="paragraph.result.type != 'TABLE'"
|
||||
ng-if="type != 'TABLE'"
|
||||
ng-click="switchApp()"
|
||||
ng-class="{'active' : !paragraph.config.helium.activeApp}"
|
||||
ng-class="{'active' : !config.helium.activeApp}"
|
||||
class="btn btn-default btn-sm"><i class="fa fa-terminal"></i>
|
||||
</button>
|
||||
|
||||
|
|
@ -36,7 +35,7 @@ limitations under the License.
|
|||
class="btn btn-default btn-sm"
|
||||
ng-repeat="app in apps"
|
||||
ng-click="switchApp(app.id)"
|
||||
ng-class="{'active' : app.id == paragraph.config.helium.activeApp}"
|
||||
ng-class="{'active' : app.id == config.helium.activeApp}"
|
||||
ng-bind-html="app.pkg.icon">
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -71,7 +70,7 @@ limitations under the License.
|
|||
</div>
|
||||
|
||||
<div class="btn-group"
|
||||
ng-if="paragraph.result.type == 'TABLE' && !asIframe && !viewOnly"
|
||||
ng-if="type == 'TABLE' && !asIframe && !viewOnly"
|
||||
style="margin-bottom: 10px;">
|
||||
<button type="button" class="btn btn-default btn-sm"
|
||||
style="margin-left:10px"
|
||||
|
|
@ -91,9 +90,9 @@ limitations under the License.
|
|||
</div>
|
||||
|
||||
<span
|
||||
ng-if="getResultType()=='TABLE' && !paragraph.config.helium.activeApp && getGraphMode()!='table' && !asIframe && !viewOnly"
|
||||
ng-if="type=='TABLE' && !paragraph.config.helium.activeApp && graphMode!='table' && !asIframe && !viewOnly"
|
||||
style="margin-left:10px; cursor:pointer; display: inline-block; vertical-align:top; position: relative; line-height:30px;">
|
||||
<a class="btnText" ng-click="toggleGraphOption()">
|
||||
settings <span ng-class="paragraph.config.graph.optionOpen ? 'fa fa-caret-up' : 'fa fa-caret-down'"></span>
|
||||
<a class="btnText" ng-click="toggleGraphSetting()">
|
||||
settings <span ng-class="config.graph.optionOpen ? 'fa fa-caret-up' : 'fa fa-caret-down'"></span>
|
||||
</a>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<div id="p{{paragraph.id}}_graph"
|
||||
<div id="p{{id}}_graph"
|
||||
class="graphContainer"
|
||||
ng-class="{'noOverflow': getGraphMode()=='table'}"
|
||||
ng-show="getResultType()=='TABLE'"
|
||||
ng-class="{'noOverflow': graphMode=='table'}"
|
||||
ng-show="type =='TABLE'"
|
||||
>
|
||||
|
||||
<div ng-repeat="viz in builtInTableDataVisualizationList track by $index"
|
||||
id="p{{paragraph.id}}_{{viz.id}}"
|
||||
ng-show="getGraphMode()==viz.id">
|
||||
id="p{{id}}_{{viz.id}}"
|
||||
ng-show="graphMode == viz.id">
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -12,10 +12,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
-->
|
||||
<div>
|
||||
<div ng-if="isGraphMode('lineChart') || isGraphMode('lineWithFocusChart')">
|
||||
<div ng-if="graphMode=='lineChart' || graphMode=='lineWithFocusChart'">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
ng-model="paragraph.config.graph.forceY"
|
||||
ng-model="config.graph.forceY"
|
||||
ng-click="onGraphOptionChange()" />
|
||||
force Y to 0
|
||||
</label>
|
||||
|
|
@ -23,24 +23,9 @@ limitations under the License.
|
|||
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
ng-model="paragraph.config.graph.lineWithFocus"
|
||||
ng-model="config.graph.lineWithFocus"
|
||||
ng-click="onGraphOptionChange()" />
|
||||
show line chart with focus
|
||||
</label>
|
||||
</div>
|
||||
<div ng-if="isGraphMode('map')">
|
||||
<label>Basemap</label>
|
||||
<span class="dropdown">
|
||||
<button type="button" class="btn btn-default btn-sm dropdown-toggle" style="min-width: 0px;" data-toggle="dropdown">
|
||||
<span ng-bind="paragraph.config.graph.map.baseMapType"></span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu" style="min-width: 70px;">
|
||||
<li ng-repeat="opt in baseMapOption">
|
||||
<a ng-click="setMapBaseMap(opt)">{{opt}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -12,10 +12,10 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
-->
|
||||
<div class="option lightBold" style="overflow: visible;"
|
||||
ng-if="getResultType()=='TABLE' && getGraphMode()!='table'
|
||||
&& paragraph.config.graph.optionOpen && !asIframe && !viewOnly">
|
||||
ng-if="type=='TABLE' && graphMode!='table'
|
||||
&& config.graph.optionOpen && !asIframe && !viewOnly">
|
||||
|
||||
<div ng-include src="'app/notebook/paragraph/paragraph-graphOptions.html'"></div>
|
||||
<div ng-include src="'app/notebook/paragraph/result/result-graphOptions.html'"></div>
|
||||
|
||||
All fields:
|
||||
<div class="allFields row">
|
||||
|
|
@ -32,15 +32,15 @@ limitations under the License.
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="getGraphMode()!='scatterChart'">
|
||||
<div class="row" ng-if="graphMode!='scatterChart'">
|
||||
<div class="col-md-4">
|
||||
<span class="columns lightBold">
|
||||
Keys
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.keys"
|
||||
ng-model="config.graph.keys"
|
||||
jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled">
|
||||
<li ng-repeat="item in paragraph.config.graph.keys">
|
||||
<li ng-repeat="item in config.graph.keys">
|
||||
<div class="btn btn-primary btn-xs">
|
||||
{{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionKeys($index)"></span>
|
||||
</div>
|
||||
|
|
@ -52,10 +52,10 @@ limitations under the License.
|
|||
<span class="columns lightBold">
|
||||
Groups
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.groups"
|
||||
ng-model="config.graph.groups"
|
||||
jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled">
|
||||
<li ng-repeat="item in paragraph.config.graph.groups">
|
||||
<li ng-repeat="item in config.graph.groups">
|
||||
<div class="btn btn-success btn-xs">
|
||||
{{item.name}} <span class="fa fa-close" ng-click="removeGraphOptionGroups($index)"></span>
|
||||
</div>
|
||||
|
|
@ -67,10 +67,10 @@ limitations under the License.
|
|||
<span class="columns lightBold">
|
||||
Values
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.values"
|
||||
ng-model="config.graph.values"
|
||||
jqyoui-droppable="{multiple:true, onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled">
|
||||
<li ng-repeat="item in paragraph.config.graph.values">
|
||||
<li ng-repeat="item in config.graph.values">
|
||||
<div class="btn-group">
|
||||
<div class="btn btn-info btn-xs dropdown-toggle"
|
||||
type="button"
|
||||
|
|
@ -93,18 +93,18 @@ limitations under the License.
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" ng-if="getGraphMode()=='scatterChart'">
|
||||
<div class="row" ng-if="graphMode=='scatterChart'">
|
||||
<div class="col-md-3">
|
||||
<span class="columns lightBold">
|
||||
xAxis
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.xAxis"
|
||||
ng-model="config.graph.scatter.xAxis"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.xAxis">
|
||||
<li ng-if="config.graph.scatter.xAxis">
|
||||
<div class="btn btn-primary btn-xs">
|
||||
{{paragraph.config.graph.scatter.xAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionXaxis($index)"></span>
|
||||
{{config.graph.scatter.xAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionXaxis($index)"></span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -114,13 +114,13 @@ limitations under the License.
|
|||
<span class="columns lightBold">
|
||||
yAxis
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.yAxis"
|
||||
ng-model="config.graph.scatter.yAxis"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.yAxis">
|
||||
<li ng-if="config.graph.scatter.yAxis">
|
||||
<div class="btn btn-success btn-xs">
|
||||
{{paragraph.config.graph.scatter.yAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionYaxis($index)"></span>
|
||||
{{config.graph.scatter.yAxis.name}} <span class="fa fa-close" ng-click="removeScatterOptionYaxis($index)"></span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -130,13 +130,13 @@ limitations under the License.
|
|||
<span class="columns lightBold">
|
||||
group
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.group"
|
||||
ng-model="config.graph.scatter.group"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.group">
|
||||
<li ng-if="config.graph.scatter.group">
|
||||
<div class="btn btn-info btn-xs">
|
||||
{{paragraph.config.graph.scatter.group.name}} <span class="fa fa-close" ng-click="removeScatterOptionGroup($index)"></span>
|
||||
{{config.graph.scatter.group.name}} <span class="fa fa-close" ng-click="removeScatterOptionGroup($index)"></span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -152,13 +152,13 @@ limitations under the License.
|
|||
<li>Zeppelin consider values as discrete when the values contain string value or the number of distinct values are bigger than 5% of total number of values.</li>
|
||||
<li>Size field button turns to grey when the option you chose is not valid.</li>"></a>
|
||||
<ul data-drop="true"
|
||||
ng-model="paragraph.config.graph.scatter.size"
|
||||
ng-model="config.graph.scatter.size"
|
||||
jqyoui-droppable="{onDrop:'onGraphOptionChange()'}"
|
||||
class="list-unstyled"
|
||||
style="height:36px">
|
||||
<li ng-if="paragraph.config.graph.scatter.size">
|
||||
<div class="btn btn-xs" style="color:white" ng-class="{'btn-warning': isValidSizeOption(paragraph.config.graph.scatter, paragraph.result.rows)}">
|
||||
{{paragraph.config.graph.scatter.size.name}} <span class="fa fa-close" ng-click="removeScatterOptionSize($index)"></span>
|
||||
<li ng-if="config.graph.scatter.size">
|
||||
<div class="btn btn-xs" style="color:white" ng-class="{'btn-warning': isValidSizeOption(config.graph.scatter)}">
|
||||
{{config.graph.scatter.size.name}} <span class="fa fa-close" ng-click="removeScatterOptionSize($index)"></span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -12,27 +12,27 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
-->
|
||||
<div
|
||||
id="p{{paragraph.id}}_resize"
|
||||
ng-if="!paragraph.config.helium.activeApp"
|
||||
id="p{{id}}_resize"
|
||||
ng-if="!config.helium.activeApp"
|
||||
style="padding-bottom: 5px;"
|
||||
resize='{"allowresize": "{{!asIframe && !viewOnly}}", "graphType": "{{getResultType()}}"}'
|
||||
resize='{"allowresize": "{{!asIframe && !viewOnly}}", "graphType": "{{type}}"}'
|
||||
resizable on-resize="resizeParagraph(width, height);">
|
||||
<div ng-include src="'app/notebook/paragraph/paragraph-graph.html'"></div>
|
||||
<div ng-include src="'app/notebook/paragraph/result/result-graph.html'"></div>
|
||||
|
||||
<div id="{{paragraph.id}}_comment"
|
||||
<div id="{{id}}_comment"
|
||||
class="text"
|
||||
ng-if="getResultType()=='TABLE' && tableDataComment"
|
||||
ng-if="type == 'TABLE' && tableDataComment"
|
||||
ng-bind-html="tableDataComment">
|
||||
</div>
|
||||
|
||||
<div id="{{paragraph.id}}_text"
|
||||
ng-if="getResultType() == 'TEXT'">
|
||||
<div id="p{{id}}_text"
|
||||
ng-if="type == 'TEXT'">
|
||||
<div class="fa fa-level-down scroll-paragraph-down"
|
||||
ng-show="showScrollDownIcon()"
|
||||
ng-click="scrollParagraphDown()"
|
||||
tooltip="Follow Output"></div>
|
||||
<div id="p{{paragraph.id}}_text"
|
||||
style="max-height: {{paragraph.config.graph.height}}px; overflow: auto"
|
||||
<div id="p{{id}}_text"
|
||||
style="max-height: {{config.graph.height}}px; overflow: auto"
|
||||
class="text"></div>
|
||||
<div class="fa fa-chevron-up scroll-paragraph-up"
|
||||
ng-show="showScrollUpIcon()"
|
||||
|
|
@ -40,21 +40,21 @@ limitations under the License.
|
|||
tooltip="Scroll Top"></div>
|
||||
</div>
|
||||
|
||||
<div id="p{{paragraph.id}}_html"
|
||||
<div id="p{{id}}_html"
|
||||
class="resultContained"
|
||||
ng-if="getResultType() == 'HTML'">
|
||||
ng-if="type == 'HTML'">
|
||||
</div>
|
||||
|
||||
<div id="p{{paragraph.id}}_angular"
|
||||
<div id="p{{id}}_angular"
|
||||
class="resultContained"
|
||||
ng-if="getResultType() == 'ANGULAR'">
|
||||
ng-if="type == 'ANGULAR'">
|
||||
</div>
|
||||
|
||||
<img id="{{paragraph.id}}_img"
|
||||
ng-if="getResultType() == 'IMG'"
|
||||
ng-src="{{getBase64ImageSrc(paragraph.result.msg)}}" />
|
||||
<img id="{{id}}_img"
|
||||
ng-if="type == 'IMG'"
|
||||
ng-src="{{getBase64ImageSrc(result.data)}}" />
|
||||
|
||||
<div id="{{paragraph.id}}_error"
|
||||
<div id="{{id}}_error"
|
||||
class="error text"
|
||||
ng-if="paragraph.status == 'ERROR'"
|
||||
ng-bind="paragraph.errorMessage">
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
|
||||
angular.module('zeppelinWebApp').controller('ResultCtrl', ResultCtrl);
|
||||
|
|
@ -37,13 +38,577 @@
|
|||
$timeout, $compile, $http, $q, websocketMsgSrv,
|
||||
baseUrlSrv, ngToast, saveAsService) {
|
||||
|
||||
$scope.parentNote = null;
|
||||
$scope.paragraph = null;
|
||||
$scope.originalText = '';
|
||||
$scope.editor = null;
|
||||
/**
|
||||
* Built-in visualizations
|
||||
*/
|
||||
$scope.builtInTableDataVisualizationList = [
|
||||
{
|
||||
id: 'table', // paragraph.config.graph.mode
|
||||
name: 'Table', // human readable name. tooltip
|
||||
icon: 'fa fa-table'
|
||||
},
|
||||
{
|
||||
id: 'multiBarChart',
|
||||
name: 'Bar Chart',
|
||||
icon: 'fa fa-bar-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'pieChart',
|
||||
name: 'Pie Chart',
|
||||
icon: 'fa fa-pie-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'stackedAreaChart',
|
||||
name: 'Area Chart',
|
||||
icon: 'fa fa-area-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'lineChart',
|
||||
name: 'Line Chart',
|
||||
icon: 'fa fa-line-chart',
|
||||
transformation: 'pivot'
|
||||
},
|
||||
{
|
||||
id: 'scatterChart',
|
||||
name: 'Scatter Chart',
|
||||
icon: 'cf cf-scatter-chart'
|
||||
}
|
||||
];
|
||||
|
||||
$scope.init = function(results, configs) {
|
||||
console.log('result controller init %o %o', results, configs);
|
||||
/**
|
||||
* Holds class and actual runtime instance and related infos of built-in visualizations
|
||||
*/
|
||||
var builtInVisualizations = {
|
||||
'table': {
|
||||
class: zeppelin.TableVisualization,
|
||||
instance: undefined // created from setGraphMode()
|
||||
},
|
||||
'multiBarChart': {
|
||||
class: zeppelin.BarchartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'pieChart': {
|
||||
class: zeppelin.PiechartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'stackedAreaChart': {
|
||||
class: zeppelin.AreachartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'lineChart': {
|
||||
class: zeppelin.LinechartVisualization,
|
||||
instance: undefined
|
||||
},
|
||||
'scatterChart': {
|
||||
class: zeppelin.ScatterchartVisualization,
|
||||
instance: undefined
|
||||
}
|
||||
};
|
||||
|
||||
// type
|
||||
$scope.type;
|
||||
|
||||
// Data of the result
|
||||
var data;
|
||||
|
||||
// config
|
||||
$scope.config;
|
||||
|
||||
// resultId = paragraph.id + index
|
||||
$scope.id;
|
||||
|
||||
// referece to paragraph
|
||||
var paragraph;
|
||||
|
||||
// index of the result
|
||||
var resultIndex
|
||||
|
||||
// TableData instance
|
||||
var tableData;
|
||||
|
||||
// available columns in tabledata
|
||||
$scope.tableDataColumns = [];
|
||||
|
||||
// graphMode
|
||||
$scope.graphMode;
|
||||
|
||||
$scope.init = function(result, config, paragraph, index) {
|
||||
console.log('result controller init %o %o %o', result, config, index);
|
||||
updateData(result, config, paragraph, index);
|
||||
renderResult($scope.type);
|
||||
};
|
||||
|
||||
$scope.$on('updateResult', function(event, result, newConfig, paragraphRef, index) {
|
||||
if (paragraph.id !== paragraphRef.id || index !== resultIndex) {
|
||||
return;
|
||||
}
|
||||
console.log('updateResult %o %o %o %o', result, newConfig, paragraphRef, index);
|
||||
|
||||
/*
|
||||
var oldType = $scope.getResultType();
|
||||
var newType = $scope.getResultType(data.paragraph);
|
||||
var oldGraphMode = $scope.getGraphMode();
|
||||
var newGraphMode = $scope.getGraphMode(data.paragraph);
|
||||
var oldActiveApp = _.get($scope.paragraph.config, 'helium.activeApp');
|
||||
var newActiveApp = _.get(data.paragraph.config, 'helium.activeApp');
|
||||
*/
|
||||
|
||||
updateData(result, newConfig, paragraph, resultIndex);
|
||||
renderResult($scope.type, true);
|
||||
});
|
||||
|
||||
var updateData = function(result, config, paragraphRef, index) {
|
||||
data = result.data;
|
||||
paragraph = paragraphRef;
|
||||
resultIndex = parseInt(index);
|
||||
|
||||
$scope.id = paragraph.id + "_" + index;
|
||||
$scope.type = result.type;
|
||||
config = config ? config : {};
|
||||
|
||||
// initialize default config values
|
||||
if (!config.graph) {
|
||||
config.graph = {};
|
||||
}
|
||||
|
||||
if (!config.graph.mode) {
|
||||
config.graph.mode = 'table';
|
||||
}
|
||||
|
||||
if (!config.graph.height) {
|
||||
config.graph.height = 300;
|
||||
}
|
||||
|
||||
if (!config.graph.optionOpen) {
|
||||
config.graph.optionOpen = false;
|
||||
}
|
||||
|
||||
if (!config.graph.keys) {
|
||||
config.graph.keys = [];
|
||||
}
|
||||
|
||||
if (!config.graph.values) {
|
||||
config.graph.values = [];
|
||||
}
|
||||
|
||||
if (!config.graph.groups) {
|
||||
config.graph.groups = [];
|
||||
}
|
||||
|
||||
if (!config.graph.scatter) {
|
||||
config.graph.scatter = {};
|
||||
}
|
||||
|
||||
$scope.graphMode = config.graph.mode;
|
||||
$scope.config = angular.copy(config);
|
||||
|
||||
if ($scope.type === 'TABLE') {
|
||||
var TableData = zeppelin.TableData;
|
||||
tableData = new TableData();
|
||||
tableData.loadParagraphResult({type: $scope.type, msg: data});
|
||||
$scope.tableDataColumns = tableData.columns;
|
||||
$scope.tableDataComment = tableData.comment;
|
||||
}
|
||||
};
|
||||
|
||||
var renderResult = function(type, refresh) {
|
||||
if (type === 'TABLE') {
|
||||
$scope.renderGraph($scope.graphMode, refresh);
|
||||
} else if (type === 'HTML') {
|
||||
renderHtml();
|
||||
} else if (type === 'ANGULAR') {
|
||||
renderAngular();
|
||||
} else if (type === 'TEXT') {
|
||||
renderText();
|
||||
}
|
||||
|
||||
/*
|
||||
getApplicationStates();
|
||||
getSuggestions();
|
||||
|
||||
if (newActiveApp && newActiveApp !== oldActiveApp) {
|
||||
var app = _.find($scope.apps, {id: newActiveApp});
|
||||
renderApp(app);
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
var renderHtml = function() {
|
||||
var retryRenderer = function() {
|
||||
var htmlEl = angular.element('#p' + $scope.id + '_html');
|
||||
if (htmlEl.length) {
|
||||
try {
|
||||
htmlEl.html(data);
|
||||
|
||||
htmlEl.find('pre code').each(function(i, e) {
|
||||
hljs.highlightBlock(e);
|
||||
});
|
||||
/*eslint new-cap: [2, {"capIsNewExceptions": ["MathJax.Hub.Queue"]}]*/
|
||||
MathJax.Hub.Queue(['Typeset', MathJax.Hub, htmlEl[0]]);
|
||||
} catch (err) {
|
||||
console.log('HTML rendering error %o', err);
|
||||
}
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
};
|
||||
|
||||
var renderAngular = function() {
|
||||
var retryRenderer = function() {
|
||||
if (angular.element('#p' + $scope.id + '_angular').length) {
|
||||
try {
|
||||
angular.element('#p' + $scope.id + '_angular').html(data);
|
||||
|
||||
$compile(angular.element('#p' + $scope.id + '_angular').contents())(paragraphScope);
|
||||
} catch (err) {
|
||||
console.log('ANGULAR rendering error %o', err);
|
||||
}
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
};
|
||||
|
||||
var renderText = function() {
|
||||
var retryRenderer = function() {
|
||||
var textEl = angular.element('#p' + $scope.id + '_text');
|
||||
if (textEl.length) {
|
||||
// clear all lines before render
|
||||
clearTextOutput();
|
||||
|
||||
if (data) {
|
||||
appendTextOutput(data);
|
||||
}
|
||||
|
||||
angular.element('#p' + $scope.id + '_text').bind('mousewheel', function(e) {
|
||||
$scope.keepScrollDown = false;
|
||||
});
|
||||
$scope.flushStreamingOutput = true;
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
};
|
||||
|
||||
var clearTextOutput = function() {
|
||||
var textEl = angular.element('#p' + $scope.id + '_text');
|
||||
if (textEl.length) {
|
||||
textEl.children().remove();
|
||||
}
|
||||
};
|
||||
|
||||
var appendTextOutput = function(msg) {
|
||||
var textEl = angular.element('#p' + $scope.id + '_text');
|
||||
if (textEl.length) {
|
||||
var lines = msg.split('\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
textEl.append(angular.element('<div></div>').text(lines[i]));
|
||||
}
|
||||
}
|
||||
if ($scope.keepScrollDown) {
|
||||
var doc = angular.element('#p' + $scope.id + '_text');
|
||||
doc[0].scrollTop = doc[0].scrollHeight;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.renderGraph = function(type, refresh) {
|
||||
clearUnknownColsFromGraphOption();
|
||||
// set graph height
|
||||
var height = $scope.config.graph.height;
|
||||
var graphContainerEl = angular.element('#p' + $scope.id + '_graph');
|
||||
graphContainerEl.height(height);
|
||||
|
||||
if (!type) {
|
||||
type = 'table';
|
||||
}
|
||||
|
||||
var builtInViz = builtInVisualizations[type];
|
||||
if (builtInViz) {
|
||||
// deactive previsouly active visualization
|
||||
for (var t in builtInVisualizations) {
|
||||
var v = builtInVisualizations[t].instance;
|
||||
if (t !== type && v && v.isActive()) {
|
||||
v.deactivate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!builtInViz.instance) { // not instantiated yet
|
||||
// render when targetEl is available
|
||||
var retryRenderer = function() {
|
||||
var targetEl = angular.element('#p' + $scope.id + '_' + type);
|
||||
|
||||
if (targetEl.length) {
|
||||
try {
|
||||
// set height
|
||||
targetEl.height(height);
|
||||
|
||||
// instantiate visualization
|
||||
var Visualization = builtInViz.class;
|
||||
builtInViz.instance = new Visualization(targetEl, $scope.config.graph);
|
||||
builtInViz.instance.render(tableData);
|
||||
builtInViz.instance.activate();
|
||||
angular.element(window).resize(function() {
|
||||
builtInViz.instance.resize();
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Graph drawing error %o', err);
|
||||
}
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
} else if (refresh) {
|
||||
console.log('Refresh data %o', tableData);
|
||||
// when graph options or data are changed
|
||||
var retryRenderer = function() {
|
||||
var targetEl = angular.element('#p' + $scope.id + '_' + type);
|
||||
if (targetEl.length) {
|
||||
targetEl.height(height);
|
||||
builtInViz.instance.setConfig($scope.config.graph);
|
||||
builtInViz.instance.render(tableData);
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
} else {
|
||||
var retryRenderer = function() {
|
||||
var targetEl = angular.element('#p' + $scope.id + '_' + type);
|
||||
if (targetEl.length) {
|
||||
targetEl.height(height);
|
||||
builtInViz.instance.activate();
|
||||
} else {
|
||||
$timeout(retryRenderer, 10);
|
||||
}
|
||||
};
|
||||
$timeout(retryRenderer);
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.switchViz = function(newMode) {
|
||||
var newConfig = angular.copy($scope.config);
|
||||
var newParams = angular.copy(paragraph.settings.params);
|
||||
|
||||
// graph options
|
||||
newConfig.graph.mode = newMode;
|
||||
|
||||
// see switchApp()
|
||||
_.set(newConfig, 'helium.activeApp', undefined);
|
||||
|
||||
commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams);
|
||||
};
|
||||
|
||||
var commitParagraphResult = function(title, text, config, params) {
|
||||
var newParagraphConfig = angular.copy(paragraph.config);
|
||||
newParagraphConfig.result = newParagraphConfig.result || [];
|
||||
newParagraphConfig.result[resultIndex] = config;
|
||||
websocketMsgSrv.commitParagraph(paragraph.id, title, text, newParagraphConfig, params);
|
||||
};
|
||||
|
||||
$scope.toggleGraphSetting = function() {
|
||||
var newConfig = angular.copy($scope.config);
|
||||
if (newConfig.graph.optionOpen) {
|
||||
newConfig.graph.optionOpen = false;
|
||||
} else {
|
||||
newConfig.graph.optionOpen = true;
|
||||
}
|
||||
var newParams = angular.copy(paragraph.settings.params);
|
||||
|
||||
commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams);
|
||||
};
|
||||
|
||||
var commitConfigChange = function(config) {
|
||||
clearUnknownColsFromGraphOption();
|
||||
var newConfig = angular.copy(config);
|
||||
var newParams = angular.copy(paragraph.settings.params);
|
||||
|
||||
commitParagraphResult(paragraph.title, paragraph.text, newConfig, newParams);
|
||||
};
|
||||
|
||||
$scope.onGraphOptionChange = function() {
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeGraphOptionKeys = function(idx) {
|
||||
$scope.config.graph.keys.splice(idx, 1);
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeGraphOptionValues = function(idx) {
|
||||
$scope.config.graph.values.splice(idx, 1);
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeGraphOptionGroups = function(idx) {
|
||||
$scope.config.graph.groups.splice(idx, 1);
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.setGraphOptionValueAggr = function(idx, aggr) {
|
||||
$scope.config.graph.values[idx].aggr = aggr;
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionXaxis = function(idx) {
|
||||
$scope.config.graph.scatter.xAxis = null;
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionYaxis = function(idx) {
|
||||
$scope.config.graph.scatter.yAxis = null;
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionGroup = function(idx) {
|
||||
$scope.config.graph.scatter.group = null;
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
$scope.removeScatterOptionSize = function(idx) {
|
||||
$scope.config.graph.scatter.size = null;
|
||||
commitConfigChange($scope.config);
|
||||
};
|
||||
|
||||
var clearUnknownColsFromGraphOption = function() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var removeUnknown = function(list) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
// remove non existing column
|
||||
var found = false;
|
||||
for (var j = 0; j < tableData.columns.length; j++) {
|
||||
var a = list[i];
|
||||
var b = tableData.columns[j];
|
||||
if (a.index === b.index && a.name === b.name) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
list.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var removeUnknownFromFields = function(fields) {
|
||||
for (var f in fields) {
|
||||
if (fields[f]) {
|
||||
var found = false;
|
||||
for (var i = 0; i < tableData.columns.length; i++) {
|
||||
var a = fields[f];
|
||||
var b = tableData.columns[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unique($scope.paragraph.config.graph.keys);
|
||||
removeUnknown($scope.paragraph.config.graph.keys);
|
||||
|
||||
removeUnknown($scope.paragraph.config.graph.values);
|
||||
|
||||
unique($scope.paragraph.config.graph.groups);
|
||||
removeUnknown($scope.paragraph.config.graph.groups);
|
||||
|
||||
removeUnknownFromFields($scope.paragraph.config.graph.scatter);
|
||||
};
|
||||
|
||||
/* select default key and value if there're none selected */
|
||||
var selectDefaultColsForGraphOption = function() {
|
||||
if ($scope.paragraph.config.graph.keys.length === 0 && tableData.columns.length > 0) {
|
||||
$scope.paragraph.config.graph.keys.push(tableData.columns[0]);
|
||||
}
|
||||
|
||||
if ($scope.paragraph.config.graph.values.length === 0 && tableData.columns.length > 1) {
|
||||
$scope.paragraph.config.graph.values.push(tableData.columns[1]);
|
||||
}
|
||||
|
||||
if (!$scope.paragraph.config.graph.scatter.xAxis && !$scope.paragraph.config.graph.scatter.yAxis) {
|
||||
if (tableData.columns.length > 1) {
|
||||
$scope.paragraph.config.graph.scatter.xAxis = tableData.columns[0];
|
||||
$scope.paragraph.config.graph.scatter.yAxis = tableData.columns[1];
|
||||
} else if (tableData.columns.length === 1) {
|
||||
$scope.paragraph.config.graph.scatter.xAxis = tableData.columns[0];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.isValidSizeOption = function(options) {
|
||||
var builtInViz = builtInVisualizations.scatterChart;
|
||||
if (builtInViz && builtInViz.instance) {
|
||||
return builtInViz.instance.isValidSizeOption(options);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.resizeParagraph = function(width, height) {
|
||||
$scope.changeColWidth(width);
|
||||
$timeout(function() {
|
||||
autoAdjustEditorHeight($scope.paragraph.id + '_editor');
|
||||
$scope.changeHeight(height);
|
||||
}, 200);
|
||||
};
|
||||
|
||||
$scope.changeHeight = function(height) {
|
||||
var newParams = angular.copy($scope.paragraph.settings.params);
|
||||
var newConfig = angular.copy($scope.paragraph.config);
|
||||
|
||||
newConfig.graph.height = height;
|
||||
|
||||
commitParagraph($scope.paragraph.title, $scope.paragraph.text, newConfig, newParams);
|
||||
};
|
||||
|
||||
$scope.exportToDSV = function(delimiter) {
|
||||
var dsv = '';
|
||||
for (var titleIndex in tableData.columns) {
|
||||
dsv += tableData.columns[titleIndex].name + delimiter;
|
||||
}
|
||||
dsv = dsv.substring(0, dsv.length - 1) + '\n';
|
||||
for (var r in tableData.rows) {
|
||||
var row = tableData.rows[r];
|
||||
var dsvRow = '';
|
||||
for (var index in row) {
|
||||
var stringValue = (row[index]).toString();
|
||||
if (stringValue.contains(delimiter)) {
|
||||
dsvRow += '"' + stringValue + '"' + delimiter;
|
||||
} else {
|
||||
dsvRow += row[index] + delimiter;
|
||||
}
|
||||
}
|
||||
dsv += dsvRow.substring(0, dsvRow.length - 1) + '\n';
|
||||
}
|
||||
var extension = '';
|
||||
if (delimiter === '\t') {
|
||||
extension = 'tsv';
|
||||
} else if (delimiter === ',') {
|
||||
extension = 'csv';
|
||||
}
|
||||
saveAsService.saveAs(dsv, 'data', extension);
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ limitations under the License.
|
|||
<script src="app/credential/credential.controller.js"></script>
|
||||
<script src="app/configuration/configuration.controller.js"></script>
|
||||
<script src="app/notebook/paragraph/paragraph.controller.js"></script>
|
||||
<script src="app/notebook/paragraph/result/result.controller.js"></script>
|
||||
<script src="app/search/result-list.controller.js"></script>
|
||||
<script src="app/notebookRepos/notebookRepos.controller.js"></script>
|
||||
<script src="components/arrayOrderingSrv/arrayOrdering.service.js"></script>
|
||||
|
|
|
|||
|
|
@ -31,14 +31,11 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.zeppelin.interpreter.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.apache.zeppelin.conf.ZeppelinConfiguration;
|
||||
import org.apache.zeppelin.display.AngularObject;
|
||||
import org.apache.zeppelin.display.AngularObjectRegistry;
|
||||
import org.apache.zeppelin.display.Input;
|
||||
import org.apache.zeppelin.interpreter.*;
|
||||
import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
|
||||
import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
|
||||
import org.apache.zeppelin.notebook.repo.NotebookRepo;
|
||||
|
|
|
|||
|
|
@ -338,8 +338,7 @@ public class Paragraph extends Job implements Serializable, Cloneable {
|
|||
context.out.flush();
|
||||
List<InterpreterResultMessage> resultMessages = context.out.toInterpreterResultMessage();
|
||||
resultMessages.addAll(ret.message());
|
||||
|
||||
return resultMessages;
|
||||
return new InterpreterResult(ret.code(), resultMessages);
|
||||
} finally {
|
||||
InterpreterContext.remove();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue