diff --git a/zeppelin-distribution/src/bin_license/LICENSE b/zeppelin-distribution/src/bin_license/LICENSE index 09f98adf793..e18cbef176b 100644 --- a/zeppelin-distribution/src/bin_license/LICENSE +++ b/zeppelin-distribution/src/bin_license/LICENSE @@ -132,6 +132,10 @@ The text of each license is also included at licenses/LICENSE-[project]-[version (The MIT License) lodash v3.9.3 (https://lodash.com/) - https://github.com/lodash/lodash/blob/3.9.3/LICENSE.txt (The MIT License) angular-filter v0.5.4 (https://github.com/a8m/angular-filter) - https://github.com/a8m/angular-filter/blob/v0.5.4/license.md (The MIT License) ngToast v1.5.5 (http://tamerayd.in/ngToast/) - http://tameraydin.mit-license.org/ + (The MIT License) Handsontable v0.24.2 (https://github.com/handsontable/handsontable) - https://github.com/handsontable/handsontable/blob/master/LICENSE + (The MIT License) Zeroclipboard v2.2.0 (https://github.com/zeroclipboard/zeroclipboard) - https://github.com/zeroclipboard/zeroclipboard/blob/v2.2.0/LICENSE + (The MIT License) Moment v2.9.0 (https://github.com/moment/moment) - https://github.com/moment/moment/blob/2.9.0/LICENSE + (The MIT License) Pikaday v1.3.2 (https://github.com/dbushell/Pikaday) - https://github.com/dbushell/Pikaday/blob/1.3.2/LICENSE (The MIT License) slf4j v1.7.10 (org.slf4j:slf4j-api:jar:1.7.10 - http://www.slf4j.org) - http://www.slf4j.org/license.html (The MIT License) slf4j-log4j12 v1.7.10 (org.slf4j:slf4j-log4j12:jar:1.7.10 - http://www.slf4j.org) - http://www.slf4j.org/license.html (The MIT License) bcprov-jdk15on v1.51 (org.bouncycastle:bcprov-jdk15on:jar:1.51 - http://www.bouncycastle.org/java.html) - http://www.bouncycastle.org/licence.html diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java index eb09539be5e..1eadd0ecef9 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java @@ -167,9 +167,8 @@ public void testSqlSpark() throws Exception { WebElement paragraph1Result = driver.findElement(By.xpath( getParagraphXPath(1) + "//div[@class=\"tableDisplay\"]")); collector.checkThat("Paragraph from SparkParagraphIT of testSqlSpark result: ", - paragraph1Result.getText().toString(), CoreMatchers.equalTo("age job marital education balance\n" + - "30 unemployed married primary 1,787") - ); + paragraph1Result.getText().toString(), CoreMatchers.equalTo("age\njob\nmarital\neducation\nbalance\n30" + + " unemployed married primary 1,787\nage\njob\nmarital\neducation\nbalance")); } catch (Exception e) { handleException("Exception in SparkParagraphIT while testSqlSpark", e); } diff --git a/zeppelin-web/.jshintrc b/zeppelin-web/.jshintrc index d15bbb95e58..bdcd213761e 100644 --- a/zeppelin-web/.jshintrc +++ b/zeppelin-web/.jshintrc @@ -31,6 +31,7 @@ "nv": false, "ace": false, "d3": false, - "BootstrapDialog": false + "BootstrapDialog": false, + "Handsontable": false } } diff --git a/zeppelin-web/bower.json b/zeppelin-web/bower.json index b8773036f23..1e19060b7d1 100644 --- a/zeppelin-web/bower.json +++ b/zeppelin-web/bower.json @@ -30,9 +30,7 @@ "ngtoast": "~2.0.0", "ng-focus-if": "~1.0.2", "bootstrap3-dialog": "bootstrap-dialog#~1.34.7", - "floatThead": "~1.3.2", - "datatables.net-bs": "~1.10.11", - "datatables.net-buttons-bs": "~1.1.2" + "handsontable": "~0.24.2" }, "devDependencies": { "angular-mocks": "1.5.0" diff --git a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js index 21dd27985fc..c3feefff4e5 100644 --- a/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js +++ b/zeppelin-web/src/app/notebook/paragraph/paragraph.controller.js @@ -1218,110 +1218,42 @@ angular.module('zeppelinWebApp') }; var setTable = function(type, data, refresh) { - var getTableContentFormat = function(d) { - if (isNaN(d)) { - if (d.length>'%html'.length && '%html ' === d.substring(0, '%html '.length)) { - return 'html'; - } else { - return ''; - } - } else { - return ''; - } - }; - - var formatTableContent = function(d) { - if (isNaN(d)) { - var f = getTableContentFormat(d); - if (f !== '') { - return d.substring(f.length+2); - } else { - return d; - } - } else { - var dStr = d.toString(); - var splitted = dStr.split('.'); - var formatted = splitted[0].replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); - if (splitted.length>1) { - formatted+= '.'+splitted[1]; - } - return formatted; - } - }; - - var renderTable = function() { - var html = ''; - html += '
| '+$scope.paragraph.result.columnNames[titleIndex].name+' | '; - } - html += '
|---|
| '+formatTableContent(v)+' | '; + var height = $scope.paragraph.config.graph.height; + angular.element('#p' + $scope.paragraph.id + '_table').css('height', height); + var resultRows = $scope.paragraph.result.rows; + var columnNames = _.pluck($scope.paragraph.result.columnNames, 'name'); + var container = document.getElementById('p' + $scope.paragraph.id + '_table'); + + var handsontable = new Handsontable(container, { + data: resultRows, + colHeaders: columnNames, + rowHeaders: false, + stretchH: 'all', + sortIndicator: true, + columnSorting: true, + contextMenu: false, + manualColumnResize: true, + manualRowResize: true, + editor: false, + fillHandle: false, + disableVisualSelection: true, + cells: function (row, col, prop) { + var cellProperties = {}; + cellProperties.renderer = function(instance, td, row, col, prop, value, cellProperties) { + Handsontable.NumericCell.renderer.apply(this, arguments); + if (!isNaN(value)) { + cellProperties.type = 'numeric'; + cellProperties.format = '0,0'; + cellProperties.editor = false; + td.style.textAlign = 'left'; + } else if (value.length > '%html'.length && '%html ' === value.substring(0, '%html '.length)) { + td.innerHTML = value.substring('%html'.length); + } + }; + return cellProperties; } - html += '